PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/administrator/components/com_menus/models/list.php

https://gitlab.com/endomorphosis/greenrenaissancejoomla
PHP | 706 lines | 526 code | 91 blank | 89 comment | 76 complexity | f239b6f5eb45fc0f1c121fcb3f0fa54d MD5 | raw file
  1. <?php
  2. /**
  3. * @version $Id: list.php 10094 2008-03-02 04:35:10Z instance $
  4. * @package Joomla
  5. * @subpackage Menus
  6. * @copyright Copyright (C) 2005 - 2008 Open Source Matters. All rights reserved.
  7. * @license GNU/GPL, see LICENSE.php
  8. * Joomla! is free software. This version may have been modified pursuant to the
  9. * GNU General Public License, and as distributed it includes or is derivative
  10. * of works licensed under the GNU General Public License or other free or open
  11. * source software licenses. See COPYRIGHT.php for copyright notices and
  12. * details.
  13. */
  14. // Check to ensure this file is included in Joomla!
  15. defined('_JEXEC') or die( 'Restricted access' );
  16. jimport( 'joomla.application.component.model' );
  17. /**
  18. * @package Joomla
  19. * @subpackage Menus
  20. */
  21. class MenusModelList extends JModel
  22. {
  23. /** @var object JTable object */
  24. var $_table = null;
  25. var $_pagination = null;
  26. /**
  27. * Returns the internal table object
  28. * @return JTable
  29. */
  30. function &getTable()
  31. {
  32. if ($this->_table == null)
  33. {
  34. $this->_table =& JTable::getInstance( 'menu');
  35. }
  36. return $this->_table;
  37. }
  38. function &getItems()
  39. {
  40. global $mainframe;
  41. static $items;
  42. if (isset($items)) {
  43. return $items;
  44. }
  45. $db =& $this->getDBO();
  46. $menutype = $mainframe->getUserStateFromRequest( "com_menus.menutype", 'menutype', 'mainmenu', 'string' );
  47. $filter_order = $mainframe->getUserStateFromRequest( 'com_menus.'.$menutype.'.filter_order', 'filter_order', 'm.ordering', 'cmd' );
  48. $filter_order_Dir = $mainframe->getUserStateFromRequest( 'com_menus.'.$menutype.'.filter_order_Dir', 'filter_order_Dir', 'ASC', 'word' );
  49. $filter_state = $mainframe->getUserStateFromRequest( 'com_menus.'.$menutype.'.filter_state', 'filter_state', '', 'word' );
  50. $limit = $mainframe->getUserStateFromRequest( 'global.list.limit', 'limit', $mainframe->getCfg( 'list_limit' ), 'int' );
  51. $limitstart = $mainframe->getUserStateFromRequest( 'com_menus.'.$menutype.'.limitstart', 'limitstart', 0, 'int' );
  52. $levellimit = $mainframe->getUserStateFromRequest( 'com_menus.'.$menutype.'.levellimit', 'levellimit', 10, 'int' );
  53. $search = $mainframe->getUserStateFromRequest( 'com_menus.'.$menutype.'.search', 'search', '', 'string' );
  54. $search = JString::strtolower( $search );
  55. $and = '';
  56. if ( $filter_state )
  57. {
  58. if ( $filter_state == 'P' ) {
  59. $and = ' AND m.published = 1';
  60. } else if ($filter_state == 'U' ) {
  61. $and = ' AND m.published = 0';
  62. }
  63. }
  64. // just in case filter_order get's messed up
  65. if ($filter_order) {
  66. $orderby = ' ORDER BY '.$filter_order .' '. $filter_order_Dir .', m.parent, m.ordering';
  67. } else {
  68. $orderby = ' ORDER BY m.parent, m.ordering';
  69. }
  70. // select the records
  71. // note, since this is a tree we have to do the limits code-side
  72. if ($search) {
  73. $query = 'SELECT m.id' .
  74. ' FROM #__menu AS m' .
  75. ' WHERE menutype = '.$db->Quote($menutype) .
  76. ' AND LOWER( m.name ) LIKE '.$db->Quote( '%'.$db->getEscaped( $search, true ).'%', false ) .
  77. $and;
  78. $db->setQuery( $query );
  79. $search_rows = $db->loadResultArray();
  80. }
  81. $query = 'SELECT m.*, u.name AS editor, g.name AS groupname, c.publish_up, c.publish_down, com.name AS com_name' .
  82. ' FROM #__menu AS m' .
  83. ' LEFT JOIN #__users AS u ON u.id = m.checked_out' .
  84. ' LEFT JOIN #__groups AS g ON g.id = m.access' .
  85. ' LEFT JOIN #__content AS c ON c.id = m.componentid AND m.type = "content_typed"' .
  86. ' LEFT JOIN #__components AS com ON com.id = m.componentid AND m.type = "component"' .
  87. ' WHERE m.menutype = '.$db->Quote($menutype) .
  88. ' AND m.published != -2' .
  89. $and .
  90. $orderby;
  91. $db->setQuery( $query );
  92. $rows = $db->loadObjectList();
  93. // establish the hierarchy of the menu
  94. $children = array();
  95. // first pass - collect children
  96. foreach ($rows as $v )
  97. {
  98. $pt = $v->parent;
  99. $list = @$children[$pt] ? $children[$pt] : array();
  100. array_push( $list, $v );
  101. $children[$pt] = $list;
  102. }
  103. // second pass - get an indent list of the items
  104. $list = JHTML::_('menu.treerecurse', 0, '', array(), $children, max( 0, $levellimit-1 ) );
  105. // eventually only pick out the searched items.
  106. if ($search) {
  107. $list1 = array();
  108. foreach ($search_rows as $sid )
  109. {
  110. foreach ($list as $item)
  111. {
  112. if ($item->id == $sid) {
  113. $list1[] = $item;
  114. }
  115. }
  116. }
  117. // replace full list with found items
  118. $list = $list1;
  119. }
  120. $total = count( $list );
  121. jimport('joomla.html.pagination');
  122. $this->_pagination = new JPagination( $total, $limitstart, $limit );
  123. // slice out elements based on limits
  124. $list = array_slice( $list, $this->_pagination->limitstart, $this->_pagination->limit );
  125. $i = 0;
  126. $query = array();
  127. foreach ( $list as $mitem )
  128. {
  129. $edit = '';
  130. switch ( $mitem->type )
  131. {
  132. case 'separator':
  133. $list[$i]->descrip = JText::_('Separator');
  134. break;
  135. case 'url':
  136. $list[$i]->descrip = JText::_('URL');
  137. break;
  138. case 'menulink':
  139. $list[$i]->descrip = JText::_('Menu Link');
  140. break;
  141. case 'component':
  142. $list[$i]->descrip = JText::_('Component');
  143. $query = parse_url($list[$i]->link);
  144. $view = array();
  145. if(isset($query['query'])) {
  146. if(strpos($query['query'], '&amp;') !== false)
  147. {
  148. $query['query'] = str_replace('&amp;','&',$query['query']);
  149. }
  150. parse_str($query['query'], $view);
  151. }
  152. $list[$i]->view = $list[$i]->com_name;
  153. if (isset($view['view']))
  154. {
  155. $list[$i]->view .= ' &raquo; '.JText::_(ucfirst($view['view']));
  156. }
  157. if (isset($view['layout']))
  158. {
  159. $list[$i]->view .= ' / '.JText::_(ucfirst($view['layout']));
  160. }
  161. if (isset($view['task']) && !isset($view['view']))
  162. {
  163. $list[$i]->view .= ' :: '.JText::_(ucfirst($view['task']));
  164. }
  165. break;
  166. default:
  167. $list[$i]->descrip = JText::_('Unknown');
  168. break;
  169. }
  170. $i++;
  171. }
  172. $items = $list;
  173. return $items;
  174. }
  175. function &getPagination()
  176. {
  177. if ($this->_pagination == null) {
  178. $this->getItems();
  179. }
  180. return $this->_pagination;
  181. }
  182. /**
  183. * Form for copying item(s) to a specific menu
  184. */
  185. function getItemsFromRequest()
  186. {
  187. static $items;
  188. if (isset($items)) {
  189. return $items;
  190. }
  191. $cid = JRequest::getVar( 'cid', array(), 'post', 'array' );
  192. JArrayHelper::toInteger($cid);
  193. if (count($cid) < 1) {
  194. $this->setError(JText::_( 'Select an item to move'));
  195. return false;
  196. }
  197. // Query to list the selected menu items
  198. $db =& $this->getDBO();
  199. $cids = implode( ',', $cid );
  200. $query = 'SELECT `id`, `name`' .
  201. ' FROM `#__menu`' .
  202. ' WHERE `id` IN ( '.$cids.' )';
  203. $db->setQuery( $query );
  204. $items = $db->loadObjectList();
  205. return $items;
  206. }
  207. /**
  208. * Gets the componet table object related to this menu item
  209. */
  210. function &getComponent()
  211. {
  212. $id = $this->_table->componentid;
  213. $component = & JTable::getInstance( 'component');
  214. $component->load( $id );
  215. return $component;
  216. }
  217. /**
  218. * Save the item(s) to the menu selected
  219. */
  220. function copy( $items, $menu )
  221. {
  222. $curr =& JTable::getInstance('menu');
  223. $itemref = array();
  224. foreach ($items as $id)
  225. {
  226. $curr->load( $id );
  227. $curr->id = NULL;
  228. $curr->home = 0;
  229. if ( !$curr->store() ) {
  230. $this->setError($row->getError());
  231. return false;
  232. }
  233. $itemref[] = array($id, $curr->id);
  234. }
  235. foreach ($itemref as $ref)
  236. {
  237. $curr->load( $ref[1] );
  238. if ($curr->parent!=0) {
  239. $found = false;
  240. foreach ( $itemref as $ref2 )
  241. {
  242. if ($curr->parent == $ref2[0]) {
  243. $curr->parent = $ref2[1];
  244. $found = true;
  245. break;
  246. } // if
  247. }
  248. if (!$found && $curr->menutype!=$menu) {
  249. $curr->parent = 0;
  250. }
  251. } // if
  252. $curr->menutype = $menu;
  253. $curr->ordering = '9999';
  254. $curr->home = 0;
  255. if ( !$curr->store() ) {
  256. $this->setError($row->getError());
  257. return false;
  258. }
  259. $curr->reorder( 'menutype = '.$this->_db->Quote($curr->menutype).' AND parent = '.(int) $curr->parent );
  260. } // foreach
  261. return true;
  262. }
  263. function move($items, $menu)
  264. {
  265. // Add all children to the list
  266. foreach ($items as $id)
  267. {
  268. $this->_addChildren($id, $items);
  269. }
  270. $row =& $this->getTable();
  271. $ordering = 1000000;
  272. $firstroot = 0;
  273. foreach ($items as $id) {
  274. $row->load( $id );
  275. // is it moved together with his parent?
  276. $found = false;
  277. if ($row->parent != 0) {
  278. foreach ($items as $idx)
  279. {
  280. if ($idx == $row->parent) {
  281. $found = true;
  282. break;
  283. } // if
  284. }
  285. }
  286. if (!$found) {
  287. $row->parent = 0;
  288. $row->ordering = $ordering++;
  289. if (!$firstroot) $firstroot = $row->id;
  290. } // if
  291. $row->menutype = $menu;
  292. if ( !$row->store() ) {
  293. $this->setError($row->getError());
  294. return false;
  295. } // if
  296. } // foreach
  297. if ($firstroot) {
  298. $row->load( $firstroot );
  299. $row->reorder( 'menutype = '.$this->_db->Quote($row->menutype).' AND parent = '.(int) $row->parent );
  300. } // if
  301. return true;
  302. }
  303. function toTrash($items)
  304. {
  305. $db =& $this->getDBO();
  306. $nd = $db->getNullDate();
  307. $state = -2;
  308. $row =& $this->getTable();
  309. $default = 0;
  310. // Add all children to the list
  311. foreach ($items as $id)
  312. {
  313. //Check if it's the default item
  314. $row->load( $id );
  315. if ($row->home != 1) {
  316. $this->_addChildren($id, $items);
  317. } else {
  318. unset($items[$default]);
  319. JError::raiseWarning( 'SOME_ERROR_CODE', JText::_('You cannot trash the default menu item'));
  320. }
  321. $default++;
  322. }
  323. if (count($items) > 0) {
  324. // Sent menu items to the trash
  325. JArrayHelper::toInteger($items, array(0));
  326. $where = ' WHERE (id = ' . implode( ' OR id = ', $items ) . ') AND home = 0';
  327. $query = 'UPDATE #__menu' .
  328. ' SET published = '.(int) $state.', parent = 0, ordering = 0, checked_out = 0, checked_out_time = '.$db->Quote($nd) .
  329. $where;
  330. $db->setQuery( $query );
  331. if (!$db->query()) {
  332. $this->setError( $db->getErrorMsg() );
  333. return false;
  334. }
  335. }
  336. // Clear the content cache
  337. // TODO: Is this necessary?
  338. $cache = & JFactory::getCache('com_content');
  339. $cache->clean();
  340. return count($items);
  341. }
  342. function fromTrash($items)
  343. {
  344. $db =& $this->getDBO();
  345. $nd = $db->getNullDate();
  346. $state = 0;
  347. // Add all children to the list
  348. foreach ($items as $id)
  349. {
  350. $this->_addChildren($id, $items);
  351. }
  352. // Sent menu items to the trash
  353. JArrayHelper::toInteger($items, array(0));
  354. $where = ' WHERE id = ' . implode( ' OR id = ', $items );
  355. $query = 'UPDATE #__menu' .
  356. ' SET published = '.(int) $state.', parent = 0, ordering = 99999, checked_out = 0, checked_out_time = '.$db->Quote($nd) .
  357. $where;
  358. $db->setQuery( $query );
  359. if (!$db->query()) {
  360. $this->setError( $db->getErrorMsg() );
  361. return false;
  362. }
  363. // Clear the content cache
  364. // TODO: Is this necessary?
  365. $cache = & JFactory::getCache('com_content');
  366. $cache->clean();
  367. return count($items);
  368. }
  369. /**
  370. * Set the state of selected menu items
  371. */
  372. function setHome( $item )
  373. {
  374. $db =& $this->getDBO();
  375. // Clear home field for all other items
  376. $query = 'UPDATE #__menu' .
  377. ' SET home = 0' .
  378. ' WHERE 1';
  379. $db->setQuery( $query );
  380. if ( !$db->query() ) {
  381. $this->setError($db->getErrorMsg());
  382. return false;
  383. }
  384. // Set the given item to home
  385. $query = 'UPDATE #__menu' .
  386. ' SET home = 1' .
  387. ' WHERE id = '.(int) $item;
  388. $db->setQuery( $query );
  389. if ( !$db->query() ) {
  390. $this->setError($db->getErrorMsg());
  391. return false;
  392. }
  393. return true;
  394. }
  395. /**
  396. * Set the state of selected menu items
  397. */
  398. function setItemState( $items, $state )
  399. {
  400. if(is_array($items))
  401. {
  402. $row =& $this->getTable();
  403. foreach ($items as $id)
  404. {
  405. $row->load( $id );
  406. if ($row->home != 1) {
  407. $row->published = $state;
  408. if ($state != 1) {
  409. // Set any alias menu types to not point to unpublished menu items
  410. $db = &$this->getDBO();
  411. $query = 'UPDATE #__menu SET link = 0 WHERE type = \'menulink\' AND link = '.(int)$id;
  412. $db->setQuery( $query );
  413. if (!$db->query()) {
  414. $this->setError( $db->getErrorMsg() );
  415. return false;
  416. }
  417. }
  418. if (!$row->check()) {
  419. $this->setError($row->getError());
  420. return false;
  421. }
  422. if (!$row->store()) {
  423. $this->setError($row->getError());
  424. return false;
  425. }
  426. } else {
  427. JError::raiseWarning( 'SOME_ERROR_CODE', JText::_('You cannot unpublish the default menu item'));
  428. return false;
  429. }
  430. }
  431. }
  432. // clean menu cache
  433. $cache =& JFactory::getCache('mod_mainmenu');
  434. $cache->clean();
  435. return true;
  436. }
  437. /**
  438. * Set the access of selected menu items
  439. */
  440. function setAccess( $items, $access )
  441. {
  442. $row =& $this->getTable();
  443. foreach ($items as $id)
  444. {
  445. $row->load( $id );
  446. $row->access = $access;
  447. // Set any alias menu types to not point to unpublished menu items
  448. $db = &$this->getDBO();
  449. $query = 'UPDATE #__menu SET link = 0 WHERE type = \'menulink\' AND access < '.(int)$access.' AND link = '.(int)$id;
  450. $db->setQuery( $query );
  451. if (!$db->query()) {
  452. $this->setError( $db->getErrorMsg() );
  453. return false;
  454. }
  455. if (!$row->check()) {
  456. $this->setError($row->getError());
  457. return false;
  458. }
  459. if (!$row->store()) {
  460. $this->setError($row->getError());
  461. return false;
  462. }
  463. }
  464. // clean menu cache
  465. $cache =& JFactory::getCache('mod_mainmenu');
  466. $cache->clean();
  467. return true;
  468. }
  469. function orderItem($item, $movement)
  470. {
  471. $row =& $this->getTable();
  472. $row->load( $item );
  473. if (!$row->move( $movement, 'menutype = '.$this->_db->Quote($row->menutype).' AND parent = '.(int) $row->parent )) {
  474. $this->setError($row->getError());
  475. return false;
  476. }
  477. // clean menu cache
  478. $cache =& JFactory::getCache('mod_mainmenu');
  479. $cache->clean();
  480. return true;
  481. }
  482. function setOrder($items, $menutype)
  483. {
  484. $total = count( $items );
  485. $row =& $this->getTable();
  486. $groupings = array();
  487. $order = JRequest::getVar( 'order', array(), 'post', 'array' );
  488. JArrayHelper::toInteger($order);
  489. // update ordering values
  490. for( $i=0; $i < $total; $i++ ) {
  491. $row->load( $items[$i] );
  492. // track parents
  493. $groupings[] = $row->parent;
  494. if ($row->ordering != $order[$i]) {
  495. $row->ordering = $order[$i];
  496. if (!$row->store()) {
  497. $this->setError($row->getError());
  498. return false;
  499. }
  500. } // if
  501. } // for
  502. // execute updateOrder for each parent group
  503. $groupings = array_unique( $groupings );
  504. foreach ($groupings as $group){
  505. $row->reorder('menutype = '.$this->_db->Quote($menutype).' AND parent = '.(int) $group.' AND published >=0');
  506. }
  507. // clean menu cache
  508. $cache =& JFactory::getCache('mod_mainmenu');
  509. $cache->clean();
  510. return true;
  511. }
  512. /**
  513. * Delete one or more menu items
  514. * @param mixed int or array of id values
  515. */
  516. function delete( $ids )
  517. {
  518. JArrayHelper::toInteger($ids);
  519. if (count( $ids )) {
  520. // Add all children to the list
  521. foreach ($ids as $id)
  522. {
  523. $this->_addChildren($id, $ids);
  524. }
  525. $db = &$this->getDBO();
  526. // Delete associated module and template mappings
  527. $where = 'WHERE menuid = ' . implode( ' OR menuid = ', $ids );
  528. $query = 'DELETE FROM #__modules_menu '
  529. . $where;
  530. $db->setQuery( $query );
  531. if (!$db->query()) {
  532. $this->setError( $menuTable->getErrorMsg() );
  533. return false;
  534. }
  535. $query = 'DELETE FROM #__templates_menu '
  536. . $where;
  537. $db->setQuery( $query );
  538. if (!$db->query()) {
  539. $this->setError( $menuTable->getErrorMsg() );
  540. return false;
  541. }
  542. // Set any alias menu types to not point to missing menu items
  543. $query = 'UPDATE #__menu SET link = 0 WHERE type = \'menulink\' AND (link = '.implode( ' OR id = ', $ids ).')';
  544. $db->setQuery( $query );
  545. if (!$db->query()) {
  546. $this->setError( $db->getErrorMsg() );
  547. return false;
  548. }
  549. // Delete the menu items
  550. $where = 'WHERE id = ' . implode( ' OR id = ', $ids );
  551. $query = 'DELETE FROM #__menu ' . $where;
  552. $db->setQuery( $query );
  553. if (!$db->query()) {
  554. $this->setError( $db->getErrorMsg() );
  555. return false;
  556. }
  557. }
  558. // clean menu cache
  559. $cache =& JFactory::getCache('mod_mainmenu');
  560. $cache->clean();
  561. return true;
  562. }
  563. /**
  564. * Delete menu items by type
  565. */
  566. function deleteByType( $type = '' )
  567. {
  568. $db = &$this->getDBO();
  569. $query = 'SELECT id' .
  570. ' FROM #__menu' .
  571. ' WHERE menutype = ' . $db->Quote( $type );
  572. $db->setQuery( $query );
  573. $ids = $db->loadResultArray();
  574. if ($db->getErrorNum()) {
  575. $this->setError( $db->getErrorMsg() );
  576. return false;
  577. }
  578. return $this->delete( $ids );
  579. }
  580. function _addChildren($id, &$list)
  581. {
  582. // Initialize variables
  583. $return = true;
  584. // Get all rows with parent of $id
  585. $db =& $this->getDBO();
  586. $query = 'SELECT id' .
  587. ' FROM #__menu' .
  588. ' WHERE parent = '.(int) $id;
  589. $db->setQuery( $query );
  590. $rows = $db->loadObjectList();
  591. // Make sure there aren't any errors
  592. if ($db->getErrorNum()) {
  593. $this->setError($db->getErrorMsg());
  594. return false;
  595. }
  596. // Recursively iterate through all children... kinda messy
  597. // TODO: Cleanup this method
  598. foreach ($rows as $row)
  599. {
  600. $found = false;
  601. foreach ($list as $idx)
  602. {
  603. if ($idx == $row->id) {
  604. $found = true;
  605. break;
  606. }
  607. }
  608. if (!$found) {
  609. $list[] = $row->id;
  610. }
  611. $return = $this->_addChildren($row->id, $list);
  612. }
  613. return $return;
  614. }
  615. }