PageRenderTime 63ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/src/legacy/util/System.php

https://github.com/antoniom/core
PHP | 905 lines | 489 code | 99 blank | 317 comment | 184 complexity | 03f0d67759814134bcd8363c2c85a732 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0, MIT
  1. <?php
  2. /**
  3. * Copyright Zikula Foundation 2009 - Zikula Application Framework
  4. *
  5. * This work is contributed to the Zikula Foundation under one or more
  6. * Contributor Agreements and licensed to You under the following license:
  7. *
  8. * @license GNU/LGPLv3 (or at your option, any later version).
  9. * @package Zikula
  10. *
  11. * Please see the NOTICE file distributed with this source code for further
  12. * information regarding copyright and licensing.
  13. */
  14. use Symfony\Component\HttpFoundation\RedirectResponse;
  15. /**
  16. * System class.
  17. *
  18. * Core class with the base methods.
  19. */
  20. class System
  21. {
  22. /**
  23. * Internals cache.
  24. *
  25. * @var array
  26. */
  27. protected static $cache = array();
  28. /**
  29. * Flush this static class' cache.
  30. *
  31. * @return void
  32. */
  33. public static function flushCache()
  34. {
  35. self::$cache = array();
  36. }
  37. /**
  38. * Get a configuration variable.
  39. *
  40. * @param string $name The name of the variable.
  41. * @param mixed $default The default value to return if the requested param is not set.
  42. *
  43. * @return mixed Value of the variable, or false on failure.
  44. */
  45. public static function getVar($name, $default = null)
  46. {
  47. if (!isset($name)) {
  48. return null;
  49. }
  50. if (array_key_exists($name, $GLOBALS['ZConfig']['System'])) {
  51. $mod_var = $GLOBALS['ZConfig']['System'][$name];
  52. } else {
  53. $mod_var = ModUtil::getVar(ModUtil::CONFIG_MODULE, $name, $default);
  54. // cache
  55. $GLOBALS['ZConfig']['System'][$name] = $mod_var;
  56. }
  57. // Known Issue: the $default value will never be used because $mod_var returned from ModUtil::getVar will
  58. // be false if the value does not exist in the database. This function will always return false in this
  59. // case. Unfortunately legacy code relies on the behavior, so it cannot be fixed. See issues #1025, #2011
  60. // and possibly others.
  61. if (isset($mod_var)) {
  62. return $mod_var;
  63. }
  64. return $default;
  65. }
  66. /**
  67. * Set a configuration variable.
  68. *
  69. * @param string $name The name of the variable.
  70. * @param mixed $value The value of the variable.
  71. *
  72. * @return boolean True on success, false on failure.
  73. */
  74. public static function setVar($name, $value = '')
  75. {
  76. $name = isset($name) ? (string)$name : '';
  77. // The database parameter are not allowed to change
  78. if (empty($name) || $name == 'system' || $name == 'prefix' || in_array($name, ServiceUtil::getManager()->getParameter('protected.systemvars'))) {
  79. return false;
  80. }
  81. // set the variable
  82. if (ModUtil::setVar(ModUtil::CONFIG_MODULE, $name, $value)) {
  83. // Update my vars
  84. $GLOBALS['ZConfig']['System'][$name] = $value;
  85. return true;
  86. }
  87. return false;
  88. }
  89. /**
  90. * Delete a configuration variable.
  91. *
  92. * @param string $name The name of the variable.
  93. *
  94. * @return mixed Value of deleted config var or false on failure.
  95. */
  96. public static function delVar($name)
  97. {
  98. if (!isset($name)) {
  99. return false;
  100. }
  101. // The database parameter are not allowed to be deleted
  102. if (empty($name) || $name == 'dbtype' || $name == 'dbhost' || $name == 'dbuname' || $name == 'dbpass' || $name == 'dbname' || $name == 'system' || $name == 'prefix' || $name == 'encoded') {
  103. return false;
  104. }
  105. // Delete the variable
  106. ModUtil::delVar(ModUtil::CONFIG_MODULE, $name);
  107. // Update my vars
  108. $val = false;
  109. if (array_key_exists($name, $GLOBALS['ZConfig']['System'])) {
  110. $val = $GLOBALS['ZConfig']['System'][$name];
  111. unset($GLOBALS['ZConfig']['System'][$name]);
  112. }
  113. // success
  114. return $val;
  115. }
  116. /**
  117. * Strip slashes.
  118. *
  119. * Stripslashes on multidimensional arrays.
  120. * Used in conjunction with FormUtil::getPassedValue.
  121. *
  122. * @param mixed &$value Variables or arrays to be stripslashed.
  123. *
  124. * @return void
  125. */
  126. public static function stripslashes(&$value)
  127. {
  128. if (empty($value)) {
  129. return;
  130. }
  131. if (!is_array($value)) {
  132. $value = stripslashes($value);
  133. } else {
  134. array_walk($value, 'System::stripslashes');
  135. }
  136. }
  137. /**
  138. * Validate a Zikula variable.
  139. *
  140. * @param mixed $var The variable to validate.
  141. * @param string $type The type of the validation to perform (email, url etc.).
  142. * @param mixed $args Optional array with validation-specific settings (deprecated).
  143. *
  144. * @return boolean True if the validation was successful, false otherwise.
  145. */
  146. public static function varValidate($var, $type, $args = 0)
  147. {
  148. if (!isset($var) || !isset($type)) {
  149. return false;
  150. }
  151. // typecasting (might be useless in this function)
  152. $var = (string)$var;
  153. $type = (string)$type;
  154. static $maxlength = array(
  155. 'modvar' => 64,
  156. 'func' => 512,
  157. 'api' => 187,
  158. 'theme' => 200,
  159. 'uname' => 25,
  160. 'config' => 64);
  161. static $minlength = array(
  162. 'mod' => 1,
  163. 'modvar' => 1,
  164. 'uname' => 1,
  165. 'config' => 1);
  166. // commented out some regexps until some useful and working ones are found
  167. static $regexp = array(// 'mod' => '/^[^\\\/\?\*\"\'\>\<\:\|]*$/',
  168. // 'func' => '/[^0-9a-zA-Z_]/',
  169. // 'api' => '/[^0-9a-zA-Z_]/',
  170. // 'theme' => '/^[^\\\/\?\*\"\'\>\<\:\|]*$/',
  171. 'email' => '/^(?:[^\s\000-\037\177\(\)<>@,;:\\"\[\]]\.?)+@(?:[^\s\000-\037\177\(\)<>@,;:\\\"\[\]]\.?)+\.[a-z]{2,6}$/Ui',
  172. 'url' => '/^([!#\$\046-\073=\077-\132_\141-\172~]|(?:%[a-f0-9]{2}))+$/i');
  173. // special cases
  174. if ($type == 'mod' && $var == ModUtil::CONFIG_MODULE) {
  175. return true;
  176. }
  177. if ($type == 'config' && ($var == 'dbtype') || ($var == 'dbhost') || ($var == 'dbuname') || ($var == 'dbpass') || ($var == 'dbname') || ($var == 'system') || ($var == 'prefix') || ($var == 'encoded')) {
  178. // The database parameter are not allowed to change
  179. return false;
  180. }
  181. if ($type == 'email' || $type == 'url') {
  182. // CSRF protection for email and url
  183. $var = str_replace(array(
  184. '\r',
  185. '\n',
  186. '%0d',
  187. '%0a'), '', $var);
  188. if (self::getVar('idnnames')) {
  189. // transfer between the encoded (Punycode) notation and the decoded (8bit) notation.
  190. $var = idn_to_utf8($var);
  191. }
  192. // all characters must be 7 bit ascii
  193. $length = strlen($var);
  194. $idx = 0;
  195. while ($length--) {
  196. $c = $var[$idx++];
  197. if (ord($c) > 127) {
  198. return false;
  199. }
  200. }
  201. }
  202. if ($type == 'url') {
  203. // check for url
  204. $url_array = @parse_url($var);
  205. if (!empty($url_array) && empty($url_array['scheme'])) {
  206. return false;
  207. }
  208. }
  209. if ($type == 'uname') {
  210. // check for invalid characters
  211. if (!preg_match('/^[\p{L}\p{N}_\.\-]+$/uD', $var)) {
  212. return false;
  213. } else {
  214. $lowerUname = mb_strtolower($var);
  215. if ($lowerUname != $var) {
  216. return false;
  217. }
  218. }
  219. }
  220. // variable passed special checks. We now to generic checkings.
  221. // check for maximal length
  222. if (isset($maxlength[$type]) && mb_strlen($var) > $maxlength[$type]) {
  223. return false;
  224. }
  225. // check for minimal length
  226. if (isset($minlength[$type]) && mb_strlen($var) < $minlength[$type]) {
  227. return false;
  228. }
  229. // check for regular expression
  230. if (isset($regexp[$type]) && !preg_match($regexp[$type], $var)) {
  231. return false;
  232. }
  233. // all tests for illegal entries failed, so we assume the var is ok ;-)
  234. return true;
  235. }
  236. /**
  237. * Get base URI for Zikula.
  238. *
  239. * @return string Base URI for Zikula.
  240. */
  241. public static function getBaseUri()
  242. {
  243. if (!array_key_exists('baseuri.path', self::$cache)) {
  244. self::$cache['baseuri.path'] = null;
  245. }
  246. if (!isset(self::$cache['baseuri.path'])) {
  247. $script_name = self::serverGetVar('SCRIPT_NAME');
  248. self::$cache['baseuri.path'] = substr($script_name, 0, strrpos($script_name, '/'));
  249. }
  250. $container = ServiceUtil::getManager();
  251. if ($container['multisites.enabled'] == 1) {
  252. self::$cache['baseuri.path'] = $container['multisites.sitedns'];
  253. }
  254. return self::$cache['baseuri.path'];
  255. }
  256. /**
  257. * Get base URL for Zikula.
  258. *
  259. * @return string Base URL for Zikula.
  260. */
  261. public static function getBaseUrl()
  262. {
  263. $server = self::serverGetVar('HTTP_HOST');
  264. // IIS sets HTTPS=off
  265. $https = self::serverGetVar('HTTPS', 'off');
  266. if ($https != 'off') {
  267. $proto = 'https://';
  268. } else {
  269. $proto = 'http://';
  270. }
  271. $path = self::getBaseUri();
  272. return "$proto$server$path/";
  273. }
  274. /**
  275. * Get homepage URL for Zikula.
  276. *
  277. * @return string Homepage URL for Zikula.
  278. */
  279. public static function getHomepageUrl()
  280. {
  281. // check the use of friendly url setup
  282. $shorturls = self::getVar('shorturls', false);
  283. $langRequired = ZLanguage::isRequiredLangParam();
  284. $expectEntrypoint = !self::getVar('shorturlsstripentrypoint');
  285. $entryPoint = self::getVar('entrypoint');
  286. if ($shorturls) {
  287. $result = self::getBaseUrl();
  288. if ($expectEntrypoint) {
  289. $result .= "$entryPoint";
  290. }
  291. if ($langRequired) {
  292. $result .= (preg_match('#/$#', $result) ? '' : '/') . ZLanguage::getLanguageCode();
  293. }
  294. } else {
  295. $result = self::getVar('entrypoint', 'index.php');
  296. if (ZLanguage::isRequiredLangParam()) {
  297. $result .= '?lang=' . ZLanguage::getLanguageCode();
  298. }
  299. }
  300. return $result;
  301. }
  302. // /**
  303. // * Carry out a redirect.
  304. // *
  305. // * @param string $redirecturl URL to redirect to.
  306. // * @param array $additionalheaders Array of header strings to send with redirect.
  307. // * @param integer $type Number type of the redirect.
  308. // *
  309. // * @return boolean True if redirect successful, false otherwise.
  310. // */
  311. // public static function redirect($redirecturl, $additionalheaders = array(), $type = 302)
  312. // {
  313. // // very basic input validation against HTTP response splitting
  314. // $redirecturl = str_replace(array(
  315. // '\r',
  316. // '\n',
  317. // '%0d',
  318. // '%0a'), '', $redirecturl);
  319. //
  320. // // Always close session before redirect
  321. // session_write_close();
  322. //
  323. // if (preg_match('!^(?:http|https|ftp|ftps):\/\/!', $redirecturl)) {
  324. // // Absolute URL - simple redirect
  325. // } elseif (substr($redirecturl, 0, 1) == '/') {
  326. // // Root-relative links
  327. // $redirecturl = 'http' . (self::serverGetVar('HTTPS') == 'on' ? 's' : '') . '://' . self::serverGetVar('HTTP_HOST') . $redirecturl;
  328. // } else {
  329. // // Relative URL
  330. // // Removing leading slashes from redirect url
  331. // $redirecturl = preg_replace('!^/*!', '', $redirecturl);
  332. // // Get base URL and append it to our redirect url
  333. // $baseurl = self::getBaseUrl();
  334. // $redirecturl = $baseurl . $redirecturl;
  335. // }
  336. //
  337. // $response = new \Symfony\Component\HttpFoundation\RedirectResponse($redirecturl, (int) $type, $additionalheaders);
  338. // $response->send();
  339. //
  340. // exit;
  341. // }
  342. /**
  343. * Check to see if this is a local referral.
  344. *
  345. * @param boolean $strict Strict checking ensures that a referer must be set as well as local.
  346. *
  347. * @return boolean True if locally referred, false if not.
  348. */
  349. public static function localReferer($strict = false)
  350. {
  351. $server = self::serverGetVar('HTTP_HOST');
  352. $referer = self::serverGetVar('HTTP_REFERER');
  353. // an empty referer returns true unless strict checking is enabled
  354. if (!$strict && empty($referer)) {
  355. return true;
  356. }
  357. // check the http referer
  358. if (preg_match("!^https?://$server/!", $referer)) {
  359. return true;
  360. }
  361. return false;
  362. }
  363. /**
  364. * Gets a server variable.
  365. *
  366. * Returns the value of $name from $_SERVER array.
  367. * Accepted values for $name are exactly the ones described by the
  368. * {@link http://www.php.net/manual/en/reserved.variables.html#reserved.variables.server PHP manual}.
  369. * If the server variable doesn't exist void is returned.
  370. *
  371. * @param string $name The name of the variable.
  372. * @param mixed $default The default value to return if the requested param is not set.
  373. *
  374. * @return mixed Value of the variable.
  375. */
  376. public static function serverGetVar($name, $default = null)
  377. {
  378. // Check the relevant superglobals
  379. if (!empty($name) && isset($_SERVER[$name])) {
  380. return $_SERVER[$name];
  381. }
  382. return $default; // nothing found -> return default
  383. }
  384. /**
  385. * Gets the host name.
  386. *
  387. * Returns the server host name fetched from HTTP headers when possible.
  388. * The host name is in the canonical form (host + : + port) when the port is different than 80.
  389. *
  390. * @return string HTTP host name.
  391. */
  392. public static function getHost()
  393. {
  394. $server = self::serverGetVar('HTTP_HOST');
  395. if (empty($server)) {
  396. // HTTP_HOST is reliable only for HTTP 1.1
  397. $server = self::serverGetVar('SERVER_NAME');
  398. $port = self::serverGetVar('SERVER_PORT');
  399. if ($port != '80') {
  400. $server .= ":$port";
  401. }
  402. }
  403. return $server;
  404. }
  405. /**
  406. * Get current URI (and optionally add/replace some parameters).
  407. *
  408. * @param array $args Additional parameters to be added to/replaced in the URI (e.g. theme, ...).
  409. *
  410. * @access public
  411. *
  412. * @return string Current URI.
  413. */
  414. public static function getCurrentUri($args = array())
  415. {
  416. // get current URI
  417. $request = self::serverGetVar('REQUEST_URI');
  418. if (empty($request)) {
  419. $scriptname = self::serverGetVar('SCRIPT_NAME');
  420. $pathinfo = self::serverGetVar('PATH_INFO');
  421. if ($pathinfo == $scriptname) {
  422. $pathinfo = '';
  423. }
  424. if (!empty($scriptname)) {
  425. $request = $scriptname . $pathinfo;
  426. $querystring = self::serverGetVar('QUERY_STRING');
  427. if (!empty($querystring)) {
  428. $request .= '?' . $querystring;
  429. }
  430. } else {
  431. $request = '/';
  432. }
  433. }
  434. // add optional parameters
  435. if (count($args) > 0) {
  436. if (strpos($request, '?') === false) {
  437. $request .= '?';
  438. } else {
  439. $request .= '&';
  440. }
  441. foreach ($args as $k => $v) {
  442. if (is_array($v)) {
  443. foreach ($v as $l => $w) {
  444. // TODO: replace in-line here too ?
  445. if (!empty($w)) {
  446. $request .= $k . "[$l]=$w&";
  447. }
  448. }
  449. } else {
  450. // if this parameter is already in the query string...
  451. if (preg_match("/(&|\?)($k=[^&]*)/", $request, $matches)) {
  452. $find = $matches[2];
  453. // ... replace it in-line if it's not empty
  454. if (!empty($v)) {
  455. $request = preg_replace("/(&|\?)$find/", "$1$k=$v", $request);
  456. // ... or remove it otherwise
  457. } elseif ($matches[1] == '?') {
  458. $request = preg_replace("/\?$find(&|)/", '?', $request);
  459. } else {
  460. $request = preg_replace("/&$find/", '', $request);
  461. }
  462. } elseif (!empty($v)) {
  463. $request .= "$k=$v&";
  464. }
  465. }
  466. }
  467. $request = substr($request, 0, -1);
  468. }
  469. return $request;
  470. }
  471. /**
  472. * Gets the current protocol.
  473. *
  474. * Returns the HTTP protocol used by current connection, it could be 'http' or 'https'.
  475. *
  476. * @return string Current HTTP protocol.
  477. */
  478. public static function serverGetProtocol()
  479. {
  480. if (preg_match('/^http:/', self::getCurrentUri())) {
  481. return 'http';
  482. }
  483. $HTTPS = self::serverGetVar('HTTPS');
  484. // IIS seems to set HTTPS = off for some reason
  485. return (!empty($HTTPS) && $HTTPS != 'off') ? 'https' : 'http';
  486. }
  487. /**
  488. * Get current URL.
  489. *
  490. * @param array $args Additional parameters to be added to/replaced in the URL (e.g. theme, ...).
  491. *
  492. * @access public
  493. * @todo cfr. BaseURI() for other possible ways, or try PHP_SELF.
  494. *
  495. * @return string Current URL.
  496. */
  497. public static function getCurrentUrl($args = array())
  498. {
  499. $server = self::getHost();
  500. $protocol = self::serverGetProtocol();
  501. $baseurl = "$protocol://$server";
  502. $request = self::getCurrentUri($args);
  503. if (empty($request)) {
  504. $scriptname = self::serverGetVar('SCRIPT_NAME');
  505. $pathinfo = self::serverGetVar('PATH_INFO');
  506. if ($pathinfo == $scriptname) {
  507. $pathinfo = '';
  508. }
  509. if (!empty($scriptname)) {
  510. $request = $scriptname . $pathinfo;
  511. $querystring = self::serverGetVar('QUERY_STRING');
  512. if (!empty($querystring)) {
  513. $request .= '?' . $querystring;
  514. }
  515. } else {
  516. $request = '/';
  517. }
  518. }
  519. return $baseurl . $request;
  520. }
  521. /**
  522. * Decode the path string into a set of variable/value pairs.
  523. *
  524. * This API works in conjunction with the new short urls
  525. * system to extract a path based variable set into the Get, Post
  526. * and request superglobals.
  527. * A sample path is /modname/function/var1:value1.
  528. *
  529. * @return void
  530. */
  531. public static function queryStringDecode()
  532. {
  533. if (self::isInstalling()) {
  534. return;
  535. }
  536. // get our base parameters to work out if we need to decode the url
  537. $module = FormUtil::getPassedValue('module', null, 'GETPOST', FILTER_SANITIZE_STRING);
  538. $func = FormUtil::getPassedValue('func', null, 'GETPOST', FILTER_SANITIZE_STRING);
  539. $type = FormUtil::getPassedValue('type', null, 'GETPOST', FILTER_SANITIZE_STRING);
  540. // check if we need to decode the url
  541. if ((self::getVar('shorturls') && (empty($module) && empty($type) && empty($func)))) {
  542. // user language is not set at this stage
  543. $lang = System::getVar('language_i18n', '');
  544. $customentrypoint = self::getVar('entrypoint');
  545. $expectEntrypoint = !self::getVar('shorturlsstripentrypoint');
  546. $root = empty($customentrypoint) ? 'index.php' : $customentrypoint;
  547. // check if we hit baseurl, e.g. domain.com/ and if we require the language URL
  548. // then we should redirect to the language URL.
  549. if (ZLanguage::isRequiredLangParam() && self::getCurrentUrl() == self::getBaseUrl()) {
  550. $uri = $expectEntrypoint ? "$root/$lang" : "$lang";
  551. self::redirect(self::getBaseUrl() . $uri);
  552. self::shutDown();
  553. }
  554. // check if entry point is part of the URL expectation. If so throw error if it's not present
  555. // since this URL is technically invalid.
  556. if ($expectEntrypoint && strpos(self::getCurrentUrl(), self::getBaseUrl() . $root) !== 0) {
  557. $protocol = System::serverGetVar('SERVER_PROTOCOL');
  558. header("{$protocol} 404 Not Found");
  559. echo __('The requested URL cannot be found');
  560. system::shutDown();
  561. }
  562. if (!$expectEntrypoint && self::getCurrentUrl() == self::getBaseUrl() . $root) {
  563. self::redirect(self::getHomepageUrl());
  564. self::shutDown();
  565. }
  566. if (!$expectEntrypoint && strpos(self::getCurrentUrl(), self::getBaseUrl() . $root) === 0) {
  567. $protocol = System::serverGetVar('SERVER_PROTOCOL');
  568. header("{$protocol} 404 Not Found");
  569. echo __('The requested URL cannot be found');
  570. system::shutDown();
  571. }
  572. // get base path to work out our current url
  573. $parsedURL = parse_url(self::getCurrentUri());
  574. // strip any unwanted content from the provided URL
  575. $tobestripped = array(self::getBaseUri(), "$root");
  576. $path = str_replace($tobestripped, '', $parsedURL['path']);
  577. $path = trim($path, '/');
  578. // split the path into a set of argument strings
  579. $args = explode('/', rtrim($path, '/'));
  580. // ensure that each argument is properly decoded
  581. foreach ($args as $k => $v) {
  582. $args[$k] = urldecode($v);
  583. }
  584. $modinfo = null;
  585. $frontController = $expectEntrypoint ? "$root/" : '';
  586. // if no arguments present
  587. if (!$args[0] && !isset($_GET['lang']) && !isset($_GET['theme'])) {
  588. // we are in the homepage, checks if language code is forced
  589. if (ZLanguage::getLangUrlRule() && $lang) {
  590. // and redirect then
  591. $response = new RedirectResponse(self::getCurrentUrl()."/$lang");
  592. $response->send();
  593. System::shutDown();
  594. }
  595. } else {
  596. // check the existing shortURL parameters
  597. // validation of the first parameter as language code
  598. if (ZLanguage::isLangParam($args[0]) && in_array($args[0], ZLanguage::getInstalledLanguages())) {
  599. // checks if the language is not enforced and this url is passing the default lang
  600. if (!ZLanguage::getLangUrlRule() && $lang == $args[0]) {
  601. // redirects the passed arguments without the default site language
  602. array_shift($args);
  603. foreach ($args as $k => $v) {
  604. $args[$k] = urlencode($v);
  605. }
  606. $response = new RedirectResponse(self::getBaseUrl().$frontController.($args ? implode('/', $args) : ''));
  607. $response->send();
  608. System::shutDown();
  609. }
  610. self::queryStringSetVar('lang', $args[0]);
  611. array_shift($args);
  612. } elseif (ZLanguage::getLangUrlRule()) {
  613. // if the lang is forced, redirects the passed arguments plus the lang
  614. foreach ($args as $k => $v) {
  615. $args[$k] = urlencode($v);
  616. }
  617. $langTheme = isset($_GET['theme']) ? "$lang/$_GET[theme]" : $lang;
  618. $response = new RedirectResponse(self::getBaseUrl().$frontController.$langTheme.'/'.implode('/', $args));
  619. $response->send();
  620. System::shutDown();
  621. }
  622. // check if there are remaining arguments
  623. if ($args) {
  624. // try the first argument as a module
  625. $modinfo = ModUtil::getInfoFromName($args[0]);
  626. if ($modinfo) {
  627. array_shift($args);
  628. }
  629. }
  630. // if that fails maybe it's a theme
  631. if ($args && !$modinfo) {
  632. $themeinfo = ThemeUtil::getInfo(ThemeUtil::getIDFromName($args[0]));
  633. if ($themeinfo) {
  634. self::queryStringSetVar('theme', $themeinfo['name']);
  635. // now shift the vars and continue as before
  636. array_shift($args);
  637. if ($args) {
  638. $modinfo = ModUtil::getInfoFromName($args[0]);
  639. if ($modinfo) {
  640. array_shift($args);
  641. }
  642. }
  643. }
  644. }
  645. // if there are parameters (not homepage)
  646. // try to see if there's a default shortURLs module
  647. if ($args && !$modinfo) {
  648. // add the default module handler into the code
  649. $modinfo = ModUtil::getInfoFromName(self::getVar('shorturlsdefaultmodule'));
  650. }
  651. }
  652. // check if there is a module and a custom url handler for it
  653. // if not decode the url using the default handler
  654. if ($modinfo && $modinfo['type'] != 0) {
  655. // prepare the arguments to the module handler
  656. array_unshift($args, ''); // support for 1.2- empty parameter due the initial explode
  657. array_unshift($args, $modinfo['url']);
  658. // set the REQUEST parameters
  659. self::queryStringSetVar('module', $modinfo['name']);
  660. // the user.function name can be the second argument string, set a default
  661. // later the custom module handler (if exists) must setup a new one if needed
  662. self::queryStringSetVar('type', 'user');
  663. if (isset($args[2])) {
  664. self::queryStringSetVar('func', $args[2]);
  665. } else {
  666. self::queryStringSetVar('func', 'index');
  667. }
  668. if (!ModUtil::apiFunc($modinfo['name'], 'user', 'decodeurl', array('vars' => $args))) {
  669. // any remaining arguments are specific to the module
  670. $argscount = count($args);
  671. for ($i = 3; $i < $argscount; $i = $i + 2) {
  672. if (isset($args[$i]) && isset($args[$i + 1])) {
  673. self::queryStringSetVar($args[$i], urldecode($args[$i + 1]));
  674. }
  675. }
  676. }
  677. }
  678. }
  679. }
  680. /**
  681. * Add a variable/value pair into the query string.
  682. *
  683. * Really the _GET superglobal.
  684. * This API also adds the variable to the _REQUEST superglobal for consistency.
  685. *
  686. * @param string $name Name of the variable to set.
  687. * @param mixed $value Value to set.
  688. *
  689. * @return bool True if successful, false otherwise.
  690. */
  691. public static function queryStringSetVar($name, $value)
  692. {
  693. if (!isset($name)) {
  694. return false;
  695. }
  696. // add the variable into the get superglobal
  697. $res = preg_match('/(.*)\[(.*)\]/i', $name, $match);
  698. if ($res != 0) {
  699. // possibly an array entry in the form a[0] or a[0][1] or a[0][1][2]
  700. parse_str($match[0], $data);
  701. foreach ($data as $k => $v) {
  702. if (is_array($v)) {
  703. foreach ($v as $kk => $vv) {
  704. if (is_array($vv)) {
  705. foreach ($vv as $kkk => $vvv) {
  706. if (is_array($vvv)) {
  707. foreach ($vvv as $kkkk => $vvvv) {
  708. $_REQUEST[$k][$kk][$kkk][$kkkk] = $_GET[$k][$kk][$kkk][$kkkk] = $value;
  709. }
  710. } else {
  711. $_REQUEST[$k][$kk][$kkk] = $_GET[$k][$kk][$kkk] = $value;
  712. }
  713. }
  714. } else {
  715. $_REQUEST[$k][$kk] = $_GET[$k][$kk] = $value;
  716. }
  717. }
  718. } else {
  719. $_REQUEST[$k] = $_GET[$k] = $value;
  720. }
  721. }
  722. } else {
  723. $_REQUEST[$name] = $_GET[$name] = $value;
  724. }
  725. return true;
  726. }
  727. /**
  728. * Shutdown.
  729. *
  730. * Gracefully shut down the framework (traps all exit and die calls),
  731. * Function halts execution.
  732. *
  733. * @param mixed $exit_param String or integer params to pass to the exit function.
  734. *
  735. * @return void
  736. */
  737. public static function shutDown($exit_param = '')
  738. {
  739. // we must deliberately cause the session to close down because if we
  740. // rely on PHP to do so after an exit is called, the framework gets shutdown
  741. // by PHP and no longer functions correctly.
  742. session_write_close();
  743. // do the exit
  744. if (empty($exit_param)) {
  745. exit();
  746. } else {
  747. exit($exit_param);
  748. }
  749. }
  750. /**
  751. * Installer running check.
  752. *
  753. * @return boolean
  754. */
  755. public static function isInstalling()
  756. {
  757. return (bool)defined('_ZINSTALLVER');
  758. }
  759. /**
  760. * Check if upgrader is running.
  761. *
  762. * @return boolean True if upgrade.php is running, otherwise false.
  763. */
  764. public static function isUpgrading()
  765. {
  766. return array_key_exists('_ZikulaUpgrader', $GLOBALS);
  767. }
  768. /**
  769. * Legacy prefilters check.
  770. *
  771. * @return boolean
  772. */
  773. public static function hasLegacyTemplates()
  774. {
  775. return false;
  776. }
  777. /**
  778. * Development mode enabled check.
  779. *
  780. * @return boolean
  781. */
  782. public static function isDevelopmentMode()
  783. {
  784. if (!isset($GLOBALS['ZConfig']['System']['development'])) {
  785. return false;
  786. }
  787. return (bool)$GLOBALS['ZConfig']['System']['development'];
  788. }
  789. /**
  790. * Get a system error template.
  791. *
  792. * @param string $templateFile File name of the system error template.
  793. *
  794. * @return string Template file path.
  795. */
  796. public static function getSystemErrorTemplate($templateFile)
  797. {
  798. $templatePath = ZIKULA_ROOT."/system/Theme/Resources/views/system/$templateFile";
  799. $override = Zikula_View::getTemplateOverride($templatePath);
  800. if ($override !== false) {
  801. return $override;
  802. } else {
  803. return $templatePath;
  804. }
  805. }
  806. }