Ответы пользователя по тегу Yii
  • Обработка изображений товаров для сайта, как правильно реализовать?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Сочетайте все три способа вместе!

    1. На подстраховку задайте в css размеры изображений и чтобы он их обрезал.
    2. Сохраняйте оригинал файла. А уже от этого оригинала генерируйте обрезанные копии для разных частей сайта:

    - Для корзины надо 50х50px
    - Для админки 100х100px
    - Для списка товаров 300х400px
    - Для просмотра товара 1000х1000px и ещё с водяным знаком.

    В таком случае вы папки изображений разделяете на две:
    - original (оригинальные фалы)
    - cache (сгенерированные из оригинала под нужные размеры).

    В дальнейшем можно удалить просто папку cache и сгенерировать новые по нужным размерам из оригиналов папки original без опаски удаление оригинала и опаски потерять оригинал совершив ошибку при обрезке.

    Сохранение оригинала ещё поможет в будущем... Например, если изменится вёрстка и нужно будет пересоздать файлы под другие размеры.

    На Yii для этого есть замечательная библиотека, которая реализует такой подход

    Пример настройки:
    public function behaviors(): array
        {
            return [
                [
                    'class' => ImageUploadBehavior::className(),
                    'attribute' => 'photo',
                    'createThumbsOnRequest' => true, //Создавать при запросе (если файлы из cache удалить, то они снова сгенерируются под новым размерам указаных ниже)
                    'filePath' => '@staticRoot/origin/posts/[[id]].[[extension]]',
                    'fileUrl' => '@static/origin/posts/[[id]].[[extension]]',
                    'thumbPath' => '@staticRoot/cache/posts/[[profile]]_[[id]].[[extension]]',
                    'thumbUrl' => '@static/cache/posts/[[profile]]_[[id]].[[extension]]',
                    'thumbs' => [
                        'admin' => ['width' => 100, 'height' => 70],
                        'thumb' => ['width' => 640, 'height' => 480],
                        'blog_list' => ['width' => 1000, 'height' => 150],
                        'widget_list' => ['width' => 228, 'height' => 228],
                        'origin' => ['processor' => [new WaterMarker(1024, 768, '@frontend/web/image/logo.png'), 'process']],
                    ],
                ],
            ];
        }


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

    3. Лучше не предупреждать что будет обрезано, а в момент загрузке на js показать как будет выглядеть изображение на всех видах верстки. Но можно и просто написать.

    Вообще это идеальный вариант. Вы можете использовать самый простой вариант и работать с простой и удобной библиотекой. Или любой другой популярной написанной на чистом php. Решать вам)
    Ответ написан
    6 комментариев
  • Пути к файлам и ресурсам на shared hosting Yiii2?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    namespace common\modules\blog\assets;
    use yii\web\AssetBundle;
    /**
     * Main blog asset bundle.
     */
    class BlogAsset extends AssetBundle
    {
        public $sourcePath = '@common/modules/blog/assets';
        public $css = [
        ];
        public $js = [
            'js/script.js'
        ];
        public $depends = [
        ];
    }


    use common\modules\blog\assets\BlogAsset; 
    BlogAsset::register($this);
    Ответ написан
  • Как получить данные после фильтрации в yii2?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    1. Запросы это ответственность не сущности, а отдельного репозитория. В Yii можно сделать модель Query. Например PostQuery. Там и делать этот запрос. Из PostSearch вы вызываете этот метод.
    3. Не совсем понял в чем проблема. Но если правильно понял, то вы говорите о связях. Используете связи.

    https://www.yiiframework.com/doc/guide/2.0/ru/db-a...

    Раздел «объявление связей»
    Ответ написан
    Комментировать
  • Как передать id пользователя во view?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    У вас есть контроллер Profile и методом actionView. В нем нужно получать Yii:$app->user->identify-getId()

    Далее искать в базе его данные по id.

    Если посты надо получать текущего пользователя, то user_id передавать не надо. Получать надо как написал выше.

    Не понимаю в чем сложность? Немного не понятен вопрос.
    Ответ написан
  • Передача данных из кнопки типа радио через отправку формы в yii2?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Как я вижу к вас в инпутах одинаковые значения name1 откуда тут name2? Исправьте инпуты
    Ответ написан
    Комментировать
  • Как нативно в yii2 разделить ActiveForm на 2 части?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Валидация у Yii форм реализована через JS. ActiveForm лишь создаёт структуру, которая нужна, а в js файле она ищет стили формы и работает с ними. Чтобы это проверить, то просто скопируйте HTML форму сгенерированную через AF и валидация никуда не пропадёт. Следовательно вам можно работать и на чистом HTML передавая данные из самой формы. Так же можно пользоваться хэлпером HTML.

    Но смысл?) Можно перейти и на twig
    Ответ написан
    Комментировать
  • Как правильно реализовать CRUD при работе с DDD и Yii2?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    1. В DDD подразумевается предметная разработка. Соотвественно CRUD тут не совсем правильно делать. Тут нужно работать с UseCase: создай товар, удали товар, оплатить товар, архивировать товар. Это уже больше чем CRUD.
    2. Во фреймворке делайте своё ядро, которое принимает DTO. Запихиваете данные в DTO далее передаёте в сервис, обрабатываете данные и пихаете через Repository в базу. В принципе все просто. Можете посмотреть курс Елисеева Дмитрия по работе с интернет магазином. Если говорить о примерах, то вот, правда на симфони.

    Так же есть пример из самого магазина
    Ответ написан
    2 комментария
  • Yii2 RESTful API зачем использовать Search модели?

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

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

    Метод all() не рекомендуется использовать для больших данных. Скрипт может зависнуть.

    В модели так же удобно делать списки для выпадающих списков формы.

    Если говорить кратко, то SearchModel это форма, в которую вы передаёте данные и фильтруете по ним. Но так как это не только форма, то её называют модель. А вообще её можно назвать и Filter.

    Обойтись без неё можно и нужно, если знаете как. Это все сделано для быстрой RAD разработки.
    Ответ написан
    Комментировать
  • Хочу написать свой AccessControl фильтр, чтобы устанавливать доступ к Экшенам контролера из админки, как лучше сделать?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Так себе задача. Но есть готовое решение то что вам нужно) RBAC.

    В композер "mdmsoft/yii2-admin": "~2.0"
    Ответ написан
    Комментировать
  • Проблемы на поддомене. Yii2?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    1. Перейдите в режим DEV и включите дебаг, чтобы понять ошибку в index файле папки web
    defined('YII_DEBUG') or define('YII_DEBUG', true);
    defined('YII_ENV') or define('YII_ENV', 'dev');

    2. Настройте субдомен в htaccess
    Ответ написан
    2 комментария
  • Как правильно организовать сохранение состояния модели перед изменением?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Создайте дополнительное поле json и туда сохраняйте состояние текущих полей, версию или просто дату создания. При модификации добавляете в массив новые данные. При откате просто заменяете текущие данные на данные из версии. Но это такое себе решение)

    Вот более подробно. https://m.habr.com/ru/post/101544/

    Это если просто. Мои мысли такие. Вообще, лучше добавить другие теги и может ещё что подскажут. Это не совсем про Yii
    Ответ написан
    1 комментарий
  • Как организовать вложенные мульти-формы в Yii2?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Используйте композитные формы
    https://github.com/ElisDN/yii2-composite-form
    Ответ написан
    2 комментария
  • Как переписать sql-запрос в ActiveQuery?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    А нельзя использовать Expression?
    Ответ написан
    Комментировать
  • Как аутентифицировать пользователя в Yii2?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Попробуйте так:
    $user = User::findOne(1);

    А вообще загрузите advanced шаблон и посмотрите как там реализовано. Можно скопировать к себе и не выдумывать.
    Ответ написан
    7 комментариев
  • Как запретить выбор прошедших дат в DatePicker?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    Добавьте
    startDate: дата в вашем в формате, например, 2019-09-13

    'startDate'=> date('d-m-Y H:i',time()),
    Ответ написан
    3 комментария
  • Можно ли выполнять частые кешированные запросы в бд yii2?

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

    Никто не делает так, как вы пытаетесь. Прочитаете про связанные данные и жадную загрузку — вопрос, думаю, отпадёт.
    Ответ написан
    6 комментариев
  • Почему не выводится картинка в виде?

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

    1. Перенесите папку uploads либо в корень проекта чтобы было так /uploads
    2. Настройте htaccess файл так, чтобы uploads можно было прочитать и все ссылки с этим началом оправлялись в эту папку.
    3. Ссылку формируйте /uploads/....

    Вариант2
    1. Перенесите папку в frontend/web/uploads
    2. Посмотрите, чтобы в htaccess было разрешено чтение и запись. (В стандартном употреблении разрешено). В стандартнойнастройке htaccess все запросы кидает в папку web. Поэтому дополнительно ничего настраивать не надо.
    3. Ссылку формируйте /uploads/....

    У вас проблема в двух моментах:
    1. Не настроен или не правильно настроен htaccess
    2. Не правильно указываете ссылку.

    Рекомендую использовать второй вариант, если хотите быстрее разобраться с ошибкой. Первый вариант немного сложнее и он больше для будущего выделения файлов на отдельный сервер или домен, как и папки frontend, backend
    Ответ написан
    2 комментария
  • Выборка данных с перебором. Yii2?

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

    У вас получится вызов по связи: $model->serSpec

    Выборка из документации:

    class Customer extends ActiveRecord
    {
        public function getOrders()
        {
            return $this->hasMany(Order::className(), ['customer_id' => 'id']);
        }
    }
    
    class Order extends ActiveRecord
    {
        public function getCustomer()
        {
            return $this->hasOne(Customer::className(), ['id' => 'customer_id']);
        }
    }


    // SELECT * FROM `customer` WHERE `id` = 123
    $customer = Customer::findOne(123);
    
    // SELECT * FROM `order` WHERE `customer_id` = 123
    // $orders - это массив объектов Order
    $orders = $customer->orders;
    Ответ написан
    7 комментариев
  • Yii2 Как добавить условие в запросе в связанных данных?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    $emails = Email::find()
        ->joinWith(['emailRecipients' => static function (ActiveQuery $query) {
            $query->andWhere(['email_recipient.status' => EmailRecipient::EMAIL_RECIPIENT_STATUS_NEW]);
        }])
        ->where(['email.status' => Email::EMAIL_STATUS_NEW])
        ->asArray()
        ->all();
    Ответ написан
    8 комментариев
  • Почему не отображается гугл карта?

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

    Добавляем во view:
    <div id="map"></div>

    <?php 
    $js = <<< JS
          function initMap() {
            var map = new google.maps.Map(document.getElementById('map'), {
              zoom: 8,
              center: {lat: -34.397, lng: 150.644}
            });
            var geocoder = new google.maps.Geocoder();
    
            document.getElementById('submit').addEventListener('click', function() {
              geocodeAddress(geocoder, map);
            });
          }
    
          function geocodeAddress(geocoder, resultsMap) {
            var address = document.getElementById('address').value;
            geocoder.geocode({'address': address}, function(results, status) {
              if (status === 'OK') {
                resultsMap.setCenter(results[0].geometry.location);
                var marker = new google.maps.Marker({
                  map: resultsMap,
                  position: results[0].geometry.location
                });
              } else {
                alert('Geocode was not successful for the following reason: ' + status);
              }
            });
          }
    JS;
    
    $this->registerJs( $js, $position = yii\web\View::POS_READY, $key = null );
    ?>​

    ВАШ ПРИМЕР


    <?php 
    $js = <<< JS
          var autocompletes, marker, infowindow, map;
        function initMap() {
             map = new google.maps.Map(document.getElementById('map'), {
              center: {lat: -33.8688, lng: 151.2195},
              zoom: 13
            });
            infowindow = new google.maps.InfoWindow();
    
            marker = new google.maps.Marker({
              map: map
            });
    
            // адрес откуда
            var inputs = document.querySelector('#place_departure');
            autocompletes = new google.maps.places.Autocomplete(inputs);
            
            google.maps.event.addListener(autocompletes, 'place_changed', function () {
                marker.setVisible(false);
                infowindow.close();
    
                var place = autocompletes.getPlace();
                if (!place.geometry) {
                    window.alert("No details available for input: '" + place.name + "'");
                    return;
                }
                
                  if (place.geometry.viewport) {
                    map.fitBounds(place.geometry.viewport);
                  } else {
                    map.setCenter(place.geometry.location);
                    map.setZoom(17);
                  }
                  
                  marker.setIcon(({
                    url: place.icon,
                    scaledSize: new google.maps.Size(35, 35)
                  }));
                  marker.setPosition(place.geometry.location);
                  marker.setVisible(true);
                  
                  var place_departure = '';
                  if (place.address_components) {
                    place_departure = [
                      (place.address_components[0] && place.address_components[0].short_name || ''),
                      (place.address_components[1] && place.address_components[1].short_name || ''),
                      (place.address_components[2] && place.address_components[2].short_name || '')
                    ].join(' ');
                  }
    
                  infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + place_departure);
                  infowindow.open(map, marker);
            });
        }
    JS;
    
    $this->registerJs( $js, $position = yii\web\View::POS_READY, $key = null );
    ?>​



    Добавляем в шаблон (layout)

    <script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"></script>
    Ответ написан
    8 комментариев