function smarty_modifier_zikularoutesmodulePathToString($path, \Zikula\RoutesModule\Entity\RouteEntity $route) { $options = $route->getOptions(); $prefix = ''; if (isset($options['i18n_prefix'])) { $prefix = '/' . $options['i18n_prefix']; } if (!isset($options['i18n']) || $options['i18n']) { $languages = ZLanguage::getInstalledLanguages(); $isRequiredLangParam = ZLanguage::isRequiredLangParam(); if (!$isRequiredLangParam) { $defaultLanguage = System::getVar('language_i18n'); unset($languages[array_search($defaultLanguage, $languages)]); } if (count($languages) > 0) { $prefix = ($isRequiredLangParam ? "/" : "{/") . implode('|', $languages) . ($isRequiredLangParam ? "" : "}"); } } $prefix = \DataUtil::formatForDisplay($prefix); $path = \DataUtil::formatForDisplay($route->getPathWithBundlePrefix()); $container = \ServiceUtil::getManager(); $path = preg_replace_callback('#%(.*?)%#', function ($matches) use($container) { return "<abbr title=\"" . \DataUtil::formatForDisplay($matches[0]) . "\">" . \DataUtil::formatForDisplay($container->getParameter($matches[1])) . "</abbr>"; }, $path); $defaults = $route->getDefaults(); $requirements = $route->getRequirements(); $dom = ZLanguage::getModuleDomain('ZikulaRoutesModule'); $path = preg_replace_callback('#{(.*?)}#', function ($matches) use($container, $defaults, $requirements, $dom) { $title = ""; if (isset($defaults[$matches[1]])) { $title .= __f('Default: %s', array(\DataUtil::formatForDisplay($defaults[$matches[1]])), $dom); } if (isset($requirements[$matches[1]])) { if ($title != "") { $title .= " | "; } $title .= __f('Requirement: %s', array(\DataUtil::formatForDisplay($requirements[$matches[1]])), $dom); } if ($title == "") { return $matches[0]; } return "<abbr title=\"{$title}\">" . $matches[0] . "</abbr>"; }, $path); return "{$prefix}<strong>{$path}</strong>"; }
/** * Decode the path string into a set of variable/value pairs. * * This API works in conjunction with the new short urls * system to extract a path based variable set into the Get, Post * and request superglobals. * A sample path is /modname/function/var1:value1. * * @return void */ public static function queryStringDecode() { if (self::isInstalling()) { return; } // get our base parameters to work out if we need to decode the url $module = FormUtil::getPassedValue('module', null, 'GETPOST', FILTER_SANITIZE_STRING); $func = FormUtil::getPassedValue('func', null, 'GETPOST', FILTER_SANITIZE_STRING); $type = FormUtil::getPassedValue('type', null, 'GETPOST', FILTER_SANITIZE_STRING); // check if we need to decode the url if (self::getVar('shorturls') && (empty($module) && empty($type) && empty($func))) { // user language is not set at this stage $lang = System::getVar('language_i18n', ''); $customentrypoint = self::getVar('entrypoint'); $expectEntrypoint = !self::getVar('shorturlsstripentrypoint'); $root = empty($customentrypoint) ? 'index.php' : $customentrypoint; // check if we hit baseurl, e.g. domain.com/ and if we require the language URL // then we should redirect to the language URL. if (ZLanguage::isRequiredLangParam() && self::getCurrentUrl() == self::getBaseUrl()) { $uri = $expectEntrypoint ? "{$root}/{$lang}" : "{$lang}"; self::redirect(self::getBaseUrl() . $uri); self::shutDown(); } // check if entry point is part of the URL expectation. If so throw error if it's not present // since this URL is technically invalid. if ($expectEntrypoint && strpos(self::getCurrentUrl(), self::getBaseUrl() . $root) !== 0) { $protocol = System::serverGetVar('SERVER_PROTOCOL'); header("{$protocol} 404 Not Found"); echo __('The requested URL cannot be found'); system::shutDown(); } if (!$expectEntrypoint && self::getCurrentUrl() == self::getBaseUrl() . $root) { self::redirect(self::getHomepageUrl()); self::shutDown(); } if (!$expectEntrypoint && strpos(self::getCurrentUrl(), self::getBaseUrl() . $root) === 0) { $protocol = System::serverGetVar('SERVER_PROTOCOL'); header("{$protocol} 404 Not Found"); echo __('The requested URL cannot be found'); system::shutDown(); } // get base path to work out our current url $parsedURL = parse_url(self::getCurrentUri()); // strip any unwanted content from the provided URL $tobestripped = array(self::getBaseUri(), "{$root}"); $path = str_replace($tobestripped, '', $parsedURL['path']); $path = trim($path, '/'); // split the path into a set of argument strings $args = explode('/', rtrim($path, '/')); // ensure that each argument is properly decoded foreach ($args as $k => $v) { $args[$k] = urldecode($v); } $modinfo = null; $frontController = $expectEntrypoint ? "{$root}/" : ''; // if no arguments present if (!$args[0] && !isset($_GET['lang']) && !isset($_GET['theme'])) { // we are in the homepage, checks if language code is forced if (ZLanguage::getLangUrlRule() && $lang) { // and redirect then $response = new RedirectResponse(self::getCurrentUrl() . "/{$lang}"); $respose->send(); System::shutDown(); } } else { // check the existing shortURL parameters // validation of the first parameter as language code if (ZLanguage::isLangParam($args[0]) && in_array($args[0], ZLanguage::getInstalledLanguages())) { // checks if the language is not enforced and this url is passing the default lang if (!ZLanguage::getLangUrlRule() && $lang == $args[0]) { // redirects the passed arguments without the default site language array_shift($args); foreach ($args as $k => $v) { $args[$k] = urlencode($v); } $response = new RedirectResponse(self::getBaseUrl() . $frontController . ($args ? implode('/', $args) : '')); $respose->send(); System::shutDown(); } self::queryStringSetVar('lang', $args[0]); array_shift($args); } elseif (ZLanguage::getLangUrlRule()) { // if the lang is forced, redirects the passed arguments plus the lang foreach ($args as $k => $v) { $args[$k] = urlencode($v); } $langTheme = isset($_GET['theme']) ? "{$lang}/{$_GET['theme']}" : $lang; $response = new RedirectResponse(self::getBaseUrl() . $frontController . $langTheme . '/' . implode('/', $args)); $response->send(); System::shutDown(); } // check if there are remaining arguments if ($args) { // try the first argument as a module $modinfo = ModUtil::getInfoFromName($args[0]); if ($modinfo) { array_shift($args); } } // if that fails maybe it's a theme if ($args && !$modinfo) { $themeinfo = ThemeUtil::getInfo(ThemeUtil::getIDFromName($args[0])); if ($themeinfo) { self::queryStringSetVar('theme', $themeinfo['name']); // now shift the vars and continue as before array_shift($args); if ($args) { $modinfo = ModUtil::getInfoFromName($args[0]); if ($modinfo) { array_shift($args); } } } } // if there are parameters (not homepage) // try to see if there's a default shortURLs module if ($args && !$modinfo) { // add the default module handler into the code $modinfo = ModUtil::getInfoFromName(self::getVar('shorturlsdefaultmodule')); } } // check if there is a module and a custom url handler for it // if not decode the url using the default handler if ($modinfo && $modinfo['type'] != 0) { // prepare the arguments to the module handler array_unshift($args, ''); // support for 1.2- empty parameter due the initial explode array_unshift($args, $modinfo['url']); // set the REQUEST parameters self::queryStringSetVar('module', $modinfo['name']); // the user.function name can be the second argument string, set a default // later the custom module handler (if exists) must setup a new one if needed self::queryStringSetVar('type', 'user'); if (isset($args[2])) { self::queryStringSetVar('func', $args[2]); } else { self::queryStringSetVar('func', 'index'); } if (!ModUtil::apiFunc($modinfo['name'], 'user', 'decodeurl', array('vars' => $args))) { // any remaining arguments are specific to the module $argscount = count($args); for ($i = 3; $i < $argscount; $i = $i + 2) { if (isset($args[$i]) && isset($args[$i + 1])) { self::queryStringSetVar($args[$i], urldecode($args[$i + 1])); } } } } } }
/** * Generate a module function URL. * * If the module is non-API compliant (type 1) then * a) $func is ignored. * b) $type=admin will generate admin.php?module=... and $type=user will generate index.php?name=... * * @param string $modname The name of the module. * @param string $type The type of function to run. * @param string $func The specific function to run. * @param array $args The array of arguments to put on the URL. * @param boolean|null $ssl Set to constant null,true,false $ssl = true not $ssl = 'true' null - leave the current status untouched, * true - create a ssl url, false - create a non-ssl url. * @param string $fragment The framgment to target within the URL. * @param boolean|null $fqurl Fully Qualified URL. True to get full URL, eg for Redirect, else gets root-relative path unless SSL. * @param boolean $forcelongurl Force ModUtil::url to not create a short url even if the system is configured to do so. * @param boolean|string $forcelang Force the inclusion of the $forcelang or default system language in the generated url. * * @return string Absolute URL for call. */ public static function url($modname, $type = null, $func = null, $args = array(), $ssl = null, $fragment = null, $fqurl = null, $forcelongurl = false, $forcelang = false) { // define input, all numbers and booleans to strings $modname = isset($modname) ? (string) $modname : ''; // note - when this legacy is to be removed, change method signature $type = null to $type making it a required argument. if (!$type) { if (System::isLegacyMode()) { $type = 'user'; LogUtil::log('ModUtil::url() - $type is a required argument, you must specify it explicitly.', E_USER_DEPRECATED); } else { throw new UnexpectedValueException('ModUtil::url() - $type is a required argument, you must specify it explicitly.'); } } // note - when this legacy is to be removed, change method signature $func = null to $func making it a required argument. if (!$func) { if (System::isLegacyMode()) { $func = 'main'; LogUtil::log('ModUtil::url() - $func is a required argument, you must specify it explicitly.', E_USER_DEPRECATED); } else { throw new UnexpectedValueException('ModUtil::url() - $func is a required argument, you must specify it explicitly.'); } } // validate if (!System::varValidate($modname, 'mod')) { return null; } // Remove from 1.4 if (System::isLegacyMode() && $modname == 'Modules') { LogUtil::log(__('Warning! "Modules" module has been renamed to "Extensions". Please update your ModUtil::url() or {modurl} calls with $module = "Extensions".')); $modname = 'Extensions'; } //get the module info $modinfo = self::getInfo(self::getIDFromName($modname)); // set the module name to the display name if this is present if (isset($modinfo['url']) && !empty($modinfo['url'])) { $modname = rawurlencode($modinfo['url']); } $entrypoint = System::getVar('entrypoint'); $host = System::serverGetVar('HTTP_HOST'); if (empty($host)) { return false; } $baseuri = System::getBaseUri(); $https = System::serverGetVar('HTTPS'); $shorturls = System::getVar('shorturls'); $shorturlsstripentrypoint = System::getVar('shorturlsstripentrypoint'); $shorturlsdefaultmodule = System::getVar('shorturlsdefaultmodule'); // Don't encode URLs with escaped characters, like return urls. foreach ($args as $v) { if (!is_array($v)) { if (strpos($v, '%') !== false) { $shorturls = false; break; } } else { foreach ($v as $vv) { if (is_array($vv)) { foreach ($vv as $vvv) { if (!is_array($vvv) && strpos($vvv, '%') !== false) { $shorturls = false; break; } } } elseif (strpos($vv, '%') !== false) { $shorturls = false; break; } } break; } } // Setup the language code to use if (is_array($args) && isset($args['lang'])) { if (in_array($args['lang'], ZLanguage::getInstalledLanguages())) { $language = $args['lang']; } unset($args['lang']); } if (!isset($language)) { $language = ZLanguage::getLanguageCode(); } $language = $forcelang && in_array($forcelang, ZLanguage::getInstalledLanguages()) ? $forcelang : $language; // Only produce full URL when HTTPS is on or $ssl is set $siteRoot = ''; if (isset($https) && $https == 'on' || $ssl != null || $fqurl == true) { $protocol = 'http' . ($https == 'on' && $ssl !== false || $ssl === true ? 's' : ''); $secureDomain = System::getVar('secure_domain'); $siteRoot = $protocol . '://' . ($secureDomain != '' ? $secureDomain : $host . $baseuri) . '/'; } // Only convert type=user. Exclude links that append a theme parameter if ($shorturls && $type == 'user' && $forcelongurl == false) { if (isset($args['theme'])) { $theme = $args['theme']; unset($args['theme']); } // Module-specific Short URLs $url = self::apiFunc($modinfo['name'], 'user', 'encodeurl', array('modname' => $modname, 'type' => $type, 'func' => $func, 'args' => $args)); if (empty($url)) { // depending on the settings, we have generic directory based short URLs: // [language]/[module]/[function]/[param1]/[value1]/[param2]/[value2] // [module]/[function]/[param1]/[value1]/[param2]/[value2] $vars = ''; foreach ($args as $k => $v) { if (is_array($v)) { foreach ($v as $k2 => $w) { if (is_numeric($w) || !empty($w)) { // we suppress '', but allow 0 as value (see #193) $vars .= '/' . $k . '[' . $k2 . ']/' . $w; // &$k[$k2]=$w } } } elseif (is_numeric($v) || !empty($v)) { // we suppress '', but allow 0 as value (see #193) $vars .= "/{$k}/{$v}"; // &$k=$v } } $url = $modname . ($vars || $func != 'main' ? "/{$func}{$vars}" : ''); } if ($modinfo && $shorturlsdefaultmodule && $shorturlsdefaultmodule == $modinfo['name']) { $pattern = '/^' . preg_quote($modinfo['url'], '/') . '\\//'; $url = preg_replace($pattern, '', $url); } if (isset($theme)) { $url = rawurlencode($theme) . '/' . $url; } // add language param to short url if (ZLanguage::isRequiredLangParam() || $forcelang) { $url = "{$language}/" . $url; } if (!$shorturlsstripentrypoint) { $url = "{$entrypoint}/{$url}" . (!empty($query) ? '?' . $query : ''); } else { $url = "{$url}" . (!empty($query) ? '?' . $query : ''); } } else { // Regular stuff $urlargs = "module={$modname}&type={$type}&func={$func}"; // add lang param to URL if (ZLanguage::isRequiredLangParam() || $forcelang) { $urlargs .= "&lang={$language}"; } $url = "{$entrypoint}?{$urlargs}"; if (!is_array($args)) { return false; } else { foreach ($args as $key => $value) { if (is_array($value)) { foreach ($value as $l => $w) { if (is_numeric($w) || !empty($w)) { // we suppress '', but allow 0 as value (see #193) if (is_array($w)) { foreach ($w as $m => $n) { if (is_numeric($n) || !empty($n)) { $n = strpos($n, '%') !== false ? $n : urlencode($n); $url .= "&{$key}" . "[{$l}][{$m}]={$n}"; } } } else { $w = strpos($w, '%') !== false ? $w : urlencode($w); $url .= "&{$key}" . "[{$l}]={$w}"; } } } } elseif (is_numeric($value) || !empty($value)) { // we suppress '', but allow 0 as value (see #193) $w = strpos($value, '%') !== false ? $value : urlencode($value); $url .= "&{$key}={$value}"; } } } } if (isset($fragment)) { $url .= '#' . $fragment; } return $siteRoot . $url; }
/** * Decode the path string into a set of variable/value pairs. * * This API works in conjunction with the new short urls * system to extract a path based variable set into the Get, Post * and request superglobals. * A sample path is /modname/function/var1:value1. * * @return void */ public static function queryStringDecode(Request $request) { if (self::isInstalling()) { return; } // Try to match a route first. // Make sure we have the correct request context. $requestContext = ServiceUtil::get('router.request_context'); $requestContext->fromRequest($request); /** @var \Symfony\Component\Routing\Matcher\RequestMatcherInterface $router */ $router = ServiceUtil::get('router'); try { $parameters = $router->matchRequest($request); if (!isset($parameters['_zkModule']) || !isset($parameters['_zkType']) || !isset($parameters['_zkFunc'])) { // This might be the web profiler or another native bundle. return; } // The following block is needed as long as not every url is a route. To be removed when all legacy routing // is removed. if ($parameters['_route'] == 'zikularoutesmodule_redirectingcontroller_removetrailingslash') { $pathInfo = $request->getPathInfo(); $requestUri = $request->getRequestUri(); // Check if url without slash exists. If it doesn't exist, it will throw an exception which is caught // by the try->catch below. $url = str_replace($pathInfo, rtrim($pathInfo, ' /'), $requestUri); $router->match($url); } $modname = strtolower($parameters['_zkModule']); $type = strtolower($parameters['_zkType']); $func = strtolower($parameters['_zkFunc']); if (isset($parameters['_locale'])) { $lang = strtolower($parameters['_locale']); $request->query->set('lang', $lang); self::queryStringSetVar('lang', $lang); } $request->attributes->set('_zkModule', $modname); $request->attributes->set('_zkType', $type); $request->attributes->set('_zkFunc', $func); $request->query->set('module', $modname); $request->query->set('type', $type); $request->query->set('func', $func); self::queryStringSetVar('module', $modname); self::queryStringSetVar('type', $type); self::queryStringSetVar('func', $func); return; } catch (ResourceNotFoundException $e) { // This is an old style url. } catch (RouteNotFoundException $e) { // This is an old style url. } catch (MethodNotAllowedException $e) { // this is an old style url. } // get our base parameters to work out if we need to decode the url $module = FormUtil::getPassedValue('module', null, 'GETPOST', FILTER_SANITIZE_STRING); $func = FormUtil::getPassedValue('func', null, 'GETPOST', FILTER_SANITIZE_STRING); $type = FormUtil::getPassedValue('type', null, 'GETPOST', FILTER_SANITIZE_STRING); // check if we need to decode the url $shorturls = self::getVar('shorturls'); if ($shorturls && empty($module) && empty($type) && empty($func)) { // user language is not set at this stage $lang = self::getVar('language_i18n', ''); $customentrypoint = self::getVar('entrypoint'); $expectEntrypoint = !self::getVar('shorturlsstripentrypoint'); $root = empty($customentrypoint) ? 'index.php' : $customentrypoint; // check if we hit baseurl, e.g. domain.com/ and if we require the language URL // then we should redirect to the language URL. if (ZLanguage::isRequiredLangParam() && self::getCurrentUrl() == self::getBaseUrl()) { $uri = $expectEntrypoint ? "{$root}/{$lang}" : $lang; self::redirect(self::getBaseUrl() . $uri); self::shutDown(); } // check if entry point is part of the URL expectation. If so throw error if it's not present // since this URL is technically invalid. if ($expectEntrypoint && self::getCurrentUrl() != self::getBaseUrl() && strpos(self::getCurrentUrl(), self::getBaseUrl() . $root) !== 0) { $protocol = self::serverGetVar('SERVER_PROTOCOL'); header("{$protocol} 404 Not Found"); echo __('The requested URL cannot be found'); self::shutDown(); } if (!$expectEntrypoint && self::getCurrentUrl() == self::getBaseUrl() . $root) { self::redirect(self::getHomepageUrl(), array(), 302, true); self::shutDown(); } if (!$expectEntrypoint && strpos(self::getCurrentUrl(), self::getBaseUrl() . $root) === 0) { $protocol = self::serverGetVar('SERVER_PROTOCOL'); header("{$protocol} 404 Not Found"); echo __('The requested URL cannot be found'); self::shutDown(); } // get base path to work out our current url $parsedURL = parse_url(self::getCurrentUri()); // strip any unwanted content from the provided URL $tobestripped = array(self::getBaseUri(), "{$root}"); $path = str_replace($tobestripped, '', $parsedURL['path']); $path = trim($path, '/'); // split the path into a set of argument strings $args = explode('/', rtrim($path, '/')); // ensure that each argument is properly decoded foreach ($args as $k => $v) { $args[$k] = urldecode($v); } $modinfo = null; $frontController = $expectEntrypoint ? "{$root}/" : ''; // if no arguments present if (!$args[0] && !isset($_GET['lang']) && !isset($_GET['theme'])) { // we are in the homepage, checks if language code is forced if (ZLanguage::getLangUrlRule() && $lang) { // and redirect then self::redirect(self::getCurrentUrl() . "/{$lang}", array(), 302, true); self::shutDown(); } } else { // check the existing shortURL parameters // validation of the first parameter as language code if (ZLanguage::isLangParam($args[0]) && in_array($args[0], ZLanguage::getInstalledLanguages())) { // checks if the language is not enforced and this url is passing the default lang if (!ZLanguage::getLangUrlRule() && $lang == $args[0]) { // redirects the passed arguments without the default site language array_shift($args); foreach ($args as $k => $v) { $args[$k] = urlencode($v); } self::redirect(self::getBaseUrl() . $frontController . ($args ? implode('/', $args) : ''), array(), 302, true); self::shutDown(); } self::queryStringSetVar('lang', $args[0], $request); array_shift($args); } elseif (ZLanguage::getLangUrlRule()) { // if the lang is forced, redirects the passed arguments plus the lang foreach ($args as $k => $v) { $args[$k] = urlencode($v); } $langTheme = isset($_GET['theme']) ? "{$lang}/{$_GET['theme']}" : $lang; self::redirect(self::getBaseUrl() . $frontController . $langTheme . '/' . implode('/', $args), array(), 302, true); self::shutDown(); } // check if there are remaining arguments if ($args) { // try the first argument as a module $modinfo = ModUtil::getInfoFromName($args[0]); if ($modinfo) { array_shift($args); } } // if that fails maybe it's a theme if ($args && !$modinfo) { $themeinfo = ThemeUtil::getInfo(ThemeUtil::getIDFromName($args[0])); if ($themeinfo) { self::queryStringSetVar('theme', $themeinfo['name'], $request); $request->attributes->set('_theme', $themeinfo['name']); // now shift the vars and continue as before array_shift($args); if ($args) { $modinfo = ModUtil::getInfoFromName($args[0]); if ($modinfo) { array_shift($args); } } } } // if there are parameters (not homepage) // try to see if there's a default shortURLs module if ($args && !$modinfo) { // add the default module handler into the code $modinfo = ModUtil::getInfoFromName(self::getVar('shorturlsdefaultmodule')); } } // check if there is a module and a custom url handler for it // if not decode the url using the default handler if ($modinfo && $modinfo['type'] != 0) { // prepare the arguments to the module handler array_unshift($args, ''); // support for 1.2- empty parameter due the initial explode array_unshift($args, $modinfo['url']); // set the REQUEST parameters self::queryStringSetVar('module', $modinfo['name'], $request); // the user.function name can be the second argument string, set a default // later the custom module handler (if exists) must setup a new one if needed self::queryStringSetVar('type', 'user', $request); if (isset($args[2])) { self::queryStringSetVar('func', $args[2], $request); } else { self::queryStringSetVar('func', 'main', $request); } if (!ModUtil::apiFunc($modinfo['name'], 'user', 'decodeurl', array('vars' => $args))) { // any remaining arguments are specific to the module $argscount = count($args); for ($i = 3; $i < $argscount; $i = $i + 2) { if (isset($args[$i]) && isset($args[$i + 1])) { self::queryStringSetVar($args[$i], urldecode($args[$i + 1]), $request); } } } } } $module = ucfirst(FormUtil::getPassedValue('module', null, 'GETPOST', FILTER_SANITIZE_STRING)); $func = ucfirst(FormUtil::getPassedValue('func', null, 'GETPOST', FILTER_SANITIZE_STRING)); $type = ucfirst(FormUtil::getPassedValue('type', null, 'GETPOST', FILTER_SANITIZE_STRING)); $arguments = array(); if (!$module) { // set the start parameters $module = self::getVar('startpage'); $type = self::getVar('starttype'); $func = self::getVar('startfunc'); $args = explode(',', self::getVar('startargs')); foreach ($args as $arg) { if (!empty($arg)) { $argument = explode('=', $arg); $arguments[$argument[0]] = $argument[1]; } } } else { $arguments = $_GET; unset($arguments['module']); unset($arguments['type']); unset($arguments['func']); } if ($shorturls) { $request->query->replace($_GET); } $request->attributes->set('_zkModule', strtolower($module)); // legacy - this is how they are received originally $request->attributes->set('_zkType', strtolower($type)); // legacy - this is how they are received originally $request->attributes->set('_zkFunc', strtolower($func)); // legacy - this is how they are received originally $request->attributes->set('_zkArgs', $arguments); }