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

/libraries/joomla/application/module/helper.php

https://github.com/brbrbr/joomla-platform
PHP | 523 lines | 324 code | 73 blank | 126 comment | 53 complexity | 14b2fe28526e24c7767f50d01b8f8528 MD5 | raw file
  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage Application
  5. *
  6. * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die();
  10. jimport('joomla.application.component.helper');
  11. /**
  12. * Module helper class
  13. *
  14. * @package Joomla.Platform
  15. * @subpackage Application
  16. * @since 11.1
  17. */
  18. abstract class JModuleHelper
  19. {
  20. /**
  21. * Get module by name (real, eg 'Breadcrumbs' or folder, eg 'mod_breadcrumbs')
  22. *
  23. * @param string $name The name of the module
  24. * @param string $title The title of the module, optional
  25. *
  26. * @return object The Module object
  27. *
  28. * @since 11.1
  29. */
  30. public static function &getModule($name, $title = null)
  31. {
  32. $result = null;
  33. $modules = JModuleHelper::_load();
  34. $total = count($modules);
  35. for ($i = 0; $i < $total; $i++)
  36. {
  37. // Match the name of the module
  38. if ($modules[$i]->name == $name || $modules[$i]->module == $name)
  39. {
  40. // Match the title if we're looking for a specific instance of the module
  41. if (!$title || $modules[$i]->title == $title)
  42. {
  43. // Found it
  44. $result = &$modules[$i];
  45. break; // Found it
  46. }
  47. }
  48. }
  49. // If we didn't find it, and the name is mod_something, create a dummy object
  50. if (is_null($result) && substr($name, 0, 4) == 'mod_')
  51. {
  52. $result = new stdClass;
  53. $result->id = 0;
  54. $result->title = '';
  55. $result->module = $name;
  56. $result->position = '';
  57. $result->content = '';
  58. $result->showtitle = 0;
  59. $result->control = '';
  60. $result->params = '';
  61. $result->user = 0;
  62. }
  63. return $result;
  64. }
  65. /**
  66. * Get modules by position
  67. *
  68. * @param string $position The position of the module
  69. *
  70. * @return array An array of module objects
  71. *
  72. * @since 11.1
  73. */
  74. public static function &getModules($position)
  75. {
  76. $app = JFactory::getApplication();
  77. $position = strtolower($position);
  78. $result = array();
  79. $modules = JModuleHelper::_load();
  80. $total = count($modules);
  81. for ($i = 0; $i < $total; $i++)
  82. {
  83. if ($modules[$i]->position == $position)
  84. {
  85. $result[] = &$modules[$i];
  86. }
  87. }
  88. if (count($result) == 0)
  89. {
  90. if (JRequest::getBool('tp') && JComponentHelper::getParams('com_templates')->get('template_positions_display'))
  91. {
  92. $result[0] = JModuleHelper::getModule('mod_' . $position);
  93. $result[0]->title = $position;
  94. $result[0]->content = $position;
  95. $result[0]->position = $position;
  96. }
  97. }
  98. return $result;
  99. }
  100. /**
  101. * Checks if a module is enabled
  102. *
  103. * @param string $module The module name
  104. *
  105. * @return boolean
  106. *
  107. * @since 11.1
  108. */
  109. public static function isEnabled($module)
  110. {
  111. $result = JModuleHelper::getModule($module);
  112. return !is_null($result);
  113. }
  114. /**
  115. * Render the module.
  116. *
  117. * @param object $module A module object.
  118. * @param array $attribs An array of attributes for the module (probably from the XML).
  119. *
  120. * @return string The HTML content of the module output.
  121. *
  122. * @since 11.1
  123. */
  124. public static function renderModule($module, $attribs = array())
  125. {
  126. static $chrome;
  127. if (constant('JDEBUG'))
  128. {
  129. JProfiler::getInstance('Application')->mark('beforeRenderModule ' . $module->module . ' (' . $module->title . ')');
  130. }
  131. $option = JRequest::getCmd('option');
  132. $app = JFactory::getApplication();
  133. // Record the scope.
  134. $scope = $app->scope;
  135. // Set scope to component name
  136. $app->scope = $module->module;
  137. // Get module parameters
  138. $params = new JRegistry;
  139. $params->loadString($module->params);
  140. // Get module path
  141. $module->module = preg_replace('/[^A-Z0-9_\.-]/i', '', $module->module);
  142. $path = JPATH_BASE . '/modules/' . $module->module . '/' . $module->module . '.php';
  143. // Load the module
  144. // $module->user is a check for 1.0 custom modules and is deprecated refactoring
  145. if (empty($module->user) && file_exists($path))
  146. {
  147. $lang = JFactory::getLanguage();
  148. // 1.5 or Core then 1.6 3PD
  149. $lang->load($module->module, JPATH_BASE, null, false, false) ||
  150. $lang->load($module->module, dirname($path), null, false, false) ||
  151. $lang->load($module->module, JPATH_BASE, $lang->getDefault(), false, false) ||
  152. $lang->load($module->module, dirname($path), $lang->getDefault(), false, false);
  153. $content = '';
  154. ob_start();
  155. include $path;
  156. $module->content = ob_get_contents() . $content;
  157. ob_end_clean();
  158. }
  159. // Load the module chrome functions
  160. if (!$chrome)
  161. {
  162. $chrome = array();
  163. }
  164. include_once JPATH_THEMES . '/system/html/modules.php';
  165. $chromePath = JPATH_THEMES . '/' . $app->getTemplate() . '/html/modules.php';
  166. if (!isset($chrome[$chromePath]))
  167. {
  168. if (file_exists($chromePath))
  169. {
  170. include_once $chromePath;
  171. }
  172. $chrome[$chromePath] = true;
  173. }
  174. // Make sure a style is set
  175. if (!isset($attribs['style']))
  176. {
  177. $attribs['style'] = 'none';
  178. }
  179. // Dynamically add outline style
  180. if (JRequest::getBool('tp') && JComponentHelper::getParams('com_templates')->get('template_positions_display'))
  181. {
  182. $attribs['style'] .= ' outline';
  183. }
  184. foreach (explode(' ', $attribs['style']) as $style)
  185. {
  186. $chromeMethod = 'modChrome_' . $style;
  187. // Apply chrome and render module
  188. if (function_exists($chromeMethod))
  189. {
  190. $module->style = $attribs['style'];
  191. ob_start();
  192. $chromeMethod($module, $params, $attribs);
  193. $module->content = ob_get_contents();
  194. ob_end_clean();
  195. }
  196. }
  197. //revert the scope
  198. $app->scope = $scope;
  199. if (constant('JDEBUG'))
  200. {
  201. JProfiler::getInstance('Application')->mark('afterRenderModule ' . $module->module . ' (' . $module->title . ')');
  202. }
  203. return $module->content;
  204. }
  205. /**
  206. * Get the path to a layout for a module
  207. *
  208. * @param string $module The name of the module
  209. * @param string $layout The name of the module layout. If alternative layout, in the form template:filename.
  210. *
  211. * @return string The path to the module layout
  212. *
  213. * @since 11.1
  214. */
  215. public static function getLayoutPath($module, $layout = 'default')
  216. {
  217. $template = JFactory::getApplication()->getTemplate();
  218. $defaultLayout = $layout;
  219. if (strpos($layout, ':') !== false)
  220. {
  221. // Get the template and file name from the string
  222. $temp = explode(':', $layout);
  223. $template = ($temp[0] == '_') ? $template : $temp[0];
  224. $layout = $temp[1];
  225. $defaultLayout = ($temp[1]) ? $temp[1] : 'default';
  226. }
  227. // Build the template and base path for the layout
  228. $tPath = JPATH_THEMES . '/' . $template . '/html/' . $module . '/' . $layout . '.php';
  229. $bPath = JPATH_BASE . '/modules/' . $module . '/tmpl/' . $defaultLayout . '.php';
  230. // If the template has a layout override use it
  231. if (file_exists($tPath))
  232. {
  233. return $tPath;
  234. }
  235. else
  236. {
  237. return $bPath;
  238. }
  239. }
  240. /**
  241. * Load published modules.
  242. *
  243. * @return array
  244. *
  245. * @since 11.1
  246. */
  247. protected static function &_load()
  248. {
  249. static $clean;
  250. if (isset($clean))
  251. {
  252. return $clean;
  253. }
  254. $Itemid = JRequest::getInt('Itemid');
  255. $app = JFactory::getApplication();
  256. $user = JFactory::getUser();
  257. $groups = implode(',', $user->getAuthorisedViewLevels());
  258. $lang = JFactory::getLanguage()->getTag();
  259. $clientId = (int) $app->getClientId();
  260. $cache = JFactory::getCache('com_modules', '');
  261. $cacheid = md5(serialize(array($Itemid, $groups, $clientId, $lang)));
  262. if (!($clean = $cache->get($cacheid)))
  263. {
  264. $db = JFactory::getDbo();
  265. $query = $db->getQuery(true);
  266. $query->select('m.id, m.title, m.module, m.position, m.content, m.showtitle, m.params, mm.menuid');
  267. $query->from('#__modules AS m');
  268. $query->join('LEFT', '#__modules_menu AS mm ON mm.moduleid = m.id');
  269. $query->where('m.published = 1');
  270. $query->join('LEFT', '#__extensions AS e ON e.element = m.module AND e.client_id = m.client_id');
  271. $query->where('e.enabled = 1');
  272. $date = JFactory::getDate();
  273. $now = $date->toMySQL();
  274. $nullDate = $db->getNullDate();
  275. $query->where('(m.publish_up = ' . $db->Quote($nullDate) . ' OR m.publish_up <= ' . $db->Quote($now) . ')');
  276. $query->where('(m.publish_down = ' . $db->Quote($nullDate) . ' OR m.publish_down >= ' . $db->Quote($now) . ')');
  277. $query->where('m.access IN (' . $groups . ')');
  278. $query->where('m.client_id = ' . $clientId);
  279. $query->where('(mm.menuid = ' . (int) $Itemid . ' OR mm.menuid <= 0)');
  280. // Filter by language
  281. if ($app->isSite() && $app->getLanguageFilter())
  282. {
  283. $query->where('m.language IN (' . $db->Quote($lang) . ',' . $db->Quote('*') . ')');
  284. }
  285. $query->order('m.position, m.ordering');
  286. // Set the query
  287. $db->setQuery($query);
  288. $modules = $db->loadObjectList();
  289. $clean = array();
  290. if ($db->getErrorNum())
  291. {
  292. JError::raiseWarning(500, JText::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $db->getErrorMsg()));
  293. return $clean;
  294. }
  295. // Apply negative selections and eliminate duplicates
  296. $negId = $Itemid ? -(int) $Itemid : false;
  297. $dupes = array();
  298. for ($i = 0, $n = count($modules); $i < $n; $i++)
  299. {
  300. $module = &$modules[$i];
  301. // The module is excluded if there is an explicit prohibition or if
  302. // the Itemid is missing or zero and the module is in exclude mode.
  303. $negHit = ($negId === (int) $module->menuid) || (!$negId && (int) $module->menuid < 0);
  304. if (isset($dupes[$module->id]))
  305. {
  306. // If this item has been excluded, keep the duplicate flag set,
  307. // but remove any item from the cleaned array.
  308. if ($negHit)
  309. {
  310. unset($clean[$module->id]);
  311. }
  312. continue;
  313. }
  314. $dupes[$module->id] = true;
  315. // Only accept modules without explicit exclusions.
  316. if (!$negHit)
  317. {
  318. // Determine if this is a 1.0 style custom module (no mod_ prefix)
  319. // This should be eliminated when the class is refactored.
  320. // $module->user is deprecated.
  321. $file = $module->module;
  322. $custom = substr($file, 0, 4) == 'mod_' ? 0 : 1;
  323. $module->user = $custom;
  324. // 1.0 style custom module name is given by the title field, otherwise strip off "mod_"
  325. $module->name = $custom ? $module->module : substr($file, 4);
  326. $module->style = null;
  327. $module->position = strtolower($module->position);
  328. $clean[$module->id] = $module;
  329. }
  330. }
  331. unset($dupes);
  332. // Return to simple indexing that matches the query order.
  333. $clean = array_values($clean);
  334. $cache->store($clean, $cacheid);
  335. }
  336. return $clean;
  337. }
  338. /**
  339. * Module cache helper
  340. *
  341. * Caching modes:
  342. * To be set in XML:
  343. * 'static' One cache file for all pages with the same module parameters
  344. * 'oldstatic' 1.5 definition of module caching, one cache file for all pages
  345. * with the same module id and user aid,
  346. * 'itemid' Changes on itemid change, to be called from inside the module:
  347. * 'safeuri' Id created from $cacheparams->modeparams array,
  348. * 'id' Module sets own cache id's
  349. *
  350. * @param object $module Module object
  351. * @param object $moduleparams Module parameters
  352. * @param object $cacheparams Module cache parameters - id or url parameters, depending on the module cache mode
  353. *
  354. * @return string
  355. *
  356. * @since 11.1
  357. *
  358. * @link JFilterInput::clean()
  359. */
  360. public static function moduleCache($module, $moduleparams, $cacheparams)
  361. {
  362. if (!isset($cacheparams->modeparams))
  363. {
  364. $cacheparams->modeparams = null;
  365. }
  366. if (!isset($cacheparams->cachegroup))
  367. {
  368. $cacheparams->cachegroup = $module->module;
  369. }
  370. $user = JFactory::getUser();
  371. $cache = JFactory::getCache($cacheparams->cachegroup, 'callback');
  372. $conf = JFactory::getConfig();
  373. // Turn cache off for internal callers if parameters are set to off and for all logged in users
  374. if ($moduleparams->get('owncache', null) === '0' || $conf->get('caching') == 0 || $user->get('id'))
  375. {
  376. $cache->setCaching(false);
  377. }
  378. // module cache is set in seconds, global cache in minutes, setLifeTime works in minutes
  379. $cache->setLifeTime($moduleparams->get('cache_time', $conf->get('cachetime') * 60) / 60);
  380. $wrkaroundoptions = array('nopathway' => 1, 'nohead' => 0, 'nomodules' => 1, 'modulemode' => 1, 'mergehead' => 1);
  381. $wrkarounds = true;
  382. $view_levels = md5(serialize($user->getAuthorisedViewLevels()));
  383. switch ($cacheparams->cachemode)
  384. {
  385. case 'id':
  386. $ret = $cache->get(
  387. array($cacheparams->class, $cacheparams->method),
  388. $cacheparams->methodparams,
  389. $cacheparams->modeparams,
  390. $wrkarounds,
  391. $wrkaroundoptions
  392. );
  393. break;
  394. case 'safeuri':
  395. $secureid = null;
  396. if (is_array($cacheparams->modeparams))
  397. {
  398. $uri = JRequest::get();
  399. $safeuri = new stdClass;
  400. foreach ($cacheparams->modeparams as $key => $value)
  401. {
  402. // Use int filter for id/catid to clean out spamy slugs
  403. if (isset($uri[$key]))
  404. {
  405. $safeuri->$key = JRequest::_cleanVar($uri[$key], 0, $value);
  406. }
  407. }
  408. }
  409. $secureid = md5(serialize(array($safeuri, $cacheparams->method, $moduleparams)));
  410. $ret = $cache->get(
  411. array($cacheparams->class, $cacheparams->method),
  412. $cacheparams->methodparams,
  413. $module->id . $view_levels . $secureid,
  414. $wrkarounds,
  415. $wrkaroundoptions
  416. );
  417. break;
  418. case 'static':
  419. $ret = $cache->get(
  420. array($cacheparams->class,
  421. $cacheparams->method),
  422. $cacheparams->methodparams,
  423. $module->module . md5(serialize($cacheparams->methodparams)),
  424. $wrkarounds,
  425. $wrkaroundoptions
  426. );
  427. break;
  428. case 'oldstatic': // provided for backward compatibility, not really usefull
  429. $ret = $cache->get(
  430. array($cacheparams->class, $cacheparams->method),
  431. $cacheparams->methodparams,
  432. $module->id . $view_levels,
  433. $wrkarounds,
  434. $wrkaroundoptions
  435. );
  436. break;
  437. case 'itemid':
  438. default:
  439. $ret = $cache->get(
  440. array($cacheparams->class, $cacheparams->method),
  441. $cacheparams->methodparams,
  442. $module->id . $view_levels . JRequest::getVar('Itemid', null, 'default', 'INT'),
  443. $wrkarounds,
  444. $wrkaroundoptions
  445. );
  446. break;
  447. }
  448. return $ret;
  449. }
  450. }