1 <?php
  2 
  3 /**
  4  * @package redaxo\core\backend
  5  */
  6 class rex_be_navigation
  7 {
  8     use rex_factory_trait;
  9 
 10     private $headlines = [];
 11     private $pages = [
 12         'default' => [],
 13         'system' => [],
 14         'addons' => [],
 15     ];
 16 
 17     /**
 18      * @return static
 19      */
 20     public static function factory()
 21     {
 22         $class = static::getFactoryClass();
 23         return new $class();
 24     }
 25 
 26     /**
 27      * @param rex_be_page $page
 28      */
 29     public function addPage(rex_be_page $page)
 30     {
 31         $blockName = 'default';
 32         if ($page instanceof rex_be_page_main) {
 33             $blockName = $page->getBlock();
 34         }
 35 
 36         if (!isset($this->pages[$blockName])) {
 37             $this->pages[$blockName] = [];
 38         }
 39 
 40         $this->pages[$blockName][] = $page;
 41     }
 42 
 43     /**
 44      * @return array
 45      */
 46     public function getNavigation()
 47     {
 48         //$this->setActiveElements();
 49         $return = [];
 50         foreach ($this->pages as $block => $blockPages) {
 51             if (is_array($blockPages) && count($blockPages) > 0 && $blockPages[0] instanceof rex_be_page_main) {
 52                 uasort($blockPages, function (rex_be_page_main $a, rex_be_page_main $b) {
 53                     $a_prio = (int) $a->getPrio();
 54                     $b_prio = (int) $b->getPrio();
 55                     if ($a_prio == $b_prio || ($a_prio <= 0 && $b_prio <= 0)) {
 56                         return strnatcasecmp($a->getTitle(), $b->getTitle());
 57                     }
 58 
 59                     if ($a_prio <= 0) {
 60                         return 1;
 61                     }
 62 
 63                     if ($b_prio <= 0) {
 64                         return -1;
 65                     }
 66 
 67                     return $a_prio > $b_prio ? 1 : -1;
 68                 });
 69             }
 70 
 71             $n = $this->_getNavigation($blockPages);
 72             if (count($n) > 0) {
 73                 $fragment = new rex_fragment();
 74                 $fragment->setVar('navigation', $n, false);
 75 
 76                 $return[] = [
 77                     'navigation' => $n,
 78                     'headline' => ['title' => $this->getHeadline($block)],
 79                 ];
 80             }
 81         }
 82         return $return;
 83     }
 84 
 85     /**
 86      * @param rex_be_page[] $blockPages
 87      *
 88      * @return array
 89      */
 90     private function _getNavigation(array $blockPages)
 91     {
 92         $navigation = [];
 93 
 94         foreach ($blockPages as $page) {
 95             if ($page->isHidden() || !$page->checkPermission(rex::getUser())) {
 96                 continue;
 97             }
 98             $n = [];
 99             $n['linkClasses'] = [];
100             $n['itemClasses'] = [];
101             $n['linkAttr'] = [];
102             $n['itemAttr'] = [];
103 
104             $n['itemClasses'][] = $page->getItemAttr('class');
105             $n['linkClasses'][] = $page->getItemAttr('class');
106 
107             foreach ($page->getItemAttr(null) as $name => $value) {
108                 $n['itemAttr'][$name] = trim($value);
109             }
110 
111             foreach ($page->getLinkAttr(null) as $name => $value) {
112                 $n['linkAttr'][$name] = trim($value);
113             }
114 
115             $n['href'] = $page->getHref();
116             $n['title'] = $page->getTitle();
117             $n['active'] = $page->isActive();
118 
119             if ($page->hasIcon()) {
120                 $n['icon'] = $page->getIcon();
121             } elseif ($page instanceof rex_be_page_main) {
122                 $n['icon'] = 'rex-icon rex-icon-package-addon';
123             }
124 
125             $subpages = $page->getSubpages();
126             if (is_array($subpages) && !empty($subpages)) {
127                 $n['children'] = $this->_getNavigation($subpages);
128             }
129 
130             $navigation[] = $n;
131         }
132 
133         return $navigation;
134     }
135 
136     protected function setActiveElements()
137     {
138         foreach ($this->pages as $blockPages) {
139             foreach ($blockPages as $page) {
140                 // check main pages
141                 if ($page->isActive()) {
142                     $page->addItemClass('active');
143 
144                     // check for subpages
145                     foreach ($page->getSubpages() as $subpage) {
146                         if ($subpage->isActive()) {
147                             $subpage->addItemClass('active');
148                         }
149                     }
150                 }
151             }
152         }
153     }
154 
155     /**
156      * @param string $block
157      * @param string $headline
158      */
159     public function setHeadline($block, $headline)
160     {
161         $this->headlines[$block] = $headline;
162     }
163 
164     /**
165      * @param string $block
166      *
167      * @return string
168      */
169     public function getHeadline($block)
170     {
171         if (isset($this->headlines[$block])) {
172             return $this->headlines[$block];
173         }
174 
175         if ($block != 'default') {
176             return rex_i18n::msg('navigation_' . $block);
177         }
178 
179         return '';
180     }
181 }
182