Упрощаем работу с TV
Продолжая тему, начатую Василием, предлагаю решение для упрощения работы с TV. Оно поможет тем, у кого логика сайта завязана на TV — запросы, фильтры и т.п.
Решается эта задача созданием полей в таблице ресурсов и копированием в них значений TV.
Покажу на своем примере.
1. Создаем TV «tv.action», которая будет признаком, что ресурс акционный. Это нужно для выборки только тех ресурсов, которые участвуют в акции. 1 — участвует, 0 — нет. Обратите внимание на префикс.
2. В таблице modx_site_content создаем поле action. Удобнее всего через phpMyAdmin.
3. Создадим вот такой небольшой плагин для нашего поля
4. Теперь на странице ресурса пишем, например, такой запрос с обычным where и без подключения TV-шек
В результате ТВ-шки работают как обычно, а вот запросы значительно упростились, так как они теперь работают только с одной таблицей. И на странице можно указывать тег с именем добавленного поля ([[*action]]), парсер обработает его быстрее, так как он не будет делать дополнительный запрос к таблице ТВ-шек. Вот такой велосипед получился.
Решается эта задача созданием полей в таблице ресурсов и копированием в них значений TV.
Покажу на своем примере.
1. Создаем TV «tv.action», которая будет признаком, что ресурс акционный. Это нужно для выборки только тех ресурсов, которые участвуют в акции. 1 — участвует, 0 — нет. Обратите внимание на префикс.
2. В таблице modx_site_content создаем поле action. Удобнее всего через phpMyAdmin.
Тип: tinyint
Длина: 1
Значение по-умолчанию: 0
Атрибуты: UNSIGNED3. Создадим вот такой небольшой плагин для нашего поля
<?php
switch ($modx->event->name) {
case 'OnMODXInit':
// Загружаем наше поле в модель ресурса
$modx->loadClass('modResource');
$modx->map['modResource']['fields']['action'] = 0;
$modx->map['modResource']['fieldMeta']['action'] = array(
'dbtype' => 'tinyint',
'precision' => 1,
'attributes' => 'unsigned',
'phptype' => 'integer',
'null' => false,
'default' => 0,
);
break;
case 'OnDocFormSave':
// Сохраняем ТВ в поле таблицы ресурса
$resource->set('action', $resource->getTVValue('tv.action'));
$resource->save();
break;
}Не забываем отметить нужные события.4. Теперь на странице ресурса пишем, например, такой запрос с обычным where и без подключения TV-шек
[[!pdoResources?
&parents=`0`
&where=`{"action":"1"}`
&tpl=`myTpl`
&depth=`0`
]]и получаем все ресурсы, для которых установлен признак акции. И никакой мороки с значениями по умолчанию, джойнами и т.п. Сложные типы TV-шек не тестировал, но думаю должно работать. Для тех, у кого много TV, скорость запросов должна заметно вырасти. Было бы интересно узнать результаты до и после.В результате ТВ-шки работают как обычно, а вот запросы значительно упростились, так как они теперь работают только с одной таблицей. И на странице можно указывать тег с именем добавленного поля ([[*action]]), парсер обработает его быстрее, так как он не будет делать дополнительный запрос к таблице ТВ-шек. Вот такой велосипед получился.
Важно!
Имя ТВ и поля должны отличаться! В противном случае, при использовании TV на странице сайта значение поля будет некорректным. Можно добавить префикс «tv» к имени ТВ-шки (подробности).Рекомендация!
Данный прием нужно использовать осторожно и только людям с устойчивой нервной системой, так как для оптимизации запросов происходит дублирование значений ТВ в таблице ресурсов. В противном случае возможны побочные действия — обострение состояния до «аж кушать не могу» из-за дублей и добавленных полей, бессоница из-за нарушения гармонии в нормализации данных (для некоторых это большой грех), головокружение и тошнота от увеличившейся скорости работы сайта. Детям использовать это можно только под присмотром взрослых! :)Комментарии: 44
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Все гениальное просто :) Твой пытливый ум еще много полезностей, чую, придумает )))
Очень надеюсь, но думаю, что дальнейшие улучшения для версии 2.х будут скоро не актуальны в связи с амбиционными планами по выпуску в скором времени MODX 3.
В массиве $tvs инфа о ТВхах в таком виде: id => name.
Я перевёл сразу 6 самых ключевых тв-шек в таблицу ресурсов и всё работает! К тому же 2 из них в формате timestamp. Всё сохраняется правильно и работает исключительно!
Пример кода для timestamp
В
Сейчас буду думать как написать код для копирования уже существующих значений в таблицу…
Там кстати у меня есть скрипты на Ajax, в которых нужно прописывать значения параллельно и в базу и в тв, но делается это легко…
При работе с ТВ запрос с фильтрацией по этим 2м ТВ выходил под 0.5 сек, сейчас — 0.06 сек. Мой плагин выглядит вот так:
Ка видите, там еще и сортировка по рейтингу тикетов есть — дарю! OnTicketVote был добавлен в последней версии Tickets.
Собственно, именно поэтому я и предпочитаю не использовать ТВ вообще. И теперь это вполне возможно, даже без miniShop2.
Везде всё хорошо =)
Тогда в плагине нужно писать так
Кроме того, нет ничего страшного в том, чтобы добавить даже 30 полей. Думаю, даже вы не заметите разницы, а уж mySQL точно.
TV — это способ расширения системных таблиц, позволяющий эмулировать добавление новых полей — на странице теги полей и TV одинаковы. Он позволяет обычным менеджерам, не программистам, достаточно легко расширять таблицу ресурсов под собственные простые задачи (заметьте, для таблицы юзеров придуман другой механизм). Но за удобство надо платить. Для более сложных задач авторы MODX предлагают решение в виде CRC, в котором вы можете добавлять свои поля в таблицу!!! Вот вам два легальных способа расширения таблиц. Если вы сторонник только первого способа, то предложенный мной вариант явно не для вас. Я даже написал рекомендацию для таких как вы.
Надо будет потом попробовать…
Мне нужно добавить несколько абсолютно-разных полей, но как я понял, phptype — это не атрибут базы, а php-эквивалент для dbtype?
Это тип, к которому будет приведено значение полученное из базы, средствами xPDO. То бишь dbtype может быть text, а phptype — и string, и json.
Я читаю здесь — github.com/modxcms/revolution/blob/89c79f7ae886184dd4136cfe09663bf5c019ee7d/core/model/schema/modx.mysql.schema.xml
это при том, что migx полей у шаблона нет. Для проверки отключаю плагин migx — вылезает путь из yandexcoordstv. Включаю migx обратно, лезу в него, закоменчиваю строки
— всё норм. Что за колдунство?) как это работает? как убрать надпись?
пашиному плагину нужно добавить событие 'OnTVInputRenderList' с таким приоритетом, чтобы он точно вызывался последним. И… больше ничего не делать. Все красиво.