Добавить сортировку по дате изменения контента

InstantCMS 2.X
#1 7 октября 2017 в 00:00
В админке тут:
" Типы контента — Имя контента — Наборы — Создать набор — Сортировка — Сортировка по полю"
есть список для выбора поля, по которому сортировать.
Как бы в этот список добавить поле последней правки?
В таблицах из "коробки" такое поле есть с названием "date_last_modified".
#2 7 октября 2017 в 02:06
Argus,
Лучше сделать хук content_list_filter и в нем отсортировать контент по какому нужно полю.
#3 7 октября 2017 в 12:13
Жаль, я не умею делать хуки.
#4 7 октября 2017 в 13:48

Жаль, я не умею делать хуки.

Argus
Это не беда. Сейчас расскажу.
Итак, во-первых решаем, что нам нужно сделать с контентом. В вашем случае нужно просто добавить в модель сортировку по определенному полю.
Смотрим, где в модели компонента контент есть вызов подходящего события. Открываем файл \system\controllers\content\frontend.php и поиском ищем слово hook. Там хуков семь штук. Нас интересуют хуки, которые отправляют на обработку модель компонента. Находим два подходящих:
  1. list($ctype, $this->model) = cmsEventsManager::hook('content_list_filter', array($ctype, $this->model));
  2. list($ctype, $this->model) = cmsEventsManager::hook("content_{$ctype['name']}_list_filter", array($ctype, $this->model));
Вот это вот $this->model как раз и есть то, куда нам надо добавить сортировку.
Теперь создаем пустой файлик content_list_filter.php (или content_posts_list_filter.php, если достаточно сортировки только в одном типе контента) и помещаем его в \system\controllers\content\hooks\.
В файле \system\controllers\content\manifest.php в конец дописываем имя нашего хука:
  1. <?php
  2.  
  3. return array(
  4.  
  5. 'hooks' => array(
  6. 'fulltext_search',
  7. 'admin_dashboard_chart',
  8. 'menu_content',
  9. 'user_delete',
  10. 'user_tab_info',
  11. 'user_tab_show',
  12. 'user_privacy_types',
  13. 'sitemap_sources',
  14. 'rss_feed_list',
  15. 'rss_content_controller_form',
  16. 'rss_content_controller_after_update',
  17. 'frontpage',
  18. 'frontpage_types',
  19. 'ctype_relation_childs',
  20. 'admin_content_dataset_fields_list',
  21. 'content_list_filter'
  22. )
  23.  
  24. );
  25.  
В файле content_list_filter.php пишем что-нибудь типа этого:
  1. <?php
  2.  
  3. class abcdefg extends cmsAction {
  4.  
  5. public function run($data){
  6.  
  7. return $data;
  8.  
  9. }
  10.  
  11. }
Потом идем в админку — компоненты — управление событиями и видим, что доступны новые события. Обновить события в базе данных.
Возвращаемся на сайт и сразу видим ошибку:
Fatal error: Class 'onContentContentListFilter' not found in D:\OSPanel\domains\DEF821.tes\system\core\controller.php on line 519
Копируем onContentContentListFilter и вставляем имя класса вместо галиматьи abcdefg, что написали в начале (можно было, конечно подумать и написать правильное имя класса сразу, но мне так проще). Получается что-то типа этого:
  1. <?php
  2.  
  3. class onContentContentListFilter extends cmsAction {
  4.  
  5. public function run($data){
  6.  
  7. return $data;
  8.  
  9. }
  10.  
  11. }
Обновляем страницу, ошибка пропала. Что в хук прилетело ($data), то и улетело. Пока наш хук ничего не меняет.
Теперь надо добраться до модели, чтобы её дополнить сортировкой. Разворачиваем входящий архив:
  1. list($ctype, $model) = $data; // Разворачиваем массив входящих данных
Теперь добавляем туда нужную сортировку:
  1. $model->orderBy('i.date_last_modified', 'desc') ; // Добавляем сортировку по дате изменения в обратном порядке
Смотрим в отладке, что оно там выбирает:
  1. SELECT i.*, u.nickname AS user_nickname, f.title AS folder_title
  2. FROM cms_con_posts i
  3. FORCE INDEX FOR ORDER BY (date_pub)
  4. INNER JOIN cms_users AS u FORCE INDEX (PRIMARY) ON u.id = i.user_id
  5. LEFT JOIN cms_content_folders AS f ON f.id = i.folder_id
  6. WHERE (i.is_parent_hidden IS NULL) AND (i.is_approved = '1') AND (i.is_deleted IS NULL) AND (i.is_pub = '1')
  7. ORDER BY i.date_last_modified DESC
  8. LIMIT 0, 15
  9.  
Всё здорово! Есть сортировка по дате модификации:
ORDER BY i.date_last_modified desc

Но теперь таким образом будет отсортирован весь контент, а нам это не нужно.
Идем в админку и создаем набор с системным именем например modified.
Теперь в хуке все действия оборачиваем в условие
  1. if (strpos($_SERVER['REQUEST_URI'], 'modified')){ // Если в ответе сервера есть индекс modified
И теперь наша сортировка будет добавляться только в наборе.
Вот получившийся файл content_list_filter.php :
  1. <?php
  2.  
  3. class onContentContentListFilter extends cmsAction {
  4.  
  5. public function run($data){
  6.  
  7. list($ctype, $model) = $data; // Разворачиваем массив входящих данных
  8.  
  9. if (strpos($_SERVER['REQUEST_URI'], 'modified')){ // Если в ответе сервера есть индекс modified
  10.  
  11. $model->orderBy('i.date_last_modified', 'desc'); // Добавляем сортировку по дате изменения в обратном порядке
  12.  
  13. }
  14.  
  15. $data = array($ctype, $model);
  16.  
  17. return $data;
  18.  
  19. }
  20.  
  21. }
Удачи в экспериментах! v
#5 7 октября 2017 в 13:55
Можно сделать проще.
1. Создать набор по дате.
2. Зайти в phpmyadmin в таблицу cms_content_datasets и нажать редактировать нужную вам запись
3. В поле sorting date_pub поменять на date_last_modified и сохранить
#6 7 октября 2017 в 14:00

В поле sorting date_pub поменять на date_last_modified и сохранить

Fuze
Да, в данном случае так намного проще.
Но мне приходилось сортировать контент по связанным таблицам, а там так просто не выходит.
#7 9 октября 2017 в 10:27
Спасибо!
Попробовал. Работают оба способа.
Хорошо бы, чтоб в выпадающем списке наборов добавилось.
#8 9 октября 2017 в 10:37

Хорошо бы, чтоб в выпадающем списке наборов добавилось.

Argus
В списке наборов галку "Публикация" поставьте.
#9 9 октября 2017 в 16:48
Я имел ввиду, что нету в выпадающем списке в "Типы контента — Имя контента — Наборы — Создать набор — Сортировка — Сортировка по полю".
В колонке "Публикация" тут "Типы контента — Имя контента — Наборы" галка стоит и в настройке виджетов Опции — Применить фильтры из набора самодельный пункт в списке есть и его можно выбирать…
Вы не можете отвечать в этой теме.
Войдите или зарегистрируйтесь, чтобы писать на форуме.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.