Дополнительными свойствами в SkeekS CMS обладают:

  • пользователи
  • элементы контента
  • разделы
$element = new \skeeks\cms\models\CmsContentElement();
$tree = new \skeeks\cms\models\CmsTree();
$user = new \skeeks\cms\models\CmsUser()

Магия в том, что каждый из выше указанных классов моделей используют поведение

/**
 * @inheritdoc
 */
public function behaviors()
{
    return array_merge(parent::behaviors(), [

        \skeeks\cms\models\behaviors\HasRelatedProperties::className() =>
        [
            'class'                             => \skeeks\cms\models\behaviors\HasRelatedProperties::className(),
            'relatedElementPropertyClassName'   => \skeeks\cms\models\CmsUserProperty::className(),
            'relatedPropertyClassName'          => \skeeks\cms\models\CmsUserUniversalProperty::className(),
        ],
    ]);
}

This behavior can be used for any other model, correctly configure it.

As a result, we have wonderful opportunities, more flexibility, which we use throughout the CMS in order to make it more universal.

And now a few examples.


Example referring to the model properties:

/* @var $element \skeeks\cms\models\CmsContentElement */

$element = \skeeks\cms\models\CmsContentElement::findOne(10);

$element->relatedPropertiesModel->toArray(); //all available properties
$element->relatedPropertiesModel->hasAttribute('name'); //This property exists?
$element->relatedPropertiesModel->getAttribute('name'); //The value of a specific property
$element->relatedPropertiesModel->getSmartAttribute('brand'); //The value of a particular property, if it is such a value list

//Getting extra. properties of the current user
\Yii::$app->user->identity->relatedPropertiesModel->getAttribute('city');

//Find the model section by its id and take her property
$tree = \skeeks\cms\models\CmsTree::findOne(10);
$tree->relatedPropertiesModel->getAttribute('bgUrl');

Если свойство является списком:

$property = $model->relatedPropertiesModel->getRelatedProperty('cat1');
if ($property->handler instanceof \skeeks\cms\relatedProperties\propertyTypes\PropertyTypeList)
{
    /**
     * @var \skeeks\cms\relatedProperties\models\RelatedPropertyEnumModel $enum
     */
    foreach ($property->enums as $enum)
    {
        echo $enum->code;
        echo $enum->value;
        echo $enum->id;
    }
}

An example of preservation and renovation of properties:

//Properties of the current user
$userProperties = \Yii::$app->user->identity->relatedPropertiesModel;

$userProperties->city = 'Moscow';
$userProperties->age = 11;
//or
$userProperties->setAttribute('city', 'Moscow');
$userProperties->setAttribute('age', 11);
//or
$userProperties->setAttributes([
    'city'  => 'Moscow',
    'age'   => 11
]);

if ($userProperties->save())
{
    echo 'Saved';
} else 
{
    echo 'Not saved';
    print_r( $userProperties->getErrors() );
}

Creating a new user

$user = new \skeeks\cms\models\CmsUser();
$user->username = 'test';

if ($user->save())
{
	$properties = $user->relatedPropertiesModel;

	$properties->setAttribute('age', '5');
	if ($properties->save())
	{
		print_r('saved');
	} else
	{
		print_r('not saved');
		print_r($properties->getErrors());
	}
}

 


Search by model value of additional properties:

If the model has the behavior of the presence of additional features, then look for these svoysvam you can:

//Search users in the age of 11
\skeeks\cms\models\CmsUser::find()

    ->joinWith('relatedElementProperties map')
    ->joinWith('relatedElementProperties.property property')

    ->andWhere(['property.code'     => 'age'])
    ->andWhere(['map.value'         => 11])

    ->all();

//Search users from Moscow
\skeeks\cms\models\CmsUser::find()

    ->joinWith('relatedElementProperties map')
    ->joinWith('relatedElementProperties.property property')

    ->andWhere(['property.code'     => 'city'])
    ->andWhere(['map.value'         => 'Moscow'])

    ->all();

 

There are slightly more complex example, when a model has this behavior, but the properties are dependent on the type. For example, in sections.

\skeeks\cms\models\CmsTree::find()

    ->joinWith('relatedElementProperties map')
    ->joinWith('relatedElementProperties.property property')

    ->andWhere(['property.code'     => 'property'])
    ->andWhere(['map.value'         => '1'])

    ->joinWith('treeType as ttype')
    ->andWhere(['ttype.code'        => 'catalog'])

    ->all();

Or in the content elements

\skeeks\cms\models\CmsContentElement::find()

    ->joinWith('relatedElementProperties map')
    ->joinWith('relatedElementProperties.property property')

    ->andWhere(['property.code'     => 'article'])
    ->andWhere(['map.value'         => 'articleValue'])

    ->joinWith('cmsContent as ccontent')
    ->andWhere(['ccontent.code'        => 'product'])

    ->one();

This reduces the number of write requests in the database

$models = \skeeks\cms\models\CmsContentElement::find()
    ->with('relatedProperties') //This reduces the number of write requests in the database
    ->all();

foreach ($models as $model)
{
    echo $model->name;
    echo $model->relatedPropertiesModel->getAttribute('propertyCode');
}