andrewdanilov / yii2-behaviors
Various behaviors for AR models
Installs: 174
Dependents: 3
Suggesters: 0
Security: 0
Stars: 1
Watchers: 2
Forks: 0
Open Issues: 0
Type:yii2-extension
Requires
- php: >=7.4.0
- andrewdanilov/yii2-ckeditor: ~1.0.1
- andrewdanilov/yii2-helpers: ~1.0.17
- andrewdanilov/yii2-input-images: ~1.0.4
- mihaildev/yii2-elfinder: *@dev
- yiisoft/yii2: ^2.0.0
README
Various behaviors for AR models
Installation
The preferred way to install this extension is through composer.
Either run
composer require andrewdanilov/yii2-behaviors "~1.0.0"
or add
"andrewdanilov/yii2-behaviors": "~1.0.0"
to the require
section of your composer.json
file.
Usage
DateBehavior
At your controller class add to behaviors()
method:
use yii\db\ActiveRecord; use andrewdanilov\behaviors\DateBehavior; class MyController extends ActiveRecord { public function behaviors() { return [ // ... [ 'class' => DateBehavior::class, // AR model attributes to process by behavior 'dateAttributes' => [ // DateTime format 'date_1' => DateBehavior::DATETIME_FORMAT, // DateTime format with current datetime as default value if param is empty 'date_2' => DateBehavior::DATETIME_FORMAT_AUTO, // Date format without time 'date_3' => DateBehavior::DATE_FORMAT, // Date format without time with current datetime as default value if param is empty 'date_4' => DateBehavior::DATE_FORMAT_AUTO, // Short notation equal to: 'date_5' => DateBehavior::DATE_FORMAT 'date_5', ], ], // ... ]; } }
DateBehavior converts date into mysql format before it will be saved to database (onBeforeSave
event)
and into display format after it is fetched from database (onAfterFind
event).
You can define display format by modifiyng Yii::$app->formatter
component in your config:
$config = [ // ... 'components' => [ // ... 'formatter' => [ 'defaultTimeZone' => 'Europe/Moscow', 'dateFormat' => 'php:d.m.Y', 'datetimeFormat' => 'php:d.m.Y H:i:s', 'timeFormat' => 'php:H:i:s', ], ], ];
If you have problems with time shifting, set defaultTimeZone
property of formatter.
TagBehavior
Use this behavior to link two models with many-to-many relation via staging table. This behavior will take care of saving new links to staging table and removing obsolete ones.
Model Product.php
<?php namespace common\models; /** * Class Product * * @property int $id * ... * @property int[] $category_ids */ class Product extends \yii\db\ActiveRecord { public $category_ids; public function behaviors() { return [ 'category' => [ // name of behavior 'class' => 'andrewdanilov\behaviors\TagBehavior', 'referenceModelClass' => 'common\models\ProductCategory', 'referenceModelAttribute' => 'product_id', 'referenceModelTagAttribute' => 'category_id', 'tagModelClass' => 'common\models\Category', 'ownerModelIdsAttribute' => 'category_ids', ] ]; } /** * Getter for retrieving child models (tags) list. * It can be used therefore as property $product->categories * or link named 'categories', i.e. $product->with('categories') * * @return \yii\db\ActiveQuery */ public function getCategories() { $behavior = $this->getBehavior('category'); // use name of behavior here ('category') if ($behavior instanceof \andrewdanilov\behaviors\TagBehavior) { return $behavior->getTags(); } return null; } // ... }
Model Category.php
<?php namespace common\models; use yii\db\ActiveRecord; /** * Class Category * * @property int $id * @property string $name * ... */ class Category extends ActiveRecord { // ... }
Model ProductCategory.php
<?php namespace common\models; use yii\db\ActiveRecord; /** * Class ProductCategory * * @property int $id * @property int $product_id * @property int $category_id */ class ProductCategory extends ActiveRecord { // ... }
View product/update.php
<?php use andrewdanilov\behaviors\TagBehavior; use common\models\Category; use common\models\Product; use yii\helpers\Html; use yii\bootstrap\ActiveForm; /* @var $this yii\web\View */ /* @var $form yii\widgets\ActiveForm */ /* @var $model Product|TagBehavior */ ?> <?php $form = ActiveForm::begin(); ?> ... <?= $form->field($model, 'category_ids')->checkboxList(Category::find()->select(['name', 'id'])->indexBy('id')->column(), ['prompt' => '']) ?> ... <div class="form-group"> <?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?> </div> <?php ActiveForm::end(); ?>
TagBehavior can be used several times in one model, so you can add at the same time categories, tags and linked products to your Product
model
JsonTypecastBehavior
Use this behavior to convert database field values saved in json-string format into array and back. This allows you to store a value in the database as a json string, but treat it as if it were an array.
use andrewdanilov\behaviors\JsonTypecastBehavior; class Item extends \yii\db\ActiveRecord { public function behaviors() { return [ 'jsontypecast' => [ 'class' => JsonTypecastBehavior::class, 'attributes' => [ 'json_field_1', // field names 'json_field_2', 'json_field_3', // ... ], ], ]; } // ... } // Use example: $item = new Item(); $item->json_field_1 = [1, 2, 3]; // before saving json_field_1 will be converted to a json string $item->save(); // then after saving it will be converted back to an array print_r($item->json_field_1); // Outputs: // Array // ( // [0] => 1 // [1] => 2 // [2] => 3 // )
RateLimitBehavior
Use this behavior to limit rate of requests from your visitors to specific controller actions.
<?php class MyController extends \yii\web\Controller { public function behaviors(): array { return array_merge(parent::behaviors(), [ 'rateLimit' => [ 'class' => \andrewdanilov\behaviors\RateLimitBehavior::class, // identityKey - key to identify current visitor, optional 'identityKey' => Yii::$app->user->id ?? Yii::$app->session->getId(), 'limits' => [ // '<action>' => [<interval>, <rate>] // <action> - идентификатор действия // <interval> - интервал, на котором проводим измерения // <rate> - доступное число запросов на указанном интервале 'index' => [1, 100], // 100 раз в секунду 'view' => 10, // 10 раз в секунду (сокращенная запись) 'create' => [60, 1], // 1 раз в минуту 'update' => [1, 1], // 1 раз в секунду ], ], ]); } }