[tvSuperSelect] 1.2.2 Кастомайз по полной программе!
Новый функционал позволяет навесить свой процессор на получение значений для любого ТВ с типом tvSuperSelect. Теперь мы можем вывести абсолютно любые значения в этом ТВ, которые передадим через наш процессор. Предлагаю рассмотреть подробнее, как это делается и что это нам даст.
Что это даёт
- Можно выдавать любые значения на выбор. Например, список ресурсов или опции miniShop2.
- Можно ограничить пользователя только значениями из нашего списка, не давая добавить ничего нового.
Кейс
Допустим, нам нужно вывести список ресурсов в ТВ поле, чтобы менеджер мог выбрать несколько из них. Выглядеть это дело у нас будет вот так:
Шаг 1
Создаём ТВ поле с типом tvSuperSelect и указываем такие настройки:- Connector URL
/assets/custom/tvssconnector.php
- Процессор
tvss/getresources
Шаг 2
Создаём файл-коннектор, в котором будет происходить запуск процессора и получение наших значений.<?php
require_once dirname(dirname(dirname(__FILE__))) . '/config.core.php';
require_once MODX_CORE_PATH . 'config/' . MODX_CONFIG_KEY . '.inc.php';
require_once MODX_CONNECTORS_PATH . 'index.php';
$modx->request->handleRequest(array(
'processors_path' => MODX_CORE_PATH . 'custom/processors/',
'location' => '',
));
Местонахождение: /assets/custom/tvssconnector.phpШаг 3
Создаём процессор, в котором будет происходить<?php
class customTvssComboGetResourcesProcessor extends modObjectGetListProcessor
{
public $classKey = 'modResource';
public $languageTopics = array('resource');
public $defaultSortField = 'menuindex';
public $defaultSortDirection = 'ASC';
/**
* @param xPDOQuery $c
*
* @return xPDOQuery
*/
public function prepareQueryBeforeCount(xPDOQuery $c)
{
if ($context_key = $this->getProperty('context_key')) {
$c->where(array('context_key' => $context_key));
}
if ($resource_id = (int)$this->getProperty('resource_id', 0)) {
$c->where(array('id:!=' => $resource_id));
}
if ($query = trim($this->getProperty('query'))) {
$c->where(array(
'id:LIKE' => "{$query}%",
'OR:pagetitle:LIKE' => "%{$query}%",
'OR:longtitle:LIKE' => "%{$query}%",
));
}
return $c;
}
/**
* @param xPDOObject $obj
*
* @return array
*/
public function prepareRow(xPDOObject $obj)
{
$array = $obj->toArray();
$array['parents'] = array();
$parents = $this->modx->getParentIds($array['id'], 4, array('context' => $array['context_key']));
if ($parents[count($parents) - 1] == 0) {
unset($parents[count($parents) - 1]);
}
if (!empty($parents) && is_array($parents)) {
$q = $this->modx->newQuery($this->classKey, array('id:IN' => $parents));
$q->select('id,pagetitle');
if ($q->prepare() && $q->stmt->execute()) {
while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
$key = array_search($row['id'], $parents);
if ($key !== false) {
$parents[$key] = $row['pagetitle'];
}
}
}
$array['parents'] = array_reverse($parents);
}
unset($parents, $q, $row, $key);
$data = array(
'display' => "<div><small>({$array['id']})</small> <b>{$array['pagetitle']}</b></div>",
'value' => $array['id'],
);
if (!empty($array['parents'])) {
$data['display'] = '<div class="parents"><small>' . join(' / ', $array['parents']) . '</small></div>' . $data['display'];
}
return $data;
}
}
return 'customTvssComboGetResourcesProcessor';
Местонахождение: /core/custom/processors/tvss/getresources.class.phpИтого
Вот и всё! На фронте у нас будет список ресурсов в виде JSON массива, который мы сможем декодировать и делать с ними всё, что угодно!{var $resources = ($_modx->resource['our_tv'] | fromJSON)}
{foreach $resources as $v}
{$v | resource : 'pagetitle'}
{/foreach}
Поблагодарить автора
Отправить деньги
Комментарии: 18
Очень круто.
Отдельное спасибо за примеры.
Отдельное спасибо за примеры.
Очень крутое обновление! Спасибо большое!
Хоть я только недавно познакомился с этим компонентом, но очень нравится. А тут еще и обновление такое! Еще раз спасибо Павел!
Хоть я только недавно познакомился с этим компонентом, но очень нравится. А тут еще и обновление такое! Еще раз спасибо Павел!
А чем это отличается от @EVAL $modx->runSnippet в обычном множественном выборе тв? Я не ерничаю, просто интересно
Не знаю, я его не использовал. Вообще не знал о существовании оного. :)
У меня tvSuperSelect много где используется, поэтому реализовал этот функционал для него.
У меня tvSuperSelect много где используется, поэтому реализовал этот функционал для него.
Как сделать выборку из определённого родителя?
я вижу только одно отличие, что можно еще добавлять свои произвольные значения на ходу.
но, если
но, если
Можно ограничить пользователя только значениями из нашего списка, не давая добавить ничего новогото тогда нет отличий.
Понятно, спасибо!
Блин, как так нет отличий — даже обидно за автора такого полезного дополнения.
Основное преимущество tvSuperSelect в том, что теги хранятся в отдельной таблице — при выборке не нужно использовать LIKE и городить всякие велосипеды.
Основное преимущество tvSuperSelect в том, что теги хранятся в отдельной таблице — при выборке не нужно использовать LIKE и городить всякие велосипеды.
отличие в способе хранения данных, и это важное отличие на мой взгляд. в обычном тв строка с разделителями, а тут json-массив
ну и плюс @EVAL это 1. костыль и 2. небезопасно. а тут всё по феншую, через коннектор
Кстати, в MODX3 @EVAL будет удален, поэтому tvSuperSelect будет более востребован.
Представленный пример почему-то отказывается работать в modx 2.8.1.
Не сталкивался ли кто-то еще с подобной проблемой?
Не сталкивался ли кто-то еще с подобной проблемой?
Забыл добавить: версия компонента 1.3.1-beta.
Голову сломал: код, очевидно, рабочий, но поле выбора не загружается.
Голову сломал: код, очевидно, рабочий, но поле выбора не загружается.
Только в 2.8.1? Что в логах PHP? Что в консоли браузера?
На другие сборки не ставил, просто тестировал фичу.
Консоль браузера:
UPD. Адреса — как в примере. Сборка локальная. Прочая функциональность компонента — выше всяких похвал.
Консоль браузера:
ext-base.js:21 POST http://censored/assets/custom/tvssconnector.php 404 (Not Found)
modx.window.js:100 Uncaught TypeError: Cannot read property 'removeClass' of undefined
at S.onHide (modx.window.js:100)
at S.afterHide (ext-all.js:21)
at S.hide (ext-all.js:21)
at Object.hide (ext-all.js:21)
at Object.show (ext-all.js:21)
at MODx.onAjaxException (modx.js?v=10320b99:122)
at h.Event.fire (ext-all.js:21)
at Ext.data.Connection.fireEvent (ext-all.js:21)
at Ext.data.Connection.handleFailure (ext-all.js:21)
at f (ext-base.js:21)
Журнал ошибок пуст.UPD. Адреса — как в примере. Сборка локальная. Прочая функциональность компонента — выше всяких похвал.
UPD. Та же ошибка воспроизводится на чистой установке Modhost.
Решение: проверить и выставить разрешения вновь создаваемых папок в assets/ (что вытекает из наличия 404 в логах при достоверно правильных путях, и что я сразу не...).
Очевидно, в новых версиях Modx, разрешения при создании папок не наследуются.
P.S. Извините за беспокойство, Павел. И спасибо за компонент.
Очевидно, в новых версиях Modx, разрешения при создании папок не наследуются.
P.S. Извините за беспокойство, Павел. И спасибо за компонент.
P.P.S. Кстати, любопытно, что на локальной сборке проблема воспроизводится и с верными правами. В любом случае, это проблема настройки разрешений, а не компонента.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.