Example #1
0
 /**
  * @param Page $page
  * @param int $level
  */
 public function listPages($page, $level)
 {
     $indent = 4;
     $title = $page->title . ' { ' . $page->id . ', ' . $page->template . ' }';
     switch ($this->indent) {
         case 0:
             $out = '|-- ' . $title;
             break;
         default:
             $i = $this->indent - $indent / 2;
             $j = $indent / 2 + 1;
             $out = '|' . str_pad(' ' . $title, strlen($title) + $j, '-', STR_PAD_LEFT);
             $out = '|' . str_pad($out, strlen($out) + $i, ' ', STR_PAD_LEFT);
     }
     $this->output->writeln($out);
     if ($page->numChildren) {
         $this->indent = $this->indent + $indent;
         foreach ($page->children($this->select) as $child) {
             if ($level === 0 || $level != 0 && $level >= $this->indent / $indent) {
                 $this->listPages($child, $level);
             }
         }
         $this->indent = $this->indent - $indent;
     }
 }
Example #2
0
 /**
  * Return number of children, optionally with conditions
  *
  * Use this over $page->numChildren property when you want to specify a selector or when you want the result to
  * include only visible children. See the options for the $selector argument. 
  *
  * @param Page $page
  * @param bool|string $selector 
  *	When not specified, result includes all children without conditions, same as $page->numChildren property.
  *	When a string, a selector string is assumed and quantity will be counted based on selector.
  * 	When boolean true, number includes only visible children (excludes unpublished, hidden, no-access, etc.)
  *	When boolean false, number includes all children without conditions, including unpublished, hidden, no-access, etc.
  * @return int Number of children
  *
  */
 public function numChildren(Page $page, $selector = null)
 {
     if (is_bool($selector)) {
         // onlyVisible takes the place of selector
         $onlyVisible = $selector;
         if (!$onlyVisible) {
             return $page->get('numChildren');
         }
         return $page->children('limit=2')->getTotal();
     } else {
         if (empty($selector) || !is_string($selector)) {
             return $page->get('numChildren');
         } else {
             return wire('pages')->count("parent_id={$page->id}, {$selector}");
         }
     }
 }
 /**
  * Render a single top navigation item for the given page
  *
  * This function designed primarily to be called by the renderTopNavItems() function. 
  *
  * @param Page $p
  * @param int $level Recursion level (default=0)
  * @return string
  *
  */
 public function renderTopNavItem(Page $p, $level = 0)
 {
     $isSuperuser = $this->wire('user')->isSuperuser();
     $showItem = $isSuperuser;
     $children = $p->numChildren && !$level && $p->name != 'page' ? $p->children("check_access=0") : array();
     $adminURL = $this->wire('config')->urls->admin;
     $out = '';
     if (!$showItem) {
         $checkPages = count($children) ? $children : array($p);
         foreach ($checkPages as $child) {
             if ($child->viewable()) {
                 $showItem = true;
                 break;
             }
         }
     }
     if (!$showItem) {
         return '';
     }
     $class = strpos(wire('page')->path, $p->path) === 0 ? 'on' : '';
     $title = strip_tags((string) $p->get('title|name'));
     $title = $this->_($title);
     // translate from context of default.php
     $out .= "<li>";
     if (!$level && count($children)) {
         $class = trim("{$class} dropdown-toggle");
         $out .= "<a href='{$p->url}' id='topnav-page-{$p}' data-from='topnav-page-{$p->parent}' class='{$class}'>{$title}</a>";
         $my = 'left-1 top';
         if ($p->name == 'access') {
             $my = 'left top';
         }
         $out .= "<ul class='dropdown-menu topnav' data-my='{$my}' data-at='left bottom'>";
         foreach ($children as $c) {
             if ($isSuperuser && ($c->id == 11 || $c->id == 16)) {
                 // has ajax items
                 $addLabel = $this->_('Add New');
                 $out .= "<li><a class='has-ajax-items' data-from='topnav-page-{$p}' href='{$c->url}'>" . $this->_($c->title) . "</a><ul>" . "<li class='add'><a href='{$c->url}add'><i class='fa fa-plus-circle'></i> {$addLabel}</a></li>" . "</ul></li>";
             } else {
                 $out .= $this->renderTopNavItem($c, $level + 1);
             }
         }
         $out .= "</ul>";
     } else {
         $class = $class ? " class='{$class}'" : '';
         $out .= "<a href='{$p->url}'{$class}>{$title}</a>";
     }
     $out .= "</li>";
     return $out;
 }
 /**
  * Render a side navigation items
  *
  * This function designed primarily to be called by the renderSideNavItems() function. 
  *
  * @param Page $p
  * @return string
  *
  */
 public function renderSideNavItem(Page $p)
 {
     $isSuperuser = $this->wire('user')->isSuperuser();
     $sanitizer = $this->wire('sanitizer');
     $modules = $this->wire('modules');
     $showItem = $isSuperuser;
     $children = $p->numChildren() ? $p->children("check_access=0") : array();
     $out = '';
     $iconName = $p->name;
     $icon = $this->wire('adminTheme')->{$iconName};
     if (!$icon) {
         $icon = 'fa-file-text-o';
     }
     $numViewable = 0;
     if (!$showItem) {
         $checkPages = count($children) ? $children : array($p);
         foreach ($checkPages as $child) {
             if ($child->viewable()) {
                 $showItem = true;
                 $numViewable++;
                 if ($numViewable > 1) {
                     break;
                 }
                 // we don't need to know about any more
             }
         }
     }
     // don't bother with a drop-down here if only 1 child
     if ($p->name == 'page' && !$isSuperuser && $numViewable < 2) {
         $children = array();
     }
     if (!$showItem) {
         return '';
     }
     if ($p->process) {
         $moduleInfo = $modules->getModuleInfo($p->process);
         $textdomain = str_replace($this->wire('config')->paths->root, '/', $this->wire('modules')->getModuleFile($p->process));
     } else {
         $moduleInfo = array();
         $textdomain = '';
     }
     if (!count($children) && !empty($moduleInfo['nav'])) {
         $children = $moduleInfo['nav'];
     }
     $class = strpos($this->wire('page')->path, $p->path) === 0 ? 'current' : '';
     // current class
     $class .= count($children) > 0 ? " parent" : '';
     // parent class
     $title = $sanitizer->entities1((string) $this->_($p->get('title|name')));
     $currentPagePath = $this->wire('page')->url;
     // use URL to support sub directory installs
     $out .= "<li>";
     if (count($children)) {
         $out .= "<a href='{$p->url}' class='{$class} {$p->name} '><i class='fa {$icon}'></i> {$title}</a>";
         $out .= "<ul>";
         foreach ($children as $c) {
             $navJSON = '';
             if (is_array($c)) {
                 // $c is moduleInfo nav array
                 $moduleInfo = array();
                 if (isset($c['permission']) && !$this->wire('user')->hasPermission($c['permission'])) {
                     continue;
                 }
                 $segments = $this->input->urlSegments ? implode("/", $this->input->urlSegments) . '/' : '';
                 $class = $currentPagePath . $segments == $p->path . $c['url'] ? 'current' : '';
                 $title = $sanitizer->entities1(__($c['label'], $textdomain));
                 $url = $p->url . $c['url'];
                 if (isset($c['navJSON'])) {
                     $navJSON = $c['navJSON'];
                     // url part
                     $moduleInfo['useNavJSON'] = true;
                 }
                 $c = $p;
                 // substitute
             } else {
                 // $c is a Page object
                 $list = array(wire('config')->urls->admin . "page/", wire('config')->urls->admin . "page/edit/");
                 in_array($currentPagePath, $list) ? $currentPagePath = wire('config')->urls->admin . "page/list/" : '';
                 $class = strpos($currentPagePath, $c->url) === 0 ? 'current' : '';
                 // child current class
                 $name = $c->name;
                 if (!$c->viewable()) {
                     continue;
                 }
                 $moduleInfo = $c->process ? $modules->getModuleInfo($c->process) : array();
                 $title = $this->getPageTitle($c);
                 if (!strlen($title)) {
                     continue;
                 }
                 $url = $c->url;
                 // The /page/ and /page/list/ are the same process, so just keep them on /page/ instead.
                 if (strpos($url, '/page/list/') !== false) {
                     $url = str_replace('/page/list/', '/page/', $url);
                 }
             }
             $quicklinks = '';
             if (!empty($moduleInfo['useNavJSON'])) {
                 // NOTE: 'useNavJSON' comes before 'nav' for AdminThemeReno only, since it does not support navJSON beyond one level
                 // meaning this bypasses 'nav' if the module happens to also provide navJSON (see ProcessRecentPages example)
                 if (empty($navJSON)) {
                     $navJSON = "navJSON/";
                 }
                 $quicklinks = $this->renderQuicklinks($c, array(), $title, $navJSON);
             } else {
                 if (!empty($moduleInfo['nav'])) {
                     $quicklinks = $this->renderQuicklinks($c, $moduleInfo['nav'], $title);
                 }
             }
             $icon = isset($moduleInfo['icon']) ? $moduleInfo['icon'] : '';
             $toggle = $quicklinks ? "<i class='quicklink-open fa fa-bolt'></i>" : "";
             if ($class == 'current' && $icon) {
                 $title = "<i class='fa fa-fw fa-{$icon} current-icon'></i>{$title}";
             }
             if ($quicklinks) {
                 $class .= " has-quicklinks";
             }
             $out .= "<li><a href='{$url}' class='{$class}' data-icon='{$icon}'><span>{$title}</span>{$toggle}</a>" . $quicklinks;
             $out .= "</li>";
         }
         $out .= "</ul>";
     } else {
         $class = $class ? " class='{$class} {$p->name}'" : "class='{$p->name}'";
         $out .= "<a href='{$p->url}' {$class}><i class='fa {$icon}'></i> <span>{$title}</span></a>";
     }
     $out .= "</li>";
     return $out;
 }
 /**
  * Render a single top navigation item for the given page
  *
  * This function designed primarily to be called by the renderTopNavItems() function. 
  *
  * @param Page $p
  * @param int $level Recursion level (default=0)
  * @return string
  *
  */
 public function renderTopNavItem(Page $p, $level = 0)
 {
     $isSuperuser = $this->wire('user')->isSuperuser();
     $showItem = $isSuperuser;
     $children = $p->numChildren && !$level ? $p->children("check_access=0") : array();
     $numChildren = count($children);
     $out = '';
     if (!$showItem) {
         $checkPages = $numChildren ? $children : array($p);
         foreach ($checkPages as $child) {
             if ($child->viewable()) {
                 $showItem = true;
                 break;
             }
         }
     }
     if (!$showItem) {
         return '';
     }
     $class = strpos($this->wire('page')->path, $p->path) === 0 ? 'on' : '';
     $title = strip_tags((string) $p->title);
     if (!strlen($title)) {
         $title = $p->name;
     }
     $title = $this->_($title);
     // translate from context of default.php
     $out .= "<li>";
     if (!$numChildren && $p->template == 'admin' && $p->process) {
         $moduleInfo = $this->wire('modules')->getModuleInfo($p->process);
         if (!empty($moduleInfo['nav'])) {
             $children = $moduleInfo['nav'];
         }
     }
     if (!$level && count($children)) {
         $class = trim("{$class} dropdown-toggle");
         $out .= "<a href='{$p->url}' id='topnav-page-{$p}' data-from='topnav-page-{$p->parent}' class='{$class}'>{$title}</a>";
         $my = 'left-1 top';
         if (in_array($p->name, array('access', 'page', 'module'))) {
             $my = 'left top';
         }
         $out .= "<ul class='dropdown-menu topnav' data-my='{$my}' data-at='left bottom'>";
         if ($children instanceof PageArray) {
             foreach ($children as $c) {
                 if (!$c->process) {
                     continue;
                 }
                 $moduleInfo = $this->wire('modules')->getModuleInfo($c->process);
                 if ($isSuperuser) {
                     $hasPermission = true;
                 } else {
                     if (!empty($moduleInfo['permissionMethod'])) {
                         $hasPermission = $c->viewable();
                     } else {
                         if (!empty($moduleInfo['permission'])) {
                             $hasPermission = $this->wire('user')->hasPermission($moduleInfo['permission']);
                         } else {
                             $hasPermission = false;
                         }
                     }
                 }
                 if (!$hasPermission) {
                     continue;
                 }
                 if (!empty($moduleInfo['nav'])) {
                     // process defines its own subnav
                     $icon = $this->getPageIcon($c);
                     $title = $this->_($c->title);
                     if (!$title) {
                         $title = $c->name;
                     }
                     $out .= "<li><a class='has-items' data-from='topnav-page-{$p}' href='{$c->url}'>{$icon}{$title}</a>" . "<ul>" . $this->renderTopNavItemArray($c, $moduleInfo['nav']) . "</ul></li>";
                 } else {
                     if (!empty($moduleInfo['useNavJSON'])) {
                         // has ajax items
                         $title = $this->getPageTitle($c);
                         if (!strlen($title)) {
                             continue;
                         }
                         $icon = $this->getPageIcon($c);
                         $out .= "<li><a class='has-items has-ajax-items' data-from='topnav-page-{$p}' data-json='{$c->url}navJSON/' " . "href='{$c->url}'>{$icon}{$title}</a><ul></ul></li>";
                     } else {
                         // regular nav item
                         $out .= $this->renderTopNavItem($c, $level + 1);
                     }
                 }
             }
         } else {
             if (is_array($children) && count($children)) {
                 $out .= $this->renderTopNavItemArray($p, $children);
             }
         }
         $out .= "</ul>";
     } else {
         $class = $class ? " class='{$class}'" : '';
         $url = $p->url;
         $icon = $level > 0 ? $this->getPageIcon($p) : '';
         // The /page/ and /page/list/ are the same process, so just keep them on /page/ instead.
         if (strpos($url, '/page/list/') !== false) {
             $url = str_replace('/page/list/', '/page/', $url);
         }
         $out .= "<a href='{$url}'{$class}>{$icon}{$title}</a>";
     }
     $out .= "</li>";
     return $out;
 }
 /**
  * Render a side navigation items
  *
  * This function designed primarily to be called by the renderSideNavItems() function. 
  *
  * @param Page $p
  * @return string
  *
  */
 public function renderSideNavItem(Page $p)
 {
     $isSuperuser = $this->wire('user')->isSuperuser();
     $showItem = $isSuperuser;
     $children = $p->numChildren ? $p->children("check_access=0") : array();
     $adminURL = $this->wire('config')->urls->admin;
     $quicklinks = array('11', '16');
     // array of page ids that use quicklinks.
     $out = '';
     $iconName = $p->name;
     $this->adminTheme()->{$iconName} ? $icon = $this->adminTheme()->{$iconName} : ($icon = 'fa-file-text-o');
     // don't bother with a drop-down here if only 1 child
     if ($p->name == 'page' && !$isSuperuser) {
         $children = array();
     }
     if (!$showItem) {
         $checkPages = count($children) ? $children : array($p);
         foreach ($checkPages as $child) {
             if ($child->viewable()) {
                 $showItem = true;
                 break;
             }
         }
     }
     if (!$showItem) {
         return '';
     }
     $class = strpos(wire('page')->path, $p->path) === 0 ? 'current' : '';
     // current class
     $class .= count($children) > 0 ? " parent" : '';
     // parent class
     $title = strip_tags((string) $p->get('title|name'));
     $title = $this->_($title);
     // translate from context of default.php
     $out .= "<li>";
     if (count($children)) {
         $out .= "<a href='{$p->url}' class='{$class} {$p->name} '><i class='fa {$icon}'></i> {$title}</a>";
         $out .= "<ul>";
         foreach ($children as $c) {
             $showQuickLinks = false;
             $class = strpos(wire('page')->path, $c->path) === 0 ? 'current' : '';
             // child current class
             if ($c->viewable()) {
                 $isSuperuser && in_array($c->id, $quicklinks) ? $showQuickLinks = true : '';
                 $showQuickLinks ? $qlink = "<i class='quicklink-open fa fa-bolt'></i>" : ($qlink = '');
                 $url = $c->url;
                 // The /page/ and /page/list/ are the same process, so just keep them on /page/ instead.
                 if (strpos($url, '/page/list/') !== false) {
                     $url = str_replace('/page/list/', '/page/', $url);
                 }
                 $out .= "<li><a href='{$url}' class='{$class}'>" . $this->_($c->title) . $qlink . "</a>";
                 if ($showQuickLinks) {
                     $c->id == 11 ? $type = "templates" : '';
                     $c->id == 16 ? $type = "fields" : '';
                     $out .= $this->renderQuicklinks(wire($type));
                     // not thrilled with this solution. Explore options.
                 }
                 $out .= "</li>";
             }
         }
         $out .= "</ul>";
     } else {
         $class = $class ? " class='{$class} {$p->name}'" : "class='{$p->name}'";
         $out .= "<a href='{$p->url}' {$class}><i class='fa {$icon}'></i> {$title}</a>";
     }
     $out .= "</li>";
     return $out;
 }
Example #7
0
 /**
  * Clone an entire page, it's assets and children and return it. 
  *
  * @param Page $page Page that you want to clone
  * @param Page $parent New parent, if different (default=same parent)
  * @param bool $recursive Clone the children too? (default=true)
  * @return Page the newly cloned page or a NullPage() with id=0 if unsuccessful.
  *
  */
 public function ___clone(Page $page, Page $parent = null, $recursive = true)
 {
     // if parent is not changing, we have to modify name now
     if (is_null($parent)) {
         $parent = $page->parent;
         $n = 1;
         $name = $page->name . '-' . $n;
     } else {
         $name = $page->name;
         $n = 0;
     }
     // make sure that we have a unique name
     while (count($parent->children("name={$name}"))) {
         $name = $page->name . '-' . ++$n;
     }
     // Ensure all data is loaded for the page
     foreach ($page->template->fieldgroup as $field) {
         $page->get($field->name);
     }
     // clone in memory
     $copy = clone $page;
     $copy->id = 0;
     $copy->setIsNew(true);
     $copy->name = $name;
     $copy->parent = $parent;
     // tell PW that all the data needs to be saved
     foreach ($copy->template->fieldgroup as $field) {
         $copy->trackChange($field->name);
     }
     $o = $copy->outputFormatting;
     $copy->setOutputFormatting(false);
     $this->save($copy);
     $copy->setOutputFormatting($o);
     // check to make sure the clone has worked so far
     if (!$copy->id || $copy->id == $page->id) {
         return new NullPage();
     }
     // copy $page's files over to new page
     $copy->filesManager->init($copy);
     $page->filesManager->copyFiles($copy->filesManager->path());
     // if there are children, then recurisvely clone them too
     if ($page->numChildren && $recursive) {
         foreach ($page->children("include=all") as $child) {
             $this->clone($child, $copy);
         }
     }
     $this->cloned($page, $copy);
     $this->debugLog('clone', "page={$page}, parent={$parent}", $copy);
     return $copy;
 }
 /**
  * Render a single top navigation item for the given page
  *
  * This function designed primarily to be called by the renderTopNavItems() function. 
  *
  * @param Page $p
  * @param int $level Recursion level (default=0)
  * @return string
  *
  */
 public function renderTopNavItem(Page $p, $level = 0)
 {
     $isSuperuser = $this->wire('user')->isSuperuser();
     $showItem = $isSuperuser;
     $children = $p->numChildren && !$level ? $p->children("check_access=0") : array();
     $numChildren = count($children);
     $out = '';
     if (!$showItem) {
         $checkPages = $numChildren ? $children : array($p);
         foreach ($checkPages as $child) {
             if ($child->viewable()) {
                 $showItem = true;
                 break;
             }
         }
     }
     if (!$showItem) {
         return '';
     }
     if ($numChildren && $p->name == 'page') {
         // don't bother with a drop-down for "Pages" if user will only see 1 "tree" item, duplicating the tab
         if ($numChildren == 2 && !$isSuperuser && !$this->wire('user')->hasPermission('page-lister')) {
             $children = array();
         }
         if ($numChildren == 1) {
             $children = array();
         }
     }
     $class = strpos($this->wire('page')->path, $p->path) === 0 ? 'on' : '';
     $title = strip_tags((string) $p->title);
     if (!strlen($title)) {
         $title = $p->name;
     }
     $title = $this->_($title);
     // translate from context of default.php
     $out .= "<li>";
     if (!$level && count($children)) {
         $class = trim("{$class} dropdown-toggle");
         $out .= "<a href='{$p->url}' id='topnav-page-{$p}' data-from='topnav-page-{$p->parent}' class='{$class}'>{$title}</a>";
         $my = 'left-1 top';
         if (in_array($p->name, array('access', 'page'))) {
             $my = 'left top';
         }
         $out .= "<ul class='dropdown-menu topnav' data-my='{$my}' data-at='left bottom'>";
         foreach ($children as $c) {
             if ($isSuperuser && ($c->id == 11 || $c->id == 16)) {
                 // has ajax items
                 $icon = $this->getPageIcon($c);
                 $addLabel = $this->_('Add New');
                 $out .= "<li><a class='has-ajax-items' data-from='topnav-page-{$p}' href='{$c->url}'>{$icon}" . $this->_($c->title) . "</a><ul>" . "<li class='add'><a href='{$c->url}add'><i class='fa fa-plus-circle'></i> {$addLabel}</a></li>" . "</ul></li>";
             } else {
                 $out .= $this->renderTopNavItem($c, $level + 1);
             }
         }
         $out .= "</ul>";
     } else {
         $class = $class ? " class='{$class}'" : '';
         $url = $p->url;
         $icon = $level > 0 ? $this->getPageIcon($p) : '';
         // The /page/ and /page/list/ are the same process, so just keep them on /page/ instead.
         if (strpos($url, '/page/list/') !== false) {
             $url = str_replace('/page/list/', '/page/', $url);
         }
         $out .= "<a href='{$url}'{$class}>{$icon}{$title}</a>";
     }
     $out .= "</li>";
     return $out;
 }