PageRenderTime 39ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://github.com/joebushi/joomla
PHP | 488 lines | 335 code | 67 blank | 86 comment | 51 complexity | bb05586edfb7174fd58284e364dedeb2 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  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('modal.js');
  62. JHtml::stylesheet('modal.css');
  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).'">';
  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>'.$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.'/components/'.$option->request['option']);
  164. $lang->load($option->request['option'].'.menu');
  165. }
  166. }
  167. }
  168. }
  169. }
  170. return $list;
  171. }
  172. protected function _getTypeOptionsByComponent($component)
  173. {
  174. // Initialise variables.
  175. $options = array();
  176. $mainXML = JPATH_SITE.'/components/'.$component.'/metadata.xml';
  177. if (is_file($mainXML)) {
  178. $options = $this->_getTypeOptionsFromXML($mainXML, $component);
  179. }
  180. if (empty($options)) {
  181. $options = $this->_getTypeOptionsFromMVC($component);
  182. }
  183. return $options;
  184. }
  185. protected function _getTypeOptionsFromXML($file, $component)
  186. {
  187. // Initialise variables.
  188. $options = array();
  189. // Attempt to load the xml file.
  190. if (!$xml = simplexml_load_file($file)) {
  191. return false;
  192. }
  193. // Look for the first menu node off of the root node.
  194. if (!$menu = $xml->xpath('menu[1]')) {
  195. return false;
  196. }
  197. else {
  198. $menu = $menu[0];
  199. }
  200. // If we have no options to parse, just add the base component to the list of options.
  201. if (!empty($menu['options']) && $menu['options'] == 'none')
  202. {
  203. // Create the menu option for the component.
  204. $o = new JObject;
  205. $o->title = $menu['name'];
  206. $o->description = $menu['msg'];
  207. $o->request = array('option' => $component);
  208. $options[] = $o;
  209. return $options;
  210. }
  211. // Look for the first options node off of the menu node.
  212. if (!$optionsNode = $menu->xpath('options[1]')) {
  213. return false;
  214. }
  215. else {
  216. $optionsNode = $optionsNode[0];
  217. }
  218. // Make sure the options node has children.
  219. if (!$children = $optionsNode->children()) {
  220. return false;
  221. }
  222. else {
  223. // Process each child as an option.
  224. foreach ($children as $child)
  225. {
  226. if ($child->getName() == 'option')
  227. {
  228. // Create the menu option for the component.
  229. $o = new JObject;
  230. $o->title = $child['name'];
  231. $o->description = $child['msg'];
  232. $o->request = array('option' => $component, (string) $optionsNode['var'] => (string) $child['value']);
  233. $options[] = $o;
  234. }
  235. elseif ($child->getName() == 'default')
  236. {
  237. // Create the menu option for the component.
  238. $o = new JObject;
  239. $o->title = $child['name'];
  240. $o->description = $child['msg'];
  241. $o->request = array('option' => $component);
  242. $options[] = $o;
  243. }
  244. }
  245. }
  246. return $options;
  247. }
  248. protected function _getTypeOptionsFromMVC($component)
  249. {
  250. // Initialise variables.
  251. $options = array();
  252. // Get the views for this component.
  253. $path = JPATH_SITE.'/components/'.$component.'/views';
  254. if (JFolder::exists($path)) {
  255. $views = JFolder::folders($path);
  256. }
  257. else {
  258. return false;
  259. }
  260. foreach ($views as $view)
  261. {
  262. // Ignore private views.
  263. if (strpos($view, '_') !== 0)
  264. {
  265. // Determine if a metadata file exists for the view.
  266. $file = $path.'/'.$view.'/metadata.xml';
  267. if (is_file($file))
  268. {
  269. // Attempt to load the xml file.
  270. if ($xml = simplexml_load_file($file))
  271. {
  272. // Look for the first view node off of the root node.
  273. if ($menu = $xml->xpath('view[1]'))
  274. {
  275. $menu = $menu[0];
  276. // If the view is hidden from the menu, discard it and move on to the next view.
  277. if (!empty($menu['hidden']) && $menu['hidden'] == 'true') {
  278. unset($xml);
  279. continue;
  280. }
  281. // Do we have an options node or should we process layouts?
  282. // Look for the first options node off of the menu node.
  283. if ($optionsNode = $menu->xpath('options[1]'))
  284. {
  285. $optionsNode = $optionsNode[0];
  286. // Make sure the options node has children.
  287. if ($children = $optionsNode->children())
  288. {
  289. // Process each child as an option.
  290. foreach ($children as $child)
  291. {
  292. if ($child->getName() == 'option')
  293. {
  294. // Create the menu option for the component.
  295. $o = new JObject;
  296. $o->title = $child['name'];
  297. $o->description = $child['msg'];
  298. $o->request = array('option' => $component, 'view' => $view, (string) $optionsNode['var'] => (string) $child['value']);
  299. $options[] = $o;
  300. }
  301. elseif ($child->getName() == 'default')
  302. {
  303. // Create the menu option for the component.
  304. $o = new JObject;
  305. $o->title = $child['name'];
  306. $o->description = $child['msg'];
  307. $o->request = array('option' => $component, 'view' => $view);
  308. $options[] = $o;
  309. }
  310. }
  311. }
  312. }
  313. else {
  314. $options = array_merge($options, (array) $this->_getTypeOptionsFromLayouts($component, $view));
  315. }
  316. }
  317. unset($xml);
  318. }
  319. } else {
  320. $options = array_merge($options, (array) $this->_getTypeOptionsFromLayouts($component, $view));
  321. }
  322. }
  323. }
  324. return $options;
  325. }
  326. protected function _getTypeOptionsFromLayouts($component, $view)
  327. {
  328. // Initialise variables.
  329. $options = array();
  330. $layouts = array();
  331. $layoutNames = array();
  332. $templateLayouts = array();
  333. // Get the layouts from the view folder.
  334. $path = JPATH_SITE.'/components/'.$component.'/views/'.$view.'/tmpl';
  335. if (JFolder::exists($path)) {
  336. $layouts = array_merge($layouts, JFolder::files($path, '.xml$', false, true));
  337. }
  338. else {
  339. return $options;
  340. }
  341. // build list of standard layout names
  342. foreach ($layouts as $layout)
  343. {
  344. // Ignore private layouts.
  345. if (strpos(JFile::getName($layout), '_') === false)
  346. {
  347. $file = $layout;
  348. // Get the layout name.
  349. $layoutNames[] = JFile::stripext(JFile::getName($layout));
  350. }
  351. }
  352. // get the template layouts
  353. // TODO: This should only search one template -- the current template for this item (default of specified)
  354. $folders = JFolder::folders(JPATH_SITE.DS.'templates','',false,true);
  355. foreach($folders as $folder)
  356. {
  357. if (JFolder::exists($folder.DS.'html'.DS.$component.DS.$view)) {
  358. $templateLayouts = JFolder::files($folder.DS.'html'.DS.$component.DS.$view, '.xml$', false, true);
  359. foreach ($templateLayouts as $layout)
  360. {
  361. $file = $layout;
  362. // Get the layout name.
  363. $templateLayoutName = JFile::stripext(JFile::getName($layout));
  364. // add to the list only if it is not a standard layout
  365. if (array_search($templateLayoutName, $layoutNames) === false) {
  366. $layouts[] = $layout;
  367. }
  368. }
  369. }
  370. }
  371. // Process the found layouts.
  372. foreach ($layouts as $layout)
  373. {
  374. // Ignore private layouts.
  375. if (strpos(JFile::getName($layout), '_') === false)
  376. {
  377. $file = $layout;
  378. // Get the layout name.
  379. $layout = JFile::stripext(JFile::getName($layout));
  380. // Create the menu option for the layout.
  381. $o = new JObject;
  382. $o->title = ucfirst($layout);
  383. $o->description = '';
  384. $o->request = array('option' => $component, 'view' => $view);
  385. // Only add the layout request argument if not the default layout.
  386. if ($layout != 'default') {
  387. $o->request['layout'] = $layout;
  388. }
  389. // Load layout metadata if it exists.
  390. if (is_file($file))
  391. {
  392. // Attempt to load the xml file.
  393. if ($xml = simplexml_load_file($file))
  394. {
  395. // Look for the first view node off of the root node.
  396. if ($menu = $xml->xpath('layout[1]'))
  397. {
  398. $menu = $menu[0];
  399. // If the view is hidden from the menu, discard it and move on to the next view.
  400. if (!empty($menu['hidden']) && $menu['hidden'] == 'true') {
  401. unset($xml);
  402. unset($o);
  403. continue;
  404. }
  405. // Populate the title and description if they exist.
  406. if (!empty($menu['title'])) {
  407. $o->title = trim((string) $menu['title']);
  408. }
  409. if (!empty($menu->message[0])) {
  410. $o->description = trim((string) $menu->message[0]);
  411. }
  412. }
  413. }
  414. }
  415. // Add the layout to the options array.
  416. $options[] = $o;
  417. }
  418. }
  419. return $options;
  420. }
  421. }