Last active
November 14, 2019 13:46
-
-
Save timkelty/93de4332e535bd65d09daece358e3332 to your computer and use it in GitHub Desktop.
Craft CMS: Adding behaviors by section, enforcing interfaces + traits
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace modules\appmodule\behaviors; | |
| use Craft; | |
| use craft\base\Element; | |
| use craft\base\ElementInterface; | |
| use craft\db\Table; | |
| use craft\elements\db\ElementQuery; | |
| use craft\elements\db\EntryQuery; | |
| use craft\elements\Entry; | |
| use craft\elements\User; | |
| use craft\helpers\StringHelper; | |
| use craft\helpers\UrlHelper; | |
| use Tightenco\Collect\Support\Collection; | |
| use verbb\supertable\elements\db\SuperTableBlockQuery; | |
| use yii\base\Behavior; | |
| use yii\helpers\Inflector; | |
| class Gear extends Behavior implements ReviewableInterface | |
| { | |
| use ReviewableTrait; | |
| public function getReviews(): EntryQuery | |
| { | |
| return Entry::find() | |
| ->section('reviews') | |
| ->relatedTo([ | |
| 'targetElement' => $this->owner, | |
| 'field' => 'product', | |
| ]); | |
| } | |
| public function getReviewSubmissionUrl(): string | |
| { | |
| return UrlHelper::siteUrl('gear/new-review', ['product' => $this->owner->id]); | |
| } | |
| public function getReviewsUrl(): string | |
| { | |
| return UrlHelper::siteUrl(implode('/', [$this->owner->uri, 'reviews'])); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace modules\appmodule\behaviors; | |
| use Craft; | |
| use craft\elements\db\EntryQuery; | |
| interface ReviewableInterface | |
| { | |
| public function getReviews(): EntryQuery; | |
| public function getReviewCount(): int; | |
| public function getReviewAverage(): float; | |
| public function getReviewSubmissionUrl(): string; | |
| public function getReviewsUrl(): string; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace modules\appmodule\behaviors; | |
| use Craft; | |
| use Tightenco\Collect\Support\Collection; | |
| use yii\base\Behavior; | |
| trait ReviewableTrait | |
| { | |
| public function getReviewCount(): int | |
| { | |
| return $this->owner->getReviews()->count(); | |
| } | |
| public function getReviewAverage(): float | |
| { | |
| return round(Collection::make($this->owner->getReviews()->all())->map(function ($item) { | |
| return intval($item->reviewRating); | |
| })->avg(), 1); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace modules\appmodule\behaviors; | |
| use Craft; | |
| use craft\base\Element; | |
| use craft\base\ElementInterface; | |
| use craft\db\Table; | |
| use craft\elements\db\EntryQuery; | |
| use craft\elements\Entry; | |
| use craft\elements\User; | |
| use Tightenco\Collect\Support\Collection; | |
| use yii\base\Behavior; | |
| class Trip extends Behavior implements ReviewableInterface | |
| { | |
| use ReviewableTrait; | |
| public function getReviewSubmissionUrl(): string | |
| { | |
| return UrlHelper::siteUrl('paddle/trips/new'); | |
| } | |
| public function getReviewsUrl(): string | |
| { | |
| return UrlHelper::siteUrl(implode('/', [$this->owner->uri, 'reviews'])); | |
| } | |
| public function getReviews(): EntryQuery | |
| { | |
| return Entry::find() | |
| ->section('tripReviews') | |
| ->relatedTo([ | |
| 'targetElement' => $this->owner, | |
| 'field' => 'trip', | |
| ]); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace modules\appmodule; | |
| use Craft; | |
| use craft\elements\Entry; | |
| use craft\events\DefineBehaviorsEvent; | |
| use craft\events\ModelEvent; | |
| use Tightenco\Collect\Support\Collection; | |
| use yii\base\Event; | |
| class Module extends \yii\base\Module | |
| { | |
| const SECTION_BEHAVIORS = [ | |
| 'products' => [ | |
| \modules\appmodule\behaviors\Gear::class, | |
| ], | |
| 'trips' => [ | |
| \modules\appmodule\behaviors\Trip::class | |
| ], | |
| ]; | |
| public function init() | |
| { | |
| parent::init(); | |
| // Yii requires an alias be set for controllerNamespace | |
| Craft::setAlias('@modules/appmodule', $this->getBasePath()); | |
| $this->controllerNamespace = Craft::$app->getRequest()->getIsConsoleRequest() | |
| ? 'modules\appmodule\console\controllers' | |
| : 'modules\appmodule\controllers'; | |
| $this->setComponents([ | |
| 'inflector' => \yii\helpers\Inflector::class, | |
| 'string' => \craft\helpers\StringHelper::class, | |
| ]); | |
| Event::on( | |
| Entry::class, | |
| Entry::EVENT_DEFINE_BEHAVIORS, | |
| function (DefineBehaviorsEvent $event) { | |
| // Avoid exceptions for unpopulated entry…not 💯why this happens in CP | |
| // https://craftcms.stackexchange.com/questions/32992/conditionally-attach-behaviors-to-craft-elements-entry-by-section | |
| if (!$event->sender->id) { | |
| return; | |
| } | |
| $event->behaviors = Collection::make(self::SECTION_BEHAVIORS) | |
| ->filter(function ($behaviors, $sectionHandle) use ($event) { | |
| return $event->sender->section->handle === $sectionHandle; | |
| }) | |
| ->prepend($event->behaviors) | |
| ->flatten() | |
| ->all(); | |
| } | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment