Получить все TV-поля ресурса в Fenom
Добрый день!
Подскажите пожалуйста, я могу получить данные какого то ресурса, например с id=5:
Данные TV ресурса могу получить так:
Например хочу так:
Подскажите пожалуйста, я могу получить данные какого то ресурса, например с id=5:
{5 | resource}
Но там не будет TV.Данные TV ресурса могу получить так:
{5 | resource : "tv_name"}
Возможно ли получить в переменную ВСЕ TV поля ресурса с их значениями?Например хочу так:
{set $res_five = 5 | resource}
и что бы потом мог использовать переменную $res_five и брать из неё данные TV, например:{$res_five["tv_name"]}
Я знаю как можно это сделать написав свой сниппет, но может это уже доступно в Fenom, или забить и просто использовать {5 | resource: «tv_name»}? Комментарии: 9
Если у вас есть списочные данные, не надо делать 100500 ТВ, используйте Migx.
Использую, но у меня 100500 Migx'ов :)
У fenom, если не ошибаюсь, нет метода получения коллекции TV. Поэтому надо написать свой сниппет. В принципе можете потом переменной присвоить результат сниппета и работать так, как хотели. Условно:
{set $res_five = '!getResourceTVs' | snippet : ['id' => 5]}
Не нашли решение?
Я тут решил немного помочь и сделал сниппет
res
res
<?php
$id = $input;
if (empty($id)) {
$resource = $modx->resource;
} else {
$resource = $modx->getObject('modResource', ['id' => intval($id)]);
}
if(!$resource) return [];
$out = $resource->toArray();
$id = $resource->id;
$sql = "
SELECT IF(tvr.value != \"\", tvr.value, tv.default_text) AS tv_value,tv.name
FROM {$modx->getTableName('modTemplateVarResource')} tvr
LEFT JOIN {$modx->getTableName('modTemplateVar')} tv
ON tv.id = tvr.tmplvarid
LEFT JOIN {$modx->getTableName('modTemplateVarTemplate')} tvt
ON tvt.tmplvarid = tvr.tmplvarid
WHERE tvr.contentid = {$id} AND tvt.templateid = {$resource->template}
";
// $modx->log(1,$sql);
$q = $modx->prepare($sql);
$q->execute();
$tvs = $q->fetchAll(PDO::FETCH_ASSOC);
foreach($tvs as $tv){
$out[$tv['name']] = $tv['tv_value'];
}
return $out;
Использовать{set $res = 1 | res}
<pre>{$res | print_r}</pre>
Расчитанно, что все tv текстовые. Если надо чтоб tv обрабатывались перед помещением в массив, то надо вызывать getTVValue.foreach($tvs as $tv){
$out[$tv['name']] = $resource->getTVValue($tv['name']);
}
Поправил немного
<?php
$id = $input;
if (empty($id)) {
$resource = $modx->resource;
} else {
$resource = $modx->getObject('modResource', ['id' => intval($id)]);
}
if(!$resource) return [];
$out = $resource->toArray();
// чтоб страница не упала в рекурсию
unset($out['content']);
$id = $resource->id;
$sql = "
SELECT IF(tvr.value != \"\", tvr.value, tv.default_text) AS tv_value, tv.name, tv.type
FROM {$modx->getTableName('modTemplateVarResource')} tvr
LEFT JOIN {$modx->getTableName('modTemplateVar')} tv
ON tv.id = tvr.tmplvarid
LEFT JOIN {$modx->getTableName('modTemplateVarTemplate')} tvt
ON tvt.tmplvarid = tvr.tmplvarid
WHERE tvr.contentid = {$id} AND tvt.templateid = {$resource->template}
";
// $modx->log(1,$sql);
$q = $modx->prepare($sql);
$q->execute();
$tvs = $q->fetchAll(PDO::FETCH_ASSOC);
foreach($tvs as $tv){
switch($tv['type']){
case 'text': case 'textarea':
$out[$tv['name']] = $tv['tv_value'];
break;
default:
$out[$tv['name']] = $resource->getTVValue($tv['name']);
}
}
return $out;
Спасибо!) А как с происходит обработка {resource_id | resource: 'tv_param_name'}
каждый такой вызов делает свой отдельный запрос в бд? Я ведь правильно понимаю — использование выше сниппета выше более рационально если надо дергать 5 — 6 полей другого ресурса?
каждый такой вызов делает свой отдельный запрос в бд? Я ведь правильно понимаю — использование выше сниппета выше более рационально если надо дергать 5 — 6 полей другого ресурса?
В pdoTools вот код модификатора
$this->_modifiers['resource'] = function ($id, $field = null) use ($pdo, $modx, $fenom) {
$pdo->debugParserModifier($id, 'resource');
/** @var modResource $resource */
if (empty($id)) {
$resource = $modx->resource;
} elseif (!is_numeric($id)) {
$field = $id;
$resource = $modx->resource;
} elseif (!$resource = $pdo->getStore($id, 'resource')) {
$resource = $modx->getObject('modResource', ['id' => intval($id)]);
$pdo->setStore($id, $resource, 'resource');
}
$output = '';
if (!empty($resource)) {
if (!empty($field)) {
if (strtolower($field) == 'content') {
$output = $resource->getContent();
} else {
$output = $resource->get($field);
if (is_null($output)) {
$output = $resource->getTVValue(preg_replace('#^tv\.#i', '', $field));
}
}
} else {
$output = $resource->toArray();
}
}
$pdo->debugParserModifier($id, 'resource');
return $output;
};
Судя по $pdo->getStore ресурс где-то кешируется. Но как-то пробовал ускорить сайт 10 вызовов {resource_id | resource: 'tv_param_name'} сильно замедляют сайт.Я ведь правильно понимаю — использование выше сниппета выше более рационально если надо дергать 5 — 6 полей другого ресурса?Более рационально, если тип поля text. $resource->getTVValue($tv['name']); делает запросы в базу.
можно наверно и другие типы полей прописать без getTVValue, но я tv почти не использую. Вдаваться в подробности их обработки не буду.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.