• YII2 Как создать гибкую модульную архитектуру?

    Screamie
    @Screamie Автор вопроса
    Денис Рыбин: Это понятно. Админ в админке, при создании страницы сам выбирает ей модуль из dropdownList. Вопрос в другом. Как заставить этот модуль работать независимо от того, куда админ в дальнейшем перенесет саму страницу.

    То есть страница может быть на третьем уровне вложенности. например /about/events/news

    И когда мы туда переходим, то запускается модуль news именно по этому адресу.

    А его адреса доступа к контроллерам меняются с /news/find-by-tags на /about/events/news/find-by-tags. Причем админ может завтра перенести эту страницу в другое место. Но это не изменит работы модуля, просто изменит адрес обращения к нему.
  • Имитировать клик по фильтру у конечных категорий?

    Screamie
    @Screamie
    То есть проблема решена? Теперь можно скрыть этот span через css и сделать проверку на его существование. Если он есть - имитируем клик по фильтру (хотя лучше написать отдельную функцию для разворачивания все полей фильра). Если нет, ничего не делаем.
  • YII2 Как создать гибкую модульную архитектуру?

    Screamie
    @Screamie Автор вопроса
    Опишу User case может быть будет понятней.

    Админ создает страницы сайта. Одну из страниц называет Новости и подключает к ней модуль Новости. Теперь внутри этой страницы в админке, не просто наполнение статичного контента, а целый модуль с его функционалом. А на фронте вместо вывода страницы со статичным контентом появляется страница модуля новостей, которая в свою очередь имеет внутренние страницы типа поиска, фильтрации, перехода к отдельной новости и т.д.

    Все хорошо, пока alias страницы новостей совпадает с контроллером модуля. Но если админ к примеру решить изменить alias на events, или перенести страницу, в какое-нибудь подменю то все рушится
  • YII2 Как создать гибкую модульную архитектуру?

    Screamie
    @Screamie Автор вопроса
    Все верно! Видимо, я не так объяснил.

    Так и должно быть. Возникает именно проблема с маршрутами. То есть для администратора панели управления видна просто страница Новости. По клику на которую он переходит к странице Модуля Новостей в Админке. Где есть управление тегами и проч.

    Он может переместить ее в иерархии страниц на любое место, но при этом при переходе на эту страницу на фронте должен подключаться модуль новостей. И как это сделать я не понимаю. Т.к. alias для страницы новостей будет строится динамически
  • Почему вместо submit срабатывает click?

    Screamie
    @Screamie
    IgorRastarov: В том то и дело. button type="submit" запускает на форме событие submit. Оно срабатывает при отправке данных формы и не имеет значения, успешная отправка или нет. Вам нужно добавить проверку на успешность отправки и там уже прописывать счетчик
  • Как избавиться от ошибки foreach?

    Screamie
    @Screamie
    Не за что! Удачного кодинга
  • Как избавиться от ошибки foreach?

    Screamie
    @Screamie
    Нужна написать метод saveByuserId() самому. Его у вас нет.

    Массив передается так, в контроллере:
    public function actionView($id)
        {
            $model = $this->findModel($id);
            $notification = new Notification();
            $shipping = new Courier(); 
    
            if ($shipping->load(Yii::$app->request->post()) && $shipping->save()) {
                $model->id_shipping = $shipping->id;
                $model->save();
                $notification->saveByIdUser(7);
    
                return $this->redirect(['view', 'id' => $model->id_zakaz]);
            }
    
            if ($model->load(Yii::$app->request->post())) {
                $model->uploadFile()->save();
    
                if ($model->status == 3 || $model->status == 6)
                    $notification->saveByIdUser($model->status)
    
                return $this->redirect(['view', 'id' => $model->id_zakaz]);
            }
    
            // Создаем параметр notifications в модели view, где будем хранить массив
           // И передаем туда массив объектов Notification
            $this->view->params['notifications'] = Notification::find()->all();
    
            return $this->render('view', [
                'model' => $this->findModel($id),
                'user_name' => $user_name,
                'shipping' => $shipping,
                'file' => $file,
            ]);
        }


    В шаблоне main.php:
    // Ваш код шаблона
    // ...
    //
    
    foreach($this->params['notifications'] as $notification){
    
        // Действия с экземпляром модели Notification, например
        echo $notification->name;
    }
  • Как избавиться от ошибки foreach?

    Screamie
    @Screamie
    Можно еще сократить. И вынести функции сохранения уведомления в модель Notification. Например так:

    public function actionView($id)
        {
            $model = $this->findModel($id);
            $notification = new Notification();
            $shipping = $model->idShipping;  // Здесь в присваиваете в $shipping id
            $shipping = new Courier(); // А здесь сразу переопределяете $shipping, то есть строчка выше не нужна
            if ($shipping->load(Yii::$app->request->post()) && $shipping->save()) {
                $model->id_shipping = $shipping->id;//Оформление доставки
                
                // В модели Notification пишем функцию saveByIdUser($id), которая будет сохранять
               // уведомление в зависимости от id, что бы не писать бизнес логику в контроллере
                $notification->saveByIdUser(7);
    
                $model->save();
                return $this->redirect(['view', 'id' => $model->id_zakaz]);
            }
    
            if ($model->load(Yii::$app->request->post())) {
    
                // Для загрузки файлов лучше написать отдельный метод в модели например uploadFile()
                // который будет проверять размер файла, наличие каталога, генерировать случайное имя и т.д.
                // во избежании проблем в будущем.
    
                /* Тогда это можно будет убрать из контроллера
                $model->file = UploadedFile::getInstance($model, 'file');//Выполнена работа дизайнером
                if(isset($model->file)){
                    $model->file->saveAs('maket/Maket_'.$model->id_zakaz.'.'.$model->file->extension);
                    $model->maket = 'Maket_'.$model->id_zakaz.'.'.$model->file->extension;
                    $model->status = 4;
                    $notification->saveByIdUser(5);
                } */ 
    
              
                $model->uploadFile();
                $model->save();
    
                if ($model->status == 3 || $model->status == 6)
                    $notification->saveByIdUser($model->status)
    
                return $this->redirect(['view', 'id' => $model->id_zakaz]);
            }
    
            return $this->render('view', [
                'model' => $this->findModel($id),
                'notification' => $notification,
                'user_name' => $user_name,
                'shipping' => $shipping,
                'file' => $file,
            ]);
        }


    И вам нужно внимательно проверить содержание этого контроллера. Т.к. там довольно много спорных моментов, но описывать все сейчас нет времени. В итоге ваш контроллер будет выглядеть примерно так

    public function actionView($id)
        {
            $model = $this->findModel($id);
            $notification = new Notification();
            $shipping = new Courier(); 
    
            if ($shipping->load(Yii::$app->request->post()) && $shipping->save()) {
                $model->id_shipping = $shipping->id;
                $model->save();
                $notification->saveByIdUser(7);
    
                return $this->redirect(['view', 'id' => $model->id_zakaz]);
            }
    
            if ($model->load(Yii::$app->request->post())) {
                $model->uploadFile()->save();
    
                if ($model->status == 3 || $model->status == 6)
                    $notification->saveByIdUser($model->status)
    
                return $this->redirect(['view', 'id' => $model->id_zakaz]);
            }
    
            return $this->render('view', [
                'model' => $this->findModel($id),
                'notification' => $notification,
                'user_name' => $user_name,
                'shipping' => $shipping,
                'file' => $file,
            ]);
        }


    Еще нужно добавить проверки при сохранении моделей и валидацию.
  • Как избавиться от ошибки foreach?

    Screamie
    @Screamie
    И такие толстые контроллеры - не айс. Вынесите бизнес логику в модель и сделайте контроллер по тоньше
  • Как избавиться от ошибки foreach?

    Screamie
    @Screamie
    Понятно. Вы передаете переменную в обычный view файл. А поймать ее хотите в layot шаблоне main.php

    Она недоступна в main.php, для того, что бы она была там доступна, вы можете создать публичное свойство у класса ZakazController, например так:

    use app\models\Notification;
    class ZakazController extends Controller
    {
    
    public function actionView($id)
        {
            $model = $this->findModel($id);
            $notification = new Notification();
            $shipping = $model->idShipping;
            $statusDisain = $model->statusDisain;
            $status = $model->status;
    
            $shipping = new Courier();
            if ($shipping->load(Yii::$app->request->post()) && $shipping->save()) {
                $model->id_shipping = $shipping->id;//Оформление доставки
    
                $notification->id_user = 7;//оформление уведомление
                $notification->name = 'Доставка '.$model->description;
                $notification->active = 0;
    
                $notification->save();
                $model->save();
                return $this->redirect(['view', 'id' => $model->id_zakaz]);
            }
    
            if ($model->load(Yii::$app->request->post())) {
                $model->file = UploadedFile::getInstance($model, 'file');//Выполнена работа дизайнером
                if(isset($model->file))
                {
                $model->file->saveAs('maket/Maket_'.$model->id_zakaz.'.'.$model->file->extension);
                $model->maket = 'Maket_'.$model->id_zakaz.'.'.$model->file->extension;
                $model->status = 4;
                $notification->id_user = 5;//оформление уведомление
                $notification->name = 'Дизайнер выполнил работу №'.$model->id_zakaz.' '.$model->description;
                $notification->active = 0;
                }            
                $model->save();
                if ($model->status == 3) {
                    $notification->id_user = 3;//оформление уведомление дизайнеру
                    $notification->name = 'Новый заказ №'.$model->id_zakaz;
                    $notification->active = 0;
                    $notification->save();
                } elseif ($model->status == 6) {
                    $notification->id_user = 6;//оформление уведомление мастеру
                    $notification->name = 'Новый заказ №'.$model->id_zakaz;
                    $notification->active = 0;
                    $notification->save();
                }
               
                return $this->redirect(['view', 'id' => $model->id_zakaz]);
            }
    
           // Здесь ищем те уведомления которые нам нужны и присваиваем их в параметр вьюшки
           $this->view->params['notification'] = Notification::find()->all();        
    
            return $this->render('view', [
                'model' => $this->findModel($id),
                'user_name' => $user_name,
                'shipping' => $shipping,
                'file' => $file,
            ]);
        }
    }


    Затем присваиваете ей нужное значение и она будет доступна в main.php, как $this->notification. Только обратите внимание, что ваш $notification будет виден только когда вы используете ZakazController. Поправил ответ, теперь присваивание происходит перед рендерингом.
  • Как избавиться от ошибки foreach?

    Screamie
    @Screamie
    Скиньте код контроллера и будет понятней. А так да, в контроллере вы используете метод render() или renderPartial() в котором первым параметром указываете view, а вторым идет именованный массив переменных для вьюшки.

    Проверьте, что передаете правильный первый аргумент в foreach. Он должен быть массивом
  • Yii2 ActiveForm не принимает значения из модели?

    Screamie
    @Screamie Автор вопроса
    Спасибо за ответ. В rules() не пусто, просто решил не писать, так как там все вроде стандартно. А оказалось, что ошибка именно там и была))) Отредактировал пост, написал в чем была проблема
  • Yii2 ActiveForm не принимает значения из модели?

    Screamie
    @Screamie Автор вопроса
    Спасибо за ответ. Конечно, я подключаю head. Видимо, забыл упомянуть, что все остальные формы и страницы работают исправно. В итоге я нашел ошибку. Она заключалась в валидаторе.

    Дело в том, что по долгу службы в последнее время приходилось работать с самописным сайтом. Там валидатор для строк реализован как "text". И, видимо, по привычке я вместо валидатора YII2 "string" указал "text". Сейчас исправил и все завелось) Вот так еще бывает)

    Но то, что в итоге нет ни ошибок ни намеков на ошибку, мне кажется упущением в YII. Все просто упало и сиди думай, где заложен анальный зонд.
  • SOAP HTTP Bad Request. Почему не вызываются функции сервиса?

    Screamie
    @Screamie Автор вопроса
    На случай если кому-то понадобится. Нашел решение.

    Дело было в неверном адресе для Actiona. Заказчик забыл скинуть токен для базы данных. Нет худа без добра, теперь я очень хорошо знаю SOAP)))
  • SOAP HTTP Bad Request. Почему не вызываются функции сервиса?

    Screamie
    @Screamie Автор вопроса
    Спасибо за ответ. То есть c моей стороны, как разработчика, я уже ничего поделать не могу? Придется через JSON стучаться?

    И на будущее, хочется просто понять SOAP. Что я должен был бы увидеть если ввожу прямую ссылку на метод и он рабочий?