Product.php 9.64 KB
<?php
    
    namespace artbox\catalog\catalog\models;
    
    use artbox\catalog\filter\models\Option;
    use artbox\core\behaviors\GalleryBehavior;
    use artbox\core\models\Image;
    use artbox\core\models\Language;
    use artbox\core\models\traits\AliasableTrait;
    use yii\behaviors\TimestampBehavior;
    use yii\db\ActiveQuery;
    use yii\db\ActiveRecord;
    use yii\helpers\Json;
    use yii2tech\ar\linkmany\LinkManyBehavior;
    use yii2tech\ar\variation\VariationBehavior;
    
    /**
     * This is the model class for table "product".
     *
     * @property int           $id
     * @property int           $brand_id
     * @property string        $video
     * @property int           $mask
     * @property bool          $status
     * @property int           $sort
     * @property int           $created_at
     * @property int           $updated_at
     * @property int           $image_id
     * @property string        $gallery
     * @property Brand         $brand
     * @property ProductLang[] $productLangs
     * @property Product[]     $recommends
     * @property Product[]     $products
     * @property Category[]    $categories
     * @property Sale[]        $sales
     * @method saveImages( $post )
     * from VariationBehavior
     * @method ActiveQuery  hasDefaultVariationRelation();
     */
    class Product extends ActiveRecord
    {
        use AliasableTrait;
        
        public $isTop;
        
        public $isNew;
        
        public $isSale;
        
        /**
         * @inheritdoc
         */
        public static function tableName()
        {
            return 'product';
        }
        
        public function beforeSave($insert)
        {
            $this->mask = 0;
            
            if ($this->isTop === '1') {
                $this->mask += 1;
            }
            if ($this->isNew === '1') {
                $this->mask += 2;
            }
            if ($this->isSale === '1') {
                $this->mask += 4;
            }
            
            return parent::beforeSave($insert);
        }
        
        public function afterFind()
        {
            parent::afterFind();
            
            $mask = (int) $this->mask;
            
            if (( $mask & 1 ) === 1) {
                $this->isTop = true;
            } else {
                $this->isTop = false;
            }
            
            if (( $mask & 2 ) === 2) {
                $this->isNew = true;
            } else {
                $this->isNew = false;
            }
            
            if (( $mask & 4 ) === 4) {
                $this->isSale = true;
            } else {
                $this->isSale = false;
            }
        }
        
        public function behaviors()
        {
            return [
                'translations'         => [
                    'class'                             => VariationBehavior::className(),
                    'variationsRelation'                => 'languages',
                    'defaultVariationRelation'          => 'language',
                    'variationOptionReferenceAttribute' => 'language_id',
                    'optionModelClass'                  => Language::className(),
                    'defaultVariationOptionReference'   => function () {
                        return Language::getCurrent()->id;
                    },
                    'optionQueryFilter'                 => function (ActiveQuery $query) {
                        $query->where(
                            [
                                'status' => true,
                            ]
                        );
                    },
                    'variationAttributeDefaultValueMap' => [
                        'title' => 'name',
                    ],
                ],
                'timestamp'            => [
                    'class' => TimestampBehavior::class,
                ],
                'linkCategoryBehavior' => [
                    'class'                      => LinkManyBehavior::class,
                    'relation'                   => 'categories',
                    'relationReferenceAttribute' => 'categoryIds',
                ],
                'linkOptionBehavior'   => [
                    'class'                      => LinkManyBehavior::class,
                    'relation'                   => 'options',
                    'relationReferenceAttribute' => 'optionIds',
                ],
                'gallery'              => [
                    'class' => GalleryBehavior::class,
                ],
            ];
        }
        
        /**
         * @inheritdoc
         */
        public function rules()
        {
            return [
                [
                    [
                        'categoryIds',
                        'optionIds',
                    ],
                    'safe',
                ],
                [
                    [
                        'brand_id',
                        'mask',
                        'sort',
                        'created_at',
                        'updated_at',
                        'image_id',
                    ],
                    'default',
                    'value' => null,
                ],
                [
                    [
                        'brand_id',
                        'mask',
                        'sort',
                        'created_at',
                        'updated_at',
                        'image_id',
                    ],
                    'integer',
                ],
                [
                    [ 'video' ],
                    'string',
                ],
                [
                    [
                        'status',
                        'isTop',
                        'isNew',
                        'isSale',
                    ],
                    'boolean',
                ],
                [
                    [ 'gallery' ],
                    'string',
                    'max' => 255,
                ],
                [
                    [ 'brand_id' ],
                    'exist',
                    'skipOnError'     => true,
                    'targetClass'     => Brand::class,
                    'targetAttribute' => [ 'brand_id' => 'id' ],
                ],
            ];
        }
        
        /**
         * @inheritdoc
         */
        public function attributeLabels()
        {
            return [
                'id'         => 'ID',
                'brand_id'   => \Yii::t('catalog', 'Brand'),
                'video'      => 'Video',
                'mask'       => 'Mask',
                'status'     => \Yii::t('catalog', 'Status'),
                'sort'       => 'Sort',
                'created_at' => 'Created At',
                'updated_at' => 'Updated At',
                'image_id'   => \Yii::t('catalog', 'Image ID'),
                'gallery'    => 'Gallery',
                'isTop'      => \Yii::t('catalog', 'isTop'),
                'isNew'      => \Yii::t('catalog', 'isNew'),
                'isSale'     => \Yii::t('catalog', 'isSale'),
                'brand'      => \Yii::t('catalog', 'Brand'),
                'categories' => \Yii::t('catalog', 'Categories'),
                'title'      => \Yii::t('catalog', 'Title'),
                'variants'   => \Yii::t('catalog', 'Variants'),
                'categoryIds'=> \Yii::t('catalog', 'Categories'),
                'optionIds'  => \Yii::t('catalog', 'Options'),
            ];
        }
        
        /**
         * @return \yii\db\ActiveQuery
         */
        public function getLanguage()
        {
            return $this->hasOne(ProductLang::className(), [ 'product_id' => 'id' ])->where(['language_id' => Language::getCurrent()->id]);
            
        }
        
        /**
         * @return \yii\db\ActiveQuery
         */
        public function getVariants()
        {
            return $this->hasMany(Variant::class, [ 'product_id' => 'id' ]);
        }
    
        /**
         * @return \yii\db\ActiveQuery
         */
        public function getVariant()
        {
            return $this->hasOne(Variant::class, [ 'product_id' => 'id' ])
                        ->orderBy('sort');
        }
        
        /**
         * @return \yii\db\ActiveQuery
         */
        public function getLanguages()
        {
            return $this->hasMany(ProductLang::className(), [ 'product_id' => 'id' ]);
        }
        
        public function getCategories()
        {
            return $this->hasMany(Category::className(), [ 'id' => 'category_id' ])
                        ->viaTable('product_to_category', [ 'product_id' => 'id' ]);
        }
        /**
         * @return ActiveQuery
         */
        public function getCategory()
        {
            return $this->hasOne(Category::className(), [ 'id' => 'category_id' ])
                        ->viaTable('product_to_category', [ 'product_id' => 'id' ]);
        }
        
        public function getBrand()
        {
            return $this->hasOne(Brand::className(), [ 'id' => 'brand_id' ]);
        }
        
        public function getOptions()
        {
            return $this->hasMany(Option::class, [ 'id' => 'product_option_excl_id' ])
                        ->viaTable('product_to_product_option_excl', [ 'product_id' => 'id' ]);
        }
        /**
         * @return string
         */
        public function getRoute()
        {
            return Json::encode(
                [
                    'product/view',
                    'id' => $this->id,
                ]
            );
        }
    
        public function getImage()
        {
            return $this->hasOne(Image::class, [ 'id' => 'image_id' ]);
        }
    }