PageRenderTime 27ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/joomla/administrator/components/com_menus/models/item.php

https://github.com/bhar1red/anahita
PHP | 800 lines | 596 code | 103 blank | 101 comment | 116 complexity | 7f7ac67981aaaadcf15c110e7b28fdcb MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * @version $Id: item.php 18162 2010-07-16 07:00:47Z ian $
  4. * @package Joomla
  5. * @subpackage Menus
  6. * @copyright Copyright (C) 2005 - 2010 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 MenusModelItem extends JModel
  22. {
  23. /**
  24. * Menu Item ID
  25. *
  26. * @var int
  27. */
  28. var $_id = null;
  29. /** @var object JTable object */
  30. var $_table = null;
  31. /** @var object JTable object */
  32. var $_url = null;
  33. /**
  34. * Overridden constructor
  35. * @access protected
  36. */
  37. function __construct()
  38. {
  39. parent::__construct();
  40. $url = JRequest::getVar('url', array(), '', 'array');
  41. if (isset($url['option']))
  42. {
  43. $this->_url = 'index.php?option='.$url['option'];
  44. unset($url['option']);
  45. if (count($url)) {
  46. foreach ($url as $k => $v)
  47. {
  48. $this->_url .= '&'.$k.'='.$v;
  49. }
  50. }
  51. }
  52. $this->setId();
  53. }
  54. function setId()
  55. {
  56. $array = JRequest::getVar('cid', array(0), '', 'array');
  57. $this->_id = (int) $array[0];
  58. if (!$this->_id) {
  59. $this->_id = JRequest::getInt('id', 0);
  60. }
  61. }
  62. function &getItem()
  63. {
  64. static $item;
  65. if (isset($item)) {
  66. return $item;
  67. }
  68. $table =& $this->_getTable();
  69. // Load the current item if it has been defined
  70. $edit = JRequest::getVar('edit',true);
  71. $cid = JRequest::getVar( 'cid', array(0), '', 'array' );
  72. JArrayHelper::toInteger($cid, array(0));
  73. if ($edit) {
  74. $table->load($cid[0]);
  75. }
  76. // Override the current item's type field if defined in the request
  77. if ($type = JRequest::getString('type')) {
  78. $table->type = $type;
  79. }
  80. // Override the current item's menutype field if defined in the request
  81. if ($menutype = JRequest::getVar('menutype', '', '', 'menutype')) {
  82. $table->menutype = $menutype;
  83. }
  84. switch ($table->type)
  85. {
  86. case 'separator':
  87. $table->link = null;
  88. $table->componentid = 0;
  89. break;
  90. case 'url':
  91. $table->componentid = 0;
  92. break;
  93. case 'menulink':
  94. $table->componentid = 0;
  95. break;
  96. case 'component':
  97. // Override the current item's link field if defined in the request
  98. if (!is_null($this->_url)) {
  99. $table->link = $this->_url;
  100. }
  101. $url = str_replace('index.php?', '', $table->link);
  102. $url = str_replace('&amp;', '&', $url);
  103. $table->linkparts = null;
  104. if(strpos($url, '&amp;') !== false)
  105. {
  106. $url = str_replace('&amp;','&',$url);
  107. }
  108. parse_str($url, $table->linkparts);
  109. $db = &$this->getDBO();
  110. if ($component = @$table->linkparts['option']) {
  111. $query = 'SELECT `id`' .
  112. ' FROM `#__components`' .
  113. ' WHERE `link` <> \'\'' .
  114. ' AND `parent` = 0' .
  115. ' AND `option` = "'.$db->getEscaped($component).'"';
  116. $db->setQuery( $query );
  117. $table->componentid = $db->loadResult();
  118. }
  119. break;
  120. }
  121. $item = $table;
  122. return $item;
  123. }
  124. function &getExpansion()
  125. {
  126. $item = &$this->getItem();
  127. $return['option'] = JRequest::getCmd('expand');
  128. $menutype = JRequest::getVar('menutype', '', '', 'menutype');
  129. if ($return['option'])
  130. {
  131. require_once(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_menus'.DS.'classes'.DS.'ilink.php');
  132. $handler = new iLink($return['option'], $item->id, $menutype);
  133. $return['html'] = $handler->getTree();
  134. return $return;
  135. } else {
  136. $return['html'] = null;
  137. }
  138. return $return;
  139. }
  140. function &getUrlParams()
  141. {
  142. // Get the state parameters
  143. $item =& $this->getItem();
  144. $params = new JParameter('');
  145. if ($state =& $this->_getStateXML())
  146. {
  147. if (is_a($state, 'JSimpleXMLElement'))
  148. {
  149. $sp =& $state->getElementByPath('url');
  150. $params->setXML($sp);
  151. if (isset($item->linkparts) && is_array($item->linkparts)) {
  152. $params->loadArray($item->linkparts);
  153. }
  154. }
  155. }
  156. return $params;
  157. }
  158. function &getStateParams()
  159. {
  160. // Get the state parameters
  161. $item =& $this->getItem();
  162. $params = new JParameter($item->params);
  163. if ($state =& $this->_getStateXML())
  164. {
  165. if (is_a($state, 'JSimpleXMLElement'))
  166. {
  167. $sp =& $state->getElementByPath('params');
  168. $params->setXML($sp);
  169. }
  170. }
  171. return $params;
  172. }
  173. function &getAdvancedParams()
  174. {
  175. // Get the state parameters
  176. $item =& $this->getItem();
  177. $params = new JParameter($item->params);
  178. if ($state =& $this->_getStateXML())
  179. {
  180. if (is_a($state, 'JSimpleXMLElement'))
  181. {
  182. $ap =& $state->getElementByPath('advanced');
  183. $params->setXML($ap);
  184. }
  185. }
  186. return $params;
  187. }
  188. function &getComponentParams()
  189. {
  190. // Initialize variables
  191. $params = null;
  192. $item = &$this->getItem();
  193. if ($item->type == 'component')
  194. {
  195. $comp = &$this->getComponent();
  196. $option = preg_replace( '#\W#', '', $comp->option );
  197. $path = JPATH_ADMINISTRATOR.DS.'components'.DS.$option.DS.'config.xml';
  198. $params = new JParameter( $item->params );
  199. if (file_exists( $path ))
  200. {
  201. $xml =& JFactory::getXMLParser('Simple');
  202. if ($xml->loadFile($path))
  203. {
  204. $document =& $xml->document;
  205. // if hide is set, don't show the component configuration while editing menu item
  206. $menu = $document->attributes('menu');
  207. if ( isset($menu) && $menu == 'hide' )
  208. {
  209. $params = null;
  210. return $params;
  211. }
  212. if (isset($document->params[0]->param))
  213. {
  214. // We will collect the hidden elements in an array
  215. // loop will mess up if we do it within the loop
  216. $hide = array();
  217. for ($i=0,$n=count($document->params[0]->param); $i<$n; $i++)
  218. {
  219. if ($document->params[0]->param[$i]->attributes('menu') == 'hide')
  220. {
  221. $hide[] = &$document->params[0]->param[$i];
  222. }
  223. else if ($document->params[0]->param[$i]->attributes('type') == 'radio' || $document->params[0]->param[$i]->attributes('type') == 'list') {
  224. $document->params[0]->param[$i]->addAttribute('default', '');
  225. $document->params[0]->param[$i]->addAttribute('type', 'list');
  226. $child = &$document->params[0]->param[$i]->addChild('option', array('value' => ''));
  227. $child->setData('Use Global');
  228. }
  229. }
  230. // Now remove any hidden elements
  231. for ($i = 0, $n = count( $hide ); $i < $n; $i++) {
  232. $document->params[0]->removeChild( $hide[$i] );
  233. }
  234. }
  235. $params->setXML( $document->params[0] );
  236. }
  237. }
  238. }
  239. return $params;
  240. }
  241. function &getSystemParams()
  242. {
  243. // Initialize variables
  244. $params = null;
  245. $item = &$this->getItem();
  246. $params = new JParameter( $item->params );
  247. if ($item->type == 'component') {
  248. $path = JPATH_BASE.DS.'components'.DS.'com_menus'.DS.'models'.DS.'metadata'.DS.'component.xml';
  249. if (file_exists( $path )) {
  250. $xml =& JFactory::getXMLParser('Simple');
  251. if ($xml->loadFile($path)) {
  252. $document =& $xml->document;
  253. $params->setXML($document->getElementByPath('state/params'));
  254. }
  255. }
  256. }
  257. return $params;
  258. }
  259. /**
  260. * Get the name of the current menu item
  261. *
  262. * @return string
  263. * @access public
  264. * @since 1.5
  265. */
  266. function getStateName()
  267. {
  268. $state =& $this->_getStateXML();
  269. if ( ! is_a($state, 'JSimpleXMLElement'))
  270. {
  271. return null;
  272. }
  273. $name = null;
  274. $sn =& $state->getElementByPath('name');
  275. if ($sn) {
  276. $name = $sn->data();
  277. }
  278. return JText::_($name);
  279. }
  280. /**
  281. * Get the description of the current menu item
  282. *
  283. * @return string
  284. * @access public
  285. * @since 1.5
  286. */
  287. function getStateDescription()
  288. {
  289. $state =& $this->_getStateXML();
  290. if ( ! is_a($state, 'JSimpleXMLElement'))
  291. {
  292. return null;
  293. }
  294. $description = null;
  295. $sd =& $state->getElementByPath('description');
  296. if ($sd) {
  297. $description = $sd->data();
  298. }
  299. return JText::_($description);
  300. }
  301. /**
  302. * Gets the componet table object related to this menu item
  303. */
  304. function &getComponent()
  305. {
  306. $item =& $this->getItem();
  307. $id = $item->componentid;
  308. $component = & JTable::getInstance( 'component');
  309. $component->load( $id );
  310. return $component;
  311. }
  312. function checkout($uid = null)
  313. {
  314. $id = JRequest::getVar('cid', array(0), '', 'array');
  315. JArrayHelper::toInteger( $id, array(0) );
  316. // Make sure we have a user id to checkout the article with
  317. if (is_null($uid)) {
  318. $user =& JFactory::getUser();
  319. $uid = $user->get('id');
  320. }
  321. // Lets get to it and checkout the thing...
  322. $item =& $this->getItem();
  323. if(!$item->checkout($uid, $id[0])) {
  324. $this->setError($this->_db->getErrorMsg());
  325. return false;
  326. }
  327. return true;
  328. }
  329. function checkin()
  330. {
  331. if ($this->_id) {
  332. $item =& $this->_getTable();
  333. if(!$item->checkin($this->_id)) {
  334. $this->setError($this->_db->getErrorMsg());
  335. return false;
  336. }
  337. return true;
  338. }
  339. return false;
  340. }
  341. function store()
  342. {
  343. // Initialize variables
  344. $db =& JFactory::getDBO();
  345. $row =& $this->getItem();
  346. $post = $this->_state->get( 'request' );
  347. switch ($post['type'])
  348. {
  349. case 'separator':
  350. break;
  351. case 'url':
  352. break;
  353. case 'menulink':
  354. $post['link'] = 'index.php?Itemid='.$post['params']['menu_item'];
  355. break;
  356. case 'component':
  357. break;
  358. }
  359. if (!$row->bind( $post )) {
  360. echo "<script> alert('".$row->getError(true)."'); window.history.go(-1); </script>\n";
  361. return false;
  362. }
  363. if ($row->id > 0)
  364. {
  365. // existing item
  366. $query = 'SELECT menutype FROM #__menu WHERE id = '.(int) $row->id;
  367. $this->_db->setQuery( $query );
  368. $oldType = $this->_db->loadResult();
  369. if ($oldType != $row->menutype) {
  370. // moved to another menu, disconnect the old parent
  371. $row->parent = 0;
  372. }
  373. $query = 'SELECT parent FROM #__menu WHERE id = '.(int) $row->id;
  374. $this->_db->setQuery( $query );
  375. $oldParent = $this->_db->loadResult();
  376. if ($oldParent != $row->parent) {
  377. // we have changed parents, so we have to fix the submenu values
  378. if ($row->parent != 0) {
  379. $query = 'SELECT sublevel FROM #__menu WHERE id = '.(int) $row->parent;
  380. $this->_db->setQuery( $query );
  381. $sublevel = $this->_db->loadResult() + 1;
  382. } else {
  383. $sublevel = 0;
  384. }
  385. $row->sublevel = $sublevel;
  386. $this->_setSubLevel( array( (int) $row->id ), $sublevel );
  387. }
  388. }
  389. else
  390. {
  391. // if new item order last in appropriate group
  392. $where = "menutype = " . $db->Quote($row->menutype) . " AND published >= 0 AND parent = ".(int) $row->parent;
  393. $row->ordering = $row->getNextOrder( $where );
  394. if( $row->parent != 0 ) {
  395. $query = 'SELECT sublevel FROM #__menu WHERE id = '. (int) $row->parent;
  396. $this->_db->setQuery($query);
  397. $row->sublevel = $this->_db->loadResult() + 1;
  398. }
  399. }
  400. if (isset($post['urlparams']) && is_array($post['urlparams']))
  401. {
  402. $pos = strpos( $row->link, '?' );
  403. if ($pos !== false)
  404. {
  405. $prefix = substr( $row->link, 0, $pos );
  406. $query = substr( $row->link, $pos+1 );
  407. $temp = array();
  408. if(strpos($query, '&amp;') !== false) {
  409. $query = str_replace('&amp;', '&', $query);
  410. }
  411. parse_str( $query, $temp );
  412. $temp2 = array_merge( $temp, $post['urlparams'] );
  413. $temp3 = array();
  414. foreach ($temp2 as $k => $v)
  415. {
  416. if ( $k && strlen($v) )
  417. {
  418. $temp3[] = $k.'='.$v;
  419. }
  420. }
  421. $url = null;
  422. $row->link = $prefix . '?' . implode( '&', $temp3 );
  423. }
  424. }
  425. if (!$row->check())
  426. {
  427. echo "<script> alert('".$row->getError(true)."'); window.history.go(-1); </script>\n";
  428. return false;
  429. }
  430. if (!$row->store())
  431. {
  432. echo "<script> alert('".$row->getError(true)."'); window.history.go(-1); </script>\n";
  433. return false;
  434. }
  435. $row->checkin();
  436. $row->reorder( 'menutype='.$db->Quote( $row->menutype ).' AND parent='.(int)$row->parent );
  437. // clean cache
  438. MenusHelper::cleanCache();
  439. return true;
  440. }
  441. /**
  442. * Delete one or more menu items
  443. * @param mixed int or array of id values
  444. */
  445. function delete( $ids )
  446. {
  447. JArrayHelper::toInteger($ids);
  448. $db = &$this->getDBO();
  449. if (count( $ids ))
  450. {
  451. // Delete associated module and template mappings
  452. $where = 'WHERE menuid = ' . implode( ' OR menuid = ', $ids );
  453. $query = 'DELETE FROM #__modules_menu '
  454. . $where;
  455. $db->setQuery( $query );
  456. if (!$db->query()) {
  457. $this->setError( $menuTable->getErrorMsg() );
  458. return false;
  459. }
  460. $query = 'DELETE FROM #__templates_menu '
  461. . $where;
  462. $db->setQuery( $query );
  463. if (!$db->query()) {
  464. $this->setError( $menuTable->getErrorMsg() );
  465. return false;
  466. }
  467. // Set any alias menu types to not point to missing menu items
  468. $query = 'UPDATE #__menu SET link = 0 WHERE type = \'menulink\' AND (link = '.implode( ' OR id = ', $ids ).')';
  469. $db->setQuery( $query );
  470. if (!$db->query()) {
  471. $this->setError( $db->getErrorMsg() );
  472. return false;
  473. }
  474. // Delete the menu items
  475. $where = 'WHERE id = ' . implode( ' OR id = ', $ids );
  476. $query = 'DELETE FROM #__menu ' . $where;
  477. $db->setQuery( $query );
  478. if (!$db->query()) {
  479. $this->setError( $db->getErrorMsg() );
  480. return false;
  481. }
  482. }
  483. // clean cache
  484. MenusHelper::cleanCache();
  485. return true;
  486. }
  487. /**
  488. * Delete menu items by type
  489. */
  490. function deleteByType( $type = '' )
  491. {
  492. $db = &$this->getDBO();
  493. $query = 'SELECT id' .
  494. ' FROM #__menu' .
  495. ' WHERE menutype = ' . $db->Quote( $type );
  496. $db->setQuery( $query );
  497. $ids = $db->loadResultArray();
  498. if ($db->getErrorNum())
  499. {
  500. $this->setError( $db->getErrorMsg() );
  501. return false;
  502. }
  503. return $this->delete( $ids );
  504. }
  505. /**
  506. * Returns the internal table object
  507. * @return JTable
  508. */
  509. function &_getTable()
  510. {
  511. if ($this->_table == null) {
  512. $this->_table =& JTable::getInstance( 'menu');
  513. }
  514. return $this->_table;
  515. }
  516. function &_getStateXML()
  517. {
  518. static $xml;
  519. if (isset($xml)) {
  520. return $xml;
  521. }
  522. $xml = null;
  523. $xmlpath = null;
  524. $item = &$this->getItem();
  525. switch ($item->type)
  526. {
  527. case 'separator':
  528. $xmlpath = JPATH_BASE.DS.'components'.DS.'com_menus'.DS.'models'.DS.'metadata'.DS.'separator.xml';
  529. break;
  530. case 'url':
  531. $xmlpath = JPATH_BASE.DS.'components'.DS.'com_menus'.DS.'models'.DS.'metadata'.DS.'url.xml';
  532. break;
  533. case 'menulink':
  534. $xmlpath = JPATH_BASE.DS.'components'.DS.'com_menus'.DS.'models'.DS.'metadata'.DS.'menulink.xml';
  535. break;
  536. case 'component':
  537. default:
  538. if (isset($item->linkparts['view']))
  539. {
  540. // View is set... so we konw to look in view file
  541. if (isset($item->linkparts['layout'])) {
  542. $layout = $item->linkparts['layout'];
  543. }
  544. elseif ( KRequest::get('get.template','cmd') ) {
  545. $layout = KRequest::get('get.template','cmd');
  546. }
  547. else {
  548. $layout = 'default';
  549. }
  550. $lpath = JPATH_ROOT.DS.'components'.DS.$item->linkparts['option'].DS.'views'.DS.$item->linkparts['view'].DS.'tmpl'.DS.$layout.'.xml';
  551. $l2path = JPATH_ROOT.DS.'components'.DS.$item->linkparts['option'].DS.'views'.DS.$item->linkparts['view'].DS.'html'.DS.$layout.'.xml';
  552. $vpath = JPATH_ROOT.DS.'components'.DS.$item->linkparts['option'].DS.'views'.DS.$item->linkparts['view'].DS.'metadata.xml';
  553. if (file_exists($lpath)) {
  554. $xmlpath = $lpath;
  555. } elseif (file_exists($l2path)) {
  556. $xmlpath = $l2path;
  557. } elseif (file_exists($vpath)) {
  558. $xmlpath = $vpath;
  559. }
  560. }
  561. if (!$xmlpath && isset($item->linkparts['option'])) {
  562. $xmlpath = JPATH_ROOT.DS.'components'.DS.$item->linkparts['option'].DS.'metadata.xml';
  563. if(!file_exists($xmlpath)) {
  564. $xmlpath = JApplicationHelper::getPath('com_xml', $item->linkparts['option']);
  565. }
  566. }
  567. break;
  568. }
  569. if (file_exists($xmlpath))
  570. {
  571. $xml =& JFactory::getXMLParser('Simple');
  572. if ($xml->loadFile($xmlpath)) {
  573. $this->_xml = &$xml;
  574. $document =& $xml->document;
  575. /*
  576. * HANDLE NO OPTION CASE
  577. */
  578. $menus =& $document->getElementByPath('menu');
  579. if (is_a($menus, 'JSimpleXMLElement') && $menus->attributes('options') == 'none') {
  580. $xml =& $menus->getElementByPath('state');
  581. } else {
  582. $xml =& $document->getElementByPath('state');
  583. }
  584. // Handle error case... path doesn't exist
  585. if (!is_a($xml, 'JSimpleXMLElement')) {
  586. return $document;
  587. }
  588. /*
  589. * HANDLE A SWITCH IF IT EXISTS
  590. */
  591. if ($switch = $xml->attributes('switch'))
  592. {
  593. $default = $xml->attributes('default');
  594. // Handle switch
  595. $switchVal = (isset($item->linkparts[$switch]))? $item->linkparts[$switch] : 'default';
  596. $found = false;
  597. foreach ($xml->children() as $child) {
  598. if ($child->name() == $switchVal) {
  599. $xml =& $child;
  600. $found = true;
  601. break;
  602. }
  603. }
  604. if (!$found) {
  605. foreach ($xml->children() as $child) {
  606. if ($child->name() == $default) {
  607. $xml =& $child;
  608. break;
  609. }
  610. }
  611. }
  612. }
  613. /*
  614. * HANDLE INCLUDED PARAMS
  615. */
  616. $children = $xml->children();
  617. if (count($children) == 1)
  618. {
  619. if ($children[0]->name() == 'include') {
  620. $ret =& $this->_getIncludedParams($children[0]);
  621. if ($ret) {
  622. $xml =& $ret;
  623. }
  624. }
  625. }
  626. if ($switch = $xml->attributes('switch'))
  627. {
  628. $default = $xml->attributes('default');
  629. // Handle switch
  630. $switchVal = ($item->linkparts[$switch])? $item->linkparts[$switch] : 'default';
  631. $found = false;
  632. foreach ($xml->children() as $child) {
  633. if ($child->name() == $switchVal) {
  634. $xml =& $child;
  635. $found = true;
  636. break;
  637. }
  638. }
  639. if (!$found) {
  640. foreach ($xml->children() as $child) {
  641. if ($child->name() == $default) {
  642. $xml =& $child;
  643. break;
  644. }
  645. }
  646. }
  647. }
  648. }
  649. }
  650. return $xml;
  651. }
  652. function &_getIncludedParams($include)
  653. {
  654. $tags = array();
  655. $state = null;
  656. $source = $include->attributes('source');
  657. $path = $include->attributes('path');
  658. $item = &$this->getItem();
  659. preg_match_all( "/{([A-Za-z\-_]+)}/", $source, $tags);
  660. if (isset($tags[1])) {
  661. for ($i=0;$i<count($tags[1]);$i++) {
  662. $source = str_replace($tags[0][$i], @$item->linkparts[$tags[1][$i]], $source);
  663. }
  664. }
  665. // load the source xml file
  666. if (file_exists( JPATH_ROOT.$source ))
  667. {
  668. $xml = & JFactory::getXMLParser('Simple');
  669. if ($xml->loadFile(JPATH_ROOT.$source)) {
  670. $document = &$xml->document;
  671. $state = $document->getElementByPath($path);
  672. }
  673. }
  674. return $state;
  675. }
  676. /**
  677. * Sets the sublevel for menu items
  678. *
  679. * @param array id values to set
  680. * @param int level to assign to the sublevel
  681. */
  682. function _setSubLevel( $cid, $level )
  683. {
  684. JArrayHelper::toInteger($cid, array(0));
  685. $ids = implode( ',', $cid );
  686. $query = 'UPDATE #__menu SET sublevel = '.(int) $level
  687. .' WHERE id IN ('.$ids.')';
  688. $this->_db->setQuery( $query );
  689. $this->_db->query();
  690. $query = 'SELECT id FROM #__menu WHERE parent IN ('.$ids.')';
  691. $this->_db->setQuery( $query );
  692. $cids = $this->_db->loadResultArray( 0 );
  693. if (!empty( $cids )) {
  694. $this->_setSubLevel( $cids, $level + 1 );
  695. }
  696. }
  697. }