Как заставить работать rating_widget из хука?

InstantCMS 2.X

Рейтинг контента формируемого хуком. Не работает голосование

#1 4 мая 2017 в 20:36
Понадобилось мне выводить датасеты контента отсортированные специальным образом.
С этим отлично справляется хук content_list_filter.php
И, казалось бы, всё хорошо, но рейтинг у выведенных материалов отличается от того, что нужен. В результате разборки с пользователями, мол почему мой материал имеет рейтинг выше, а первый не он. И каждый раз объяснения про то, что за вчерашний и другие дни рейтинг в зачет не идет и т.д.
Впихнуть изменения рейтинга в модель не представляется возможным, поэтому решил использовать хук content_{$ctype['name']}_before_list.
Прямо в хуке формирую модель для датасета, там же получаю массив контента, там же получаю рейтинг. Выводится всё замечательно, но… голосование в виджете рейтинга не работает. После нажатия на голосовалку индикатор загрузки зависает навсегда.
Вставлял console.log в rating.js и понял, что почему-то нет значения url: '/rating/vote'
Аякс просто не знает кому звонить.
Значение это формируется в конце файла \templates\default\controllers\rating\widget.tpl.php
  1. <?php if ($is_first_widget) { ?>
  2. <script>
  3. icms.rating.setOptions({
  4. url: '<?php echo $this->href_to('vote'); ?>'
  5. });
  6. </script>
  7. <?php }?>
А в начале этого же файла написано:
  1. <?php $is_first_widget = $this->addJS('templates/default/js/rating.js'); ?>
И почему-то это не срабатывает.
Если отменить проверку $is_first_widget например так:
  1. <?php if (1==1) { ?>
  2. <script>
  3. icms.rating.setOptions({
  4. url: '<?php echo $this->href_to('vote'); ?>'
  5. });
  6. </script>
  7. <?php }?>
всё сразу прекрасно работает.

Пробовал уже в разных местах хука писать $is_first_widget == 1 или == true — бесполезно.
Кто поможет в беде?
#2 4 мая 2017 в 20:48
$is_first_widget и всё что с ним связано — это так обозначается тот момент, когда на странице надо вывести код, повторяющийся в цикле, только один раз.
Вероятно в вашем хуке нет подключения яваскрипта
  1. $this->addJS('templates/default/js/rating.js')
или оно неверно прописано, так как $this в хуке, уже не тот, что был вчера и третьего дня в шаблоне
#3 4 мая 2017 в 20:59

Вероятно в вашем хуке нет подключения яваскрипта

Loadырь
Пробовал.
class 'content' does not have a method 'addJS'
#4 4 мая 2017 в 20:59
Ris, по-видимому, вы ячейки с рейтингом переопределяете на свои в вашем хуке и
  1. <?php $is_first_widget = $this->addJS('templates/default/js/rating.js'); ?>
Уже отработал ранее, т.е. указанный скрипт подключился и все попытки его подключения вновь возвращают false, которое и записывается в $is_first_widget.
Варианты:
1. Текущий HTML виджета реплейсить, меняя что вам нужно.
2. В вашем хуке сделать что-то вроде:

  1. $this->cms_template->addHead('<script>icms.rating.setOptions({url: "'.href_to('rating', 'vote').'"});</script>');
3. В вашем хуке content_{$ctype['name']}_list_filter сделайте значение $ctype['is_rating'] в 0 или false. Пожалуй этот вариант самый лучший.
#5 4 мая 2017 в 21:09

2. В вашем хуке сделать что-то вроде:

Fuze
Не работает.
$this->cms_template->addJS('templates/default/js/rating.js')
не ругается, но тоже не работает.
Пробовал вне кода php писать
  1. <script>icms.rating.setOptions({url: "'.href_to('rating', 'vote').'"});</script>
ругается в консоли Uncaught ReferenceError: icms is not defined

1. Текущий HTML виджета реплейсить, меняя что вам нужно.

Fuze
А это как?

3. В вашем хуке content_{$ctype['name']}_list_filter сделайте значение $ctype['is_rating'] в 0 или false. Пожалуй этот вариант самый лучший.

Fuze
Виджет рейтинга пропал. shock

Уже отработал ранее, т.е. указанный скрипт подключился и все попытки его подключения вновь возвращают false, которое и записывается в $is_first_widget.

Fuze
А нельзя ли его как-то отключить, чтобы он потом подключился?
Или $is_first_widget = true в шаблон отправить принудительно?
#6 4 мая 2017 в 21:29

Не работает.

Ris
должно работать по идее

не ругается, но тоже не работает.

Ris
Так и подключать не за чем, данный скрипт у вас ранее подключен.

ругается в консоли Uncaught ReferenceError: icms is not defined

Ris
Правильно, тогда уж надо вот так:
  1. <script>
  2. $(function(){
  3. icms.rating.setOptions({url: "'.href_to('rating', 'vote').'"});
  4. });
  5. </script>

Виджет рейтинга пропал.

Ris
Тогда я не понял что вы делаете в хуке content_{$ctype['name']}_before_list. Хук вызывается, когда виджеты рейтинга сформированы. И еще попробуйте тогда в хуке content_{$ctype['name']}_before_list обратно включить $ctype['is_rating'] в 1.

А это как?

Ris
  1. foreach($items as $id=>$item){
  2. $items[$id]['rating_widget'] = str_replace('что найти', 'чем заменить', $item['rating_widget']);
  3. }
#7 4 мая 2017 в 21:34

Тогда я не понял что вы делаете в хуке content_{$ctype['name']}_before_list. Хук вызывается, когда виджеты рейтинга сформированы.

Fuze
Приходится формировать новые виджеты. Прямо в хуке. С нужными значениями рейтинга.
Ведь список заново получается из модели без виджетов рейтинга.
#8 4 мая 2017 в 21:36

Приходится формировать новые виджеты. Прямо в хуке. С нужными значениями рейтинга.
Ведь список заново получается из модели без виджетов рейтинга.

Ris
Тогда попробуйте в первом хуке, где фильтр, выключать рейтинг ($ctype['is_rating'] = 0;), во втором включать ($ctype['is_rating'] = 1;). Должно получиться.
#9 4 мая 2017 в 21:45

Тогда попробуйте в первом хуке, где фильтр, выключать рейтинг ($ctype['is_rating'] = 0;), во втором включать ($ctype['is_rating'] = 1;). Должно получиться.

Fuze
Я первый хук фильтра совсем выключил. Во втрором хуке content_{$ctype['name']}_before_list формируется модель и из нее новый список контента:
  1. $this->model->filterIn("id", $newcom)->order_by = "FIELD(i.id, $newstr)";
  2. $items = $this->model->getContentItems($ctype['name']);
Потом туда виджеты рейтинга засовываются:
  1. // Рейтинг
  2. if ($ctype['is_rating'] && $items && $this->isControllerEnabled('rating')){
  3.  
  4. $rating_controller = cmsCore::getController('rating', new cmsRequest(array(
  5. 'target_controller' => $this->name,
  6. 'target_subject' => $ctype['name']
  7. ), cmsRequest::CTX_INTERNAL));
  8.  
  9. $is_rating_allowed = cmsUser::isAllowed($ctype['name'], 'rate');
  10. $is_first_widget = true;
  11.  
  12. foreach($items as $id=>$item){
  13. $is_rating_enabled = $is_rating_allowed && ($item['user_id'] != $this->cms_user->id);
  14. $items[$id]['rating_widget'] = $rating_controller->getWidget($item['id'], $item['rating'], $is_rating_enabled);
  15. }
  16.  
  17. }

<script>
$(function(){
icms.rating.setOptions({url: "'.href_to('rating', 'vote').'"});
});
</script>

Fuze
Uncaught ReferenceError: $ is not defined
#10 4 мая 2017 в 21:53

Я первый хук фильтра совсем выключил.

Ris
Включите

Во втрором хуке content_{$ctype['name']}_before_list формируется модель и из нее новый список контента:

Ris
Смысла от сортировки тут нет. Сортировать нужно в предыдущем хуке.

1 хук — нужная сортировка, $ctype['is_rating'] = 0
2 хук формирование виджета рейтинга, $ctype['is_rating'] = 1
профит
#11 4 мая 2017 в 23:08
Fuze,
Включил оба хука. В первом выбираю список контента, во втором подменяю рейтинг.
Если сделать так:

1 хук — нужная сортировка, $ctype['is_rating'] = 0
2 хук формирование виджета рейтинга, $ctype['is_rating'] = 1

Fuze
получаю Notice: Undefined index: rating_widget in ...
Если убрать отключение-включение рейтинга — голосование работает четко, но у первого контента в спике виджет рейтинга пустой и количество запросов sql возрастает с 28-ми до 42-х… Ведь рейтинг на подмену не от балды берется, а приходится повторить те же операции, что и в первом виджете.
Все же это довольно запутанный и многоступенчатый метод.
Попробую всё же найти способ просто отправить в шаблон виджета $is_first_widget = true;

В общем убился, но так ничего путного и не придумал.
Нарисовал в \templates\default\controllers\rating\widget.tpl.php
  1. <?php if ($is_first_widget || substr($_SERVER['REQUEST_URI'], 0, 16) == '/мой_датасет' )
Костыль, конечно, но в шаблоне и так пришлось многое допилить.
Fuze, Loadырь, огромное спасибо за помощь!
Теперь понял, как и что.
Но всё равно создатель яваскрипта — явно недобрый человек… smile
Вы не можете отвечать в этой теме.
Войдите или зарегистрируйтесь, чтобы писать на форуме.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.