Ответы пользователя по тегу Yii
  • Почему не работает Codeception на чистом шаблоне Yii2?

    @AlexKuznec Автор вопроса
    Сам протупил, по какой-то инструкции установил Codeception глобально, в отдельной директории.
    Оказывается, всё встроено в шаблон и надо просто запускать
    vendor/bin/codecept run
    Ответ написан
    Комментировать
  • Какие минусы прописать все правила полей в AR модели Yii2?

    @AlexKuznec
    Вроде как ActiveRecord и реализует всё это: проверка поступающих значений, сценарии для контроля, когда какие атрибуты могут быть изменены.
    save(), кажется, тоже сохраняет только изменившиеся значения (можете покопаться в исходниках или документации, так как я в этом месте глубоко не копал).
    Как образец, можете посмотреть реализацию регистрации и логинов (несколько форм и контроллеров) в приложении advanced.
    Ответ написан
    Комментировать
  • MySQL и Yii2 GridView: фильтрация на русском языке становится регистрово-зависимой?

    @AlexKuznec Автор вопроса
    Оказалось, что проблема была в настройках подключения к базе данных, а именно, я закомментировал явную установку кодировки шрифтов.
    'db' => [
                'class' => 'yii\db\Connection',
                ...
                'charset' => 'utf8mb4',
                ...
            ],

    Явная установка кодировки превратила все русские записи из базы в каракули, но экспорт и импорт данных заново (это делалось средствами Yii2) всё решил.
    Ответ написан
    Комментировать
  • Как вывести данные в GridView с динамическим набором колонок?

    @AlexKuznec
    Можно указывать для каждой колонки параметр 'visible', примерно так:
    [
             'attribute' => 'verified',
             'visible' => is_visible('verified'),
    ],

    где is_visible некая функция или метод, или ассоциативный массив со значениями.

    В целом, смотрите исходный код виджетов и других классов, заполняйте данные по аналогии или наследуйте класс и модифицируйте сами функции. Часто это быстрее поиска ответов через гугл (но документацию тоже знать надо). Я уже много чего таким образом подправил)

    Например, чтобы DetailView не выводил пустые значения, достаточно сделать так:
    class NotNullDetailView extends DetailView
    {
        protected function normalizeAttributes()
        {
            parent::normalizeAttributes();
    
            foreach ($this->attributes as $i => $attribute) {
                if ($attribute['value'] === null || $attribute['value'] === '')
                    unset($this->attributes[$i]);
            }
        }
    }
    Ответ написан
    Комментировать
  • Yii2 ошибка триггера при попытке удалить запись?

    @AlexKuznec Автор вопроса
    Как подсказал padlyuck, Yii2 самостоятельно не обрабатывает запреты триггеров в базе на удаление, поэтому пришел в такому варианту экшена удаления:

    public function actionDelete($id)
        {
            try {
                $this->findModel($id)->delete();
                Yii::$app->session->setFlash('success', Yii::t('app', 'controller.Food.deleted'));
            } catch (\Exception $e) {
                Yii::$app->session->setFlash('error', Yii::t('app', 'controller.Food.cannot_delete'));
            }
            
            return $this->redirect(['index']);
        }
    Ответ написан
    Комментировать
  • Как сделать контроллер тонким?

    @AlexKuznec
    Не совсем понял что нужно, но в генераторе моделей Gii галочка "Generate ActiveQuery" не для вашего случая?
    Ответ написан
  • Yii2: Почему не возвращается массив?

    @AlexKuznec
    Если это просто функция, уберите "action" из названия. Экшены должны возвращать ответ сервера в виде строки (обычно html или json).
    Ответ написан
    Комментировать
  • Как отключить логирование в yii2?

    @AlexKuznec
    Чтобы отключить совсем, попробуйте убрать строчку в конфиге
    'bootstrap' => ['log']

    В других ответах так делать не советуют, но можно отключить на время, чтобы оценить, действительно ли проблема в нем.
    Ответ написан
    1 комментарий
  • Как передать значение свойства модели внутри её rules()?

    @AlexKuznec Автор вопроса
    Так и не разобрался, почему данные в rules() подгружаются из базы, а не load(), может быть даже разработчикам напишу) ведь код в вопросе значительно красивей того, который работает.

    В итоге добавлено поведение:
    public function behaviors()
        {
            return [
                [
                    'class' => AttributeBehavior::className(),
                    'attributes' => [
                        ActiveRecord::EVENT_BEFORE_INSERT => 'time',
                        ActiveRecord::EVENT_BEFORE_UPDATE => 'time',
                    ],
                    'value' => function ($event) {
                        // время устанавливается исходя из выбранного пользователем часового пояса
                        $model = $event->sender;
                        $datetime = new DateTime($model->usertime, new DateTimeZone($model->timezone));
                        return $datetime->getTimestamp();
                    },
                ],
            ];
        }


    И 'time' убрал из rules():
    public function rules()
        {
            return [
                [['usertime'], 'date', 'type' => 'datetime'],
                [['usertime', 'timezone'], 'required'],
                [['name', 'timezone', 'period'], 'trim'],
                [['name', 'timezone', 'period'], 'string', 'max' => 255],
               ...
            ];
        }
    Ответ написан
    Комментировать
  • Список часовых поясов для php?

    @AlexKuznec Автор вопроса
    Собрал нужный код, получилась такая функция, возвращающая массив для dropDownList() из Yii2 с элементами вида:

    'Asia/Krasnoyarsk' => '(UTC+07:00) Красноярск'

    Массив с двумерной сортировкой, сначала по сдвигу, потом по имени.
    Локализация пока слабовата, может быть поэтому IntlTimeZone class пока почти не документирован.

    Кстати, внутри функции устанавливается часовой пояс UTC для вычисления сдвига по времени, я не знаю область его действия. Так что используйте с осторожностью. Вообще, часть с вычислением этого сдвига мне не нравится. Если кто знает способ лучше - напишите в комментариях.

    /* robust list of timezones */
    function get_list_of_timezones($locale) {
    
        date_default_timezone_set('UTC');
    
        $identifiers = DateTimeZone::listIdentifiers();
        foreach($identifiers as $i) {
            // create date time zone from identifier
            $dtz = new DateTimeZone($i);
            // create timezone from identifier
            $tz = IntlTimeZone::createTimeZone($i);
            // if IntlTimeZone is unaware of timezone ID, use identifier as name, else use localized name
            if ($tz->getID() === 'Etc/Unknown' or $i === 'UTC') $name = $i;
            else $name =  $tz->getDisplayName(false, 3, $locale);
            // time offset
            $offset = $dtz->getOffset(new DateTime());
            $sign   = ($offset < 0) ? '-' : '+';
    
            $tzs[] = [
                'code'   => $i,
                'name'   => '(UTC' . $sign . date('H:i', abs($offset)) . ') ' . $name,
                'offset' => $offset,
            ];
        }
    
        \yii\helpers\ArrayHelper::multisort($tzs, ['offset', 'name']);
    
        // sort by offset
    //    usort($tzs, function($a, $b){
    //        if ($a['offset'] > $b['offset']) {
    //            return 1;
    //        }
    //        elseif ($a['offset'] < $b['offset']) {
    //            return -1;
    //        }
    //        elseif ($a['name'] > $b['name']) {
    //            return 1;
    //        }
    //        elseif ($a['name'] < $b['name']) {
    //            return -1;
    //        }
    //        return 0;
    //    });
    
        return array_column($tzs, 'name', 'code');
    }
    ?>
    Ответ написан
    3 комментария
  • Аутентификация на Yii?

    @AlexKuznec
    В шаблоне Advanced реализована полноценная регистрация с созданием таблицы и восстановлением пароля через почту.
    Ответ написан
    Комментировать
  • Yii2 bootstrap tabs - как сделать горизонтальную прокрутку вкладок?

    @AlexKuznec Автор вопроса
    Вот это больше подходит:
    https://github.com/mikejacobson/jquery-bootstrap-s...
    Ответ написан
    Комментировать
  • Как в Yii2 узнать часовой пояс пользователя?

    @AlexKuznec Автор вопроса
    В общем, на данный момент нашел 2 более-менее готовых решения:

    1) Геолокация по IP.
    Плюсы: реализовано для Yii2, можно узнать страну, регион и город пользователя, что кроме часового пояса дает нам информацию о предполагаемом языке и валюте пользователя. Хотя, браузеры собирают языковые предпочтения пользователя, так что при их наличии лучше использовать их.
    Минусы: сложность системы, не гарантирует верный результат, есть небольшая плата при высоких нагрузках (легко окупится рекламой на сайте).
    https://github.com/marciocamello/yii2-sypexgeo/

    2) Определение часового пояса через JavaScript на стороне клиента.
    Плюсы: просто, бесплатно.
    Минусы: не найдено реализаций для Yii2, работает только при корректных настройках времени у пользователя и актуальной базы данных о часовых поясах (у меня, к примеру, для Барнаула отображаются устаревшие данные).

    Я взял вот эту библиотечку:
    https://github.com/barbushin/dater

    и встроил в Yii2 следующим образом (если предложите вариант получше - буду благодарен):
    в конфигурации:
    'components' => [
    'timezoneDetector' => [
    'class' => 'Dater\TimezoneDetector',
    ]
    ],

    'on ' . yii\base\Application::EVENT_BEFORE_REQUEST => function ($event) {
    $clientTimezone = Yii::$app->timezoneDetector->getClientTimezone(); // часовой пояс пользователя
    if (isset($clientTimezone)) Yii::$app->timeZone = $clientTimezone;
    },

    и в шаблоне layouts/main.php
    < head>
    ...
    <?= Yii::$app->timezoneDetector->getHtmlJsCode() // определение часового пояса пользователя ?>
    ...
    < /head>

    вставка в шаблон приложения дополнительного кода мне не нравится, так как хотел написать поведение для Yii2, но следующий код у меня работать не стал (пробовал на разные события цеплять)
    'on ' . yii\base\Application::EVENT_AFTER_REQUEST => function ($event) {
    Yii::$app->view->registerJs(Yii::$app->timezoneDetector->getHtmlJsCode(), yii\web\View::POS_HEAD);
    }
    Ответ написан
    Комментировать
  • Почему TimestampBehavior в Yii2 выбрасывает ошибку?

    @AlexKuznec
    Я по мануалу добавил в класс модели:

    public function behaviors()
    {
    return [
    TimestampBehavior::className(),
    ];
    }

    всё работает, 'created_at' и 'updated_at' являются полями по умолчанию, их можно не указывать. заполняются текущим временем по UTC также по умолчанию
    Ответ написан