Проблема с TV параметрами в MODx
$modx -> resource -> setTVValue(11, 1);
print_r($modx -> resource -> getTVValue(11));
$modx -> resource -> setTVValue(11, 2);
print_r($modx -> resource -> getTVValue(11));
That code outputs 2 and 2, when must outputs 1 and 2, the whole code is in the snippet, resource cache is turned off, snippet call is not cacheble too, like "[[!..."
Переводить не стал, думаю ты язык знаешь, вот тот же вопрос на stackoverflow.com/questions/14052207/modx-revo-settvvalue-returns-old-data
print_r($modx -> resource -> getTVValue(11));
$modx -> resource -> setTVValue(11, 2);
print_r($modx -> resource -> getTVValue(11));
That code outputs 2 and 2, when must outputs 1 and 2, the whole code is in the snippet, resource cache is turned off, snippet call is not cacheble too, like "[[!..."
Переводить не стал, думаю ты язык знаешь, вот тот же вопрос на stackoverflow.com/questions/14052207/modx-revo-settvvalue-returns-old-data
Комментарии: 28
Быстро подорвался и на вапрос атветил, да?
Тогда предлагаю добавить в форму вопроса поле «Волшебное слово» xD. Помочь сможешь? Пожаааалуйста )
Да хоть бы код в тег code оформил, хрен с ним, с «пожалуйста».
Работает без проблем, но только при одном условии — если вызывается не на странице, ТВ которой он должен обновить.
А вот так — выдаёт прикольный глюк, очевидно связанный с кэшированием.
Почему выходит такая фигня — мне не ведомо, а копать исходники времени нет.
Работает без проблем, но только при одном условии — если вызывается не на странице, ТВ которой он должен обновить.
if ($res = $modx->getObject('modResource', 1)) {
$res->setTVValue(1, 1);
echo $res->getTVValue(1);
$res->setTVValue(1, 2);
echo $res->getTVValue(1);
die;
// 12
}
А вот так — выдаёт прикольный глюк, очевидно связанный с кэшированием.
if ($res = $modx->getObject('modResource', $modx->resource->id)) {
$res->setTVValue(1, 1);
echo $res->getTVValue(1);
$res->setTVValue(1, 2);
echo $res->getTVValue(1);
die;
// 22
}
Поэтому, переходим на обычный xPDOif ($tv = $modx->getObject('modTemplateVarResource', array('tmplvarid' => 1, 'contentid' => $modx->resource->id))) {
$tv->set('value', 1);
echo $tv->get('value');
//$tv->save(); //по желанию
$tv->set('value', 2);
echo $tv->get('value');
die;
// 12
}
Почему выходит такая фигня — мне не ведомо, а копать исходники времени нет.
В ходе обработки запроса modx загружает ресурс и все его tv-параметры, и потом при получении значений tv-параметров обращается к первоначальным данным. После установки нового значения надо выполнить что-то вроде:
$modx->resource->set('tv_name', null);
А можно полный код, а то я не понял к какому варианту применимо.
После этой строки вашего первоначального кода:
$modx->resource->setTVValue(11, 1);
надо добавить$modx->resource->set('tv_name', null);
или$tv = $modx->resource->get('tv_name');
if (is_array($tv)) {
$tv[1] = 1;
$modx->resource->set('tv_name', $tv);
}
где tv_name — имя tv-параметра с id равным 11. Это позволит дальше на странице использовать новое значение tv-параметра, если оно необходимо.
Хороший хак, спасибо, это позволит не уходить от стандартного АПИ модэкса, но как говорил Безумкин — выглядит не очень красиво, но думаю да и Х* с ним, хотя я сам тот еще эстет в этом плане )
А как сохранить новое значение в ТВ?
$modx->resource->save() не помогает, конечно. А если значение нужно только на время работы скрипта, и сохранять его не надо — то и ТВ ни к чему, можно любое имя написать.
$modx->resource->save() не помогает, конечно. А если значение нужно только на время работы скрипта, и сохранять его не надо — то и ТВ ни к чему, можно любое имя написать.
Сохранить новое значение стандартным способом:
$modx->resource->setTVValue(.., ...);
тот код просто использовать вдобавок, чтобы обновить значение у текущего ресурса modx, на время обращения к нему.
Ну да, точно =)
Спасибо за новый способ работы с ТВ.
Спасибо за новый способ работы с ТВ.
Спасибо так же и от меня, чувствую сэкономили вы мне часов эдак n*999
А так же интересно узнать откуда инфа по столь завуалированным нюансам? Почитать думаю не вредно будет.
Лучший источник информации — исходный код :) Сам просто сталкивался с такой ситуацией и пришлось покопаться, чтобы дойти до истины.
Ясно, я так делал, только пока язык учил, сейчас желания лезть в чужой код отпало на совсем — это очень много времени съедает, поэтому стараюсь использовать продукты которые не требуют чтобы кроме их непосредственных вохможностей была необходимость перелопачивать код, считаю такие продукты на уровне нашего автопрома, купил и ковыряйся )))
Да, так и есть. А выводит он 22 потому, что 2 было сохранено в прошлый раз.
Если по очереди комментировать вызовы setTVValue — хорошо видно.
А ваш хак отлично работает, хоть и выглядит это некрасиво.
Если по очереди комментировать вызовы setTVValue — хорошо видно.
А ваш хак отлично работает, хоть и выглядит это некрасиво.
if ($res = $modx->getObject('modResource', $modx->resource->id)) {
$modx->resource->set('test', null);
$res->setTVValue(1, 1);
echo $res->getTVValue(1);
$modx->resource->set('test', null);
$res->setTVValue(1, 2);
echo $res->getTVValue(1);
die;
//12
}
Чуть выше привел более эстетичное решение. Какое бы оно некрасивое не было, без него страница не увидит новое значения tv-параметра, если оно будет изменено, к примеру, сниппетом :)
В моем случае помогло вот такое ваше решение.
$modx->resource->set('nodeShop_orderState', null);
$modx->resource->set('nodeShop_orderData', null);
$result = array(
$this -> resource -> setTVValue('nodeShop_orderState', json_encode($orderState)),
$this -> resource -> setTVValue('nodeShop_orderData', json_encode($orderData))
);
if(array_sum($result) != 2) return;
После
$modx->resource->set('nodeShop_orderState', null);
$modx->resource->set('nodeShop_orderData', null);
Тв сразу же актуальны.
Спасибо тебе огроменное Андрей, спустя 3 года!.. У меня сейчас из-за этого глюка чуть мозг не взорвался ))
Да да, первый вариант, как раз вызывается на той самой странице, которую должен обновить, второй вариант, глючит, а третий вот как раз ждал от вас, спасибки огромное, он работает! Как в воду глядел, хотел на чистом xPDO написать. Кстати я еще нашел такой вариант, учудил тип с форума
$modx->resource->set('SendTestEmail', $fields);
у него такая же проблема была Ссылка на ветку, главное что во первых работает, но во вторых непонятно где он хранит эти данные у объекта, облазив БД не нашел никаких значений даже близко, что думаешь об этом методе?
Судя по тому, что пишет Боб Рей — оно сохраняется в ТВ, а не в объект.
Вот и я так думал пока не залз в БД и не увидел что там НЕТ этого значения =). Что то огонь какой то с этим API у них.
У меня оно и не сохраняется.
Это поле будет работать только во время выполнения скрипта. То есть, методом set мы выставляем любое поле с любым значением, потом можем его использовать как хотим, а после работы оно пропадает — ибо сохранить его некуда, в модели то его нет.
Если же ничего туда не писать, а просто print_r($modx->resource->get('test')); — то будут данные ТВ параметра.
Всё это очень интересно, но мне надо работать, так что не буду копать «почему всё именно так, а не иначе». Вообще, стараюсь не использовать ТВ, если это возможно.
Это поле будет работать только во время выполнения скрипта. То есть, методом set мы выставляем любое поле с любым значением, потом можем его использовать как хотим, а после работы оно пропадает — ибо сохранить его некуда, в модели то его нет.
Если же ничего туда не писать, а просто print_r($modx->resource->get('test')); — то будут данные ТВ параметра.
Всё это очень интересно, но мне надо работать, так что не буду копать «почему всё именно так, а не иначе». Вообще, стараюсь не использовать ТВ, если это возможно.
Странно я проверял, потому что тоже думал что будет во время выполнения скрипта, и у меня писалось, то есть сперва я выставлял через сет а потом брал через гет закомментировав сет и у меня все показывалось как будто значение сохранилось.
Ну — щас через админку смотрел, не сохраняется.
Хотя, уже ничему не удивлюсь =)
Хотя, уже ничему не удивлюсь =)
Блин, да это мой косяк, извиняюсь, глаз замылился, действительно это атрибут на время выполнения скрипта. Видимо Боб до сих пор мучается =)
Пробовал так, тот же результат, ТВ упорно меняется только после того как я один раз открою страницу, как будто тв у объекта сейвятся после отработки скрипта.
$tv = $modx->getObject('modTemplateVar',array('id'=>'11'));
$tv -> setValue($modx->resource->get('id'), 88);
$tv->save();
print_r($modx -> resource -> getTVValue(11));
Выводит сперва значение которое было, после перезагрузки страницы уже то что выставляю в скрипте.
$tv = $modx->getObject('modTemplateVar',array('id'=>'11'));
$tv -> setValue($modx->resource->get('id'), 88);
$tv->save();
print_r($modx -> resource -> getTVValue(11));
Выводит сперва значение которое было, после перезагрузки страницы уже то что выставляю в скрипте.
Попробуй сниппет вызывать плагином до рендера страницы
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.