PageRenderTime 28ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/backoffice/services/MenuService.class.php

http://pagizer-cms.googlecode.com/
PHP | 458 lines | 293 code | 83 blank | 82 comment | 57 complexity | 5ebd78c52e9a5fe063c3332597c05445 MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1
  1. <?php
  2. /**
  3. * This file is part of the Pagizer package.
  4. *
  5. * For the full copyright and license information, please view the LICENSE
  6. * file that was distributed with this source code.
  7. *
  8. * @copyright Copyright (c) 2010 Advisa (http://www.advisa.fr)
  9. * @author Pagizer Core Team <team@pagizer.org>
  10. * @package Pagizer
  11. * @subpackage backoffice
  12. */
  13. /**
  14. * Service to display the left menu (sliding menu)
  15. */
  16. class m_backoffice_services_MenuService extends f_core_Service
  17. {
  18. private static $instance;
  19. private static $LABELWORDWRAP = 15;
  20. /* @var $xmlObject f_xml_Xpath */
  21. private $xmlObject;
  22. private $xmlArray;
  23. private $parserFileName = "treeParser";
  24. private $module;
  25. private $nodeId;
  26. private $rootFolderId;
  27. /**
  28. * @return m_backoffice_services_MenuService
  29. */
  30. private function __construct()
  31. {
  32. return $this;
  33. }
  34. /**
  35. * Get singleton instance
  36. *
  37. * @return m_backoffice_services_MenuService
  38. */
  39. public static function getInstance()
  40. {
  41. if(self::$instance === null)
  42. {
  43. self::$instance = new self();
  44. }
  45. return self::$instance;
  46. }
  47. // ********************************************* SLIDER MENU ********************************************************
  48. /**
  49. * Get the slider menu tree
  50. *
  51. * @param string $moduleName
  52. * @param int $nodeId
  53. * @param integer $rootFolderId
  54. * @param string $lang
  55. * @param bool $ext
  56. * @return array
  57. */
  58. public function getMenuTree($moduleName, $nodeId = null, $lang = null, $ext = null, $forceChild = false)
  59. {
  60. if(is_null($lang)) $lang = $this->getContextLang();
  61. if(is_null($ext)) $ext = false;
  62. if(is_null($moduleName)) $moduleName = "website";
  63. $this->module = $moduleName;
  64. $this->parseModuleTreefile($moduleName);
  65. $rootNode = m_backoffice_services_RootNodeService::getInstance()->getModuleRootNode($moduleName, $lang);
  66. $this->rootFolderId = $rootNode->getUniqueId();
  67. if(is_null($nodeId))
  68. {
  69. $nodeId = $this->rootFolderId;
  70. }
  71. $this->nodeId = $nodeId;
  72. $defaultModules = array("website", "medias", "users", "backoffice");
  73. // Special case, if is website rootNode, get all websites
  74. if($moduleName == "website" && $nodeId == $rootNode->getUniqueId())
  75. {
  76. $tree = $this->getAllWebsitesTreeNodes($nodeId, $this->getAuthorizedDocTypes(), $lang);
  77. }
  78. elseif($moduleName == "backoffice")
  79. {
  80. $tree = $this->getModulesTreeNodes($nodeId, $lang);
  81. }
  82. elseif(!in_array($moduleName, $defaultModules) && $forceChild == false)
  83. {
  84. $tree = $this->getTreeNodes($nodeId, $this->getAuthorizedDocTypes(), $lang, $moduleName, true);
  85. }
  86. else
  87. {
  88. $tree = $this->getTreeNodes($nodeId, $this->getAuthorizedDocTypes(), $lang, $moduleName);
  89. }
  90. return $tree;
  91. }
  92. /**
  93. * Special case : get nodes for My modules menu
  94. *
  95. * @param integer $nodeId
  96. * @param string $lang
  97. * @return array
  98. */
  99. private function getModulesTreeNodes($nodeId, $lang = null)
  100. {
  101. $rootNodeService = m_backoffice_services_RootNodeService::getInstance();
  102. $nodes = array();
  103. // My modules root node
  104. $nodes[] = $this->newMenuItem($rootNodeService->getModuleRootNode("backoffice", $lang))->setSlide(true)->setAsRoot();
  105. foreach(f_file_Directory::getInstance(MODULES_DIR)->getSubdirs() as $moduleDir)
  106. {
  107. // get module description
  108. $desc = f_package_Description::getInstance($moduleDir->getPath().DS."package.xml");
  109. if(!is_null($desc))
  110. {
  111. // if module is an extension get menu item
  112. if($desc->getType() == 'extension')
  113. {
  114. $moduleNode = $desc->hasModuleRootNode() ? $rootNodeService->getModuleRootNode($desc->getName(), $lang) : $rootNodeService->createModuleRootNode($desc->getName(), $lang);
  115. $node = $this->newMenuItem($moduleNode)->setId($desc->getName())->setModuleName($desc->getName())->setSlide(true)->setAsChild();
  116. if(f_context_User::getInstance()->hasRight($desc->getName()."_Show"))
  117. {
  118. $nodes[$desc->getName()] = $node;
  119. }
  120. }
  121. }
  122. }
  123. $order = f_context_User::getInstance()->getUser()->getExtraParameter('modulesOrder');
  124. if(!is_null($order))
  125. {
  126. $result[0] = $nodes[0];
  127. unset($nodes[0]);
  128. foreach($order as $k => $module)
  129. {
  130. $result[$k+1] = $nodes[$module];
  131. unset($nodes[$module]);
  132. }
  133. $result = array_merge($result, $nodes);
  134. return $result;
  135. }
  136. return $nodes;
  137. }
  138. private function getTreeNodes($nodeId, $docTypes, $lang = null, $ext = null, $forceChild = false)
  139. {
  140. $lang = strtoupper($lang);
  141. // if node is a generic module
  142. if($forceChild == true)
  143. {
  144. $rootNodeService = m_backoffice_services_RootNodeService::getInstance();
  145. $parent = $rootNodeService->getModuleRootNode("backoffice", $lang);
  146. if(is_null($parent))
  147. {
  148. $parent = $rootNodeService->createModuleRootNode("backoffice", $lang);
  149. }
  150. $menuItem = $this->newMenuItem($parent)->setSlide(true);
  151. if($this->rootFolderId == $nodeId) $menuItem->setAsRoot();
  152. $nodes[] = $menuItem;
  153. }
  154. $node = $this->getDocumentProvider()->getByUniqueId($nodeId, $lang);
  155. if($node instanceof m_backoffice_documents_RootNode)
  156. {
  157. $node->setModule($this->module);
  158. }
  159. $parents = f_relation_ManagerNew::getInstance($node)->getParents()->recursively()->withModel($docTypes)->retrieveIdsAndModels();
  160. if(is_array($parents))
  161. {
  162. $nbParents = count($parents);
  163. foreach($parents as $key => $parentId)
  164. {
  165. $parent = $this->getDocumentProvider()->getByModelAndUniqueId($parentId['model'], $parentId['id'], $lang);
  166. if($parent instanceof m_backoffice_documents_RootNode)
  167. {
  168. $parent = $parent->getVoDocument()->setModule($this->module);
  169. }
  170. $menuItem = $this->newMenuItem($parent)->setSlide($key != ($nbParents-1));
  171. if($parent instanceof m_backoffice_documents_RootNode)
  172. {
  173. $menuItem->setModuleName($this->module);
  174. }
  175. if($this->rootFolderId == $nodeId) $menuItem->setAsRoot();
  176. $nodes[] = $menuItem;
  177. }
  178. }
  179. if($node->canSlide() == false || !$node->isTranslated())
  180. {
  181. $parentLang = $lang;
  182. if(method_exists($node, "isTranslated"))
  183. {
  184. $parentLang = $node->getVO();
  185. }
  186. $parents = f_relation_ManagerNew::getInstance($node)->getParents()->withModel($docTypes)->withLang($parentLang)->retrieveDocuments();
  187. $parent = end($parents);
  188. $parentNodeId = $parent->getUniqueId();
  189. foreach($nodes as $k => $node)
  190. {
  191. if($node->getUniqueId() == $parentNodeId)
  192. {
  193. $nodes[$k]->setAsLastParent();
  194. }
  195. }
  196. $childs = f_relation_ManagerNew::getInstance($parent)->getChilds()->withModel($docTypes)->retrieveIdsAndModels();
  197. }
  198. else
  199. {
  200. $childs = f_relation_ManagerNew::getInstance($node)->getChilds()->withModel($docTypes)->retrieveIdsAndModels();
  201. $nodeItem = array();
  202. if(isset($nodes) && isset($nodes[count($nodes)-1]))
  203. {
  204. $nodes[count($nodes)-1]->setSlide(true);
  205. }
  206. $menuItem = $this->newMenuItem($node);
  207. $menuItem ->setSlide($node->getUniqueId() == $nodeId && !$ext ? false : true)
  208. //->setModuleName($ext)
  209. ->setAsTranslated()
  210. ->setAsLastParent();
  211. if($node instanceof m_backoffice_documents_RootNode)
  212. {
  213. $menuItem->setModuleName($this->module);
  214. }
  215. $nodes[] = $menuItem;
  216. }
  217. $childIds = Array();
  218. $childIdsLang = Array();
  219. foreach($childs as $childId)
  220. {
  221. if($childId["lang"] == $lang)
  222. {
  223. $childIds[] = $childId;
  224. }
  225. else
  226. {
  227. $childIdsLang[] = $childId;
  228. }
  229. }
  230. if(!empty($childIds) || !empty($childIdsLang))
  231. {
  232. $childIds = array_merge($childIds, $childIdsLang);
  233. $new = array();
  234. $exclude = array("");
  235. for ($i = 0; $i<=count($childIds)-1; $i++)
  236. {
  237. if (!in_array(trim($childIds[$i]["id"]) ,$exclude))
  238. {
  239. $new[] = $childIds[$i]; $exclude[] = trim($childIds[$i]["id"]);
  240. }
  241. }
  242. $childIds = $new;
  243. }
  244. foreach($childIds as $childId)
  245. {
  246. $child = $this->getDocumentProvider()->getByModelAndUniqueId($childId['model'], $childId['id'], $lang);
  247. if($child->getModel() == 'modules_backoffice/folder')
  248. {
  249. if($child->getModule() == $ext)
  250. {
  251. $nodes[] = $this->newMenuItem($child)->setAsChild();
  252. }
  253. }
  254. else
  255. {
  256. $nodes[] = $this->newMenuItem($child)->setAsChild();
  257. }
  258. }
  259. return $nodes;
  260. }
  261. private function getAllWebsitesTreeNodes($nodeId, $docTypes, $lang)
  262. {
  263. $node = f_document_Provider::getInstance()->getByModelAndUniqueId('backoffice/rootNode', $nodeId, $lang);
  264. $nodes = array();
  265. // add websites root node
  266. $nodes[] = $this->newMenuItem($node)->setSlide(false)->setAsLastParent();
  267. // get childs
  268. $childs = f_relation_ManagerNew::getInstance($node)->getChilds()->withModel("modules_website/website")->retrieveDocuments();
  269. foreach($childs as $child)
  270. {
  271. if(!$child->isATranslation())
  272. {
  273. $nodes[] = $this->newMenuItem($child)->setAsChild()->setSlide(true);
  274. }
  275. }
  276. return $nodes;
  277. }
  278. private function newMenuItem($document)
  279. {
  280. return m_backoffice_extends_MenuNode::createNewFromDocument($document, $this->module, $this->nodeId);
  281. }
  282. // ***********************************************************************************************
  283. /**
  284. * Parse the given module menu configuration file
  285. *
  286. * @param string $moduleName
  287. * @param string $xmlFileName
  288. * @return m_backoffice_services_MenuService
  289. */
  290. public function parseModuleTreefile($moduleName)
  291. {
  292. $xmlFileName = str_replace(".xml", "", $this->parserFileName).".xml";
  293. $file = f_file_Resolver::getModuleFilePath($moduleName, 'config'.DS.$xmlFileName);
  294. if(!is_null($file))
  295. {
  296. $this->parseXML($file);
  297. }
  298. else
  299. {
  300. throw new Exception("No tree parser XML file in ".$filePath);
  301. }
  302. return $this;
  303. }
  304. /**
  305. * Parse a module menu configuration file
  306. *
  307. * @param string $xmlFile path to the xml file
  308. * @return m_backoffice_services_MenuService
  309. */
  310. private function parseXML($xmlFile)
  311. {
  312. $this->xmlObject = f_xml_Xpath::getInstance($xmlFile);
  313. $nodes = $this->xmlObject->getElementsFromXpath("items/item");
  314. $this->xmlArray = array();
  315. if(!is_null($nodes))
  316. {
  317. /* @var $node f_xml_XmlElement */
  318. foreach ($nodes as $node)
  319. {
  320. $this->xmlArray[$node->getAttributeValue("documentType")]['attributes'] = $node->getAttributes();
  321. $actions = $node->getSubElements("actions");
  322. if(!is_null($actions))
  323. {
  324. /* @var $action f_xml_XmlElement */
  325. foreach($actions as $action)
  326. {
  327. $this->xmlArray[$node->getAttributeValue("documentType")]['actions'][$action->getAttributeValue("name")] = $action->getAttributes();
  328. }
  329. }
  330. }
  331. }
  332. return $this;
  333. }
  334. /**
  335. * Returns authorized document types to display in menu
  336. *
  337. * @return array|null
  338. */
  339. public function getAuthorizedDocTypes()
  340. {
  341. if(is_array($this->xmlArray))
  342. {
  343. return array_keys($this->xmlArray);
  344. }
  345. return null;
  346. }
  347. /**
  348. * Get actions attributed to a document type
  349. *
  350. * @param string $documentType
  351. * @return array or null
  352. */
  353. public function getActionsByDocumentType($documentType)
  354. {
  355. if(isset($this->xmlArray[$documentType]['actions']))
  356. {
  357. return $this->xmlArray[$documentType]['actions'];
  358. }
  359. return null;
  360. }
  361. /**
  362. * Get attributs for a document type
  363. *
  364. * @param string $documentType
  365. * @return array or null
  366. */
  367. public function getAttributesByDocumentType($documentType)
  368. {
  369. if(isset($this->xmlArray[$documentType]['attributes']))
  370. {
  371. return $this->xmlArray[$documentType]['attributes'];
  372. }
  373. return null;
  374. }
  375. }