Расширение: бренд

Внимание! Мы рекомендуем вам прочитать разделы Архитектура, Класс ElementItem, Класс ElementCollection для полного понимания архитектуры проекта.

Добавить настраиваемое поле

В этом разделе мы рассмотрим все необходимые шаги, которые необходимо выполнить, чтобы добавить настраиваемое поле «my_field» в модель бренда и отобразить его в шаблоне с использованием класса BrandItem.

Шаг 1. Создайте собственный плагин

Вам необходимо создать собственный плагин, в который мы добавим весь собственный код в ваш проект. Если этот плагин уже был создан, вам следует перейти к шагу 2.

Bы можете найти больше информации о плагинах в документации OctoberCMS.

Например, мы будем использовать настраиваемый плагин с именем Lovata.BaseCode.

Файл: plugins/lovata/basecode/Plugin.php

                            
                        
    <?php namespace Lovata\BaseCode;

    use System\Classes\PluginBase;
    
    class Plugin extends PluginBase
    {
        public function boot()
        {
            //...
        }
    }
Шаг 2: Создайте поле в базе данных

1. Создайте файл миграции, чтобы добавить настраиваемое поле в базу данных.

Вы можете найти дополнительную информацию о миграции в документации OctoberCMS.

Файл: plugins/lovata/basecode/updates/update_table_brands_1.php

                            
                        
    <?php namespace Lovata\BaseCode\Updates;

    use Schema;
    use Illuminate\Database\Schema\Blueprint;
    use October\Rain\Database\Updates\Migration;
    
    /**
     * Class UpdateTableBrands1
     * @package Lovata\BaseCode\Updates
     */
    class UpdateTableBrands1 extends Migration
    {
        const TABLE_NAME = 'lovata_shopaholic_brands';
    
        public function up()
        {
            if (!Schema::hasTable(self::TABLE_NAME) || Schema::hasColumn(self::TABLE_NAME, 'my_field')) {
                return;
            }
    
            Schema::table(self::TABLE_NAME, function (Blueprint ">$obTable)
            {
                $obTable->boolean('my_field')->default(0);
            });
        }
    
        public function down()
        {
            if (!Schema::hasTable(self::TABLE_NAME) || !Schema::hasColumn(self::TABLE_NAME, 'my_field')) {
                return;
            }
    
            Schema::table(self::TABLE_NAME, function (Blueprint $obTable)
            {
                $obTable->dropColumn(['my_field']);
            });
        }
    }

2. Создайте файл version.yaml и добавьте в него файл миграции.

Вы можете найти больше информации о файле версии в документации OctoberCMS.

Файл: plugins/lovata/basecode/updates/version.yaml

                            
                        
    1.0.0:
    - 'Initialize plugin.'
    - update_table_brands_1.php

3. Запустите команду php artisan october: up.

Шаг 3. Добавьте поле в бэкэнде

1. Создайте класс событий, чтобы добавить настраиваемое поле в бэкэнд-форму.

Вы можете найти дополнительную информацию о расширении плагинов в документации OctoberCMS.

Файл: plugins/lovata/basecode/classes/event/brand/ExtendBrandFieldsHandler.php

                            
                        
    <?php namespace Lovata\BaseCode\Classes\Event\Brand;

    use Lovata\Toolbox\Classes\Event\AbstractBackendFieldHandler;
    
    use Lovata\Shopaholic\Models\Brand;
    use Lovata\Shopaholic\Controllers\Brands;
    
    /**
     * Class ExtendBrandFieldsHandler
     * @package Lovata\BaseCode\Classes\Event\Brand
     */
    class ExtendBrandFieldsHandler extends AbstractBackendFieldHandler
    {
        /**
         * Extend field
         * @param \Backend\Widgets\Form $obWidget
         */
        protected function extendFields($obWidget)
        {
            $arAdditionFields = [
                'my_field' => [
                    'label'   => 'My field',
                    'tab'     => 'lovata.toolbox::lang.tab.settings',
                    'type'    => 'checkbox',
                ],
            ];
    
            $obWidget->addTabFields($arAdditionFields);
        }
    
        /**
         * Get model class name
         * @return string
         */
        protected function getModelClass() : string
        {
            return Brand::class;
        }
    
        /**
         * Get controller class name
         * @return string
         */
        protected function getControllerClass() : string
        {
            return Brands::class;
        }
    }

2. Добавьте прослушиватель событий в файл Plugin.php.

Файл: plugins/lovata/basecode/Plugin.php

                            
                        
    <?php namespace Lovata\BaseCode;

    use Event;
    use System\Classes\PluginBase;
    use Lovata\BaseCode\Classes\Event\Brand\ExtendBrandFieldsHandler;
    
    //...
    
    public function boot()
    {
        Event::subscribe(ExtendBrandFieldsHandler::class);
    }
Шаг 4. Добавьте поле в кеш

1. Создайте класс событий для расширения модели бренда.

Вы можете найти дополнительную информацию о расширении плагинов в документации OctoberCMS.

Файл: plugins/lovata/basecode/classes/event/brand/ExtendBrandModel.php

                            
                        
    <?php namespace Lovata\BaseCode\Classes\Event\Brand;

    use Lovata\Shopaholic\Models\Brand;
    
    /**
     * Class ExtendBrandModel
     * @package Lovata\BaseCode\Classes\Event\Brand
     */
    class ExtendBrandModel
    {
        public function subscribe()
        {
            Brand::extend(function ($obBrand) {
                /** @var Brand $obBrand */
                $obBrand->fillable[] = 'my_field';
    
                $obBrand->addCachedField(['my_field']);
            });
        }
    }

2. Добавьте прослушиватель событий в файл Plugin.php.

Файл: plugins/lovata/basecode/Plugin.php

                            
                        
    <?php namespace Lovata\BaseCode;

    use Event;
    use System\Classes\PluginBase;
    use Lovata\BaseCode\Classes\Event\Brand\ExtendBrandFieldsHandler;
    
    //...
    
    public function boot()
    {
        Event::subscribe(ExtendBrandFieldsHandler::class);
    }
Шаг 4. Добавьте поле в кеш

1. Создайте класс событий для расширения модели бренда.

Вы можете найти дополнительную информацию о расширении плагинов в документации OctoberCMS.

Файл: plugins/lovata/basecode/classes/event/brand/ExtendBrandModel.php

                            
                        
    <?php namespace Lovata\BaseCode;

    use Event;
    use System\Classes\PluginBase;
    use Lovata\BaseCode\Classes\Event\Brand\ExtendBrandFieldsHandler;
    use Lovata\BaseCode\Classes\Event\Brand\ExtendBrandModel;
    
    //...
    
    public function boot()
    {
        Event::subscribe(ExtendBrandFieldsHandler::class);
        Event::subscribe(ExtendBrandModel::class);
    }

3. Очистить кеш с помощью команды php artisan cache: clear.

Шаг 5: Вывод поля
                            
                        
    use Lovata\Shopaholic\Classes\Item\BrandItem;

    //Get item object with ID = 1
    $obBrandItem = BrandItem::make(1);
    if ($obBrandItem->my_field) {
        echo 'My field == true';
    } else {
      echo 'My field == false';
    }

Добавить собственный фильтр

В этом разделе мы рассмотрим все необходимые шаги, которые необходимо выполнить, чтобы добавить собственный фильтр по полю «my_field» в класс BrandCollection. В разделе вы можете найти информацию о добавлении в модель настраиваемого поля «my_field».

Шаг 1. Добавьте собственный метод в коллекцию

1. Создайте класс событий для расширения класса BrandCollection.

Файл: plugins/lovata/basecode/classes/event/brand/ExtendBrandCollection.php

                            
                        
    <?php namespace Lovata\BaseCode\Classes\Event\Brand;

    use Lovata\Shopaholic\Models\Brand;
    use Lovata\Shopaholic\Classes\Collection\BrandCollection;
    
    /**
     * Class ExtendBrandCollection
     * @package Lovata\BaseCode\Classes\Event\Brand
     */
    class ExtendBrandCollection
    {
        public function subscribe()
        {
            BrandCollection::extend(function ($obBrandList) {
                $this->addCustomMethod($obBrandList);
            });
        }
    
        /**
         * Add myCustomMethod method
         * @param BrandCollection $obBrandList
         */
        protected function addCustomMethod($obBrandList)
        {
            $obBrandList->addDynamicMethod('myCustomMethod', function () use ($obBrandList) {
    
                $arResultIDList = (array) Brand::where('my_field', true)->lists('id');
    
                return $obBrandList->intersect($arResultIDList);
            });
        }
    }

2. Добавьте прослушиватель событий в файл Plugin.php.

Файл: plugins/lovata/basecode/Plugin.php

                            
                        
    <?php namespace Lovata\BaseCode;

    use Event;
    
    //...
    use Lovata\BaseCode\Classes\Event\Brand\ExtendBrandCollection;
    //...
    
    public function boot()
    {
        //...
        Event::subscribe(ExtendBrandCollection::class);
    }
Шаг 2. Получите объект коллекции с настраиваемым фильтром
                            
                        
    use Lovata\Shopaholic\Classes\Collection\BrandCollection;

    $obBrandList = BrandCollection::make()->myCustomMethod();

Добавить собственный фильтр с кешированием

Шаг 1. Создайте собственный магазин

1. Создать класс магазина.

Файл: plugins/lovata/basecode/classes/store/brand/GetCustomList.php

                            
                        
    <?php namespace Lovata\BaseCode\Classes\Store\Brand;

    use Lovata\Shopaholic\Models\Brand;
    use Lovata\Toolbox\Classes\Store\AbstractStoreWithoutParam;
    
    /**
     * Class GetCustomList
     * @package Lovata\BaseCode\Classes\Store\Brand
     */
    class GetCustomList extends AbstractStoreWithoutParam
    {
        protected static $instance;
    
        /**
         * Get ID list from database
         * @return array
         */
        protected function getIDListFromDB() : array
        {
            $arElementIDList = (array) Brand::where('my_field', true)->lists('id');
    
            return $arElementIDList;
        }
    }

Файл: plugins/lovata/basecode/classes/store/BrandListStore.php

                            
                        
    <?php namespace Lovata\BaseCode\Classes\Store;

    use Lovata\Toolbox\Classes\Store\AbstractListStore;
    
    use Lovata\BaseCode\Classes\Store\Brand\GetCustomList;
    
    /**
     * Class BrandListStore
     * @package Lovata\BaseCode\Classes\Store
     * @property GetCustomList $my_custom
     */
    class BrandListStore extends AbstractListStore
    {
        protected static $instance;
    
        /**
         * Метод инициализации магазина
         */
        protected function init()
        {
            $this->addToStoreList('my_custom', GetCustomList::class);
        }
    }
Шаг 2. Добавление очистки кеша

1. Измените событие, которое мы добавили в раздел «Добавить настраиваемое поле» на шаге «Шаг 4: Добавить поле в кеш».

Файл: plugins/lovata/basecode/classes/event/brand/ExtendBrandModel.php

                            
                        
    <?php namespace Lovata\BaseCode\Classes\Event\Brand;

    use Lovata\Toolbox\Classes\Event\ModelHandler;
    
    use Lovata\Shopaholic\Models\Brand;
    use Lovata\Shopaholic\Classes\Item\BrandItem;
    use Lovata\BaseCode\Classes\Store\BrandListStore;
    
    /**
     * Class ExtendBrandModel
     * @package Lovata\BaseCode\Classes\Event\Brand
     */
    class ExtendBrandModel extends ModelHandler
    {
        /** @var Brand */
         protected $obElement;
    
         /**
          * @param $obEvent
          */
         public function subscribe($obEvent)
         {
            parent::subscribe($obEvent);
    
            Brand::extend(function ($obBrand) {
                /** @var Brand $obBrand */
                $obBrand->fillable[] = 'my_field';
    
                $obBrand->addCachedField(['my_field']);
            });
        }
    
        /**
         * Обработчик событий после сохранения
         */
        protected function afterSave()
        {
            $this->checkFieldChanges('my_field', BrandListStore::instance()->my_custom);
        }
    
        /**
         * После удаления обработчика события
         */
        protected function afterDelete()
        {
            if ($this->obElement->my_field) {
                BrandListStore::instance()->my_custom->clear();
            }
        }
    
        /**
         * Получить класс модели
         * @return string
         */
        protected function getModelClass()
        {
            return Brand::class;
        }
    
        /**
         * Получить класс элементов
         * @return string
         */
        protected function getItemClass()
        {
            return BrandItem::class;
        }
    }
Шаг 3. Добавьте собственный метод в коллекцию

1. Создайте класс событий для расширения класса BrandCollection.

Файл: plugins/lovata/basecode/classes/event/brand/ExtendBrandCollection.php

                            
                        
    <?php namespace Lovata\BaseCode\Classes\Event\Brand;

    use Lovata\BaseCode\Classes\Store\BrandListStore;
    use Lovata\Shopaholic\Classes\Collection\BrandCollection;
    
    /**
     * Class ExtendBrandCollection
     * @package Lovata\BaseCode\Classes\Event\Brand
     */
    class ExtendBrandCollection
    {
        public function subscribe()
        {
            BrandCollection::extend(function ($obBrandList) {
                $this->addCustomMethod($obBrandList);
            });
        }
    
        /**
         * Добавить метод myCustomMethod
         * @param BrandCollection $obBrandList
         */
        protected function addCustomMethod($obBrandList)
        {
            $obBrandList->addDynamicMethod('myCustomMethod', function () use ($obBrandList) {
    
                $arResultIDList = BrandListStore::instance()->my_custom->get();
    
                return $obBrandList->intersect($arResultIDList);
            });
        }
    }

2. Добавьте прослушиватель событий в файл Plugin.php.

Файл: plugins/lovata/basecode/Plugin.php

                            
                        
    <?php namespace Lovata\BaseCode;

    use Event;
    
    //...
    use Lovata\BaseCode\Classes\Event\Brand\ExtendBrandCollection;
    //...
    
    public function boot()
    {
        //...
        Event::subscribe(ExtendBrandCollection::class);
    }
Шаг 4. Получите объект коллекции с настраиваемым фильтром
                            
                        
    use Lovata\Shopaholic\Classes\Collection\BrandCollection;

    $obBrandList = BrandCollection::make()->myCustomMethod();