MODX Evo Jotx (part 2)

Введение


На тему Jot я уже писал немного. Но пришлось еще глубже вникать и надо как-то закрепить структуру этого сниппета. Была задача вывести данные юзера из личного кабинета. Я поначалу тупо впал в ступор. Казалось, что плейсхолдеры заточены под таблицы самого jot. Читать доки как всегда - дело бесполезное. Пришлось лезть в исходники. Предлагаю подробнее разобраться в выводе комментов. Все оказалось круче.

Выборка комментариев.


В Jotx все основные задачи(режимы) разделены на "actions". И за вывод комментариев отвечает actions '/assets/snippets/jot/actions/comments.inc.php' или '/assets/snippets/jot/actions/treecomments.inc.php'. В зависимости от конфигурации.

Пример из конфига: $action = isset($action) ? $action : 'tree'; 

В этом случае ищется файл "tree.inc.php", тот подключает 'form.inc.php' и 'treecomments.inc.php'.

 

В этом файле(tree.inc.php) ищется функция $action+"_mode" и запускается. Как параметр передается ссылка на экземпляр класса Jot.

А функция пытается вывести:

  • $output = treecomments_mode($object);
  • $output .= form_mode($object);
  • return $output;

Из провайдера(см. про провайдер) вызывается :

  • GetComments
  • последний выывает событие doEvent("onBeforeGetComments",array("docid"=>$docid,"tagid"=>$tagid,"viewtype"=>$viewtype,"upc"=>$upc,"sort"=>$sort,"offset"=>$offset,"length"=>$length,"sql"=>&$sql,"userid"=>$userid)))). тут можно вернуть что-нибудь свое и остальной вывод прервется.
  • далее вызывается GetCommentsArray($sql,$docid,$tagid,$upc,$userid) . наконец запрос к таблице jot_content и присоединяется таблиц manager_users, user_attributes, web_users,web_user_attributes.
  • цикл по выборке. вызов getCustomFieldsArray($ids); $ids - все выбранные id комментов. в последней - выборка из  таблицы fields. т.е. кастомные поля. обычно email, name, img. Там чисто привязка к id коммента. Не к юзеру. Это, похоже, больше для анонимов.
  • getUserPostCount, а там doEvent("onBeforeGetUserPostCount",array("docid"=>$docid,"tagid"=>$tagid))))
  • и тут выборка всех комметов(по переданным id) с группировкой по 'createdby'; возврат - массив [userId=>count].

В итоге 

  • $comments=array();
  • $comments[] = $row;  вся строка из таблицы jot_content плюс все данные юзера (из таблиц manager_users, user_attributes, web_users,web_user_attributes)
  • $comment["custom"] = $custom[$comment["id"]];   - плюс кастомные поля из таблицы fields
  • $comment["userpostcount"] = intval($userpostcount[$comment["createdby"]]);   - плюс кол-во комментов автора.
  • $arrComments[] = $comment; - отдельный коммент довабляется в общий массив
  • doEvent("onGetComments",array("arrComments"=>$arrComments,"docid"=>$docid,"tagid"=>$tagid,"upc"=>$upc,"userid"=>$userid)) вызов обратки
  • и возрат массива комметов

$viewtype:

  • 0 - published = 0; - выбрать неопубликованные
  • 1 - published = 1; default - опубликованные
  • 2 - and published >= 0; выбрать все

$upc (user post count) кол-во постов автора

  • 0 - array()
  • 1 - default: $userpostcount = $this->getUserPostCount("*",$tagid); 
  • 2 - $userpostcount = $this->getUserPostCount($docid,$tagid);

На выходе имеем: 

$arr_par=Array
(
    [arrComments] => Array
        (
            [0] => Array
                (
                    [id] => 99
                    [title] => new comment
                    [tagid] => 
                    [published] => 1
                    [uparent] => 587
                    [parent] => 0
                    [flags] => 
                    [secip] => 212.100.145.84
                    [sechash] => 4336d19912d79aaf4a04a28cf1c7e845
                    [content] => Соглашусь с автором, дверь в большую комнату сделана неудобно. В самом углу. Дверной наличник не получается полностью приклеить. Нам рабочие его обрезали.
                    [mode] => 0
                    [createdby] => -73
                    [createdon] => 1492666351
                    [editedby] => 0
                    [editedon] => 0
                    [deleted] => 0
                    [deletedon] => 0
                    [deletedby] => 0
                    [publishedon] => 0
                    [publishedby] => 0
                    [rating] => 8
                    [username] => elena@mail.ru
                    [fullname] => Елена
                    [email] => elena@mail.ru
                    [role] => 0
                    [gender] => 0
                    [country] => 
                    [photo] => assets/snippets/webloginpe/userimages/73.JPG
                    [custom] => 
                    [userpostcount] => 3
                )

            [1] => Array
                (
.
.
.                )

            [2] => Array
                (
.
.
.                )

        )

    [docid] => 587
    [tagid] => 
    [upc] => 1
    [userid] => *
)


Провайдер - это интерфейс к таблицам.


JotХ - весьма навороченный сниппет. Поэтому все операции с базой (таблицами) вынесены в отдельный класс.

Доступ - $myInstJot->provaider

  • /assets/snippets/jot/includes/jot.db.class.inc.php
  • class CJotDataDb
  • function Set($field, $value)
  • function Get($field)
  • function getFields() 
  • function setCustom($field, $value)
  • function getCustom($field)
  • function FirstRun($path)
  • function getCustomFieldsArray($id_values) 
  • function Comment($id=0)
  • function Save()
  • function Delete()
  • function hasPosted($interval,$user) 
  • function getUserPostCount($docid,$tagid)
  • function GetCommentCount($docid,$tagid,$viewtype,$userid='*')
  • function getOrderByDirection($dir = "a")
  • function GetComments($docid,$tagid,$viewtype,$upc,$sort,$offset,$length,$userid='*')
  • function GetCommentsArray($query,$docid,$tagid,$upc,$userid='*')
  • function hasSubscription($docid = 0,$tagid = '', $user = array())
  • function getSubscriptions($docid = 0,$tagid = '')
  • function Subscribe($docid = 0,$tagid = '', $user = array())
  • function Unsubscribe($docid = 0,$tagid = '', $user = array())
  • function isValidComment($docid = 0,$tagid = '', $commentid = 0)
  • function doEvent($event,$params=array())
  • function sqlPart($docid,$tagid,$userid="*")

Чтобы получить комменты : $array_comments = $myInstJot->provider-> GetComments ($param["docids"], $aram["tagids"], $view, $param["upc"], $param["sortby"], 0, 0, $param["userids"]);

Таблицы Jot


  • jot_fields
  • jot_subscriptions
  • jot_content

 

 jot_content: 

Field 192 stringType 589815 blobNull 9 stringKey 9 stringDefault 589815 blobExtra 90 string
id int(10) NO PRI   auto_increment
title varchar(255) YES      
tagid varchar(255) YES MUL    
published int(1) NO   0  
uparent int(10) NO MUL    
parent int(10) NO MUL 0  
flags varchar(25) YES      
secip varchar(32) YES MUL    
sechash varchar(32) YES      
content mediumtext YES      
mode int(1) NO   1  
createdby int(10) NO   0  
createdon int(20) NO   0  
editedby int(10) NO   0  
editedon int(20) NO   0  
deleted int(1) NO   0  
deletedon int(20) NO   0  
deletedby int(10) NO   0  
publishedon int(20) NO   0  
publishedby int(10) NO   0  
rating int(11) NO   0  

parent - id  коммента-родителя

uparent - id 'контейнера'. это страница, вопрос, топик, фото и т.д. т.е. к чему написан комметарий или ответ на коммент

Вывод в HTML


У Jot своя система обработки шаблонов(чанков), т.е. парсинга. 

Для этого используется класс CChunkie. /assets/snippets/jot/includes/chunkie.class.inc.php.

  • CChunkie($template = '') - конструктор
  • function CreateVars($value = '', $key = '', $path = '') - создает переменные phx ( cchancueItem->phx->placeholders[...])
  • AddVar($name, $value) - просто вызывает CreateVars
  • getTemplate($tpl) - тут варианты: html, чанк, @CODE:..., @FILE:..... в нашем случае - $tplComments в конфигурации
  • function Render() - тут $this->phx->Parse($this->template); т.е. парсит phx

 

В итоге:

  • в actions вызывается функция Render. в моем случае - $object->config["html"]["comments"] = treeRender($tree, 0 , $object, 1); - отсюда и [+jot.html.comments+], если попросить все в плейсхолдеры (&placeholders=`1`)
  • в Render - цикл по массиву комментов
    • $tpl->AddVar('jot',$object->config);
    • $tpl->AddVar('comment',$row);
    • $tpl->AddVar('jot.wrapper ..... - тут рекурсивный вызов и jot.wrapper присваивается весь вывод.
    • $res .= $tpl->Render(); - работает парсер phx 
  • получаем плейсхолдеры
    • типа [+comment.id+] = "comment"+"поле таблицы jot-content, присоединенные данные пользователя и прочие(см. выше вывод выборки из базы)"
    • типа [+jot.html.comments+]="jot"+"поля массива config". смысл - можно самому скомпоновать структуру. Естественно, заблокировав вывод и все направить в плейсхолдеры (&placeholders=`1` &output=`0`).
      • [+jot.html.navigation+] - блок навигации
      • [+jot.html.comments+] - блок комментов
      • [+jot.html.moderate+] - блок модерации
      • [+jot.html.form+] - форма
    • [+jot.wrapper+] - весь вывод
  • doEvent("onSetCommentsOutput")  - запуск события

Вывод: все в общем около дела, как говорят на вологодчине). Можно назначить плейсхолдеры на все элементы массива выборки(см. выше), конфига и весь вывод.

Если же данных вам все-таки не хватает то вспомним, что перед возвратом массива выбранных постов, сразу после выборки вызывается событие ->doEvent("onGetComments",array("arrComments"=>$arrComments,"docid"=>$docid,"tagid"=>$tagid,"upc"=>$upc,"userid"=>$userid)) . Вот им и можно воспользоваться. Идея - понапихать в итоговый массив своих данных. А там они должны автоматом загрузится в плейсхолдеры.

Обработка событий


Вызов событий через function doEvent($event,$params=array()) ;

Забавно то, что сами параметры можно узнать только в исходнике))). Нигде я не нашел описания. 

  • $event - событие. Например: "cppvJotEvent"
    • если существует такая фунция, то она и будет вызвана с $params
    • если нет такой фукции, то ищется в плагинах.
    • можно назначить через запятую несколько функций или плагинов.

Комментарии 0






Разрешённые теги: <b><i><br>Добавить новый комментарий: