Михаил Проектов


Михаил Проектов

  • Михаил Проектов Михаил Проектов 3 сентября 2018 16:03 #

    Спасибо!

    в ответ на Конфиг docker-compose для Webasyst Framework

  • Михаил Проектов Михаил Проектов 7 ноября 2016 22:11 #

    В церкви смрад и полумрак,
    Дьяки курят ладан. Нет!
    И в церкви все не так,
    Все не так, как надо.

    Путем несложных манипуляций достаем фактически отправляемые SQL запросы для обоих вариантов вызова метода getProducts(). Например, при настройках списка брать 8 товаров с самым низким рейтингом получаем

    $collection->getProducts()
    'SELECT p.* FROM shop_product p ORDER BY rating ASC LIMIT 8'

    $collection->getProducts('id')
    'SELECT p.id FROM shop_product p ORDER BY rating ASC LIMIT 8'

    А теперь Павел, если попробуете выполнить это в консоли MySQL, то опять убедитесь, что причина на стороне базы.

    По-прежнему неоднозначность результата вызвана одинаковыми значениями полей сортировки и неоднозначным поведением MySQL в таких ситуациях.

    Для получения "стабильных" результатов при одинаковых значениях полей сортировки, необходимо последним в ORDER BY добавить гарантированно уникальный ключ, например id.

    Изменение идеологическое и насколько оно необходимо в базовом коде приложения shop не готов спорить.

    В плагине можно пользоваться наследником класса shopProductsCollection с измененным методом getOrderBy()

    в ответ на shopProductsCollection и динамические списки

  • Михаил Проектов Михаил Проектов 7 ноября 2016 13:41 #

    Поясните более подробно какие именно URL работают не так как Вы ожидаете?
    Что получается на выходе?

    Что это такое?

    waRequest::param('pages_url')

    Подозреваю, что там согласно представленному файлу маршрутов должно быть

    waRequest::param('url')


    в ответ на Routing в своем приложении

  • Михаил Проектов Михаил Проектов 4 ноября 2016 06:09 #

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

    Простой тест демонстрирует, что не так как ожидает Павел.

    Сначала берем два значения без условия:

    CREATE TABLE order_test (id int, sort int);
    INSERT order_test VALUES (1,0),(2,0),(3,0),(4,0);
    SELECT id FROM order_test ORDER BY sort LIMIT 2;

    Получаем:

    +------+
    | id   |
    +------+
    |    4 |
    |    2 |
    +------+

    Теперь добавим условие:

    SELECT id FROM order_test WHERE id in (2,3,4)  ORDER BY sort LIMIT 2;

    И получаем:

    +------+
    | id   |
    +------+
    |    2 |
    |    3 |
    +------+

    в ответ на shopProductsCollection и динамические списки

  • Михаил Проектов Михаил Проектов 3 ноября 2016 08:07 #

    Попробуйте методы из

    /**
     * Static class to manage contact fields
     */
    class waContactFields
    

    Например там есть

        /**
         * Add a new field to custom_fields.php if its id is unique (throws waException otherwise)
         * @throws waException
         * @param waContactField $field
         * @deprecated use ::updateField() instead
         */
        public static function createField($field)

    в ответ на Приложение Контакты. Создание дополнительных полей при установке плагина.

  • Михаил Проектов Михаил Проектов 3 ноября 2016 07:52 #

    Про "с характеристиками размеров" не очень понятно.
    Какой это тип?
    Попробовал для текстового input, характеристика "Подошва" (sole):

    $id = 1891;
    $model = new shopProductFeaturesModel();
    wa_dumpc(
    	$model->getValues($id)
    );
    Array
    (
      color => Array
      (
        3 => shopColorValue object
        {
          shopColorValuecode => '16777215'
          shopColorValuevalue => 'Белый'
          shopColorValueid => '3'
          shopColorValuesort => '1'
          shopColorValue_data => NULL
          feature_id => '2'
        }
      )
      brand => 'Converse'
      country => 'США'
      style => 'M7652'
      sole => 'Вулканизированная резина'
    )
    

    в ответ на Как получить значения характеристик товара?

  • Михаил Проектов Михаил Проектов 2 ноября 2016 05:44 #

    Динамические списки реализованы через ORDER BY и LIMIT.
    Когда в условиях появляется WHERE он лишь ограничивает выборку перед сортировкой.
    Вероятно тот список из 50 таки не содержит изначальные 8 ID.
    Проверил у себя и работает как и ожидалось.

    Создаем два стандартных динамических списка "Хиты продаж".
    В первом ограничение 8 - best8, во втором 50 - best50.
    По ним делаем коллекции:

    $collection = new shopProductsCollection('set/best8');
    $filter = new shopProductsCollection('set/best50');
    

    Посмотрим исходный список:

    wa_dumpc(
    	array_keys($collection->getProducts('id'))
    );
    Array
    (
      0 => 1891
      1 => 783
      2 => 1886
      3 => 1892
      4 => 1890
      5 => 1996
      6 => 1885
      7 => 1888
    )

    Получаем id из второго списка, перемешиваем для чистоты эксперимента и добавляем условие в коллекцию:

    $keys = array_keys($filter->getProducts('id'));
    shuffle($keys);
    $pids = implode(',',$keys);
    $collection->addWhere('p.id in ('.$pids.')');

    Смотрим что на выходе:

    wa_dumpc(
    	$collection->getSQL(),
    	array_keys($collection->getProducts('id'))
    );
    'FROM shop_product p WHERE p.id in (888,1043,1996,1892,2372,3094,2420,1884,708,3298,3300,3293,2119,3296,1105,1888,2422,1116,1886,524,710,2074,1887,2078,1885,1891,2530,3291,2024,1889,786,706,3297,783,3086,2472,3292,3348,1117,3299,2137,790,3294,1882,3091,1890,2594,2394,2595,1907)'
    
    Array
    (
      0 => 1891
      1 => 783
      2 => 1886
      3 => 1892
      4 => 1890
      5 => 1996
      6 => 1885
      7 => 1888
    )
    

    Получили те же 8 id.

    в ответ на shopProductsCollection и динамические списки

  • Михаил Проектов Михаил Проектов 19 августа 2016 22:24 #

    У многих производителей, как оказалось, один SKU поставляется с разными штрих-кодами. Сделал колонкой в таблице артикулов, а теперь все равно придется отдельно выносить.

    в ответ на Сильно ли загрузит сайт характеристика типа select и много-много ее значений

  • Михаил Проектов Михаил Проектов 30 июля 2016 23:21 #

    Доброй ночи!

    За подготовку данных для отображения корзины отвечает класс shopFrontendCartAction.

    Далее на примере темы default.

    Шаблон отображения в файле cart.html

    Отправка данных об изменениях в корзине через JavaScript - файл cart.js.

    Обработку изменений в корзине на стороне сервера выполняют контроллеры
    shopFrontendCartAddController, shopFrontendCartSaveController, shopFrontendCartDeleteController.

    В акции shopFrontendCartAction предусмотрен хук frontend_cart, который позволяет передать дополнительные данные в шаблон корзины.

    Блок добавления товара в корзину на карточке товара и из списка товаров в стандартной теме выводится одним шаблоном product.cart.html.

    Если Вам удалось сделать добавление через карточку, и Вы делали изменения в product.сart.html, то вероятно и добавление из списка должно заработать.


    в ответ на Добавление товара в корзину согласно указанному минимальному количеству

  • Михаил Проектов Михаил Проектов 29 июля 2016 00:55 #

    Можно реализовать через выбор артикула по характеристикам.

    У салата "Цезарь" будут артикулы "Цезарь-Понедельник", "Цезарь-Вторник" и т.д.

    На карточке салата будет выбор дня недели как характеристики.

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

    Если при этом в категории выводить фильтр по дням недели, то выбор значения в фильтре автоматически применится при переходе в карточку.

    Дерево категорий тогда не нужно бить по дням, а просто по типам блюд.

    в ответ на Узнать, из какой категории выбран товар

  • Михаил Проектов Михаил Проектов 15 июля 2016 11:49 #

    Если я правильно понял, то не хватает данных из локали:

    {$currency = waCurrency::getInfo($wa->shop->currency())}
    {$locale = waLocale::getInfo($wa->locale())}
    {$currency['decimal_point'] = $locale['decimal_point']}
    {$currency['frac_digits']  = $locale['frac_digits']}
    {$currency['thousands_sep'] = $locale['thousands_sep']}

    в ответ на $currency_info в cart.html

  • Михаил Проектов Михаил Проектов 6 июля 2016 19:26 #

    И все-таки, что выводит код из моего примера выше?

    в ответ на помогите вывести contacts_view из контактов

  • Михаил Проектов Михаил Проектов 6 июля 2016 19:21 #

    А что с файлами дальше делать нужно? Может waFiles подойдет?

    в ответ на Как получить экземпляр любого уже загруженного файла на подобии waImage::factory("image")

  • Михаил Проектов Михаил Проектов 5 июля 2016 18:14 #

    Уточните какие данные есть в таблице contacts_view

    в ответ на помогите вывести contacts_view из контактов

  • Михаил Проектов Михаил Проектов 2 июля 2016 03:56 #

    Сергей, в яблочко!
    Спасибо!

    в ответ на Поддержка 4-х байтовых символов.

  • Михаил Проектов Михаил Проектов 1 июля 2016 17:58 #

    Попробуйте, думаю это то что Вы ищете:

    $contact_id = 1;
    $view_model = new contactsViewModel();
    $views = $view_model->getByField(compact('contact_id'))
    wa_dumpc($views);

    в ответ на помогите вывести contacts_view из контактов

  • Михаил Проектов Михаил Проектов 1 июля 2016 15:43 #

    Этот плагин системного приложения, не приложения сайт. Уточните вопрос.

    в ответ на общий хук в бэкенде в head?

  • Михаил Проектов Михаил Проектов 29 июня 2016 06:45 #

    В системном приложении webasyst появилось событие backend_header.

    С его помощью можно получить и поправить шапку бэкенда.

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

    /wa-system/webasyst/lib/plugins/headertest/lib/config/plugin.php

    <?php

    return array(
    'name' => 'Тестируем шапку бэкенда',
    'version' => '0.1',
    'handlers' => array(
    'backend_header' => 'backendHeader',
    ) );

    /wa-system/webasyst/lib/plugins/headertest/lib/webasystHeadertest.plugin.php

    <?php

    class webasystHeadertestPlugin extends waPlugin
    {
    public function backendHeader(&$params)
    {
    wa_dumpc($params);
    } }

    в ответ на общий хук в бэкенде в head?

  • Михаил Проектов Михаил Проектов 29 июня 2016 06:32 #

    Мне в свое время помогло {waLocale::loadByDomain('shop')}

    в ответ на Подключение языковых файлов разных приложений

  • Михаил Проектов Михаил Проектов 26 июня 2016 19:16 #

    Придется сделать расширение для стандартной shopCategoryModel.

    Существующий метод shopCategoryModel->getTree не предполагает вариантов изменения сортировки.

    в ответ на Поменять порядок вывода категории

  • Михаил Проектов Михаил Проектов 24 июня 2016 17:13 #

    Например так:

    $country_iso3 = 'kaz';
    $code = 'AM';
    $model = new waRegionModel();
    $region = $model->get($country_iso3, $code);
    wa_dumpc(
    	$region['name']
    );

    в ответ на Полное название выбранного региона доставки

  • Михаил Проектов Михаил Проектов 17 июня 2016 22:58 #

    Чтобы не создавать экземпляр класса приложения, а только подгрузить его классы можно вызвать:

    SystemConfig::getAppConfig('shop')->getClasses();

    в ответ на Доступ к классам приложения shop

  • Михаил Проектов Михаил Проектов 17 июня 2016 22:50 #

    Я не писал, что надо ссылку на штатный logout менять на ccылку на главную страницу.
    Что мешает выполнить logout в своем action или controller?
    Я рассказал как можно направить пользователя в обход штатного logout на свой обработчик, который может делать все что угодно.
    Этот обработчик не заменят при обновлении.

    в ответ на Разлогиниться не на окно входа а на главную сайта?

  • Михаил Проектов Михаил Проектов 17 июня 2016 09:37 #

    Не претендую на изящество, но как вариант решения - отправлять пользователя на свою измененную акцию или контроллер logout.

    В системном приложении webasyst появилось событие backend_header. С его помощью можно получить и поправить шапку бэкенда, в том числе и ссылку на logout.

    Обработать событие возможно несколькими способами:

    • В нужном приложении добавить handler для события системного приложения webasyst и в нем поправить вывод шапки бэкенда.
    • Добавить плагин для системного приложения webasyst и в нем обрабатывать событие backend_header.

    Без использования события backend_header можно в любом приложении или его плагине с помощью JS переопределять штатную ссылку на logout.


    в ответ на Разлогиниться не на окно входа а на главную сайта?

  • Михаил Проектов Михаил Проектов 16 июня 2016 08:49 #

    В документации подробное описание с примерами :

    В акции готовим html:

    $view = wa()->getView();
    $control = waHtmlControl::getControl(waHtmlControl::CONTACTFIELD, 'contact_field', array(
        'title'               => 'Контактное поле',
        'description'         => 'Выберите контактное поле',
        'namespace'           => 'settings',
        'control_wrapper'     => '<div class="field"><div class="name">%s</div><div class="value">%s%s</div></div>',
        'title_wrapper'       => '%s',
        'description_wrapper' => '<br><span class="hint">%s</span>'
        ));
    $view->assign(compact('control'));

    В шаблоне выводим:

    {$control}

    в ответ на Как получить список CONTACTFIELD

  • Михаил Проектов Михаил Проектов 15 июня 2016 23:21 #

    Да, нашел.

    Так ведь оно от настроек плагина зависит. Либо явно указанный обработчик для routing, либо включенный frontend:

    if (isset($plugin_info['frontend']) && $plugin_info['frontend']) {
        $plugin_info['handlers']['routing'] = 'routing';
    }
    

    И при этом ссылка на экземпляр никуда не сохраняется. Отрабатывает по event'у метод routing и экземпляр класса в корзину.

    Отвечая автору топика, таки нет, не плодятся копии без надобности.

    в ответ на Получение экземпляра плагина из его экшена

  • Михаил Проектов Михаил Проектов 15 июня 2016 22:30 #
    Зачем плодить новые объекты, если при вызове экшена уже есть класс плагина.

    Сильно не искал, но не нашел, где создается экземпляр плагина при вызове экшена или контроллера.

    Вижу, что создается только экземпляр класса экшена или контроллера.

    Подскажите, что я пропустил?

    в ответ на Получение экземпляра плагина из его экшена

  • Михаил Проектов Михаил Проектов 15 мая 2016 03:48 #

    Там есть еще хук products_collection.
    Можно с его помощью "уложиться" в один запрос.

    в ответ на shopProductsCollection — коллекции и запросы в базу

  • Михаил Проектов Михаил Проектов 24 марта 2016 16:33 #

    Посмотрите готовый класс waNestedSetModel.

    Он решает задачи хранения древовидной структуры.

    На его базе построены категории магазина, отзывы к товарам магазина, комментарии в приложениях блог, хаб и фото.

    И немного теории...

    в ответ на Дерево сообщений

  • Михаил Проектов Михаил Проектов 24 марта 2016 16:17 #

    Проверил в developer'e и Ваш формат и вариант из формы сохранения контакта.
    Оба работают.
    Данные в базе сохраняются.

    $firstname = 'First';
    $lastname = 'Last';
    $middlename = 'Middle';
    $sex = 'M';
    $birth_day = '01';
    $birth_month = '01';
    $birth_year = '1970';
    
        
    $contact1 = new waContact();
    $contact1->save(array(
        'name'          => $firstname.' '.$lastname,
        'firstname'     => $firstname,
        'middlename'    => $middlename,
        'lastname'      => $lastname,
        'sex'           => $sex,
        'birthday'     => array (
            "value" => array (
                "day" => $birth_day,
                "month" => $birth_month,
                "year" => $birth_year,
                )
            )
        )
    );
    
    $contact2 = new waContact();
    $contact2->save(array(
        'name'          => $firstname.' '.$lastname,
        'firstname'     => $firstname,
        'middlename'    => $middlename,
        'lastname'      => $lastname,
        'sex'           => $sex,
        'birth_day'    => $birth_day,
        'birth_month' => $birth_month,
        'birth_year' => $birth_year,
    ));
    
    $contact_test1 = new waContact($contact1->getId());
    $contact_test2 = new waContact($contact2->getId());
    
    wa_dumpc(
        $contact_test1->get('birthday'),
        $contact_test1->get('sex'),
        $contact_test2->get('birthday'),
        $contact_test2->get('sex')
    );

    Вывод:

    PHP
    dumped from /var/www/webasyst/wa-apps/developer/lib/actions/developerBackendExec.action.php(25) : eval()'d code line #47:
    
    Array
    (
      data => Array
      (
        year => '1970'
        month => '1'
        day => '1'
      )
      value => '1 января 1970'
    )
    
    'm'
    
    Array
    (
      data => Array
      (
        year => '1970'
        month => '1'
        day => '1'
      )
      value => '1 января 1970'
    )
    
    'm'
    
        'prefix' => 'webasyst',
        'version' => '1.5.6',
    

    в ответ на Непонятки с созданием контакта.