PageRenderTime 34ms CodeModel.GetById 12ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 0ms

/web/concrete/helpers/concrete/dashboard.php

https://github.com/glockops/concrete5
PHP | 648 lines | 506 code | 105 blank | 37 comment | 124 complexity | 6ce7842242bfb5ad674099ad843e9205 MD5 | raw file
  1<?
  2/**
  3 * @package Helpers
  4 * @category Concrete
  5 * @author Andrew Embler <andrew@concrete5.org>
  6 * @copyright  Copyright (c) 2003-2008 Concrete5. (http://www.concrete5.org)
  7 * @license    http://www.concrete5.org/license/     MIT License
  8 */
  9
 10/**
 11 * Functions for use with the C5 dashboard.
 12 * @package Helpers
 13 * @category Concrete
 14 * @author Andrew Embler <andrew@concrete5.org>
 15 * @copyright  Copyright (c) 2003-2008 Concrete5. (http://www.concrete5.org)
 16 * @license    http://www.concrete5.org/license/     MIT License
 17 */
 18
 19defined('C5_EXECUTE') or die("Access Denied.");
 20class ConcreteDashboardHelper {
 21
 22	/** 
 23	 * Checks to see if a user has access to the C5 dashboard.
 24	 */
 25	public function canRead() {
 26		$c = Page::getByPath('/dashboard', 'ACTIVE');
 27		$cp = new Permissions($c);
 28		return $cp->canViewPage();
 29	}
 30	
 31	
 32	public function canAccessComposer() {
 33		$c = Page::getByPath('/dashboard/composer', 'ACTIVE');
 34		$cp = new Permissions($c);
 35		return $cp->canViewPage();
 36	}
 37
 38	/**
 39	 * Test if the current path is within the dashboard.
 40	 * Optionally, a Page or path can be passed to test.
 41	 * 
 42	 * @param  Page | string $page (optional)
 43	 * @return [boolean]
 44	 */
 45	public function inDashboard($page = false) {
 46		if ($page instanceof Page && !$page->isError()) {
 47			$path = $page->getCollectionPath();
 48		} elseif (is_string($page)) {
 49			$path = $page;
 50		} else {
 51			$request = Request::get();
 52			$path = $request->getRequestCollectionPath();
 53		}
 54		return strpos($path, '/dashboard') === 0;
 55	}
 56	
 57	public function getDashboardPaneFooterWrapper($includeDefaultBody = true) {
 58		$html = '</div></div></div></div>';
 59		if ($includeDefaultBody) {
 60			$html .= '</div>';
 61		}
 62		return $html;
 63	}
 64	
 65	public function getDashboardPaneHeaderWrapper($title = false, $help = false, $span = 'span12', $includeDefaultBody = true, $navigatePages = array(), $upToPage = false, $favorites = true) {
 66		
 67		$spantotal = 12;
 68		$offset = preg_match('/offset([0-9]+)/i', $span, $offsetmatches);
 69		if ($offset) {
 70			$offsettotal = $offsetmatches[1];
 71			$hasspan = preg_match('/span([0-9]+)/i', $span, $spanmatches);
 72			if ($hasspan) {
 73				$spantotal = $spanmatches[1];
 74				$gridtotal = ($offsettotal * 2) + $spantotal;
 75			}
 76		}
 77		
 78		if ($gridtotal > 12) {
 79			// we are working with legacy bootstrap 16-column grid
 80			// we take the offset and then we subtract from the span
 81			$spantotal = $spantotal - ($gridtotal - 12);
 82			$spantotal .= ' offset' . $offsettotal;
 83			$span = 'span' . $spantotal;
 84		}
 85		
 86		$html = '<div class="ccm-ui"><div class="row"><div class="' . $span . '"><div class="ccm-pane">';
 87		$html .= self::getDashboardPaneHeader($title, $help, $navigatePages, $upToPage, $favorites);
 88		if ($includeDefaultBody) {
 89			$html .= '<div class="ccm-pane-body ccm-pane-body-footer">';
 90		}
 91		return $html;
 92	}
 93	
 94	public function getDashboardPaneHeader($title = false, $help = false, $navigatePages = array(), $upToPage = false, $favorites = true) {
 95		$c = Page::getCurrentPage();
 96		$vt = Loader::helper('validation/token');
 97		$token = $vt->generate('access_quick_nav');
 98
 99		$currentMenu = array();
100		$nh = Loader::helper('navigation');
101		$trail = $nh->getTrailToCollection($c);
102		if (count($trail) > 1 || count($navigatePages) > 1 || is_object($upToPage)) { 
103			$parent = Page::getByID($c->getCollectionParentID());
104			if (count($trail) > 1 && (!is_object($upToPage))) {
105				$upToPage = Page::getByID($parent->getCollectionParentID());
106			}
107			Loader::block('autonav');
108			$subpages = array();
109			if ($navigatePages !== -1) { 
110				if (count($navigatePages) > 0) { 
111					$subpages = $navigatePages;
112				} else { 
113					$subpages = AutonavBlockController::getChildPages($parent);
114				}
115			}
116			
117			$subpagesP = array();
118			if(is_array($subpages)) {
119				foreach($subpages as $sc) {
120					$cp = new Permissions($sc);
121					if ($cp->canViewPage()) { 
122						$subpagesP[] = $sc;
123					}
124				}
125			}
126			
127			if (count($subpagesP) > 0 || is_object($upToPage)) { 
128				$relatedPages = '<ul id="ccm-page-navigate-pages-content" class="dropdown-menu">';
129		
130				foreach($subpagesP as $sc) { 
131					if ($sc->getAttribute('exclude_nav')) {
132						continue;
133					}
134		
135					if ($c->getCollectionPath() == $sc->getCollectionPath() || (strpos($c->getCollectionPath(), $sc->getCollectionPath()) == 0) && strpos($c->getCollectionPath(), $sc->getCollectionPath()) !== false) {
136						$class= 'nav-selected';
137					} else {
138						$class = '';
139					}
140					
141					$relatedPages .= '<li class="' . $class . '"><a href="' . $nh->getLinkToCollection($sc, false, true) . '">' . t($sc->getCollectionName()) . '</a></li>';
142				}
143		
144				if ($upToPage) { 
145					$relatedPages .= '<li class="ccm-menu-separator"></li>';
146					$relatedPages .= '<li><a href="' . $nh->getLinkToCollection($upToPage, false, true) . '">' . t('&lt; Back to %s', t($upToPage->getCollectionName())) . '</a></li>';
147				}
148				$relatedPages .= '</ul>';
149				$navigateTitle = t($parent->getCollectionName());
150			}
151		}
152		
153
154		$html = '<div class="ccm-pane-header">';
155		
156		$class = 'ccm-icon-favorite';
157		$qn = ConcreteDashboardMenu::getMine();
158		$quicknav = $qn->getItems(false);
159		if (in_array($c->getCollectionPath(), $quicknav)) {
160			$class = 'ccm-icon-favorite-selected';	
161		}
162		$html .= '<ul class="ccm-pane-header-icons">';
163		if (!$help) {
164			$ih = Loader::helper('concrete/interface/help');
165			$pageHelp = $ih->getPages();
166			if (isset($pageHelp[$c->getCollectionPath()])) {
167				$help = $pageHelp[$c->getCollectionPath()];
168			}
169		}
170		
171		if (is_array($help)) {
172			$help = $help[0] . '<br/><br/><a href="' . $help[1] . '" class="btn small" target="_blank">' . t('Learn More') . '</a>';
173		}
174		
175		if (isset($relatedPages)) { 
176			$html .= '<li><a href="" class="ccm-icon-navigate-pages" data-toggle="dropdown" title="' . $navigateTitle . '" id="ccm-page-navigate-pages">' . t('Help') . '</a>' . $relatedPages . '</li>';
177		}
178		
179		if ($help) {
180			$html .= '<li><span style="display: none" id="ccm-page-help-content">' . $help . '</span><a href="javascript:void(0)" class="ccm-icon-help" title="' . t('Help') . '" id="ccm-page-help">' . t('Help') . '</a></li>';
181		}
182		
183		if ($favorites) {
184		$html .= '<li><a href="javascript:void(0)" id="ccm-add-to-quick-nav" onclick="ccm_toggleQuickNav(' . $c->getCollectionID() . ',\'' . $token . '\')" class="' . $class . '">' . t('Add to Favorites') . '</a></li>';
185		}
186
187		$html .= '<li><a href="javascript:void(0)" onclick="ccm_closeDashboardPane(this)" class="ccm-icon-close">' . t('Close') . '</a></li>';
188		$html .= '</ul>';
189		if (!$title) {
190			$title = $c->getCollectionName();
191		}
192		$html .= '<h3>' . $title . '</h3>';
193		$html .= '</div>';
194		return $html;
195	}
196	
197	public function getDashboardBackgroundImage() {
198		$feed = array();
199		// this feed is an array of standard PHP objects with a SRC, a caption, and a URL
200		// allow for a custom white-label feed
201		$filename = date('Ymd') . '.jpg';
202		$obj = new stdClass;
203		$obj->checkData = false;
204		$obj->displayCaption = false;
205		
206		if (defined('WHITE_LABEL_DASHBOARD_BACKGROUND_FEED') && WHITE_LABEL_DASHBOARD_BACKGROUND_FEED != '') {
207			$image = WHITE_LABEL_DASHBOARD_BACKGROUND_FEED . '/' . $filename;
208		} else if (defined('WHITE_LABEL_DASHBOARD_BACKGROUND_SRC') && WHITE_LABEL_DASHBOARD_BACKGROUND_SRC != '') {
209			$image = WHITE_LABEL_DASHBOARD_BACKGROUND_SRC;
210			if ($image == 'none') {
211				$image = '';
212			}
213		} else {
214			$obj->checkData = true;
215			$imageSetting = Config::get('DASHBOARD_BACKGROUND_IMAGE');
216			if ($imageSetting == 'custom') {
217				$fo = File::getByID(Config::get('DASHBOARD_BACKGROUND_IMAGE_CUSTOM_FILE_ID'));
218				if (is_object($fo)) {
219					$image = $fo->getRelativePath();
220				}
221			} else if ($imageSetting == 'none') {
222				$image = '';
223			} else { 
224				if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on')) {
225					$image = DASHBOARD_BACKGROUND_FEED_SECURE . '/' . $filename;
226				} else {
227					$image = DASHBOARD_BACKGROUND_FEED . '/' . $filename;
228				}
229				$obj->displayCaption = true;
230			}
231		}
232		$obj->filename = $filename;
233		$obj->image = $image;
234		return $obj;
235	}
236	
237	public function addQuickNavToMenus($html) {
238		$recent = '';
239		ob_start();		
240
241			$c = Page::getCurrentPage();
242			if (!is_array($_SESSION['ccmQuickNavRecentPages'])) {
243				$_SESSION['ccmQuickNavRecentPages'] = array();
244			}
245
246			$session_pages = array_filter($_SESSION['ccmQuickNavRecentPages']);
247			$session_pages[] = $c->getCollectionID();
248
249			// Remove duplicates, making sure the most recent is kept.
250			$session_pages = array_reverse(array_unique(array_reverse($session_pages)));
251
252			// Tidy and eliminate non-existent collections, prep for later
253			$breadcrumb_map = array();
254			$last = 0;
255			if (count($session_pages) > 0) {
256				foreach($session_pages as $_cID) {
257					$_c = Page::getByID($_cID);
258					if ($_c->isError()) {
259						continue;
260					}
261					$breadcrumb_map[$_cID] = $_c;
262					$last = $_cID;
263				}
264			}
265			// limit size, keeping numeric keys constant
266			$max_breadcrumb_size = 5;
267			// (NB - by using the above, the way is kept open for the size to be adjustable in the future)
268			if (count($breadcrumb_map) > $max_breadcrumb_size) {
269				$breadcrumb_map = array_slice($breadcrumb_map,-$max_breadcrumb_size, null, true);
270			}
271
272			$_SESSION['ccmQuickNavRecentPages'] = array_keys($breadcrumb_map);
273
274			if (count($breadcrumb_map) > 0) { ?>
275				<ul class="breadcrumb">
276				<li><strong><?php echo t('Recent')?></strong> <span class="divider">:</span></li>
277				<?php 
278				// create links
279				foreach($breadcrumb_map as $_cID=>$_c) {
280					$name = t('(No Name)');
281					if ($_c->getCollectionName()) {
282						$name = $_c->getCollectionName();
283					}
284					$divider = '';
285					if ($_cID != $last) {
286						$divider = '<span class="divider">/</span>';
287					}
288					?> <li><a id="ccm-recent-page-<?php echo $_c->getCollectionID()?>" href="<?php echo Loader::helper('navigation')->getLinkToCollection($_c)?>"><?php echo t($name)?></a><?php echo $divider?></li>
289					<?php 
290				}
291				?>
292				</ul>
293				<?
294			}
295		$recent = ob_get_contents();
296		ob_end_clean();
297		$html = str_replace("<!--recent-->", $recent, $html);		
298		return str_replace(array("\n", "\r", "\t"), "", $html);
299	}
300
301	public function getDashboardAndSearchMenus() {
302
303		if (isset($_SESSION['dashboardMenus'][Localization::activeLocale()])) {
304			return $_SESSION['dashboardMenus'][Localization::activeLocale()];
305		}
306				
307		$d = ConcreteDashboardMenu::getMine();
308		$items = $d->getItems();
309
310		ob_start(); ?>
311			<div id="ccm-intelligent-search-results">
312			<?
313			$page = Page::getByPath('/dashboard');
314			$children = $page->getCollectionChildrenArray(true);
315			
316			$packagepages = array();
317			$corepages = array();
318			foreach($children as $ch) {
319				$page = Page::getByID($ch);
320				$pageP = new Permissions($page);
321				if ($pageP->canRead()) { 
322					if (!$page->getAttribute("exclude_nav")) {
323						if ($page->getPackageID() > 0) {
324							$packagepages[] = $page;
325						} else {
326							$corepages[] = $page;
327						}
328					}
329				} else {
330					continue;
331				}
332			
333				if ($page->getAttribute('exclude_search_index')) {
334					continue;
335				}
336				
337				if ($page->getCollectionPath() == '/dashboard/system') {
338					$ch2 = $page->getCollectionChildrenArray();
339				} else {
340					$ch2 = $page->getCollectionChildrenArray(true);
341				}
342				?>
343				
344				<div class="ccm-intelligent-search-results-module ccm-intelligent-search-results-module-onsite">
345				
346				<h1><?=t($page->getCollectionName())?></h1>
347				
348				
349				<ul class="ccm-intelligent-search-results-list">
350				<? if (count($ch2) == 0) { ?>
351					<li><a href="<?=Loader::helper('navigation')->getLinkTocollection($page, false, true)?>"><?=t($page->getCollectionName())?></a><span><?=t($page->getCollectionName())?> <?=t($page->getAttribute('meta_keywords'))?></span></li>
352				<? } ?>
353				
354				<?
355				if ($page->getCollectionPath() == '/dashboard/system') { ?>
356					<li><a href="<?=Loader::helper('navigation')->getLinkTocollection($page, false, true)?>"><?=t('View All')?></a><span><?=t($page->getCollectionName())?> <?=t($page->getAttribute('meta_keywords'))?></span></li>
357				<?				
358				}
359				
360				foreach($ch2 as $chi) {
361					$subpage = Page::getByID($chi); 
362					$subpageP = new Permissions($subpage);
363					if (!$subpageP->canRead()) {
364						continue;
365					}
366
367					if ($subpage->getAttribute('exclude_search_index')) {
368						continue;
369					}
370			
371					?>
372					<li><a href="<?=Loader::helper('navigation')->getLinkTocollection($subpage, false, true)?>"><?=t($subpage->getCollectionName())?></a><span><? if ($page->getCollectionPath() != '/dashboard/system') { ?><?=t($page->getCollectionName())?> <?=t($page->getAttribute('meta_keywords'))?> <? } ?><?=t($subpage->getCollectionName())?> <?=t($subpage->getAttribute('meta_keywords'))?></span></li>
373					<? 
374				}
375				?>
376				</ul>
377				
378				</div>
379				<? }
380				
381				$custHome = Page::getByPath('/dashboard/home');
382				$custHomeP = new Permissions($custHome);
383				if ($custHomeP->canRead()) {
384				?>
385				
386				<div class="ccm-intelligent-search-results-module ccm-intelligent-search-results-module-onsite">
387				
388				<h1><?=t('Dashboard Home')?></h1>
389				
390				
391				<ul class="ccm-intelligent-search-results-list">
392					<li><a href="<?=View::url('/dashboard/home')?>"><?=t('Customize')?> <span><?=t('Customize Dashboard Home')?></span></a></li>
393				</ul>
394				
395				</div>
396				
397				<? } ?>
398				
399				<div class="ccm-intelligent-search-results-module ccm-intelligent-search-results-module-loading">
400				<h1><?=t('Your Site')?></h1>
401				<ul class="ccm-intelligent-search-results-list" id="ccm-intelligent-search-results-list-your-site">
402				</ul>
403				</div>
404				
405				<? if (ENABLE_INTELLIGENT_SEARCH_HELP) { ?>
406				<div class="ccm-intelligent-search-results-module ccm-intelligent-search-results-module-offsite ccm-intelligent-search-results-module-loading">
407				<h1><?=t('Help')?></h1>
408				<ul class="ccm-intelligent-search-results-list" id="ccm-intelligent-search-results-list-help">
409				</ul>
410				</div>
411				<? } ?>
412				
413				<? if (ENABLE_INTELLIGENT_SEARCH_MARKETPLACE) { ?>
414				<div class="ccm-intelligent-search-results-module ccm-intelligent-search-results-module-offsite ccm-intelligent-search-results-module-loading">
415				<h1><?=t('Add-Ons')?></h1>
416				<ul class="ccm-intelligent-search-results-list" id="ccm-intelligent-search-results-list-marketplace">
417				</ul>
418				</div>
419				<? } ?>				
420			</div>
421			
422			<div id="ccm-dashboard-overlay">
423			<div id="ccm-dashboard-overlay-core">
424			<div class="ccm-dashboard-overlay-inner" id="ccm-dashboard-overlay-main">
425			
426			<!--recent-->
427						
428			
429			<? 
430			$currentHeader = false;
431			$x = 0;
432			$itemsChanged = false;
433			foreach($items as $path) { 
434			
435				$p = Page::getByPath($path, 'ACTIVE');
436				// If page is not found etc, remove it from items
437				if ($p->isError()) {
438					$d->remove($p);
439					$itemsChanged = true;
440					continue;
441				}
442				$pc = new Permissions($p);
443				if ($pc->canViewPage()) {
444					
445					$name = t($p->getCollectionName());
446					$parent = Page::getByID($p->getCollectionParentID(), 'ACTIVE');
447					if ($parent->getCollectionPath() == '/dashboard') {
448						$parent = $p;
449						$name = t('Home');						
450					}
451					
452					if ($currentHeader != $parent->getCollectionID()) { ?>
453						<? if ($currentHeader != false) { ?>
454							</ul>
455							</div>
456							<? $x++; ?>
457							<? if ($x % 4 == 0) { ?>
458								<div class="clearfix" style="padding-bottom: 0px"></div>
459							<? } ?>
460							
461						<? } ?>
462
463						<div class="ccm-dashboard-overlay-module">
464						<h1><?=t($parent->getCollectionName())?></h1>
465						<ul>			
466						
467						<? $currentHeader = $parent->getCollectionID(); ?>		
468
469					<? } ?>
470					
471						<li><a href="<?=Loader::helper('navigation')->getLinkToCollection($p, false, true)?>"><?=$name?></a></li>
472
473				
474				<? } ?>
475				
476							
477			<? } ?>
478			<?
479			if ($itemsChanged) {
480				$u = new User;
481				$u->saveConfig('QUICK_NAV_BOOKMARKS', serialize($d));
482			}
483			?>
484			<? if ($currentHeader != false) { ?>
485							</ul>
486							</div>
487			<? } ?>
488			</div>
489			</div>
490			<div id="ccm-dashboard-overlay-misc" class="ccm-dashboard-overlay-misc-rounded">
491			<div class="ccm-dashboard-overlay-inner">
492
493            <?
494
495			// Before we throw in a UL, we check permissions, etc. to see if any of the LI items need to be shown.
496			$systemNews = Page::getByPath('/dashboard/news');
497			$systemNewsP = new Permissions($systemNews);
498			$canAccessNews = $systemNewsP->canRead();
499
500			$systemSettings = Page::getByPath('/dashboard/system');
501			$systemSettingsP = new Permissions($systemSettings);
502			$canAccessSystem = $systemSettingsP->canRead();
503
504			$tpa = new TaskPermission();
505			$canAccessExtend = $tpa->canInstallPackages();
506			$systemExtend = Page::getByPath('/dashboard/extend');
507			$systemExtendP = new Permissions($systemExtend);
508			$canViewExtend = $systemExtendP->canRead();
509
510			// If any need to be shown then we proceed...
511			if($canAccessNews || $canAccessSystem || ($canAccessExtend && $canViewExtend)){ ?>
512
513                <ul>
514
515                <? if ($canAccessNews) { ?>
516                    <li><a href="<?=View::url('/dashboard/news')?>"><strong><?=t('News')?></strong></a><?=t('Learn about your site and concrete5.')?></li>
517                <? } ?>
518
519				<? if ($canAccessSystem) { ?>
520                    <li><a href="<?=View::url('/dashboard/system')?>"><strong><?=t('System &amp; Settings')?></strong></a><?=t('Secure and setup your site.')?></li>
521                <? } ?>
522
523                <? if ($canAccessExtend && $canViewExtend) { ?>
524                    <li><a href="<?php echo View::url('/dashboard/extend') ?>"><strong><?php echo t("Extend concrete5") ?></strong></a> – 
525                    <? if (ENABLE_MARKETPLACE_SUPPORT) { ?>
526                    <?php echo sprintf(t('<a href="%s">Install</a>, <a href="%s">update</a> or download more <a href="%s">themes</a> and <a href="%s">add-ons</a>.'),
527                        View::url('/dashboard/extend/install'),
528                        View::url('/dashboard/extend/update'),
529                        View::url('/dashboard/extend/themes'),
530                        View::url('/dashboard/extend/add-ons')); ?>
531                    <? } else { ?>
532					<?php echo sprintf(t('<a href="%s">Install</a> or <a href="%s">update</a> packages.'),
533                        View::url('/dashboard/extend/install'),
534                        View::url('/dashboard/extend/update'))?>
535                    <? } ?>
536					</li>
537                <? } ?>
538
539                </ul>
540
541            <? } ?>
542
543			</div>
544			</div>
545			<div id="ccm-dashboard-overlay-footer">
546			<div class="ccm-dashboard-overlay-inner">
547			<a href="<?=View::url('/dashboard')?>"><?=t('View Full Dashboard')?>  <i class="icon-arrow-right"></i></a>
548			</div>
549			</div>
550			</div>
551		<?
552			$html = ob_get_contents();
553			ob_end_clean();
554			
555		return str_replace(array("\n", "\r", "\t"), "", $html);
556	
557	}
558}
559
560class ConcreteDashboardMenu {
561	
562	protected $items;
563	public function getItems($sort = true) {
564		if ($sort) {
565			usort($this->items, array('ConcreteDashboardMenu', 'sortItems'));
566		}
567		return $this->items;
568	}
569	
570	protected static function sortItems($a, $b) {
571		$subpatha = substr($a, 11); // /dashboard
572		$subpathb = substr($b, 11); // /dashboard
573		$segmentsa = explode('/', $subpatha);
574		$segmentsb = explode('/', $subpathb);
575		$segmenta = substr($subpatha, 0, strpos($subpatha, '/'));
576		$segmentb = substr($subpathb, 0, strpos($subpathb, '/'));
577		if (count($segmentsa) == 3 && count($segmentsb) == 3) {
578			$subpatha = $segmenta[0] . '/' . $segmenta[1];
579			$subpathb = $segmentb[0] . '/' . $segmentb[1];
580			$segmenta .= '/' . $segmentsa[1];
581			$segmentb .= '/' . $segmentsb[1];
582			
583		}
584
585		if (!$segmenta) {
586			$segmenta = $subpatha;
587		}
588		if (!$segmentb) {
589			$segmentb = $subpathb;
590		}
591		$db = Loader::db();
592		$displayorderA = intval($db->GetOne('select cDisplayOrder from Pages p inner join PagePaths cp on p.cID = cp.cID where cPath = ?', array('/dashboard/' . $segmenta)));
593		$displayorderB = intval($db->GetOne('select cDisplayOrder from Pages p inner join PagePaths cp on p.cID = cp.cID where cPath = ?', array('/dashboard/' . $segmentb)));
594
595		if ($displayorderA > $displayorderB) {
596			return 1;
597		} else if ($displayorderA < $displayorderB) {
598			return -1;
599		} else {
600			$displayorderA = intval($db->GetOne('select cDisplayOrder from Pages p inner join PagePaths cp on p.cID = cp.cID where cPath = ?', array('/dashboard/' . $subpatha)));
601			$displayorderB = intval($db->GetOne('select cDisplayOrder from Pages p inner join PagePaths cp on p.cID = cp.cID where cPath = ?', array('/dashboard/' . $subpathb)));
602			if ($displayorderA > $displayorderB) {
603				return 1;
604			} else if ($displayorderA < $displayorderB) {
605				return -1;
606			}
607		}
608	}
609	
610	public function contains($c) {
611		return in_array($c->getCollectionPath(), $this->items);
612	}
613	
614	public function add($c) {
615		$this->items[] = $c->getCollectionPath();
616	}
617
618	public function remove($c) {
619		unset($this->items[array_search($c->getCollectionPath(), $this->items)]);
620	}
621
622	public static function getMine() {
623		$u = new User();
624		$qn = unserialize($u->config('QUICK_NAV_BOOKMARKS'));
625		if (is_object($qn)) {
626			return $qn;
627		}
628		$qn = new ConcreteDashboardMenu();
629		$qnx = new ConcreteDashboardDefaultMenu();
630		$qn->items = $qnx->items;
631		return $qn;	
632	}
633}
634
635class ConcreteDashboardDefaultMenu extends ConcreteDashboardMenu {
636	
637	public $items = array(
638		'/dashboard/composer/write',
639		'/dashboard/composer/drafts',
640		'/dashboard/sitemap/full',
641		'/dashboard/sitemap/search',
642		'/dashboard/files/search',
643		'/dashboard/files/sets',
644		'/dashboard/reports/statistics',
645		'/dashboard/reports/forms'
646	);
647
648}