Ответы пользователя по тегу Yii
  • Почему так много памяти употребляет Yii2-excel с файлами формата xlsx?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    1. Откажитесь при работе с Exel данными в виде объектов - передавайте простые массивы. Это сильно сократит память, особенно если используете AR.
    2. Используйте очереди и консольное приложение. Консольное приложение не имеет ограничений по памяти и длительности.
    Ответ написан
    Комментировать
  • Как можно заполнить AccessControl в yii2?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Вы все сделали правильно, однако, когда пользователь гость — фильтры yii2 автоматически редиректят его на страницу входа.

    По умолчанию адрес входа: site/login. Адрес можно поменять в компоненте user приложения. По умолчанию используется класс yii\web\User Чтобы поменять путь к логину необходимо настроить user компонент в config.

    Так как у вас advanced шаблон и имеются два приложения (backend и frontend), то возможны два способа настроек:

    1. Если форма входа общая
    //common/config/main.php
    'user' => [
        'loginUrl' => ['/admin/auth/login']
    ],

    2. Если форма входа разные:
    //backend/config/main.php
    'user' => [
        'loginUrl' => ['/admin/auth/login']
    ],
    
    //frontend/layout/main.php
    'user' => [
        'loginUrl' => ['/auth/login']
    ],

    Так же можно вызвать форму из шаблона по js
    //config
    'user' => [
        'loginUrl' => ['/?login=true']
    ],
    
    //frontend/layout/main.php
    $script = <<< JS
    $('#login').trigger('click'); //вызываем окно с формой логина
    JS;

    Существует минимум три способа для перекрытия страниц общими правилами фильтрации:

    1. Помещаем общие правила в «главный» контроллер, от которого наследуются все контроллеры приложения.
    2. Прикрепляем глобальный фильтр с общими правилами, который будет перекрывать все экшены приложения.
    3. Выносим общие правила в отдельные классы-фильтры, которые можно подключить в контроллере, модуле или во всем приложении.

    Рекомендую использовать третий вариант. Не рекомендую использовать первый вариант. В некоторых случаях — второй.

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

    Если мы разрабатываем приложение, в котором есть не только web controller, но так же api controller, console controller, то при таком подходе нам необходимо создать три контроллера с одинаковыми общими правилами или применить ещё один уровень наследования. В конечном итоге от дублирования кода или от большой вложенности кода не уйти.

    Если мы оставим три общих контроллера, то при изменении правил, мы можем забыть изменить их в другом месте. Из-за чего что-то будет работать не запланировано.

    Второй вариант дает нашему коду некую «загадочность» (магию), а так же усложняет тестирование.

    При использовании 3 варианта код редактируется всегда в одном файле на все контроллеры модули и приложения. Код тестируется отдельно от контроллеров и соответствует SOLID.

    На эту тему можно посмотреть Дмитрия Елисеева.
    Ответ написан
    Комментировать
  • Как в Yii2 после добавления данных очистить форму и вывести flash сообщение на той же странице без повторной отправки?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Если вам не нужно делать редирект на другую страницу — можно перезагрузить страницу используя $this->refresh(). Страница перезагрузится, форма очистится, flash сообщения будут отображены. После чего можно снова заполнять форму новыми данными.

    Из вашего кода пропадут лишние строки:

    public function actionAdd()
    {
        $model = new News();
    
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            Yii::$app->session->setFlash('success', 'Удача: Новость добавлена!');
            return $this->refresh();
        } else {
            Yii::$app->session->setFlash('error', 'Ошибка: Не удалось добавить новость!');
        }
    
        return $this->render('add', compact('model'));
    }
    Ответ написан
    Комментировать
  • Есть ли смысл делать CRUD на yii2 без ajax?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Для ответа на этот вопрос нужно понимать несколько нюансов:

    1. Это 2012 год. За 8 лет в программировании много что поменялось. Я считаю, что нужно обучаться каждые пол года и узнавать новые технологии, а так же их применять в своих проектах.

    2. В последнее время от jQuery активно отказываются. На смену им приходят frontend Фреймворки: Vue, Angular, React и др.

    В 2020 году, чаще всего, проект разделяется на два приложения: frontend (UI) и backend (API).

    Для frontend выбирают фреймворк на js, а для backend выбирают, чаще всего, фреймворк на php.

    frontend взаимодействует с backend через API.

    3. Гибрид никто не отменял. Есть приложения, в которых совмещен backend и frontend В одном приложении. В таких проектах js стараются использовать минимально.

    Поюзайте этот сайт вопросов и вы сами увидите, что не так много функций реализованных на «ajax». Если таких разделов станет много, то вам следует использовать разделение на 2 приложения из пункта 2. В CRUD приложении тем более AJAX будет минимальным.

    Моё мнение:
    1. Если вы не знаете хорошо js, то используйте его минимально в своих проектах, а тем более если это jQuery.
    2. CRUD используйте без AJAX. Возможно будет так, что на одной странице будет несколько форм. Не пугайтесь этого. Просто подумайте о рефакторинге.
    3. “AJAX” используйте в тех случаях, когда действительно нужны действия без перезагрузки страницы: лайки, добавление товара в корзину, добавление в закладки и так далее. Такие действия должны быть оправданы и разумны.

    Подумайте, как можно реализовать это одним файлом на все CRUD действия. Например, я реализовал фильтрацию без перезагрузки страницы на всех index страницах. Но нужно хорошо знать как устроен Фреймворк и уметь пользоваться этим.
    Ответ написан
    Комментировать
  • TinyMCE в Yii2 - после форматирования текста отображаются теги html. Как исправить?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Это называется форматирование данных.

    Для гибкого форматирования HTML на странице или при сохранении, командой Yii был реализован специальный хелпер HTML Purifier.. У него есть масса различных настроек. Можно посмотреть как использовать на примере Yii 1.0. Либо ознакомиться с официальной документацией.
    Ответ написан
    Комментировать
  • Как настроить yii2 в iis8?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Если ваша виртуальная машина работает по сети, то используйте в адресной строке ip адрес машины вместо 127.0.0.1 и localhost. Почитайте про это. Настройте сами хосты. У вас проект должен быть доступен по адресу: http://10.12.155.34/project

    Далее настройте свой веб сервер так, чтобы он все запросы по http://10.12.155.34/project слал в frontend/web/index.php

    Вопрос не совсем относится к yii это больше по настройке сервера и работе по сети.
    Ответ написан
    Комментировать
  • Yii2 Личные мгновенные сообщения для пользователей сайта?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Готовых нет. Так как мгновенные сообщения по типу авито сложно сделать без websocket или подобных технологий. Поэтому готовых расширений нет. Ищите что-то просто на php и интегрируйте в yii2.
    Ответ написан
    1 комментарий
  • Как правильно написать в UrlManager rules?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Вместо ID передавайте SLUG. И будет у вас счастье. А в URLManager обычные регулярные выражения. Почитайте о slug yii2 и вы поймёте как это делается. Задача типичная и популярная. Например Как реализовать slug в yii2?
    Ответ написан
    Комментировать
  • Как вставить один вид гридвью в другой вид?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Так же точно, только переменные называете свои. В контроллере:
    $userDataProvider = new ()
    $userSeachModel = $userDataProvider->...
    
    $postDataProvider = new ()
    $postSeachModel = $postDataProvider->...


    Создаёте все в контроллере и передаёте в вид эти переменные.

    В результате получится в виде так:

    <?= GridView::widget([
            'dataProvider' => $userDataProvider ,
            'filterModel' => $userSeachModel,
            'columns' => []
    ]?>
    ....
    
    <?= GridView::widget([
            'dataProvider' => $postDataProvider ,
            'filterModel' => $postSeachModel,
            'columns' => []
    ]?>


    Можно и использовать без поисковой модели, если это просто вывод записей и DataProvider на массивах.
    Ответ написан
  • Yii2 почему не работают пути со / в начале?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    А где вы видите тут абсолютный путь? Почитайте
    Ответ написан
    2 комментария
  • Как сделать ссылку с словами?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Так же как для id, только для slug. Это называется slug. Как реализовать slug в yii2?
    Ответ написан
    Комментировать
  • Как реализовать асинхронную закгрузку view?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    А что там Вы хотите готового? Асинхронная загрузка это только JS. Поэтому любой ajax запрос подойдет. Там делать нечего, зачем ещё готовое что-то лепить. Ну если хотите - можете использовать PJAX, но это уже прошлый век и на него все плюются.
    Ответ написан
    Комментировать
  • Как заставить обновляться PJAX по таймеру?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    По примеру:
    <?php Pjax::begin([
        'id' => 'list-messages',
        'enablePushState' => false,
        'formSelector' => false,
        'linkSelector' => false,
    ]) ?>
    <?= $this->render('_list', ['dataProvider' => $dataProvider, 'pages' => $pages,]) ?>
    <?php Pjax::end() ?>

    <?php $this->registerJs(<<<JS
            function updateList() {
              $.pjax.reload({container: '#list-messages'});
            }
            setInterval(updateList, 150000);
    JS
        ); ?>
    Ответ написан
    Комментировать
  • Получить запись из бд, если не найдена, вернуть с другими параметрами?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Зачем делать условия на SQL? Сделайте два запроса. Если первый запрос результат NULL , то посылаете второй запрос для значения Default.
    $translation = Translation::find()->where(...)->one;
    //если не нашли перевод, то по-умолчанию
    if(!$translation) {
          $translation = Translation::find()->where(...)->one
    }
    Ответ написан
    Комментировать
  • Yii2, что означает код ошибки ноль на прод версии?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Уберите вообще этот ноль из ошибок везде и программируйте нормально. Проблема в вашей или чьей-то фантазии. Сами же говорите что такого статуса ошибок нет. А у вас есть...
    Ответ написан
    Комментировать
  • Yii debug panel не подключается, как исправить ошибку?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    У вас проблема, скорее всего, с urlManager или htaccess, если используете Apache. Ошибку выдаёт 404. А это значит, что такой страницы не существует. Настройте как положено эти два пункта. Если будут другие ошибки - пишите.
    Ответ написан
    Комментировать
  • По какому волшебству добавление в корзину может происходить "через один"?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Вы весь код проекта выложите))

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

    Используйте тесты. Ищите ошибки через дебаггер.
    Ответ написан
    8 комментариев
  • Почему не работает mailer yii2?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Перевод:
    Не удалось установить соединение с хостом smtp.mail.ru [Сеть недоступна # 101]
    не благодарите за перевод)

    Если вы не понимаете по-русски, то тут говориться, что вы указали либо не правильные данные для подключения к smtp.mail.ru, либо сервер не доступен. Проверьте настройки подключения.
    Ответ написан
  • Как сделать запрос с условием где две даты одинаковые?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Если даты в одном формате, то так:
    $query = User::find()
      ->where(['=', 'created_at', 'updated_at'])
      ->all();
    Ответ написан
    Комментировать
  • Как правильно организовать код, файлы в проекте?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    1. Сервисы - это вспомогательный код, перед моделью, который вы выносите из контроллера. Пример. Сами сервисы не должны посылать запросы напрямую в базу. Для это го делается отдельный репозиторий, который передается через конструктор в сервис.

    2. Сервисы подключаются в контроллер через конструктор и обращаются к ним как
    $this->userService->create($userFrom или $userDto);

    3. Делить сервисы можно хоть на каждое действие (UseCase)
    ..../Service/User/Create/Service.php всё зависит от вашей архитектуры. Выносите тогда, когда кода в сервисе становится много. Либо сразу.

    Можете ещё почитать это Архитектура приложения. Как сделать независимые модули (сервисы)? и посмотреть тот репозиторий из github, который вставлял в качестве примера.

    Ваш код можно переписать так: Исключил контроллер и PageRepository
    class UserService
    {
        public $users; 
        public $pages; 
    
        public function __construct(UserRepository $users, PageRepository $pages) 
        {
            $this->users = $users;
            $this->pages = $pages;
        }
            
        public function createUser(CreateForm $form) : void
        {
            if($this->users->existsByEmail($form->email)) {
                thow new DomainExeption('Пользователь уже существует!')
            }
    
            $user = new User([
                'username' => $form->username,
                'name' => $form->name,
                'email' => $form->email
            ]);
    
            $page = new Page([
                'name' => $form->page->name
            ]);
    
            ...
    
            $transaction->begin();
            try{
                $this->users->save($user);
                $this->pages->save($page);
                $transaction->commit();
            }
            catch{
              $transaction->rollBack();
            }
    
            //PS Транзакцию тоже можно вынести в отдельный сервис.
        }
    }
    
    class UserRepository
    {        
        public function save(User $user): bool
        {
            if (!$user->save(false)) {
                throw new \RuntimeException('Saving error.');
            }
        }
            
        public function existsByEmail(string $email): bool
        {
            return User::find()->andWhere(['email' => $email])->exists();
        }
    }
    Ответ написан
    2 комментария