В данном разделе опубликована информация, которая призвана решить спорные вопросы и определить порядок действий при их возникновении. Группой разработчиков мы собрали наиболее полный список рекомендаций, который поможет вам в создании новых модулей и приложений на Yii
Бизнес-логике не место в ActiveRecord, контроллере и тем более в представлении. Размещать бизнес-логику необходимо в отдельных классах с говорящими названиями “СущностьДействие”. В результате получаются “худые” контроллер и ActiveRecord. Данный подход повышает читабельность проекта в разы, а также позволяет производить тестирование бизнес-логики.
class UserCreator extends BaseObject{public $emailAccept = false;public $beforeCreateEvent = UserEvent::EVENT_BEFORE_CREATE;public $afterCreateEvent = UserEvent::EVENT_AFTER_CREATE;public $validate = true;public $role = DbManager::ROLE_USER;protected $model;/*** UserCreator constructor.* @param User $model* @param array $config*/public function __construct(User $model, $config = []){$this->model = $model;parent::__construct($config);}/*** @return false|User*/public function execute(){$event = new UserEvent();Yii::$app->user->trigger($this->beforeCreateEvent, $event);if(!$event->release) return false;$transaction = Yii::$app->db->beginTransaction();try {if($this->emailAccept) {$this->model->status = User::STATUS_INACTIVE;$this->model->generateEmailAcceptToken();}$this->model->confirm = true;$this->model->generateAuthKey();if ($this->model->save($this->validate)) {if($this->emailAccept && !self::sendMail($this->model)) {return false;}$role = Yii::$app->authManager->getRole($this->role);Yii::$app->authManager->assign($role, $this->model->id);Yii::$app->user->trigger($this->afterCreateEvent, new UserEvent(['userId' => $this->model->id]));$transaction->commit();return $this->model;}} catch (\Exception $e) {$transaction->rollBack();}return false;}/*** @param User $model* @return bool*/public static function sendMail(User $model){return Yii::$app->mailer->compose(['html' => '@common/modules/users/mail/emailAcceptToken-html','text' => '@common/modules/users/mail/emailAcceptToken-text'], ['model' => $model])->setFrom(Yii::$app->params['noReplyEmail'])->setTo($model->email)->setSubject(Module::t('register_form_email_subject'))->send();}}
beforeSave, afterSave, beforeFind, afterFind в ActiveRecord для тяжелой бизнес-логики (например, запросы к сторонним ресурсам, парсинг Excel, тяжелых XML файлов и т.д).auth_item и auth_item_child в обход миграций. Все обновления в БД осуществляются только посредством оформления миграции.yii\db\Migration.yii\db\Query.
$users = (new Query())->select('id')->from('{{%user}}')->all();
Если в проекте используется СУБД MySQL для использования внешних ключей (Foreign keys) и транзакций, в качестве системы хранения данных (Storage engine) должна быть выбрана InnoDB. При создании таблицы в БД необходимо использовать следующую конструкцию:
$tableOptions = null;if ($this->db->driverName === 'mysql') {$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB';}$this->createTable('{{%auth2fa}}', ['id' => $this->primaryKey(),'user_id' => $this->integer(11)->notNull()->comment('Пользователь'),'secret_key' => $this->string(16)->notNull()->comment('Секретный ключ'),'created_at' => $this->integer(11)->comment('Дата создания записи'),'updated_at' => $this->integer(11)->comment('Дата изменения записи'),], $tableOptions);
down() в миграциях обязателен к реализации, если миграция является обратимой. Нежелательно, чтобы метод down возвращал false.php yii migrate/redo n.batchInsert() вместо конструкции, когда вызывается insert() в цикле (то же касается и консольных алгоритмов).batch(), each() вместо all() (то же касается и консольных алгоритмов).{{%table_name}}. Это даст возможность использовать префиксы таблиц в БД. При использовании данного шаблона не забудьте применить следующий пункт в кодогенераторе Gii при генерации модели:
Html::tag(), Html::beginTag(), Html::endTag(). За счет этого html верстка становится нечитабельной и нет никакой подсветки html тегов.
$textAreaPlaceholder = "ДА\nДа\nда\ny\nYes\nYES\n+";$valuePlaceholder = "1";echo Html::beginTag('div', ['class' => 'hidden']);echo $form->field($model, 'convert')->textarea(['rows' => 6]);echo Html::endTag('div');$model->convert = json_decode($model->convert, true);echo Html::beginTag('table', ['class' => 'table list_table_for_validation_rules']);echo Html::beginTag('thead');echo Html::beginTag('tr');echo Html::tag('th', 'Список возможных значений', ['width' => '48%']);echo Html::tag('th', 'Заменить на', ['width' => '48%']);echo Html::tag('th', '', ['width' => '4%']);echo Html::endTag('tr');echo Html::endTag('thead');echo Html::beginTag('tbody');$help = Html::tag('div', '', ['class' => 'help-block']);if (is_array($model->convert))foreach ($model->convert as $listJson) {echo Html::beginTag('tr');echo Html::tag('td', Html::textarea('list_replaced_list[]', implode("\n", $listJson['list']), ['rows' => 4, 'class' => 'form-control list_replaced_list', 'placeholder' => $textAreaPlaceholder]) . $help, ['class' => 'list_replaced_list_wrapper']);echo Html::tag('td', Html::textarea('list_replaced_val[]', $listJson['value'], ['rows' => 4, 'class' => 'form-control list_replaced_val', 'placeholder' => $valuePlaceholder]) . $help, ['class' => 'list_replaced_val_wrapper']);$button = Html::a(Html::tag('i', '', ['class' => 'fa fa-times']), 'javascript:;', ['class' => 'btn btn-danger remove_list_replaced_val']);echo Html::tag('td', $button);echo Html::endTag('tr');}echo Html::endTag('tbody');echo Html::beginTag('tfoot');echo Html::beginTag('tr');echo Html::tag('td', Html::textarea('list_replaced_list[]', '', ['rows' => 4, 'class' => 'form-control list_replaced_list', 'placeholder' => $textAreaPlaceholder]) . $help, ['class' => 'list_replaced_list_wrapper']);echo Html::tag('td', Html::textarea('list_replaced_val[]', '', ['rows' => 4, 'class' => 'form-control list_replaced_val', 'placeholder' => $valuePlaceholder]) . $help, ['class' => 'list_replaced_val_wrapper']);$button = Html::a(Html::tag('i', '', ['class' => 'fa fa-save']), 'javascript:;', ['class' => 'btn btn-success add_list_replaced_val']);echo Html::tag('td', $button);echo Html::endTag('tr');echo Html::endTag('tfoot');echo Html::endTag('table');
Общие положения
if ($password) {$this->password_hash = Yii::$app->security->generatePasswordHash($password);}
Классы
Константы
Свойства
Методы
getСurrentUser().
$foo->bar($longArgument,$longerArgument,$muchLongerArgument);
Переменные
Переменная должна наиболее полно описывать представляемую сущность, это значит, что она должна иметь понятное название, по которому можно судить о ее предназначении.
Комментирование - важный аспект разработки приложений на Yii 2. Игнорирование создания понятных комментариев отнимает значительно большего времени при поддержке и командной разработке проектов. Ниже мы привели основные нюансы простановки комментариев в коде, чтобы на выходе можно было сгенерировать удобную и понятную документацию по проекту.
Обратите внимание, что комментарий типа # не используется. Это связано с тем, что на основании оставленных комментариев генерируется документация к разрабатываемому программному продукту.
/*** Форма редактирования пользователя** @property string $email* @property string $name* @property string $surname* @property string $position* @property string $password* @property string $repeatPassword* @property boolean $sendEmailPassword* @property boolean $sendEmailRegister* @property integer $status* @property UploadedFile $photo* @property boolean $deletePhoto* @property string $timezone* @property string $role*/
@mixin для подключенных поведений к классу для того, чтобы PHPStorm знал о методах, реализованных в этих поведениях:Далее описываются константы, если есть, и записываются в верхнем регистре:
/*** @mixin UploadImageBehavior* @mixin AccessBehavior* @mixin MultilingualBehavior*/
При описании свойства необходимо задать тип данных через
/*** Тип пользователя: юр. лицо* @var integer*/const TYPE_CORP = 3;
@var и дать описание:Описание статических свойств:
/*** @var string Название базы данных*/public $database;
Методы могут содержать комментарий родительского метода класса. Это характерезуется
/*** @var array Индикаторы цен за 6 месяцев*/public static $priceSixMonths = [4, 8];
@inheritdoc параметром. Пример ниже говорит о том, что у метода уже есть комментарий. Читай комментарий родительского метода.
/** @var \common\modules\content\models\Post $model */
'value' => function($model) {/** @var \common\modules\document\models\Document $model */return $model->user->getUsernameWithEmail();}
'value' => function(Document $model) {return $model->user->getUsernameWithEmail();}
Во время проектирования таблиц БД необходимо добавлять комментарии для полей таблиц:
$this->createTable('{{%document}}', ['id' => $this->primaryKey(),'author_id' => $this->integer(11)->notNull()->comment('Автор'),'user_id' => $this->integer(11)->notNull()->comment('Пользователь'),'name' => $this->string(150)->notNull()->comment('Наименование'),'filename' => $this->string(50)->notNull()->comment('Файл'),'size' => $this->string(50)->notNull()->comment('Размер файла'),'extension' => $this->string(10)->notNull()->comment('Расширение файла'),'hash' => $this->string(64)->notNull()->comment('Hash файла (SHA-256)'),'is_active' => $this->smallInteger(1)->notNull()->defaultValue(0)->comment('Видимость'),'order' => $this->smallInteger()->unsigned()->notNull()->defaultValue(0)->comment('Сортировка'),'created_at' => $this->integer(11)->notNull()->comment('Дата создания записи'),'updated_at' => $this->integer(11)->notNull()->comment('Дата обновления записи')], $tableOptions);
Компонент gii во фреймворке Yii2 позволяет генерировать AR модели для таблиц БД. Установив галочку “Generate Labels from DB Comments”,
мы получим указанные комментарии в методе attributeLabels , который задает метки атрибутов.
public function attributeLabels(){return ['id' => 'ID','author_id' => 'Автор','user_id' => 'Пользователь','name' => 'Наименование','filename' => 'Файл','size' => 'Размер файла','extension' => 'Расширение файла','hash' => 'Hash файла (SHA-256)','is_active' => 'Видимость','order' => 'Сортировка','created_at' => 'Дата создания записи','updated_at' => 'Дата обновления записи',];}
А также название полей появятся в веб-приложении для администрирования СУБД.
Для того, чтобы мы смогли Вам предоставить доступ расскажите немного о себе
Опишите в форме ниже задачу, которую требуется реализовать.