/** * For performance reasons this returns a stripped down info array with * just the slug, engine and id guaranteed to be present, NO title * @param mixed $url * @param mixed $remainder * @return mixed */ public static function getMatchingEnginePageInfo($url, &$remainder) { // The URL should match a_page, which should allow us to break the slug out and learn the // user's culture in a way that doesn't hardcode whether cultures are present and how etc. $routes = sfContext::getInstance()->getRouting()->getRoutes(); $culture = aTools::getUserCulture(); if (isset($routes['a_page'])) { $r = $routes['a_page']; $parameters = $r->matchesUrl($url); if ($parameters) { // Since we're not really visiting a_page the culture won't switch // if we don't visit some normal page in French before the engine page. // We resolve this by implementing the culture switch here if (isset($parameters['sf_culture'])) { $culture = $parameters['sf_culture']; $user = sfContext::getInstance()->getUser(); if ($user) { $user->setCulture($culture); } } } } // Engines won't work on sites where the CMS is not mounted at the root of the site // unless we examine the a_page route to determine a prefix. Generate the route properly // then lop off the controller name, if any $prefix = ''; $culturePrefix = ''; if (!isset(aPageTable::$dummyUrlCache[$culture])) { aPageTable::$dummyUrlCache[$culture] = sfContext::getInstance()->getRouting()->generate('a_page', array('slug' => 'dummy', 'sf_culture' => $culture), false); } $dummyUrl = aPageTable::$dummyUrlCache[$culture]; $rr = preg_quote(sfContext::getInstance()->getRequest()->getRelativeUrlRoot(), '/'); // The URL we're being asked to examine has already // lost its relative_root_url, so don't include $rr in // the prefix we attempt to remove // Tolerate and ignore a query string (which will be there if sf_culture is not prettified by the route) $re = "/^(\\/\\w+\\.php)?{$rr}(.*)\\/dummy(?:\\?.*)?\$/"; if (preg_match($re, $dummyUrl, $matches)) { $controllerPrefix = $matches[1]; $culturePrefix = $matches[2]; } aPageTable::$engineCachePagePrefix = $prefix; $url = preg_replace('/^' . preg_quote($prefix, '/') . '/', '', $url); // Now remove the culture prefix too so we don't fail to find the page $url = preg_replace('/^' . preg_quote($culturePrefix, '/') . '/', '', $url); // Moved caching after the rewrites, otherwise it never works for // interesting frontend controller names, URLs with cultures in them, etc. if ($url === aPageTable::$engineCacheUrl) { $remainder = aPageTable::$engineCacheRemainder; return aPageTable::$engineCachePageInfo; } $urls = array(); // Remove any query string $twig = preg_replace('/\\?.*$/', '', $url); while (true) { if ($twig === '/' || !strlen($twig)) { // Either we've been called for the home page, or we just // stripped the first slash and are now considering the home page $urls[] = '/'; break; } $urls[] = $twig; if (!preg_match('/^(.*)\\/[^\\/]+$/', $twig, $matches)) { break; } $twig = $matches[1]; } $pageInfo = Doctrine_Query::create()->select('p.*, length(p.slug) as len')->from('aPage p')->whereIn('p.slug', $urls)->andWhere('p.engine IS NOT NULL')->orderBy('len desc')->limit(1)->fetchOne(array(), Doctrine::HYDRATE_ARRAY); aPageTable::$engineCachePageInfo = $pageInfo; aPageTable::$engineCacheUrl = $url; aPageTable::$engineCacheRemainder = false; if ($pageInfo) { $remainder = substr($url, strlen($pageInfo['slug'])); aPageTable::$engineCacheRemainder = $remainder; return $pageInfo; } return false; }