aliroMenuHandler.php

Go to the documentation of this file.
00001 <?php
00002 
00003 /*******************************************************************************
00004  * Aliro - the modern, accessible content management system
00005  *
00006  * Aliro is open source software, free to use, and licensed under GPL.
00007  * You can find the full licence at http://www.gnu.org/copyleft/gpl.html GNU/GPL
00008  *
00009  * The author freely draws attention to the fact that Aliro derives from Mambo,
00010  * software that is controlled by the Mambo Foundation.  However, this section
00011  * of code is totally new.  If it should contain any fragments that are similar
00012  * to Mambo, please bear in mind (1) there are only so many ways to do things
00013  * and (2) the author of Aliro is also the author and copyright owner for large
00014  * parts of Mambo 4.6.
00015  *
00016  * Tribute should be paid to all the developers who took Mambo to the stage
00017  * it had reached at the time Aliro was created.  It is a feature rich system
00018  * that contains a good deal of innovation.
00019  *
00020  * Your attention is also drawn to the fact that Aliro relies on other items of
00021  * open source software, which is very much in the spirit of open source.  Aliro
00022  * wishes to give credit to those items of code.  Please refer to
00023  * http://aliro.org/credits for details.  The credits are not included within
00024  * the Aliro package simply to avoid providing a marker that allows hackers to
00025  * identify the system.
00026  *
00027  * Copyright in this code is strictly reserved by its author, Martin Brampton.
00028  * If it seems appropriate, the copyright will be vested in the Aliro Organisation
00029  * at a suitable time.
00030  *
00031  * Copyright (c) 2007 Martin Brampton
00032  *
00033  * http://aliro.org
00034  *
00035  * counterpoint@aliro.org
00036  *
00037  * Basic menu classes are here.  aliroAdminMenu is the simple class that provides
00038  * objects corresponding to rows in the admin menu table.
00039  *
00040  * aliroMenu likewise corresponds to rows in the user menu table.  It has a few
00041  * extra methods.
00042  *
00043  * aliroMenuLink is the simple data class that is used to communicate between the
00044  * aliroMenuCreator and menu modules.  This allows all the menu logic to remain in
00045  * the Aliro core, while all the presentation is handled by installable modules.
00046  *
00047  * aliroMenuHandler does most of the work for manipulating menu data.  It is a
00048  * cached singleton, so it only loads its data from the database periodically in
00049  * normal operation.
00050  *
00051  */
00052 
00053 class aliroMenuItem extends aliroDatabaseRow {
00054     protected $DBclass = 'aliroCoreDatabase';
00055     protected $tableName = '#__menu';
00056     protected $rowKey = 'id';
00057 
00058     public function load( $oid=null ) {
00059         trigger_error ('Should not ->load() a menu - aliroMenuHandler can provide the whole menu using getMenuByID($id)');
00060         echo aliroRequest::trace();
00061     }
00062 
00063     public function getParams () {
00064         if ($this->params) {
00065             $params = new aliroParameters($this->params);
00066         }
00067         else {
00068             $info = criticalInfo::getInstance();
00069             $xmlfile = $info->absolute_path.$this->xmlfile;
00070             $xmldata = file_get_contents($xmlfile);
00071             if (false == $xmldata) {
00072                 trigger_error (T_('aliroMenuItem class could not find XML file ').$xmlfile);
00073                 return '';
00074             }
00075             $xmlparser = new aliroXMLParamsDefault;
00076             $params = $xmlparser->paramsFromString($xmldata);
00077         }
00078         return $params;
00079     }
00080 
00081     public function linkComponentData ($component) {
00082         $this->name = $component->name;
00083         $this->link = 'index.php?option='.$component->option;
00084         $this->type = 'component';
00085         $this->componentid = $component->id;
00086         $this->component = $component->option;
00087         $this->xmlfile = $component->xmlfile;
00088     }
00089 
00090 }
00091 
00092 // Provided only for compatibility
00093 class mosMenu extends aliroMenuItem {
00094 
00095 }
00096 
00097 class aliroMenuLink {
00098     public $id = 0;
00099     public $name = '';
00100     public $link = '';
00101     public $image = '';
00102     public $opener = '';
00103     public $image_last = 0;
00104     public $level = 0;
00105     public $active = false;
00106     public $subactive = false;
00107 }
00108 
00112 class aliroMenuHandler extends cachedSingleton {
00113     private $menus = null;
00114     private $counts = null;
00115     private $byParentOrder = null;
00116     private $main_home = null;
00117 
00118     protected static $instance = __CLASS__;
00119 
00123     protected function __construct () {
00124         $sql = "SELECT * FROM #__menu ORDER BY ordering";
00125         $this->menus = aliroCoreDatabase::getInstance()->doSQLget($sql, 'aliroMenuItem', 'id');
00126         foreach ($this->menus as $key=>$menu) {
00127             if (is_null($this->main_home) AND 'mainmenu' == $menu->menutype AND $menu->published AND 0 == $menu->parent) $this->main_home = $menu;
00128              // Ensure that published is always 0 or 1
00129             $this->menus[$key]->published = $menu->published ? 1 : 0;
00130             $this->byParentOrder[$menu->menutype][$menu->parent][] = $key;
00131             if (isset($this->counts[$menu->menutype][$menu->published])) $this->counts[$menu->menutype][$menu->published]++;
00132             else $this->counts[$menu->menutype][$menu->published] = 1;
00133         }
00134     }
00135 
00139     public static function getInstance () {
00140         return is_object(self::$instance) ? self::$instance : (self::$instance = parent::getCachedSingleton(self::$instance));
00141     }
00142 
00143     public function getMenuByID ($id) {
00144         return isset($this->menus[$id]) ? $this->menus[$id] : null;
00145     }
00146 
00147     public function getMenuCount ($type, $published=1) {
00148         return isset($this->counts[$type][$published]) ? $this->counts[$type][$published] : 0;
00149     }
00150 
00151     public function getCountByTypeComponentID ($type, $sections) {
00152         $count = 0;
00153         foreach ($this->menus as $menu) {
00154             if ($menu->menutype == $type AND in_array($menu->componentid, $sections) AND 1 == $menu->published) $count++;
00155         }
00156         return $count;
00157     }
00158 
00159     public function getMenutypes () {
00160         $types = array();
00161         foreach ($this->menus as $menu) $types[$menu->menutype] = 1;
00162         ksort($types);
00163         if (0 == count($types)) return array('mainmenu');
00164         return array_keys($types);
00165     }
00166 
00167     public function getIDByMenutypeQuery ($type, $query) {
00168         $query = str_replace('&amp;', '&', $query);
00169         foreach ($this->menus as $menu) {
00170             if ($menu->published == 1 AND ($type == '*' OR $menu->menutype == $type) AND $menu->link == 'index.php?'.$query) return $menu->id;
00171         }
00172         return null;
00173     }
00174 
00175     public function getAllMenusByMenutype ($type) {
00176         $menus = array();
00177         foreach ($this->menus as $menu) if ($menu->menutype == $type) $menus[] = $menu;
00178         return $menus;
00179     }
00180 
00181     public function getAllMenusByType ($type) {
00182         $menus = array();
00183         foreach ($this->menus as $menu) if ($menu->type == $type) $menus[] = $menu;
00184         return $menus;
00185     }
00186 
00187     public function getMenusByIDTypes ($componentid, $types) {
00188         $menus = array();
00189         foreach ($this->menus as $menu) {
00190             if ($componentid != $menu->componentid) continue;
00191             foreach ($types as $type) if (false !== strpos($menu->link, $type)) {
00192                 $menus = $menu;
00193                 continue;
00194             }
00195         }
00196         return $menus;
00197     }
00198 
00199     private function getIDLikeQuery ($query_items, $published=false) {
00200         $min = 999;
00201         $result = 0;
00202         foreach ($this->menus as $menu) {
00203             if (substr($menu->link,0,10) != 'index.php?' OR ($published AND !$menu->published)) continue;
00204             $link = str_replace('&amp;', '&', substr($menu->link,10));
00205             $link_items = explode('&', $link);
00206             $diff = count(array_diff($link_items, $query_items));
00207             if ($diff < $min) {
00208                 $min = $diff;
00209                 $result = $menu->id;
00210             }
00211             elseif ($diff == $min AND $menu->menutype == 'mainmenu') $result = $menu->id;
00212         }
00213         if ($min AND isset($_SESSION['aliro_Itemid'])) $result = $_SESSION['aliro_Itemid'];
00214         return $result;
00215     }
00216 
00217     public function matchURL ($published=true) {
00218         if (!isset($_REQUEST['option'])) {
00219             $this->setHome();
00220             $result = $this->getHome();
00221         }
00222         else {
00223             if ($_SERVER['QUERY_STRING']) $query_items = explode('&', $_SERVER['QUERY_STRING']);
00224             else $query_items = array();
00225             foreach ($_POST as $name=>$value) $query_items[] = $name.'='.$value;
00226             $link = $this->getIDLikeQuery($query_items, $published);
00227             if ($link) $result = $this->menus[$link];
00228             else $result = null;
00229         }
00230         if ($result) {
00231             $optionstring = 'option='.aliroRequest::getInstance()->getOption();
00232             if (false === strpos($result->link, $optionstring)) return null;
00233             $_SESSION['aliro_Itemid'] = $result->id;
00234         }
00235         return $result;
00236    }
00237 
00238     public function getIDByTypeCid ($type, $componentid, $unpublished=false) {
00239         foreach ($this->menus as $menu) {
00240             if (($unpublished OR $menu->published == 1) AND ('*' == $type OR $menu->type == $type) AND $menu->componentid == $componentid) return $menu->id;
00241         }
00242         return null;
00243     }
00244 
00245     public function getGlobalBlogSectionCount () {
00246         $count = 0;
00247         foreach ($this->menus as $menu) {
00248             if ($menu->type == 'content_blog_section' AND $menu->published == 1 AND $menu->componentid == 0) $count++;
00249         }
00250         return $count;
00251     }
00252 
00253     private function addMenus ($menutype, &$result, $menukeys, $published, $level) {
00254         $authoriser = aliroAuthoriser::getInstance();
00255         foreach ($menukeys as $key) {
00256             $menu = $this->menus[$key];
00257             $menu->level = $level;
00258             if ($published AND !$menu->published) continue;
00259             if (!$authoriser->checkUserPermission ('view', 'mosMenuEntry', $menu->id)) continue;
00260             $result[] = $menu;
00261             if (isset($this->byParentOrder[$menutype][$menu->id])) $this->addMenus($menutype, $result, $this->byParentOrder[$menutype][$menu->id], $published, $level+1);
00262         }
00263     }
00264 
00265     public function &getByParentOrder ($menutype, $published=1) {
00266         $result = array();
00267         if (isset($this->byParentOrder[$menutype][0])) {
00268             $this->addMenus($menutype, $result, $this->byParentOrder[$menutype][0], $published, 0);
00269         }
00270         return $result;
00271     }
00272 
00273     public function getHome () {
00274         return $this->main_home;
00275     }
00276 
00277     public function setHome () {
00278         if ($this->main_home) {
00279             $requests = explode ('&', substr($this->main_home->link, 10));
00280             foreach ($requests as $request) {
00281                 $parts = explode ('=', $request);
00282                 if (count($parts == 2)) $_REQUEST[$parts[0]] = $_POST[$parts[0]] = $parts[1];
00283             }
00284         }
00285         return isset($_REQUEST['option']) ? $_REQUEST['option'] : null;
00286     }
00287 
00288     public function updateNames ($oldname, $newname, $type) {
00289         $database = aliroCoreDatabase::getInstance();
00290         $database->doSQL("UPDATE #__menu SET name='$newname' WHERE name='$oldname' AND type='$type'");
00291         $this->clearCache();
00292     }
00293 
00294     public function publishMenus ($ids, $new_publish, $type=null) {
00295         foreach ($ids as &$id) $id = intval($id);
00296         $new_publish = intval($new_publish);
00297         $idlist = implode (',', $ids);
00298         $database = aliroCoreDatabase::getInstance();
00299         $sql = "UPDATE #__menu SET published = $new_publish WHERE id IN ($idlist)";
00300         if ($type) $sql .= " AND type='$type'";
00301         $database->doSQL ($sql);
00302         $this->clearCache();
00303     }
00304 
00305     public function changeOrder ($id, $direction, $menutype) {
00306         $menu = $this->getMenuByID($id);
00307         $movement = 'down' == $direction ? 15 : -15;
00308         $this->updateOrdering (array($id => $menu->ordering + $movement), $menutype);
00309     }
00310 
00311     public function updateOrdering ($orders, $menutype) {
00312         foreach ($orders as $id=>$order) {
00313             $menu =  $this->getMenuByID($id);
00314             if ($menu->ordering != $order) $changes[$id] = $order;
00315         }
00316         foreach ($this->getByParentOrder($menutype, 0) as $menu) {
00317             $ordering = isset($changes[$menu->id]) ? $changes[$menu->id] : $menu->ordering;
00318             $allmenus[$menu->level][$ordering] = $menu->id;
00319         }
00320         $changed = false;
00321         $query = "UPDATE #__menu SET ordering = CASE ";
00322         foreach ($allmenus as $level=>$orderings) {
00323             $order = 10;
00324             ksort($orderings);
00325             foreach ($orderings as $ordering=>$id) {
00326                 $menu = $this->getMenuByID($id);
00327                 if ($order != $menu->ordering) {
00328                     $query .= "WHEN id = $id THEN $order ";
00329                     $changed = true;
00330                 }
00331                 $order += 10;
00332             }
00333         }
00334         if ($changed) {
00335             $query .= 'ELSE ordering END';
00336             aliroCoreDatabase::getInstance()->doSQL ($query);
00337             $this->clearCache();
00338         }
00339     }
00340 
00341     public function setPathway ($Itemid) {
00342         if ($Itemid) {
00343             $menu = $this->getMenuByID($Itemid);
00344             if ($menu->parent) $this->setPathway($menu->parent);
00345             $pathway = aliroPathway::getInstance();
00346             $pathway->addItem($menu->name, $menu->link."&Itemid=$Itemid");
00347         }
00348     }
00349 
00350     public function deleteMenus ($cid) {
00351         if (is_array($cid)) {
00352             foreach ($cid as &$id) $id = intval($id);
00353             $idlist = implode(',', $cid);
00354         }
00355         else $idlist = intval($cid);
00356         $database = aliroCoreDatabase::getInstance();
00357         $database->doSQL ("DELETE FROM #__menu WHERE id IN($idlist)");
00358         $this->clearCache();
00359         self::$instance = __CLASS__;
00360     }
00361 
00362     public function saveMenu ($menu) {
00363         if ($menu instanceof aliroMenuItem) {
00364             $database = aliroCoreDatabase::getInstance();
00365             if ($menu->id == 0) {
00366                 $menu->parent = intval($menu->parent);
00367                 $database->setQuery ("SELECT MAX(ordering) FROM `#__menu` WHERE `parent` = $menu->parent GROUP BY `parent`");
00368                 $menu->ordering = $database->loadResult() + 1;
00369             }
00370             if (!$menu->store()) die ('Store menu object failed');
00371             $this->clearCache();
00372             self::$instance = __CLASS__;
00373         }
00374         else die ('Asked to store something not a menu object');
00375     }
00376 
00377 }

Generated on Wed May 14 13:01:56 2008 for ALIRO by  doxygen 1.5.5