Дмитрий Зарубин

Дмитрий Зарубин

С нами с 29 апреля 2013; Место в рейтинге пользователей: #122
Дмитрий Зарубин
08 августа 2018, 15:15
0
Если убрать связи то выходит такое:
[2018-08-08 15:11:10] (ERROR @ F:\server\bin\OpenServer\domains\rework-addchar.loc\core\xpdo\xpdo.class.php : 1828)

No foreign key definition for parentClass: acProduct using relation alias: Data

[2018-08-08 15:11:10] (WARN @ F:\server\bin\OpenServer\domains\rework-addchar.loc\core\xpdo\om\xpdoobject.class.php : 1129)

Could not getOne: foreign key definition for alias Data not found.

[2018-08-08 15:11:10] (ERROR @ F:\server\bin\OpenServer\domains\rework-addchar.loc\core\xpdo\xpdo.class.php : 1828)

No foreign key definition for parentClass: acProduct using relation alias: msProductData

[2018-08-08 15:11:10] (WARN @ F:\server\bin\OpenServer\domains\rework-addchar.loc\core\xpdo\om\xpdoobject.class.php : 1250)

Foreign key definition for class , alias msProductData not found, or cardinality is not 'one'.

[2018-08-08 15:11:10] (WARN @ F:\server\bin\OpenServer\domains\rework-addchar.loc\core\xpdo\om\xpdoobject.class.php : 1256)

Could not add related object! Array
(
    [id] => 
    [article] => 
    [price] => 0
    [old_price] => 0
    [weight] => 0
    [image] => 
    [thumb] => 
    [vendor] => 0
    [made_in] => 
    [new] => 
    [popular] => 
    [favorite] => 
    [tags] => 
    [color] => 
    [size] => 
    [source] => 1
)
И невозможность достать что либо из msProductData (price, color и тд).
Дмитрий Зарубин
08 августа 2018, 14:28
0
Схема:
<?xml version="1.0" encoding="UTF-8"?>
<model package="addchar" baseClass="xPDOObject" platform="mysql" defaultEngine="InnoDB" phpdoc-package="addchar" version="0.2">

    <object class="acChar" table="ac_characteristics" extends="xPDOObject">
        <field key="key" dbtype="varchar" precision="250" phptype="string" null="false" index="pk" />
        <field key="title" dbtype="varchar" precision="255" phptype="string" null="false" default="" />
        <field key="type" dbtype="varchar" precision="255" phptype="string" null="false" default="" />

        <index alias="key" name="key" primary="false" unique="false" type="BTREE">
            <column key="key" length="" collation="A" null="false" />
        </index>

        <composite alias="Value" class="acProductChar" local="key" foreign="key_char" cardinality="many" owner="local" />
    </object>

    <object class="acProductChar" table="ac_product_characteristics" extends="xPDOObject">
        <field key="key_char" dbtype="varchar" precision="250" phptype="string" null="false" />
        <field key="product_id" dbtype="int" precision="10" phptype="integer" attributes="unsigned" null="false" />
        <field key="value" dbtype="text" phptype="string" null="false" default="" />

        <index alias="key_char" name="key_char" primary="true" unique="false" type="BTREE">
            <column key="key_char" length="" collation="A" null="false" />
        </index>

        <index alias="product_id" name="product_id" primary="false" unique="false" type="BTREE">
            <column key="product_id" length="" collation="A" null="false" />
        </index>

        <aggregate alias="Char" class="acChar" local="key_char" foreign="key" cardinality="one" owner="foreign" />
        <aggregate alias="Product" class="acProduct" local="product_id" foreign="id" cardinality="one" owner="foreign"/>
    </object>

    <object class="acProduct" extends="msProduct">
        <field key="class_key" dbtype="varchar" precision="100" phptype="string" null="false" default="acProduct"/>

        <aggregate alias="Category" class="msCategory" local="parent" foreign="id" cardinality="one" owner="foreign"/>
        <composite alias="Chars" class="acProductChar" local="id" foreign="product_id" cardinality="many" owner="local"/>
        <composite alias="Data" class="msProductData" local="id" foreign="id" cardinality="one" owner="local"/>
        <composite alias="Categories" class="msCategoryMember" local="id" foreign="product_id" cardinality="many"
                   owner="local"/>
        <composite alias="Options" class="msProductOption" local="id" foreign="product_id" cardinality="many"
                   owner="local"/>
    </object>

</model>
Конструктор:
function __construct(xPDO & $xpdo) {

        parent::__construct($xpdo);
        parent::set('class_key', 'acProduct');

    }
Как я понял проблема действительно в модели, так как ошибки на который виснет это вызов $this->loadClass в классе xpdo.
Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 262144 bytes) in F:\server\bin\OpenServer\domains\rework-addchar.loc\core\xpdo\xpdo.class.php on line 596

Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 262144 bytes) in Unknown on line 0

Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 262144 bytes) in Unknown on line 0
Плюс 596 строчка в xpdo это:
$typePos= strrpos($fqn, '_' . $this->config['dbtype']);
Как я понимаю сюда попадает файл класса acproduct.class.php из папки model/<name_component>/, а должен попадать из папки model/<name_component>/mysql/, единственное я понятия не имею как это отдебажить или проверить свою догадку.
Дмитрий Зарубин
18 августа 2017, 15:02
+1
Нет. Это реализовано посредством MIGX ТВшки в ресурсе с фильтрацией. В поле прописана ссылка на ЧПУ страницу и всё что надо для сео. Отработка идёт как сниппетом при загрузке страницы, так и ajax на событие mse2_load.
Дмитрий Зарубин
09 августа 2017, 20:49
+1
Таки интересно получилось. Даже наверно куплю для нового проекта.)
А если не секрет, то сколько на него ушло времени? Как в общем, так и чистого.)
Дмитрий Зарубин
28 июля 2017, 15:38
0
Евгений, всегда пожалуйста!)
Мы кстати свой тоже значительно доработали и помудрили с быстродействием. Отрабатывает даже на 40000 товаров в бд на отлично. Можно глянуть на работу тут vivaset.ru/avtomaticheskie-vyiklyuchateli/.
Кстати, вдруг вам пригодится идея: в самой нижней части у нас выводится блок со ссылками, которые читают поисковики. В нашем случае мы формируем их записывая значения в плейсхолдер с массивом в чанках фильтров. Не уверен что это получится нормально на смарти. Но на феном работает отлично.
Дмитрий Зарубин
01 июня 2017, 16:33
0
Не уверен, что это будет скоро.)
Но я обязательно сделаю апдейт этой статьи со ссылкой на новую.
Дмитрий Зарубин
01 июня 2017, 16:02
0
TV MIGX, который в свою очередь представляет собой JSON. Там уже можно разгуляться как хочешь.
Дмитрий Зарубин
01 июня 2017, 14:07
0
Данная версия нет. Новая версия умеет и с опциями, и с вендорами, и с парентами. Ниже написал, что проект, на котором всё это реализовано, пока на стадии релиза и пока не знаю когда смогу сделать статью на это всё.
Дмитрий Зарубин
01 июня 2017, 14:06
+2
Добрый день!
Мы на одном из проектов, который запустится в ближайшее время, уже доработали всё что нужно. И чуть более правильный принцип работы ЧПУ, и учёт всех всех параметров со сменой мета и заголовков, а также возможность задавать кастомный для каждой ссылки.
Плюс всё это также работает по аяксу.
Пока не могу сказать точно когда доберусь, чтобы выложить всё это и описать принципы работы, но в планах есть.
Дмитрий Зарубин
15 ноября 2016, 02:04
0
Отбой. Второй вариант не прокатит. Только что проверил.
Дмитрий Зарубин
15 ноября 2016, 02:02
0
Всё как говорит Иван. Объект минишопа в вашем случае недоступен потому, что скрипт минишопа подставляется перед закрытием боди перед тем, как передать шаблон на сторону клиента. Поэтому есть 2 варианта:
1. Поставить ваш скрипт после закрытия боди и перед закрытием хтмл.
2. Подключать скрипт минишопа вручную перед вашим скриптом. Только тут нужно будет убрать его путь в настройках симтемы.
Дмитрий Зарубин
28 июля 2016, 13:15
0
Предупреждаю сразу, откомментирован он крайне хреново.) Плюс его невозможно сделать универсальным, а под какие-то нюансы нужно подгонять.
<?php
if ($modx->event->name == 'OnPageNotFound') {
    $alias = $modx->context->getOption('request_param_alias', 'q');
    if (isset($_REQUEST[$alias])) {
        
        $request = $page = trim($_REQUEST[$alias], "/");
        $tmp = explode('/', $request);
        
        for ($i = count($tmp); $i > 0; $i--) {
            // Определяем id раздела.
            if ($section = $modx->findResource($page . '/')) break;
            $page = trim(str_replace($tmp[$i-1], '', $page), "/");
        }
         
        if ($section) {
            
            $tmp = explode('/', trim(str_replace($page, '', $request), "/"));
            
            $filter_params = array( // Массив соответствия алиаса параметру фильтра
                );
                
            $alias = array( // Массив соответствия алиаса столбцу в БД
                    'brand' => 'manufacturer'
                );
            
            $check = false; // Обнуляем проверку
            foreach ($tmp as $filter) {
                if ($filter == '') continue;
                $filter_arr = explode('-', $filter);
                // Получаем параметр и значение
                $param = array_shift($filter_arr);
                $value = implode('-', $filter_arr); $filter_val = false;
                $filter_param = array_key_exists($param, $filter_params) ? $filter_params[$param] : $param;
                
                /*if ($param == 'series') {
                    $value = str_replace('-',' ',str_replace("'","\'",$value));
                    
                    $query = new xPDOCriteria($modx, "SELECT id
                                                        FROM modx_site_content
                                                        WHERE
                                                            pagetitle LIKE '$value'");
                    if ($query->prepare() && $query->stmt->execute()) {
                        $result = $query->stmt->fetchAll(PDO::FETCH_COLUMN);
                        $filter_val .= $result[0];
                    }
                    else return false;
                    // Присваиваем значение категории в переменную
                    $filter_val = trim($filter_val, ",");
                }
                else*/if ($param == 'page') {
                    // Получаем страницы
                    $filter_val = str_replace('-',',',$value);
                }
                elseif ($param != 'price' || $param != 'sort' || $param != 'tpl') {
                    $value = str_replace("'", "\'", $value);
                    $value_tr = $modx->runSnippet('translit_str', array('input' => $value, 'options' => 're'));
                    $column_name = array_key_exists($param, $alias) ? $alias[$param] : $param;
                    
                    $value_tr = str_replace(' усб',' usb', str_replace(' тв',' tv', $value_tr));
                    $value_fix = str_replace(' ','-',$value_tr);
                    
                    $query = new xPDOCriteria($modx, "SELECT $column_name
                                                        FROM modx_ms2_products
                                                        WHERE
                                                            $column_name LIKE '$value'
                                                            OR
                                                            $column_name LIKE '$value_tr'
                                                            OR
                                                            $column_name LIKE '$value_fix'");
                                                            
                    if ($query->prepare() && $query->stmt->execute()) {
                        $result = $query->stmt->fetchAll(PDO::FETCH_COLUMN);
                        $filter_val .= $result[0].',';
                    }
                    
                    // Присваиваем значение фильтра в переменную
                    $filter_val = trim($filter_val, ",");
                }
                    
                // Осталось выставить нужные переменные в запрос, как будто юзер их сам указал
                if ($filter_val) {$_GET[$filter_param] = $_REQUEST[$filter_param] = $filter_val; $check = true;}
            }
            
            // Есть ли параметры
            if ($check) {
            	// А теперь подсовывем юзеру страницу, а дальше сниппет на ней сам разберётся
            	$modx->sendForward($section);
            }
            // Иначе ничего не делаем и юзер получает 404 или его перехватывает другой плагин.
        }
    }
}
Дмитрий Зарубин
28 февраля 2016, 23:46
0
Всегда пожалуйста!
Дмитрий Зарубин
27 февраля 2016, 23:02
+2
Если в общих чертах, то я использовал компонент MIGX и его TV типа migx. Данные она хранит в json. Потом я смотрю, есть ли у меня в этой твшке бренд или серия, которые сейчас в Гет, и вывожу значения в плейсхолдеры. Работает отлично. Могу разместить сниппет и аякс в отдельной заметке, если нужно. А пример вот тут shop.bodybuilding.ua/katalog/protein/. Работает и по аяксу, и по прямому переходу.
А по-поводу индексации Владимир сказал правильно. Просто размещаете те ссылки, которые вам надо и где надо. У меня в частности они идут со страницы товара — в хлебных крошках и в нижнем блоке shop.bodybuilding.ua/katalog/protein/muscle-tech-platinum-whey-909-g-pr-000099.html.
Дмитрий Зарубин
27 февраля 2016, 13:11
0
Точно. Прошу прощения, сейчас добавлю. Да и немного изменю этот код, потому что я уже его доработал чуток.
Дмитрий Зарубин
23 февраля 2016, 11:09
0
Кирилл, Василий исправил баг. Можно обновлять пакет, если он у вас есть.)
Дмитрий Зарубин
22 февраля 2016, 17:47
1
0
Кирилл, покопавшись обнаружил, что это небольшой баг mFilter2, который завязан именно на категориях. Когда вы выбираете категорию, ставите фильтр цены (а возможно и любой ползунковый) так, что не находит результатов, а потом возвращаете его в прежнее положение, то урл очищается и остаётся только цена. Понял это по одному проекту, на котором пока нет ЧПУ и стоит более старая версия — shop.bodybuilding.ua/brendyi/bodybuildingua.html.
В техподдержку по этому вопросу уже отписал, так что думаю пофиксят в ближайшее время.
Дмитрий Зарубин
22 февраля 2016, 15:00
0
Спасибо. Сейчас поправлю.
Дмитрий Зарубин
22 февраля 2016, 15:00
0
Тайтл, h1 и тексты на странице также будут подхватываться именно те, которые надо. Для этого есть отдельный функционал. Просто они ещё не заполнены.
Дмитрий Зарубин
22 февраля 2016, 02:49
+1
Ну кстати да, на счёт индексации согласен.)
Но СЕОшникам сложно что-то доказать. И лучше им не давать аргументов для ответа на вопрос «А почему сайт не продвигается?».)