/** * 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])); } } } } } }
private function validate_menu($array) { /* * Menu should be an array of arrays: * [id] = array( * [lang] = array ( * [data][lang] = [lang] * [data][parent] = exist * ) * ) */ if (!is_array($array)) { return false; } $ids = array_keys($array); $ids[] = 0; foreach ($array as $id => $node) { if (!is_numeric($id) || !is_array($node)) { return false; } foreach ($node as $lang => $data) { if (!ZLanguage::isLangParam($lang) || !is_array($data) || empty($data['name']) || !ZLanguage::isLangParam($data['lang']) || !in_array($data['parent'],$ids)){ return false; } } } return true; }
/** * 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); }
public function onKernelRequest(GetResponseEvent $event) { if (!$event->isMasterRequest()) { return; } if (\System::isInstalling()) { return; } $request = $event->getRequest(); if ($request->attributes->has('_controller')) { // routing is already done return; } /** * It is possible the code below will throw an exception. The absence of a try/catch block here * allows this exception to 'bubble up' to the exception handler. * @see \Zikula\Bundle\CoreBundle\EventListener\ExceptionListener */ if ($request->isXmlHttpRequest()) { $this->ajax($event); } $module = $request->attributes->get('_zkModule'); $type = $request->attributes->get('_zkType', 'user'); $func = $request->attributes->get('_zkFunc', 'index'); $arguments = $request->attributes->get('_zkArgs'); // get module information $modinfo = ModUtil::getInfoFromName($module); if (!$module) { // module could not be filtered from url. $path = $event->getRequest()->getPathInfo(); if ($path == '' || $path == '/') { $isAllowedNonModulePage = true; } else { $customentrypoint = System::getVar('entrypoint'); $root = empty($customentrypoint) ? 'index.php' : $customentrypoint; // get base path to work out our current url $parsedURL = parse_url($request->getRequestUri()); // strip any unwanted content from the provided URL $toBeStripped = array($request->getBasePath(), "{$root}"); $path = str_replace($toBeStripped, '', $parsedURL['path']); $path = trim($path, '/'); $args = explode('/', rtrim($path, '/')); // if only arg is a lang param, then allow this Uri $isAllowedNonModulePage = count($args) == 1 && \ZLanguage::isLangParam($args[0]) && in_array($args[0], \ZLanguage::getInstalledLanguages()); } if ($isAllowedNonModulePage) { // we have a static homepage $this->setResponse($event, new Response('')); } else { throw new NotFoundHttpException(__('Page not found.')); } } else { if (!$modinfo) { throw new NotFoundHttpException(__('Page not found.')); } // call the requested/homepage module $moduleBundle = ModUtil::getModule($module); if (null !== $moduleBundle) { $return = ModUtil::func($modinfo['name'], $type, $func); } else { $return = ModUtil::func($modinfo['name'], $type, $func, $arguments); } if (false === $return) { // hack for BC since modules currently use ModUtil::func without expecting exceptions - drak. throw new NotFoundHttpException(__('Page not found.')); } else { if (true === $return) { // controllers should not return boolean anymore, this is BC for the time being. $response = new PlainResponse(); } else { if (false === $return instanceof Response) { $response = new Response($return); } else { $response = $return; } } $this->setResponse($event, $response); } } }