PageRenderTime 159ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/administrator/components/com_menus/models/fields/menutype.php

https://github.com/cosmocommerce/joomla
PHP | 490 lines | 337 code | 67 blank | 86 comment | 51 complexity | 5b82d13c0ca5fd6e4b114e09cfe1e3be MD5 | raw file
Possible License(s): Apache-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * @version $Id$
  4. * @copyright Copyright (C) 2005 - 2010 Open Source Matters, Inc. All rights reserved.
  5. * @license GNU General Public License version 2 or later; see LICENSE.txt
  6. */
  7. defined('JPATH_BASE') or die;
  8. jimport('joomla.html.html');
  9. /**
  10. * Form Field class for the Joomla Framework.
  11. *
  12. * @package Joomla.Administrator
  13. * @subpackage com_menus
  14. * @since 1.6
  15. */
  16. class JFormFieldMenuType extends JFormFieldList
  17. {
  18. /**
  19. * The field type.
  20. *
  21. * @var string
  22. */
  23. public $type = 'MenuType';
  24. /**
  25. * A reverse lookup of the base link URL to Title
  26. *
  27. * @var array
  28. */
  29. protected $_rlu = array();
  30. /**
  31. * Method to get the field input.
  32. *
  33. * @return string The field input.
  34. */
  35. protected function _getInput()
  36. {
  37. // Initialise variables.
  38. $html = array();
  39. $types = $this->_getTypeList();
  40. $size = ($v = $this->_element->attributes('size')) ? ' size="'.$v.'"' : '';
  41. $class = ($v = $this->_element->attributes('class')) ? 'class="'.$v.'"' : 'class="text_area"';
  42. switch ($this->value)
  43. {
  44. case 'url':
  45. $value = JText::_('Menus_Type_External_URL');
  46. break;
  47. case 'alias':
  48. $value = JText::_('Menus_Type_Alias');
  49. break;
  50. case 'separator':
  51. $value = JText::_('Menus_Type_Separator');
  52. break;
  53. default:
  54. $link = $this->_form->getValue('link');
  55. // Clean the link back to the option, view and layout
  56. $value = JText::_(JArrayHelper::getValue($this->_rlu, MenusHelper::getLinkKey($link)));
  57. break;
  58. }
  59. // Load the javascript and css
  60. JHtml::_('behavior.framework');
  61. JHtml::script('system/modal.js', false, true);
  62. JHtml::stylesheet('system/modal.css', array(), true);
  63. // Attach modal behavior to document
  64. $document = JFactory::getDocument();
  65. $document->addScriptDeclaration("
  66. window.addEvent('domready', function() {
  67. var div = new Element('div').setStyle('display', 'none').injectBefore(document.id('menu-types'));
  68. document.id('menu-types').injectInside(div);
  69. SqueezeBox.initialize();
  70. SqueezeBox.assign($$('input.modal'), {
  71. parse: 'rel'
  72. });
  73. });");
  74. $html[] = '<input type="text" readonly="readonly" disabled="disabled" value="'.$value.'"'.$size.$class.'>';
  75. $html[] = '<input type="button" class="modal" value="'.JText::_('Menus_Change_Linktype').'" rel="{handler:\'clone\', target:\'menu-types\'}">';
  76. $html[] = '<input type="hidden" name="'.$this->inputName.'" value="'.htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8').'">';
  77. $html[] = '<div id="menu-types">';
  78. $html[] = $types;
  79. $html[] = '</div>';
  80. return implode("\n", $html);
  81. }
  82. protected function _getTypeList()
  83. {
  84. // Initialise variables.
  85. $html = array();
  86. $types = $this->_getTypeOptions();
  87. $html[] = '<h2 class="modal-title">'.JText::_('Menus_Type_Choose').'</h2>';
  88. $html[] = '<ul class="menu_types">';
  89. foreach ($types as $name => $list)
  90. {
  91. $html[] = '<li>';
  92. $html[] = '<dl class="menu_type">';
  93. $html[] = ' <dt>'.JText::_($name).'</dt>';
  94. $html[] = ' <dd>';
  95. $html[] = ' <ul>';
  96. foreach ($list as $item)
  97. {
  98. $html[] = ' <li>';
  99. $html[] = ' <a class="choose_type" href="index.php?option=com_menus&amp;task=item.setType&amp;type='.base64_encode(json_encode(array('title'=>$item->title, 'request'=>$item->request))).'" title="'.JText::_($item->description).'">'.JText::_($item->title).'</a>';
  100. $html[] = ' </li>';
  101. }
  102. $html[] = ' </ul>';
  103. $html[] = ' </dd>';
  104. $html[] = '</dl>';
  105. $html[] = '</li>';
  106. }
  107. $html[] = '<li>';
  108. $html[] = '<dl class="menu_type">';
  109. $html[] = ' <dt>'.JText::_('Menus_Type_System').'</dt>';
  110. $html[] = ' <dd>';
  111. // $html[] = ' '.JText::_('Menus_Type_System_Desc');
  112. $html[] = ' <ul>';
  113. $html[] = ' <li>';
  114. $html[] = ' <a class="choose_type" href="index.php?option=com_menus&amp;task=item.setType&amp;type='.base64_encode(json_encode(array('title'=>'url'))).'" title="'.JText::_('Menus_Type_External_URL_Desc').'">'.JText::_('Menus_Type_External_URL').'</a>';
  115. $html[] = ' </li>';
  116. $html[] = ' <li>';
  117. $html[] = ' <a class="choose_type" href="index.php?option=com_menus&amp;task=item.setType&amp;type='.base64_encode(json_encode(array('title'=>'alias'))).'" title="'.JText::_('Menus_Type_Alias_Desc').'">'.JText::_('Menus_Type_Alias').'</a>';
  118. $html[] = ' </li>';
  119. $html[] = ' <li>';
  120. $html[] = ' <a class="choose_type" href="index.php?option=com_menus&amp;task=item.setType&amp;type='.base64_encode(json_encode(array('title'=>'separator'))).'" title="'.JText::_('Menus_Type_Separator_Desc').'">'.JText::_('Menus_Type_Separator').'</a>';
  121. $html[] = ' </li>';
  122. $html[] = ' </ul>';
  123. $html[] = ' </dd>';
  124. $html[] = '</dl>';
  125. $html[] = '</li>';
  126. $html[] = '</ul>';
  127. return implode("\n", $html);
  128. }
  129. /**
  130. * Method to get the available menu item type options.
  131. *
  132. * @return array Array of groups with menu item types.
  133. * @since 1.6
  134. */
  135. protected function _getTypeOptions()
  136. {
  137. jimport('joomla.filesystem.file');
  138. // Initialise variables.
  139. $lang = &JFactory::getLanguage();
  140. $list = array();
  141. // Get the list of components.
  142. $db = & JFactory::getDBO();
  143. $db->setQuery(
  144. 'SELECT `name`, `element` AS "option"' .
  145. ' FROM `#__extensions`' .
  146. ' WHERE `type` = "component"' .
  147. ' AND `enabled` = 1' .
  148. ' ORDER BY `name`'
  149. );
  150. $components = $db->loadObjectList();
  151. foreach ($components as $component)
  152. {
  153. if ($options = $this->_getTypeOptionsByComponent($component->option))
  154. {
  155. $list[$component->name] = $options;
  156. // Create the reverse lookup for link-to-name.
  157. foreach ($options as $option)
  158. {
  159. if (isset($option->request))
  160. {
  161. $this->_rlu[MenusHelper::getLinkKey($option->request)] = $option->get('title');
  162. if (isset($option->request['option'])) {
  163. $lang->load($option->request['option'].'.menu', JPATH_ADMINISTRATOR, null, false, false)
  164. || $lang->load($option->request['option'].'.menu', JPATH_ADMINISTRATOR.'/components/'.$option->request['option'], null, false, false)
  165. || $lang->load($option->request['option'].'.menu', JPATH_ADMINISTRATOR, $lang->getDefault(), false, false)
  166. || $lang->load($option->request['option'].'.menu', JPATH_ADMINISTRATOR.'/components/'.$option->request['option'], $lang->getDefault(), false, false);
  167. }
  168. }
  169. }
  170. }
  171. }
  172. return $list;
  173. }
  174. protected function _getTypeOptionsByComponent($component)
  175. {
  176. // Initialise variables.
  177. $options = array();
  178. $mainXML = JPATH_SITE.'/components/'.$component.'/metadata.xml';
  179. if (is_file($mainXML)) {
  180. $options = $this->_getTypeOptionsFromXML($mainXML, $component);
  181. }
  182. if (empty($options)) {
  183. $options = $this->_getTypeOptionsFromMVC($component);
  184. }
  185. return $options;
  186. }
  187. protected function _getTypeOptionsFromXML($file, $component)
  188. {
  189. // Initialise variables.
  190. $options = array();
  191. // Attempt to load the xml file.
  192. if (!$xml = simplexml_load_file($file)) {
  193. return false;
  194. }
  195. // Look for the first menu node off of the root node.
  196. if (!$menu = $xml->xpath('menu[1]')) {
  197. return false;
  198. }
  199. else {
  200. $menu = $menu[0];
  201. }
  202. // If we have no options to parse, just add the base component to the list of options.
  203. if (!empty($menu['options']) && $menu['options'] == 'none')
  204. {
  205. // Create the menu option for the component.
  206. $o = new JObject;
  207. $o->title = $menu['name'];
  208. $o->description = $menu['msg'];
  209. $o->request = array('option' => $component);
  210. $options[] = $o;
  211. return $options;
  212. }
  213. // Look for the first options node off of the menu node.
  214. if (!$optionsNode = $menu->xpath('options[1]')) {
  215. return false;
  216. }
  217. else {
  218. $optionsNode = $optionsNode[0];
  219. }
  220. // Make sure the options node has children.
  221. if (!$children = $optionsNode->children()) {
  222. return false;
  223. }
  224. else {
  225. // Process each child as an option.
  226. foreach ($children as $child)
  227. {
  228. if ($child->getName() == 'option')
  229. {
  230. // Create the menu option for the component.
  231. $o = new JObject;
  232. $o->title = $child['name'];
  233. $o->description = $child['msg'];
  234. $o->request = array('option' => $component, (string) $optionsNode['var'] => (string) $child['value']);
  235. $options[] = $o;
  236. }
  237. elseif ($child->getName() == 'default')
  238. {
  239. // Create the menu option for the component.
  240. $o = new JObject;
  241. $o->title = $child['name'];
  242. $o->description = $child['msg'];
  243. $o->request = array('option' => $component);
  244. $options[] = $o;
  245. }
  246. }
  247. }
  248. return $options;
  249. }
  250. protected function _getTypeOptionsFromMVC($component)
  251. {
  252. // Initialise variables.
  253. $options = array();
  254. // Get the views for this component.
  255. $path = JPATH_SITE.'/components/'.$component.'/views';
  256. if (JFolder::exists($path)) {
  257. $views = JFolder::folders($path);
  258. }
  259. else {
  260. return false;
  261. }
  262. foreach ($views as $view)
  263. {
  264. // Ignore private views.
  265. if (strpos($view, '_') !== 0)
  266. {
  267. // Determine if a metadata file exists for the view.
  268. $file = $path.'/'.$view.'/metadata.xml';
  269. if (is_file($file))
  270. {
  271. // Attempt to load the xml file.
  272. if ($xml = simplexml_load_file($file))
  273. {
  274. // Look for the first view node off of the root node.
  275. if ($menu = $xml->xpath('view[1]'))
  276. {
  277. $menu = $menu[0];
  278. // If the view is hidden from the menu, discard it and move on to the next view.
  279. if (!empty($menu['hidden']) && $menu['hidden'] == 'true') {
  280. unset($xml);
  281. continue;
  282. }
  283. // Do we have an options node or should we process layouts?
  284. // Look for the first options node off of the menu node.
  285. if ($optionsNode = $menu->xpath('options[1]'))
  286. {
  287. $optionsNode = $optionsNode[0];
  288. // Make sure the options node has children.
  289. if ($children = $optionsNode->children())
  290. {
  291. // Process each child as an option.
  292. foreach ($children as $child)
  293. {
  294. if ($child->getName() == 'option')
  295. {
  296. // Create the menu option for the component.
  297. $o = new JObject;
  298. $o->title = $child['name'];
  299. $o->description = $child['msg'];
  300. $o->request = array('option' => $component, 'view' => $view, (string) $optionsNode['var'] => (string) $child['value']);
  301. $options[] = $o;
  302. }
  303. elseif ($child->getName() == 'default')
  304. {
  305. // Create the menu option for the component.
  306. $o = new JObject;
  307. $o->title = $child['name'];
  308. $o->description = $child['msg'];
  309. $o->request = array('option' => $component, 'view' => $view);
  310. $options[] = $o;
  311. }
  312. }
  313. }
  314. }
  315. else {
  316. $options = array_merge($options, (array) $this->_getTypeOptionsFromLayouts($component, $view));
  317. }
  318. }
  319. unset($xml);
  320. }
  321. } else {
  322. $options = array_merge($options, (array) $this->_getTypeOptionsFromLayouts($component, $view));
  323. }
  324. }
  325. }
  326. return $options;
  327. }
  328. protected function _getTypeOptionsFromLayouts($component, $view)
  329. {
  330. // Initialise variables.
  331. $options = array();
  332. $layouts = array();
  333. $layoutNames = array();
  334. $templateLayouts = array();
  335. // Get the layouts from the view folder.
  336. $path = JPATH_SITE.'/components/'.$component.'/views/'.$view.'/tmpl';
  337. if (JFolder::exists($path)) {
  338. $layouts = array_merge($layouts, JFolder::files($path, '.xml$', false, true));
  339. }
  340. else {
  341. return $options;
  342. }
  343. // build list of standard layout names
  344. foreach ($layouts as $layout)
  345. {
  346. // Ignore private layouts.
  347. if (strpos(JFile::getName($layout), '_') === false)
  348. {
  349. $file = $layout;
  350. // Get the layout name.
  351. $layoutNames[] = JFile::stripext(JFile::getName($layout));
  352. }
  353. }
  354. // get the template layouts
  355. // TODO: This should only search one template -- the current template for this item (default of specified)
  356. $folders = JFolder::folders(JPATH_SITE.DS.'templates','',false,true);
  357. foreach($folders as $folder)
  358. {
  359. if (JFolder::exists($folder.DS.'html'.DS.$component.DS.$view)) {
  360. $templateLayouts = JFolder::files($folder.DS.'html'.DS.$component.DS.$view, '.xml$', false, true);
  361. foreach ($templateLayouts as $layout)
  362. {
  363. $file = $layout;
  364. // Get the layout name.
  365. $templateLayoutName = JFile::stripext(JFile::getName($layout));
  366. // add to the list only if it is not a standard layout
  367. if (array_search($templateLayoutName, $layoutNames) === false) {
  368. $layouts[] = $layout;
  369. }
  370. }
  371. }
  372. }
  373. // Process the found layouts.
  374. foreach ($layouts as $layout)
  375. {
  376. // Ignore private layouts.
  377. if (strpos(JFile::getName($layout), '_') === false)
  378. {
  379. $file = $layout;
  380. // Get the layout name.
  381. $layout = JFile::stripext(JFile::getName($layout));
  382. // Create the menu option for the layout.
  383. $o = new JObject;
  384. $o->title = ucfirst($layout);
  385. $o->description = '';
  386. $o->request = array('option' => $component, 'view' => $view);
  387. // Only add the layout request argument if not the default layout.
  388. if ($layout != 'default') {
  389. $o->request['layout'] = $layout;
  390. }
  391. // Load layout metadata if it exists.
  392. if (is_file($file))
  393. {
  394. // Attempt to load the xml file.
  395. if ($xml = simplexml_load_file($file))
  396. {
  397. // Look for the first view node off of the root node.
  398. if ($menu = $xml->xpath('layout[1]'))
  399. {
  400. $menu = $menu[0];
  401. // If the view is hidden from the menu, discard it and move on to the next view.
  402. if (!empty($menu['hidden']) && $menu['hidden'] == 'true') {
  403. unset($xml);
  404. unset($o);
  405. continue;
  406. }
  407. // Populate the title and description if they exist.
  408. if (!empty($menu['title'])) {
  409. $o->title = trim((string) $menu['title']);
  410. }
  411. if (!empty($menu->message[0])) {
  412. $o->description = trim((string) $menu->message[0]);
  413. }
  414. }
  415. }
  416. }
  417. // Add the layout to the options array.
  418. $options[] = $o;
  419. }
  420. }
  421. return $options;
  422. }
  423. }