diff --git a/CHANGELOG.md b/CHANGELOG.md index 49e0152..db6ede3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,107 +1,138 @@ # (MODX)EvolutionCMS.snippets.ddMenuBuilder changelog + +## Version 2.1 (2020-03-07) +* \+ Snippet: All templates has the following placeholders: + * \+ `[+totalAllChildren+]` — total number of displayed children at all levels. + * \+ `[+totalThisLevelChildren+]` — total number of displayed immediate children. + * \+ `[+level+]` — item level in menu. +* \* `\ddMenuBuilder` + * \+ `\ddMenuBuilder::generate`: + * \+ Return the following 2 counters: + * \+ `$result['totalAll']` — total number of items displayed at all levels. + * \+ `$result['totalThisLevel']` — total number of items displayed at this level. + * \+ Added the parameter `$params->level` for internal use only. + * \* Returns `stdClass` instead of `arrayAssociative`. + * \* `\ddMenuBuilder::prepareProviderParams`: + * \+ The `$params->providerParams` parameter can be set as `stdClass` too. + * \* Returns `stdClass` instead of `arrayAssociative`. + * \* `\ddMenuBuilder::$templates`: Now it's `stdClass`. +* \+ Composer.json. +* \+ CHANGELOG: Small improvements. +* \+ README: + * \+ Requires. + * \+ Documentation → Installation. + + ## Version 2.0 (2019-06-13) * \* Attention! Backward compatibility is broken! * \* Attention! (MODX)EvolutionCMS.libraries.ddTools >= 0.24.1 is required. * \* Template parameters refactoring. * \+ Added templates for unpublished items: - * \+ $templates['itemUnpub'] — The menu item template for unpublished document. Default: $templates['item']. - * \+ $templates['itemUnpubActive'] — The menu item template for unpublished document which is one of the parents to the current document when the current document doesn't displayed in the menu (e. g. excluded by the “depth” parameter). Default: $templates['itemActive']. -* \* “ddTools::$modx” is used instead of global “$modx”. + * \+ `$templates['itemUnpub']` — The menu item template for unpublished document. Default: `$templates['item']`. + * \+ `$templates['itemUnpubActive']` — The menu item template for unpublished document which is one of the parents to the current document when the current document doesn't displayed in the menu (e. g. excluded by the `depth` parameter). Default: `$templates['itemActive']`. +* \* `\ddTools::$modx` is used instead of global `$modx`. * \* Fixed an error when docs that must be hidden will be showed. * \* Refactoring, other small changes. + ## Version 1.13b (2018-10-17) * \* Attention! PHP >= 5.6 is required. -* \* ddMenuBuilder snippet: - * \* Wrong type of “providerParams” was fixed. -* \* ddMenuBuilder class: +* \* Snippet: + * \* Wrong type of `providerParams` was fixed. +* \* `\ddMenuBuilder`: * \* Small refactoring. * \* Optimization: - * \- ddMenuBuilder->generate: Redudnand “array_merge” removed, - * \- ddMenuBuilder->generate: Убран проход по всем документам в дереве который определял где находится активный документ. + * \- `\ddMenuBuilder::generate`: Redudnand `array_merge` removed, + * \- `\ddMenuBuilder::generate`: Убран проход по всем документам в дереве который определял где находится активный документ. + ## Version 1.12 (2017-08-30) -* \* Menu item active status is no logner depends on the “show_in_menu” children flag. -* \+ Added JSON format support for the “providerParams” and “placeholders” parameters. -* \* Attention! MODXEvo.library.ddTools >= 0.20 is required. +* \* Attention! (MODX)EvolutionCMS.libraries.ddTools >= 0.20 is required. +* \* Menu item active status is no logner depends on the `show_in_menu` children flag. +* \+ Added JSON format support for the `providerParams` and `placeholders` parameters. + ## Version 1.11 (2016-11-25) * \* Attention! PHP >= 5.4 is required. -* \* Attention! MODXEvo.library.ddTools >= 0.16.1 is required. +* \* Attention! (MODX)EvolutionCMS.libraries.ddTools >= 0.16.1 is required. * \+ Added an ability to pass ids of the selected documents to output. * \* Short array syntax is used because it's more convenient. -* \* ddMenuBuilder Class: +* \* `\ddMenuBuilder`: * \* Unpublished docs will be used if needed. - * \* ddMenuBuilder->generate: - * \* Now takes custom “where” clauses instead of parent id. + * \* `\ddMenuBuilder::generate`: + * \* Now takes custom `where` clauses instead of parent id. * \* Refactoring parameters style. * \* Other minor changes. + ## Version 1.10 (2016-09-12) -* \+ Added an ability to pass additional data into a “tpls_outer” template (see the “placeholders” parameter). -* \+ Added support of “@CODE:” keyword prefix in the snippet templates. -* \* Attention! Snippet now requires MODXEvo >= 1.1. +* \* Attention! MODXEvo >= 1.1 is required. +* \+ Added an ability to pass additional data into a `tpls_outer` template (see the `placeholders` parameter). +* \+ Added support of `@CODE:` keyword prefix in the snippet templates. + ## Version 1.9 (2015-12-28) -* \* Внимание! Используется «modx.ddTools» 0.15. -* \* ddMenuBuilder snippet: - * \* Вместо прямого обращения к полю «$modx->config» используется метод «$modx->getConfig». +* \* Attention! (MODX)EvolutionCMS.libraries.ddTools >= 0.15 is required. +* \* Snippet: + * \* Вместо прямого обращения к полю `$modx->config` используется метод `$modx->getConfig`. * \* Следующие параметры были переименованы (старые имена поддерживаются, но не рекомендуются к использованию): - * \* «tplRow» → «tpls_item». - * \* «tplHere» → «tpls_itemHere». - * \* «tplActive» → «tpls_itemActive». - * \* «tplParentRow» → «tpls_itemParent». - * \* «tplParentHere» → «tpls_itemParentHere». - * \* «tplParentActive» → «tpls_itemParentActive». - * \* «tplUnpubParentRow» → «tpls_itemParentUnpub». - * \* «tplUnpubParentActive» → «tpls_itemParentUnpubActive». - * \* «tplWrap» → «tpls_outer». - * \* Параметр «tpls_itemParentHere» по умолчанию равен `
  • [+menutitle+]
  • ` (значение по умолчанию больше не зависит от параметра «tpls_itemParent»). Решение неоднозначное, подумать. -* \* ddMenuBuilder class обновлён до 2.0: + * \* `tplRow` → `tpls_item`. + * \* `tplHere` → `tpls_itemHere`. + * \* `tplActive` → `tpls_itemActive`. + * \* `tplParentRow` → `tpls_itemParent`. + * \* `tplParentHere` → `tpls_itemParentHere`. + * \* `tplParentActive` → `tpls_itemParentActive`. + * \* `tplUnpubParentRow` → `tpls_itemParentUnpub`. + * \* `tplUnpubParentActive` → `tpls_itemParentUnpubActive`. + * \* `tplWrap` → `tpls_outer`. + * \* Параметр `tpls_itemParentHere` по умолчанию равен `
  • [+menutitle+]
  • ` (значение по умолчанию больше не зависит от параметра `tpls_itemParent`). Решение неоднозначное, подумать. +* \* `\ddMenuBuilder` обновлён до 2.0: * \* Теперь это обычный объект, поля и методы не статические. - * \* Публичный только метод «generate», остальные поля и методы приватные. - * \- Удалено поле «$table», вместо него используется «ddTools::$tables['site_content']». - * \* Поле «ddMenuBuilder->id» переименовано в «ddMenuBuilder->hereDocId». - * \+ Добавлены значения по умолчанию для полей «sortDir» и «where». - * \+ Значения шаблонов по умолчанию хранятся в поле «ddMenuBuilder->templates». + * \* Публичный только метод `generate`, остальные поля и методы приватные. + * \- Удалено поле `$table`, вместо него используется `\ddTools::$tables['site_content']`. + * \* Поле `\ddMenuBuilder::$id` переименовано в `\ddMenuBuilder::$hereDocId`. + * \+ Добавлены значения по умолчанию для полей `sortDir` и `where`. + * \+ Значения шаблонов по умолчанию хранятся в поле `\ddMenuBuilder::$templates`. * \* Переименованы шаблоны. * \+ Добавлен конструктор. - * \* Обработка параметров «showPublishedOnly», «showInMenuOnly» и формирование SQL-условия вынесены из сниппета в конструктор класса «ddMenuBuilder». - * \* Обработка значений шаблонов по умолчанию вынесена из сниппета в конструктор класса «ddMenuBuilder». - * \* Подключение библиотеки «modx.ddTools» вынесено в конструктор. - * \* Вместо прямого обращения к полю «$modx->config» используется метод «$modx->getConfig». - * \* Файл «assets/snippets/ddMenuBuilder/ddmenubuilder.class.php» переименован в «assets/snippets/ddMenuBuilder/ddMenuBuilder.class.php». - * \* Внимание! Используется «modx.ddTools» 1.0.15. + * \* Обработка параметров `showPublishedOnly`, `showInMenuOnly` и формирование SQL-условия вынесены из сниппета в конструктор класса `\ddMenuBuilder`. + * \* Обработка значений шаблонов по умолчанию вынесена из сниппета в конструктор класса `\ddMenuBuilder`. + * \* Подключение библиотеки `modx.ddTools` вынесено в конструктор. + * \* Вместо прямого обращения к полю `$modx->config` используется метод `$modx->getConfig`. + * \* Файл `assets/snippets/ddMenuBuilder/ddmenubuilder.class.php` переименован в `assets/snippets/ddMenuBuilder/ddMenuBuilder.class.php`. + ## Version 1.8 (2015-02-05) -* \* ddMenuBuilder snippet: - * \* Плэйсхолдер «[+wrapper+]» во всех шаблонах заменён на «[+children+]». -* \* ddMenuBuilder class: - * \+ Добавлен метод «ddMenuBuilder::getOutputTemplate». - * \* Метод «ddMenuBuilder::generate»: - * \* Переменная «$children» должна быть определена. - * \* Для проверки наличия дочерних документов используется «empty» вместо простого логического значения (т.к. пустой массив также означает отсутствие детей). +* \* Snippet: + * \* Плэйсхолдер `[+wrapper+]` во всех шаблонах заменён на `[+children+]`. +* \* `\ddMenuBuilder`: + * \+ Добавлен метод `\ddMenuBuilder::getOutputTemplate`. + * \* Метод `\ddMenuBuilder::generate`: + * \* Переменная `$children` должна быть определена. + * \* Для проверки наличия дочерних документов используется `empty` вместо простого логического значения (т.к. пустой массив также означает отсутствие детей). * \* Рефакторинг: - * \* Один «return» вместо нескольких. - * \* Переменная «$tpl» объявляется в любом случае. - * \* Элемент массива «str» объявляется в самом начале, таким образом, он всегда существует. + * \* Один `return` вместо нескольких. + * \* Переменная `$tpl` объявляется в любом случае. + * \* Элемент массива `str` объявляется в самом начале, таким образом, он всегда существует. * \* Код определения шаблона для вывода документа вынесен в отдельный метод. - * \* Обработка пустого «menutitle» документа делается только если документ будет выводиться. + * \* Обработка пустого `menutitle` документа делается только если документ будет выводиться. * \* Определение «активности» текущего документа объеденено в одно условие и перенесено после парсинга. * \* Парсинг текущего пункта меню делается только если шаблон определён (если не определён, значит выводить не надо). * \* Всегда возвращает массив. * \* Поля результирующего массива переименованы: - * \* «act» → «hasActive». - * \* «str» → «outputString». - * \* В массиве документа поле «wrapper» переименовано в «children». - * \* В результирующем массиве в любом случае будут поля «hasActive» и «outputString». - * \* Переменная «$doc» в любом случае будет содержать поле «children» с массивом дочерних документов, в случае если их нет или не нужно выводить, «$doc['children']['outputString']» будет равняться пустой строке. + * \* `act` → `hasActive`. + * \* `str` → `outputString`. + * \* В массиве документа поле `wrapper` переименовано в `children`. + * \* В результирующем массиве в любом случае будут поля `hasActive` и `outputString`. + * \* Переменная `$doc` в любом случае будет содержать поле `children` с массивом дочерних документов, в случае если их нет или не нужно выводить, `$doc['children']['outputString']` будет равняться пустой строке. * \* Определение шаблона и прочие операции, связанные с выводом, производятся только если в этом есть смысл. - * \* Удалена переменная «$sql». + * \- Удалена переменная `$sql`. * \* Удалены устаревшие комментарии, исправлено оформление кода и прочие незначительные изменения. + ## Version 1.7 (2012-10-17) -* \+ «Первая» версия. +* \+ The first release. + \ No newline at end of file diff --git a/README.md b/README.md index 898a920..7a44261 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,35 @@ # (MODX)EvolutionCMS.snippets.ddMenuBuilder -Fresh, simple and flexible template-driven menu builder. Initially inspired by combination of the Wayfinder and Ditto advantages with significant code simplification. -___ -Visit the following [link](http://code.divandesign.biz/modx/ddmenubuilder) to read the documentation, instructions & changelog. \ No newline at end of file + +Simple and flexible template-driven menu builder. +Initially inspired by combination of the Wayfinder and Ditto advantages with significant code simplification. + + +## Requires +* PHP >= 5.6 +* [(MODX)EvolutionCMS](https://github.com/evolution-cms/evolution) >= 1.1 +* [(MODX)EvolutionCMS.libraries.ddTools](https://code.divandesign.biz/modx/ddtools) >= 0.24.1 + + +## Documentation + + +### Installation + + +#### 1. Elements → Snippets: Create a new snippet with the following data + +1. Snippet name: `ddMenuBuilder`. +2. Description: `2.1 Simple and flexible template-driven menu builder.`. +3. Category: `Core → Navigation`. +4. Parse DocBlock: `no`. +5. Snippet code (php): Insert content of the `ddMenuBuilder_snippet.php` file from the archive. + + +#### 2. Elements → Manage Files: + +1. Create a new folder `assets/snippets/ddMenuBuilder/`. +2. Extract the archive to the folder (except `ddMenuBuilder_snippet.php`). + + +## [Home page →](http://code.divandesign.biz/modx/ddmenubuilder) \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..a7d0aaf --- /dev/null +++ b/composer.json @@ -0,0 +1,22 @@ +{ + "name": "dd/evolutioncms-snippets-ddmenubuilder", + "type": "modxevo-snippet", + "version": "2.1", + "description": "Simple and flexible template-driven menu builder. Initially inspired by combination of the Wayfinder and Ditto advantages with significant code simplification.", + "keywords": [ + "modx", + "modx evo", + "modx evolution", + "evo", + "evo cms", + "evolutioncms", + "evolution cms", + "ddmenubuilder", + "navigation", + "menu" + ], + "require": { + "php": ">=5.6.0", + "dd/modxevo-library-ddtools": ">=0.24.1" + } +} \ No newline at end of file diff --git a/ddMenuBuilder.class.php b/ddMenuBuilder.class.php index 8bcd56a..f0d5d64 100644 --- a/ddMenuBuilder.class.php +++ b/ddMenuBuilder.class.php @@ -1,18 +1,32 @@ = 5.6. * @uses (MODX)EvolutionCMS >= 1.1 {@link https://github.com/evolution-cms/evolution } * @uses (MODX)EvolutionCMS.libraries.ddTools >= 0.24.1 {@link http://code.divandesign.biz/modx/ddtools } * - * @copyright 2009–2019 DivanDesign {@link http://www.DivanDesign.biz } + * @copyright 2009–2020 DivanDesign {@link http://www.DivanDesign.biz } */ class ddMenuBuilder { private $hereDocId, + + /** + * @var $templates {stdClass} + * @var $templates->item {string} + * @var $templates->itemHere {string} + * @var $templates->itemActive {string} + * @var $templates->itemUnpub {string} + * @var $templates->itemUnpubActive {string} + * @var $templates->itemParent {string} + * @var $templates->itemParentHere {string} + * @var $templates->itemParentActive {string} + * @var $templates->itemParentUnpub {string} + * @var $templates->itemParentUnpubActive {string} + */ $templates = [ 'item' => '
  • [+menutitle+]
  • ', 'itemHere' => '
  • [+menutitle+]
  • ', @@ -35,28 +49,31 @@ class ddMenuBuilder { /** * __construct - * @version 1.7 (2019-06-08) + * @version 1.8 (2020-03-03) * - * @param $params {array_associative|stdClass} — The object of params. + * @param $params {arrayAssociative|stdClass} — The object of params. * @param $params->showPublishedOnly {boolean} — Брать ли только опубликованные документы. Default: true. * @param $params->showInMenuOnly {boolean} — Брать ли только те документы, что надо показывать в меню. Default: true. * @param $params->sortDir {'ASC'|'DESC'} — Направление сортировки. Default: 'ASC'. * @param $params->templates {array} — Шаблоны элементов меню. Default: $this->templates. * @param $params->templates['item'] {array} — Шаблон элемента. Default: '
  • [+menutitle+]
  • '. * @param $params->templates['itemHere'] {array} — Шаблон текущего элемента (когда находимся на этой странице). Default: '
  • [+menutitle+]
  • '. - * @param $params->templates['itemActive'] {array} — Шаблон элемента, если один из его дочерних документов here, но при этом не отображается в меню (из-за глубины, например). Default: $this->templates['itemHere']. + * @param $params->templates['itemActive'] {array} — Шаблон элемента, если один из его дочерних документов here, но при этом не отображается в меню (из-за глубины, например). Default: $this->templates->itemHere. * @param $params->templates['itemParent'] {array} — Шаблон элемента-родителя. Default: '
  • [+menutitle+]
  • '. * @param $params->templates['itemParentHere'] {array} — Шаблон активного элемента-родителя. Default: '
  • [+menutitle+]
  • '. - * @param $params->templates['itemParentActive'] {array} — Шаблон элемента-родителя, когда дочерний является here. Default: $this->templates['itemParentHere']. - * @param $params->templates['itemParentUnpub'] {array} — Шаблон элемента-родителя, если он не опубликован. Default: $this->templates['itemParent']. - * @param $params->templates['itemParentUnpubActive'] {array} — Шаблон элемента-родителя, если он не опубликован и дочерний является активным. Default: $this->templates['itemParentActive']. + * @param $params->templates['itemParentActive'] {array} — Шаблон элемента-родителя, когда дочерний является here. Default: $this->templates->itemParentHere. + * @param $params->templates['itemParentUnpub'] {array} — Шаблон элемента-родителя, если он не опубликован. Default: $this->templates->itemParent. + * @param $params->templates['itemParentUnpubActive'] {array} — Шаблон элемента-родителя, если он не опубликован и дочерний является активным. Default: $this->templates->itemParentActive. * @param $params->hereDocId {integer} — ID текущего документа. Default: \ddTools::$modx->documentIdentifier. */ public function __construct($params = []){ global $modx; //Include (MODX)EvolutionCMS.libraries.ddTools - require_once($modx->getConfig('base_path') . 'assets/libs/ddTools/modx.ddtools.class.php'); + require_once( + $modx->getConfig('base_path') . + 'assets/libs/ddTools/modx.ddtools.class.php' + ); //Defaults $params = (object) array_merge( @@ -70,26 +87,28 @@ public function __construct($params = []){ (array) $params ); + $this->templates = (object) $this->templates; + //Если шаблоны переданы if (!empty($params->templates)){ //Перебираем шаблоны объекта foreach ( $params->templates as - $templateName => $templateContent + $templateName => + $templateContent ){ //Если шаблон передан — сохраняем - if (array_key_exists( - $templateName, - $this->templates + if (property_exists( + $this->templates, + $templateName )){ - $params->templates[$templateName] = \ddTools::$modx->getTpl($params->templates[$templateName]); - }else{ - //Remove invalid templates - unset($params->templates[$templateName]); + $this->templates->{$templateName} = \ddTools::$modx->getTpl($templateContent); } } } + unset($params->templates); + //Все параметры задают свойства объекта foreach ( $params as @@ -105,32 +124,32 @@ public function __construct($params = []){ } //Шаблон активного элемента по умолчанию равен шаблону текущего элемента - if (is_null($this->templates['itemActive'])){ - $this->templates['itemActive'] = $this->templates['itemHere']; + if (is_null($this->templates->itemActive)){ + $this->templates->itemActive = $this->templates->itemHere; } //Шаблон неопубликованного элемента по умолчанию равен шаблону элемента - if (is_null($this->templates['itemUnpub'])){ - $this->templates['itemUnpub'] = $this->templates['item']; + if (is_null($this->templates->itemUnpub)){ + $this->templates->itemUnpub = $this->templates->item; } //Шаблон неопубликованного элемента по умолчанию равен шаблону элемента - if (is_null($this->templates['itemUnpubActive'])){ - $this->templates['itemUnpubActive'] = $this->templates['itemActive']; + if (is_null($this->templates->itemUnpubActive)){ + $this->templates->itemUnpubActive = $this->templates->itemActive; } //Шаблон активного элемента-родителя по умолчанию равен шаблону текущего элемента-родителя - if (is_null($this->templates['itemParentActive'])){ - $this->templates['itemParentActive'] = $this->templates['itemParentHere']; + if (is_null($this->templates->itemParentActive)){ + $this->templates->itemParentActive = $this->templates->itemParentHere; } //Шаблон неопубликованного элемента-родителя по умолчанию равен шаблону элемента-родителя - if (is_null($this->templates['itemParentUnpub'])){ - $this->templates['itemParentUnpub'] = $this->templates['itemParent']; + if (is_null($this->templates->itemParentUnpub)){ + $this->templates->itemParentUnpub = $this->templates->itemParent; } //Шаблон неопубликованного активного элемента-родителя по умолчанию равен шаблону активного элемента-родителя - if (is_null($this->templates['itemParentUnpubActive'])){ - $this->templates['itemParentUnpubActive'] = $this->templates['itemParentActive']; + if (is_null($this->templates->itemParentUnpubActive)){ + $this->templates->itemParentUnpubActive = $this->templates->itemParentActive; } //Валидация типов @@ -151,11 +170,11 @@ public function __construct($params = []){ /** * getOutputTemplate - * @version 1.3 (2019-06-08) + * @version 1.3.1 (2020-03-03) * * @desc Подбирает необходимый шаблон для вывода документа. * - * @param $params {stdClass|array_associative} — The object of params. @required + * @param $params {stdClass|arrayAssociative} — The object of params. @required * @param $params->docId {integer} — ID документа. @required * @param $params->docPublished {boolean} — Признак публикации документа. @required * @param $params->docShowedInMenu {boolean} — Признак отображения документа в меню. @required @@ -176,18 +195,18 @@ private function getOutputTemplate($params){ //Если текущий пункт является активным if ($params->docId == $this->hereDocId){ //Шаблон активного родительского пункта меню - $result = $this->templates['itemParentHere']; + $result = $this->templates->itemParentHere; //Если не не активный }else{ //Если один из дочерних был активным if ($params->hasActiveChildren){ //Сообщаем, что что-то активное есть //Шаблон родительского пункта меню, когда активный один из дочерних - $result = $this->templates['itemParentActive']; + $result = $this->templates->itemParentActive; //Если активных дочерних не было }else{ //Шаблон родительского пункта меню - $result = $this->templates['itemParent']; + $result = $this->templates->itemParent; } } //Если не опубликован @@ -196,11 +215,11 @@ private function getOutputTemplate($params){ if ($params->hasActiveChildren){ //Сообщаем, что что-то активное есть //Шаблон неопубликованного родительского пункта меню, когда активный один из дочерних - $result = $this->templates['itemParentUnpubActive']; + $result = $this->templates->itemParentUnpubActive; //Если активных дочерних не было }else{ //Шаблон неопубликованного родительского пункта меню - $result = $this->templates['itemParentUnpub']; + $result = $this->templates->itemParentUnpub; } } //Если дочерних нет (отображаемых дочерних) @@ -224,22 +243,22 @@ private function getOutputTemplate($params){ //Если текущий пункт является активным if ($params->docId == $this->hereDocId){ //Шаблон активного пункта - $result = $this->templates['itemHere']; + $result = $this->templates->itemHere; //Если активен какой-то из дочерних, не участвующих в визуальном отображении }else if($params->hasActiveChildren){ - $result = $this->templates['itemActive']; + $result = $this->templates->itemActive; //Если не не активный }else{ //Шаблон пункта меню - $result = $this->templates['item']; + $result = $this->templates->item; } }else{ //Если активен какой-то из дочерних, не участвующих в визуальном отображении (он не может быть «here», потому что неопубликован) if ($params->hasActiveChildren){ - $result = $this->templates['itemUnpubActive']; + $result = $this->templates->itemUnpubActive; }else{ //Шаблон неопубликованного пункта меню - $result = $this->templates['itemUnpub']; + $result = $this->templates->itemUnpub; } } } @@ -250,24 +269,29 @@ private function getOutputTemplate($params){ /** * prepareProviderParams - * @version 0.1.1 (2019-06-08) + * @version 0.3 (2020-03-03) * - * @param $params {stdClass|array_associative} — The object of params. @required + * @param $params {stdClass|arrayAssociative} — The object of params. @required * @param $params->provider {'parent'|'select'} — Name of the provider that will be used to fetch documents. Default: 'parent'. - * @param $params->providerParams {array_associative} — Parameters to be passed to the provider. + * @param $params->providerParams {stdClass|arrayAssociative} — Parameters to be passed to the provider. * - * @return {array_associative} + * @return {stdClass} */ public function prepareProviderParams($params = []){ //Defaults $params = (object) array_merge( [ - 'provider' => 'parent' + 'provider' => 'parent', + 'providerParams' => [] ], (array) $params ); - $result = [ + if (is_array($params->providerParams)){ + $params->providerParams = (object) $params->providerParams; + } + + $result = (object) [ 'where' => [], 'depth' => 1 ]; @@ -276,43 +300,51 @@ public function prepareProviderParams($params = []){ case 'select': //Required paremeter if ( - isset($params->providerParams['ids']) && - !empty($params->providerParams['ids']) + isset($params->providerParams->ids) && + !empty($params->providerParams->ids) ){ - if (is_array($params->providerParams['ids'])){ - $params->providerParams['ids'] = implode( + if (is_array($params->providerParams->ids)){ + $params->providerParams->ids = implode( ',', - $params->providerParams['ids'] + $params->providerParams->ids ); } - $result['where'][] = '`id` IN(' . $params->providerParams['ids'] . ')'; + $result->where[] = + '`id` IN(' . + $params->providerParams->ids . + ')' + ; }else{ //Never - $result['where'][] = '0 = 1'; + $result->where[] = '0 = 1'; } break; - default: case 'parent': + default: //Defaults - $params->providerParams = array_merge( + $params->providerParams = (object) array_merge( [ 'parentIds' => 0, 'depth' => 1 ], - $params->providerParams + (array) $params->providerParams ); - if (is_array($params->providerParams['parentIds'])){ - $params->providerParams['parentIds'] = implode( + if (is_array($params->providerParams->parentIds)){ + $params->providerParams->parentIds = implode( ',', - $params->providerParams['parentIds'] + $params->providerParams->parentIds ); } - $result['where'][] = '`parent` IN(' . $params->providerParams['parentIds'] . ')'; - $result['depth'] = $params->providerParams['depth']; + $result->where[] = + '`parent` IN(' . + $params->providerParams->parentIds . + ')' + ; + $result->depth = $params->providerParams->depth; break; } @@ -321,26 +353,39 @@ public function prepareProviderParams($params = []){ /** * generate - * @version 3.2 (2019-06-08) + * @version 4.0.1 (2020-03-03) * * @desc Сторит меню. * - * @param $params {stdClass|array_associative} — The object of params. @required + * @param $params {stdClass|arrayAssociative} — The object of params. @required * @param $params->where {array} — Условия выборки. @required * @param $params->where[i] {string} — Условие. @required * @param $params->depth {integer} — Глубина поиска. Default: 1. + * @param $params->level {integer} — For internal using only, not recommended to pass it. Default: 1. * - * @return {array} + * @return $result {stdClass} + * @return $result->hasActive {boolean} + * @return $result->totalAll {integer} — Количество отображаемых пунктов всех уровней. + * @return $result->totalThisLevel {integer} — Количество отображаемых пунктов этого уровня. + * @return $result->outputString {string} */ public function generate($params){ //Defaults - $params = (object) array_merge([ - 'depth' => 1 - ], (array) $params); + $params = (object) array_merge( + [ + 'depth' => 1, + //For internal using only, not recommended to pass it + 'level' => 1 + ], + (array) $params + ); - $result = [ + $result = (object) [ //Считаем, что активных пунктов по дефолту нет 'hasActive' => false, + //Как и вообще пунктов + 'totalAll' => 0, + 'totalThisLevel' => 0, //Результирующая строка 'outputString' => '' ]; @@ -374,30 +419,46 @@ public function generate($params){ if (\ddTools::$modx->db->getRecordCount($dbRes) > 0){ //Проходимся по всем пунктам текущего уровня while ($doc = \ddTools::$modx->db->getRow($dbRes)){ + $doc = (object) $doc; + //Пустые дети - $children = [ + $children = (object) [ 'hasActive' => false, + 'totalAll' => 0, 'outputString' => '' ]; //И для вывода тоже пустые - $doc['children'] = $children; + $doc->children = $children; + //Количество отображаемых потомков всех уровней + $doc->totalAllChildren = 0; + //Количество отображаемых непосредственных потомков + $doc->totalThisLevelChildren = 0; //Если это папка (т.е., могут быть дочерние) - if ($doc['isfolder']){ + if ($doc->isfolder){ //Получаем детей (вне зависимости от того, нужно ли их выводить) $children = $this->generate([ 'where' => [ - 'parent' => '`parent` = '.$doc['id'], + 'parent' => + '`parent` = ' . + $doc->id + , //Any hidemenu 'hidemenu' => '`hidemenu` != 2' ], - 'depth' => $params->depth - 1 + 'depth' => $params->depth - 1, + 'level' => $params->level + 1 ]); + //Можно смело наращивать без условия, т. к. возвращается количество отображаемых детей + $result->totalAll += $children->totalAll; + //Если надо выводить глубже if ($params->depth > 1){ //Выводим детей - $doc['children'] = $children; + $doc->children = $children; + $doc->totalAllChildren = $children->totalAll; + $doc->totalThisLevelChildren = $children->totalThisLevel; } } @@ -405,23 +466,31 @@ public function generate($params){ if ($params->depth > 0){ //Получаем правильный шаблон для вывода текущеёго пункта $tpl = $this->getOutputTemplate([ - 'docId' => $doc['id'], - 'docPublished' => !!$doc['published'], + 'docId' => $doc->id, + 'docPublished' => !!$doc->published, //Требуется для определения, надо ли выводить текущий документ, т. к. выше в запросе получаются документы вне зависимости от отображения в меню - 'docShowedInMenu' => !$doc['hidemenu'], - 'hasActiveChildren' => $children['hasActive'], - 'hasChildrenOutput' => $doc['children']['outputString'] != '' + 'docShowedInMenu' => !$doc->hidemenu, + 'hasActiveChildren' => $children->hasActive, + 'hasChildrenOutput' => $doc->children->outputString != '' ]); //Если шаблон определён (документ надо выводить) if ($tpl != ''){ + //Пунктов меню становится больше + $result->totalAll++; + $result->totalThisLevel++; + //Если вдруг меню у документа не задано, выставим заголовок вместо него - if (trim($doc['menutitle']) == ''){$doc['menutitle'] = $doc['pagetitle'];} + if (trim($doc->menutitle) == ''){ + $doc->menutitle = $doc->pagetitle; + } //Подготовим к парсингу - $doc['children'] = $doc['children']['outputString']; + $doc->children = $doc->children->outputString; + $doc->level = $params->level; + //Парсим - $result['outputString'] .= ddTools::parseText([ + $result->outputString .= ddTools::parseText([ 'text' => $tpl, 'data' => $doc ]); @@ -430,10 +499,10 @@ public function generate($params){ //Если мы находимся на странице текущего документа или на странице одного из дочерних (не важно отображаются они или нет, т.е., не зависимо от глубины) if ( - $doc['id'] == $this->hereDocId || - $children['hasActive'] + $doc->id == $this->hereDocId || + $children->hasActive ){ - $result['hasActive'] = true; + $result->hasActive = true; } } } diff --git a/ddMenuBuilder_snippet.php b/ddMenuBuilder_snippet.php index 458924a..45350b7 100644 --- a/ddMenuBuilder_snippet.php +++ b/ddMenuBuilder_snippet.php @@ -1,26 +1,22 @@ = 5.6. - * @uses (MODX)EvolutionCMS >= 1.1 {@link https://github.com/evolution-cms/evolution } - * @uses (MODX)EvolutionCMS.libraries.ddTools >= 0.24.1 {@link http://code.divandesign.biz/modx/ddtools } + * @see README.md * * Data provider parameters: * @param $provider {'parent'|'select'} — Name of the provider that will be used to fetch documents. Default: 'parent'. - * @param $providerParams {stirng_json|string_queryFormated} — Parameters to be passed to the provider. The parameter must be set as JSON (https://en.wikipedia.org/wiki/JSON) or Query string (https://en.wikipedia.org/wiki/Query_string). + * @param $providerParams {stirngJsonObject|stringQueryFormated} — Parameters to be passed to the provider. The parameter must be set as JSON (https://en.wikipedia.org/wiki/JSON) or Query string (https://en.wikipedia.org/wiki/Query_string). * When $provider == 'parent' => - * @param $providerParams['parentIds'] {array|string_commaSepareted} — Parent IDs — the starting points for the menu. Specify '0' to start from the site root. Default: '0'. - * @param $providerParams['parentIds'][i] {integer_documentID} — Parent ID. @required + * @param $providerParams['parentIds'] {array|stringCommaSepareted} — Parent IDs — the starting points for the menu. Specify '0' to start from the site root. Default: '0'. + * @param $providerParams['parentIds'][i] {integerDocumentID} — Parent ID. @required * @param $providerParams['depth'] {integer} — The depth of documents to build the menu. Default: 1. * @example &providerParams=`{"parentId": 1, "depth": 2}`. * @example &providerParams=`parentId=1&depth=2`. * When $provider == 'select' => - * @param $providerParams['ids'] {array|string_commaSepareted} — Document IDs. @required - * @param $providerParams['ids'][i] {integer_documentID} — Document ID. @required + * @param $providerParams['ids'] {array|stringCommaSepareted} — Document IDs. @required + * @param $providerParams['ids'][i] {integerDocumentID} — Document ID. @required * @example &providerParams=`{"ids": [1, 2, 3]}`. * @example &providerParams=`ids=1,2,3`. * @@ -30,34 +26,37 @@ * @param $showInMenuOnly {0|1} — Show only documents visible in the menu. Default: 1. * * Template parameters: - * @param $templates {stirng_json|string_queryFormated} — Templates. All templates can be set as chunk name or code via “@CODE:” prefix. Placeholders available in all templates: [+id+], [+menutitle+] (will be equal to [+pagetitle+] if empty), [+pagetitle+], [+published+], [+isfolder+]. - * @param $templates['item'] {string_chunkName|string} — The menu item template. Default: '
  • [+menutitle+]
  • '. - * @param $templates['itemHere'] {string_chunkName|string} — The menu item template for the current document. Default: '
  • [+menutitle+]
  • '. - * @param $templates['itemActive'] {string_chunkName|string} — The menu item template for a document which is one of the parents to the current document when the current document doesn't displayed in the menu (e. g. excluded by the “depth” parameter). Default: $templates['itemHere']. + * @param $templates {stirngJsonObject|stringQueryFormated} — Templates. All templates can be set as chunk name or code via “@CODE:” prefix. Placeholders available in all templates: [+id+], [+menutitle+] (will be equal to [+pagetitle+] if empty), [+pagetitle+], [+published+], [+isfolder+], [+totalAllChildren+], [+totalThisLevelChildren+], [+level+]. + * @param $templates['item'] {stringChunkName|string} — The menu item template. Default: '
  • [+menutitle+]
  • '. + * @param $templates['itemHere'] {stringChunkName|string} — The menu item template for the current document. Default: '
  • [+menutitle+]
  • '. + * @param $templates['itemActive'] {stringChunkName|string} — The menu item template for a document which is one of the parents to the current document when the current document doesn't displayed in the menu (e. g. excluded by the “depth” parameter). Default: $templates['itemHere']. * - * @param $templates['itemUnpub'] {string_chunkName|string} — The menu item template for unpublished document. Default: $templates['item']. - * @param $templates['itemUnpubActive'] {string_chunkName|string} — The menu item template for unpublished document which is one of the parents to the current document when the current document doesn't displayed in the menu (e. g. excluded by the “depth” parameter). Default: $templates['itemActive']. + * @param $templates['itemUnpub'] {stringChunkName|string} — The menu item template for unpublished document. Default: $templates['item']. + * @param $templates['itemUnpubActive'] {stringChunkName|string} — The menu item template for unpublished document which is one of the parents to the current document when the current document doesn't displayed in the menu (e. g. excluded by the “depth” parameter). Default: $templates['itemActive']. * - * @param $templates['itemParent'] {string_chunkName|string} — The menu item template for documents which has a children displayed in menu. Default: '
  • [+menutitle+]
  • ';. - * @param $templates['itemParentHere'] {string_chunkName|string} — The menu item template for the current document when it has children displayed in menu. Default: '
  • [+menutitle+]
  • '. - * @param $templates['itemParentActive'] {string_chunkName|string} — The menu item template for a document which has the current document as one of the children. Default: $templates['itemParentHere']. + * @param $templates['itemParent'] {stringChunkName|string} — The menu item template for documents which has a children displayed in menu. Default: '
  • [+menutitle+]
  • ';. + * @param $templates['itemParentHere'] {stringChunkName|string} — The menu item template for the current document when it has children displayed in menu. Default: '
  • [+menutitle+]
  • '. + * @param $templates['itemParentActive'] {stringChunkName|string} — The menu item template for a document which has the current document as one of the children. Default: $templates['itemParentHere']. * - * @param $templates['itemParentUnpub'] {string_chunkName|string} — The menu item template for unpublished documents which has a children displayed in menu. Default: $templates['itemParent']. - * @param $templates['itemParentUnpubActive'] {string_chunkName|string} — The menu item template for an unpublished document which has the current document as one of the children. Default: $templates['itemParentActive']. + * @param $templates['itemParentUnpub'] {stringChunkName|string} — The menu item template for unpublished documents which has a children displayed in menu. Default: $templates['itemParent']. + * @param $templates['itemParentUnpubActive'] {stringChunkName|string} — The menu item template for an unpublished document which has the current document as one of the children. Default: $templates['itemParentActive']. * - * @param $templates['outer'] {string_chunkName|string} — Wrapper template. Available placeholders: [+children+]. Default: ''. + * @param $templates['outer'] {stringChunkName|string} — Wrapper template. Available placeholders: [+children+]. Default: ''. * - * @param $placeholders {stirng_json|string_queryFormated} — Additional data as query string has to be passed into “templates['outer']”. The parameter must be set as JSON (https://en.wikipedia.org/wiki/JSON) or Query string (https://en.wikipedia.org/wiki/Query_string). Default: —. + * @param $placeholders {stirngJsonObject|stringQueryFormated} — Additional data as query string has to be passed into “templates['outer']”. The parameter must be set as JSON (https://en.wikipedia.org/wiki/JSON) or Query string (https://en.wikipedia.org/wiki/Query_string). Default: —. * @example &placeholders=`{"pladeholder1": "value1", "pagetitle", "My awesome pagetitle!"}`. * @example &placeholders=`pladeholder1=value1&pagetitle=My awesome pagetitle!`. * * @link http://code.divandesign.biz/modx/ddmenubuilder * - * @copyright 2009–2019 DivanDesign {@link http://www.DivanDesign.biz } + * @copyright 2009–2020 DivanDesign {@link http://www.DivanDesign.biz } */ //Подключаем класс (ddTools подключится там) -require_once($modx->getConfig('base_path') . 'assets/snippets/ddMenuBuilder/ddMenuBuilder.class.php'); +require_once( + $modx->getConfig('base_path') . + 'assets/snippets/ddMenuBuilder/ddMenuBuilder.class.php' +); //Prepare template params $templates = ddTools::encodedStringToArray($templates); @@ -73,11 +72,17 @@ ]; //Направление сортировки -if (isset($sortDir)){$ddMenuBuilder_params['sortDir'] = $sortDir;} +if (isset($sortDir)){ + $ddMenuBuilder_params['sortDir'] = $sortDir; +} //По умолчанию будут только опубликованные документы -if (isset($showPublishedOnly)){$ddMenuBuilder_params['showPublishedOnly'] = $showPublishedOnly;} +if (isset($showPublishedOnly)){ + $ddMenuBuilder_params['showPublishedOnly'] = $showPublishedOnly; +} //По умолчанию будут только документы, у которых стоит галочка «показывать в меню» -if (isset($showInMenuOnly)){$ddMenuBuilder_params['showInMenuOnly'] = $showInMenuOnly;} +if (isset($showInMenuOnly)){ + $ddMenuBuilder_params['showInMenuOnly'] = $showInMenuOnly; +} $ddMenuBuilder = new ddMenuBuilder($ddMenuBuilder_params); @@ -102,7 +107,9 @@ $placeholders = []; } -$placeholders['children'] = $result['outputString']; +$placeholders['children'] = $result->outputString; +$placeholders['totalAllChildren'] = $result->totalAll; +$placeholders['totalThisLevelChildren'] = $result->totalThisLevel; return ddTools::parseText([ 'text' => $templates['outer'],