initSQLs для Yii2

В классе yii\db\Connection, заменившем CDbConnection пропал параметр initSQLs. Теперь для настройки таймзоны соединения с базой данных требуется навешивать обработчик события:

    'components' => [
        'db' => [
            'on afterOpen' => function($event) {
                $event->sender->createCommand('set time_zone="+00:00"')->execute();
            },
        ],

Валидация «только латинские символы»

Сабж делается легко, как всегда:

public function validateLatin($attribute)
{
    $value = $this->$attribute;
    if (preg_match('/[^\x20-\x7f]/', $value))
        $this->addError($attribute, 'Only latin symbols are allowed'));
}

Yii артель

Создали с коллегой артель по веб-разработке с использованием Yii/Yii2. Оказываем широкий спектр услуг, включающий в себя проектирование, backend-frontend разработку, техническую поддержку. Работаем быстро, делаем хорошо. Возможна почасовая и сдельная оплата.

В общем, обращайтесь: yiidreamteam.com

Использование CDataProviderIterator

Начиная с версии 1.1.13 в Yii появилась возможность работать с большими наборами моделей ActiveRecord посредством итератора. Это позволяет значительно уменьшить потребления памяти. Использовать итератор легко и просто:

// создаем критерий
$criteria = new CDbCriteria();
$criteria->addCondition('status = 1');

// создаем DataProvider, использующий критерий
$provider = new CActiveRecordProvider('User', ['criteria' => $criteria]);

// создаем итератор и обходим результирующую выборку 
$iterator = new CDataProviderIterator($provider);
foreach ($iterator as $user) {
    ...
}

Отключение CWebLogRoute и YiiDebugToolbarRoute из контроллера

Порой требуется отключать некоторые веб логгеры для того, чтобы их код не портил вывод. Делается это так:

foreach (Yii::app()->log->routes as $route)
    if ($route instanceof CWebLogRoute || $route instanceof YiiDebugToolbarRoute)
        $route->enabled = false;

Переход на Yii2: DataColumn

В Yii2 изменились параметры описания колонок для GridView. Параметр name теперь называется attribute, параметр type теперь называется format.

Было:

'columns' => [
    [
        'type' => 'html',
        'name' => 'categoryId',
        'value' => function($data) {
            return CHtml::link($data->category->name, ['object-category/update', 'id' => $data->categoryId]);
        }
    ],
],

Стало:

'columns' => [
    [
        'format' => 'html',
        'attribute' => 'categoryId',
        'value' => function($data) {
            return Html::a($data->category->name, ['object-category/update', 'id' => $data->categoryId]);
        }
    ],
],

Переход на Yii2: Дропдаун-листы

Актив-форма в Yii2 была сильно переработана, в частности был изменен подход к созданию инпутов. Кроме того, ушел в прошлое широко известный в узких кругах хелпер CHtml::listData. Вместо него на сцену Yii2 выходит ArrayHelper::map.

echo $form->field($model, 'categoryId')->dropDownList(
    ArrayHelper::map(ObjectCategory::find()->asArray()->all(), 'id', 'name'),
    ['prompt' => 'Выберите из списка']
);

Локализация TbDateRangeRow

В свежем бустере есть классный виджет для выборки диапазона дат. К сожалению, этот виджет не поддерживает локализацию из коробки. Приходится костылить такие вот конструкции:

< ?=
$form->dateRangeRow($model, 'period', [
    'options' => [
        'format' => 'DD.MM.YYYY',
        'locale' => [
            'applyLabel' => 'Применить',
            'cancelLabel' => 'Очистить',
            'fromLabel' => 'От',
            'toLabel' => 'До',
            'weekLabel' => 'Н',
            'customRangeLabel' => 'Задать даты',
            'firstDay' => 1,
        ],
        'ranges' => [
            'Сегодня' => 'js:[moment(), moment()]',
            'Вчера' => 'js:[moment().subtract("days", 1), moment().subtract("days", 1)]',
            'Последние 7 дней' => 'js:[moment().subtract("days", 6), moment()]',
            'Последние 30 дней' => 'js:[moment().subtract("days", 29), moment()]',
            'В этом месяце' => 'js:[moment().startOf("month"), moment().endOf("month")]',
            'В прошлом месяце' => 'js:[moment().subtract("month", 1).startOf("month"), moment().subtract("month", 1).endOf("month")]',
        ]
    ],
]); ?>

Валидатор сравнения даты/времени для Yii

Валидатор, позволяющий сравнивать атрибуты модели как DateTime по аналогии с CCompareValidator.

Пример использования:

public function rules()
{
    return [
        ['endDate', 'vendor.lagman.yii-datetime-compare-validator.DateTimeCompareValidator',
            'compareAttribute' => 'beginDate', 'format'=>'d.m.Y', 'operator' => '=='],
        ['endTime', 'vendor.lagman.yii-datetime-compare-validator.DateTimeCompareValidator',
            'compareAttribute' => 'beginTime', 'format'=>'H:i:s', 'operator' => '>='],
    ];
}

GitHub: https://github.com/russianlagman/yii-datetime-compare-validator
Packagist: https://packagist.org/packages/lagman/yii-datetime-compare-validator

Виджет, предупреждающий о несохраненных данных в форме

Выложил виджет, предупреждающий о несохраненных данных в CActiveForm при попытке уйти со страницы (например, при клике по ссылке или при попытке обновить страницу).

Пример использования:

$this->widget('vendor.lagman.yii-unsaved-form-widget.UnsavedFormWidget', [
    'message'=>'Имеются несохраненные данные!',
    'form'=>$form,
]);

GitHub: https://github.com/russianlagman/yii-unsaved-form-widget
Packagist: https://packagist.org/packages/lagman/yii-unsaved-form-widget