Alias.php 8.58 KB
<?php
    
    namespace artbox\core\models;
    
    use artbox\core\helpers\SlugHelper;
    use artbox\core\models\interfaces\AliasInterface;
    use Yii;
    use yii\base\InvalidParamException;
    use yii\db\ActiveRecord;
    use yii\helpers\Json;
    
    /**
     * This is the model class for table "alias".
     *
     * @property integer $id
     * @property string  $value
     * @property string  $route
     * @property string  $title
     * @property string  $description
     * @property string  $h1
     * @property string  $robots
     * @property string  $seo_text
     * @property string  $entity
     * @property string  $fields
     * @property integer $language_id
     */
    class Alias extends ActiveRecord implements AliasInterface
    {
        
        const SCENARIO_CREATE = 'create';
        const SCENARIO_UPDATE = 'update';
        
        /**
         * @inheritdoc
         */
        public static function tableName()
        {
            return 'alias';
        }
        
        public function scenarios()
        {
            $scenarios = parent::scenarios();
            $scenarios[ self::SCENARIO_CREATE ] = [
                'value',
                'route',
                'title',
                'description',
                'h1',
                'robots',
                'seo_text',
                'language_id',
                'entity',
            ];
            $scenarios[ self::SCENARIO_UPDATE ] = [
                'value',
                'title',
                'description',
                'h1',
                'robots',
                'seo_text',
            ];
            return $scenarios;
        }
        
        /**
         * @inheritdoc
         */
        public function rules()
        {
            return [
                [
                    [ 'value' ],
                    'required',
                ],
                [
                    [
                        'value',
                        'title',
                        'robots',
                        'h1',
                        'route',
                        'entity',
                    ],
                    'string',
                    'max' => 255,
                ],
                [
                    [
                        'description',
                        'seo_text',
                    ],
                    'string',
                ],
                [
                    [ 'value' ],
                    'filter',
                    'filter' => function ($value) {
                        return SlugHelper::slugify($value);
                    },
                ],
                [
                    [ 'robots' ],
                    'match',
                    'pattern' => '~^(no)?index\s?\,\s?(no)?follow$~',
                    'message' => Yii::t('core', "Doesn't look like robots"),
                ],
                [
                    [ 'robots' ],
                    'match',
                    'pattern' => '~^(no)?index\s?\,\s?(no)?follow$~',
                    'message' => Yii::t('core', "Doesn't look like robots"),
                ],
                [
                    [ 'language_id' ],
                    'integer',
                ],
                [
                    [ 'language_id' ],
                    'exist',
                    'targetClass'     => Language::className(),
                    'targetAttribute' => 'id',
                ],
                //                [
                //                    [ 'route' ],
                //                    'match',
                //                    'pattern' => '/^{[\'"]0[\'"]:["\'][\w-\/]+["\'][,\w\s\'":]*}$/',
                //                ],
                [
                    [
                        'route',
                        'language_id',
                    ],
                    'unique',
                    'targetAttribute' => [
                        'route',
                        'language_id',
                    ],
                ],
            ];
        }
        
        /**
         * @inheritdoc
         */
        public function attributeLabels()
        {
            return [
                'id'          => Yii::t('core', 'ID'),
                'value'       => Yii::t('core', 'Value'),
                'route'       => Yii::t('core', 'Route'),
                'title'       => Yii::t('core', 'Title'),
                'robots'      => Yii::t('core', 'Meta robots'),
                'h1'          => Yii::t('core', 'H1'),
                'description' => Yii::t('core', 'Description'),
                'seo_text'    => Yii::t('core', 'Seo text'),
                'entity'      => Yii::t('core', 'Entity'),
                'fields'      => Yii::t('core', 'Available fields'),
                'language_id' => Yii::t('core', 'Language'),
            ];
        }
        
        /**
         * Check $fields property availability in $entity class and return only validated fields.
         *
         * @return array
         */
        public function getCheckedFields()
        {
            /**
             * @var ActiveRecord $model
             */

            $model = \Yii::createObject($this->entity);
            $fields = Json::decode($this->fields);

            $checked = [];
            if ($fields !== null) {
                foreach ($fields as $field => $fieldTitle) {
                    $currentField = explode('.', $field);
                    $result = $model;
                    foreach ($currentField as $index => $item) {
                        if (($index + 1) < count($currentField)) {
                            $result = $result->getRelation($item, false);
                            if (empty($result)) {
                                break;
                            } else {
                                $result = \Yii::createObject($result->modelClass);
                            }
                        } else {
                            if ($result->canGetProperty($item)) {
                                $checked[$field] = $fieldTitle;
                            }
                        }
                    }
                }
            }
            return $checked;
        }
        
        /**
         * Find one alias model by url
         *
         * @param string                       $url
         * @param \artbox\core\models\Language $language
         *
         * @return array|\artbox\core\models\Alias|null
         */
        public static function findUrl(string $url, Language $language)
        {
            return self::find()
                       ->where([ 'value' => ltrim($url, '/') ])
                       ->andWhere([ 'language_id' => $language->id ])
                        ->andWhere([
                            '!=',
                            'value', 'home'
                                   ])
                       ->one();
        }
        
        /**
         * @param array                        $route
         * @param \artbox\core\models\Language $language
         *
         * @return array|\artbox\core\models\Alias|null
         */
        public static function findRoute(array $route, Language $language)
        {
            try {
                $encodedRoute = Json::encode(
                    $route,
                    JSON_FORCE_OBJECT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
                );
            } catch (InvalidParamException $exception) {
                return null;
            }
            $query = self::find()
                         ->where(
                             [
                                 'route' => $encodedRoute,
                             ]
                         );
            $query->andWhere([ 'language_id' => $language->id ]);
            return $query->one();
        }
        
        public function getTitle(): string
        {
            return strval($this->title);
        }
        
        public function getDesc(): string
        {
            return strval($this->description);
        }
        
        public function getH1(): string
        {
            return strval($this->h1);
        }
        
        public function getText(): string
        {
            return strval($this->seo_text);
        }
        
        public function getRobots(): string
        {
            return strval($this->robots);
        }
        public function getFields(): string
        {
            return strval($this->fields);
        }
        public function getSeoText(): string
        {
            return strval($this->seo_text);
        }
        public function getId()
        {
            return $this->id;
        }
    }