/** * Goes trough the access matching rules and returns the access match. * The returned match is an associative array with: * name => string Name of the siteaccess (same as folder name) * type => int The constant that represent the matching used * uri_part => array(string) List of path elements that was used in start of url for the match * * @since 4.4 * @param eZURI $uri * @param string $host * @param string(numeric) $port * @param string $file Example '/index.php' * @return array */ public static function match( eZURI $uri, $host, $port = 80, $file = '/index.php' ) { eZDebugSetting::writeDebug( 'kernel-siteaccess', array( 'uri' => $uri, 'host' => $host, 'port' => $port, 'file' => $file ), __METHOD__ ); $ini = eZINI::instance(); if ( $ini->hasVariable( 'SiteAccessSettings', 'StaticMatch' ) ) { $match = $ini->variable( 'SiteAccessSettings', 'StaticMatch' ); if ( $match != '' ) { $access = array( 'name' => $match, 'type' => eZSiteAccess::TYPE_STATIC, 'uri_part' => array() ); return $access; } } list( $siteAccessList, $order ) = $ini->variableMulti( 'SiteAccessSettings', array( 'AvailableSiteAccessList', 'MatchOrder' ) ); $access = array( 'name' => $ini->variable( 'SiteSettings', 'DefaultAccess' ), 'type' => eZSiteAccess::TYPE_DEFAULT, 'uri_part' => array() ); if ( $order == 'none' ) return $access; $order = $ini->variableArray( 'SiteAccessSettings', 'MatchOrder' ); // Change the default type to eZSiteAccess::TYPE_URI if we're using URI MatchOrder. // This is to keep backward compatiblity with the ezurl operator. ezurl has since // rev 4949 added default siteaccess to generated URLs, even when there is // no siteaccess in the current URL. if ( in_array( 'uri', $order ) ) { $access['type'] = eZSiteAccess::TYPE_URI; } foreach ( $order as $matchprobe ) { $name = ''; $type = ''; $match_type = ''; $uri_part = array(); switch( $matchprobe ) { case 'servervar': { if ( $serversiteaccess = eZSys::serverVariable( $ini->variable( 'SiteAccessSettings', 'ServerVariableName' ), true ) ) { $access['name'] = $serversiteaccess; $access['type'] = eZSiteAccess::TYPE_SERVER_VAR; return $access; } else continue; } break; case 'port': { if ( $ini->hasVariable( 'PortAccessSettings', $port ) ) { $access['name'] = $ini->variable( 'PortAccessSettings', $port ); $access['type'] = eZSiteAccess::TYPE_PORT; return $access; } else continue; } break; case 'uri': { $type = eZSiteAccess::TYPE_URI; $match_type = $ini->variable( 'SiteAccessSettings', 'URIMatchType' ); if ( $match_type == 'map' ) { if ( $ini->hasVariable( 'SiteAccessSettings', 'URIMatchMapItems' ) ) { $match_item = $uri->element( 0 ); $matchMapItems = $ini->variableArray( 'SiteAccessSettings', 'URIMatchMapItems' ); foreach ( $matchMapItems as $matchMapItem ) { $matchMapURI = $matchMapItem[0]; $matchMapAccess = $matchMapItem[1]; if ( $access['name'] == $matchMapAccess and in_array( $matchMapAccess, $siteAccessList ) ) { $uri_part = array( $matchMapURI ); } if ( $matchMapURI == $match_item and in_array( $matchMapAccess, $siteAccessList ) ) { $uri->increase( 1 ); $uri->dropBase(); $access['name'] = $matchMapAccess; $access['type'] = $type; $access['uri_part'] = array( $matchMapURI ); return $access; } } } } else if ( $match_type == 'element' ) { $match_index = $ini->variable( 'SiteAccessSettings', 'URIMatchElement' ); $elements = $uri->elements( false ); $elements = array_slice( $elements, 0, $match_index ); $name = implode( '_', $elements ); $uri_part = $elements; } else if ( $match_type == 'text' ) { $match_item = $uri->elements(); $matcher_pre = $ini->variable( 'SiteAccessSettings', 'URIMatchSubtextPre' ); $matcher_post = $ini->variable( 'SiteAccessSettings', 'URIMatchSubtextPost' ); } else if ( $match_type == 'regexp' ) { $match_item = $uri->elements(); $matcher = $ini->variable( 'SiteAccessSettings', 'URIMatchRegexp' ); $match_num = $ini->variable( 'SiteAccessSettings', 'URIMatchRegexpItem' ); } else continue; } break; case 'host': { $type = eZSiteAccess::TYPE_HTTP_HOST; $match_type = $ini->variable( 'SiteAccessSettings', 'HostMatchType' ); $match_item = $host; if ( $match_type == 'map' ) { if ( $ini->hasVariable( 'SiteAccessSettings', 'HostMatchMapItems' ) ) { $matchMapItems = $ini->variableArray( 'SiteAccessSettings', 'HostMatchMapItems' ); foreach ( $matchMapItems as $matchMapItem ) { $matchMapHost = $matchMapItem[0]; $matchMapAccess = $matchMapItem[1]; if ( $matchMapHost == $host ) { $access['name'] = $matchMapAccess; $access['type'] = $type; return $access; } } } } else if ( $match_type == 'element' ) { $match_index = $ini->variable( 'SiteAccessSettings', 'HostMatchElement' ); $match_arr = explode( '.', $match_item ); $name = $match_arr[$match_index]; } else if ( $match_type == 'text' ) { $matcher_pre = $ini->variable( 'SiteAccessSettings', 'HostMatchSubtextPre' ); $matcher_post = $ini->variable( 'SiteAccessSettings', 'HostMatchSubtextPost' ); } else if ( $match_type == 'regexp' ) { $matcher = $ini->variable( 'SiteAccessSettings', 'HostMatchRegexp' ); $match_num = $ini->variable( 'SiteAccessSettings', 'HostMatchRegexpItem' ); } else continue; } break; case 'host_uri': { $type = eZSiteAccess::TYPE_HTTP_HOST_URI; if ( $ini->hasVariable( 'SiteAccessSettings', 'HostUriMatchMapItems' ) ) { $uriString = $uri->elements(); $matchMapItems = $ini->variableArray( 'SiteAccessSettings', 'HostUriMatchMapItems' ); $defaultHostMatchMethod = $ini->variable( 'SiteAccessSettings', 'HostUriMatchMethodDefault' ); foreach ( $matchMapItems as $matchMapItem ) { $matchHost = $matchMapItem[0]; $matchURI = $matchMapItem[1]; $matchAccess = $matchMapItem[2]; $matchHostMethod = isset( $matchMapItem[3] ) ? $matchMapItem[3] : $defaultHostMatchMethod; if ( $matchURI !== '' && strpos($uriString, $matchURI) !== 0 ) continue; switch( $matchHostMethod ) { case 'strict': { $hasHostMatch = ( $matchHost === $host ); } break; case 'start': { $hasHostMatch = ( strpos($host, $matchHost) === 0 ); } break; case 'end': { $hasHostMatch = ( strstr($host, $matchHost) === $matchHost ); } break; case 'part': { $hasHostMatch = ( strpos($host, $matchHost) !== false ); } break; default: { $hasHostMatch = false; eZDebug::writeError( "Unknown host_uri host match: $matchHostMethod", "access" ); } break; } if ( $hasHostMatch ) { if ( $matchURI !== '' ) { $matchURIFolders = explode( '/', $matchURI ); $uri->increase( count( $matchURIFolders ) ); $uri->dropBase(); $access['uri_part'] = $matchURIFolders; } $access['name'] = $matchAccess; $access['type'] = $type; return $access; } } } } break; case 'index': { $type = eZSiteAccess::TYPE_INDEX_FILE; $match_type = $ini->variable( 'SiteAccessSettings', 'IndexMatchType' ); $match_item = $file; if ( $match_type == 'element' ) { $match_index = $ini->variable( 'SiteAccessSettings', 'IndexMatchElement' ); $match_pos = strpos( $match_item, '.php' ); if ( $match_pos !== false ) { $match_item = substr( $match_item, 0, $match_pos ); $match_arr = explode( '_', $match_item ); $name = $match_arr[$match_index]; } } else if ( $match_type == 'text' ) { $matcher_pre = $ini->variable( 'SiteAccessSettings', 'IndexMatchSubtextPre' ); $matcher_post = $ini->variable( 'SiteAccessSettings', 'IndexMatchSubtextPost' ); } else if ( $match_type == 'regexp' ) { $matcher = $ini->variable( 'SiteAccessSettings', 'IndexMatchRegexp' ); $match_num = $ini->variable( 'SiteAccessSettings', 'IndexMatchRegexpItem' ); } else continue; } break; default: { eZDebug::writeError( "Unknown access match: $matchprobe", "access" ); } break; } if ( $match_type == 'regexp' ) $name = self::matchRegexp( $match_item, $matcher, $match_num ); else if ( $match_type == 'text' ) $name = self::matchText( $match_item, $matcher_pre, $matcher_post ); if ( isset( $name ) && $name != '' ) { $name = preg_replace( array( '/[^a-zA-Z0-9]+/', '/_+/', '/^_/', '/_$/' ), array( '_', '_', '', '' ), $name ); if ( in_array( $name, $siteAccessList ) ) { if ( $type == eZSiteAccess::TYPE_URI ) { if ( $match_type == 'element' ) { $uri->increase( $match_index ); $uri->dropBase(); } else if ( $match_type == 'regexp' ) { $uri->setURIString( $match_item ); } else if ( $match_type == 'text' ) { $uri->setURIString( $match_item ); } } $access['type'] = $type; $access['name'] = $name; $access['uri_part'] = $uri_part; return $access; } } } return $access; }
/** * Goes trough the access matching rules and returns the access match. * The returned match is an associative array with: * name => string Name of the siteaccess (same as folder name) * type => int The constant that represent the matching used * uri_part => array(string) List of path elements that was used in start of url for the match * * @since 4.4 * @param eZURI $uri * @param string $host * @param string(numeric) $port * @param string $file Example '/index.php' * @return array */ public static function match(eZURI $uri, $host, $port = 80, $file = '/index.php') { eZDebugSetting::writeDebug('kernel-siteaccess', array('uri' => $uri, 'host' => $host, 'port' => $port, 'file' => $file), __METHOD__); $ini = eZINI::instance(); if ($ini->hasVariable('SiteAccessSettings', 'StaticMatch')) { $match = $ini->variable('SiteAccessSettings', 'StaticMatch'); if ($match != '') { $access = array('name' => $match, 'type' => eZSiteAccess::TYPE_STATIC, 'uri_part' => array()); return $access; } } list($siteAccessList, $order) = $ini->variableMulti('SiteAccessSettings', array('AvailableSiteAccessList', 'MatchOrder')); $access = array('name' => $ini->variable('SiteSettings', 'DefaultAccess'), 'type' => eZSiteAccess::TYPE_DEFAULT, 'uri_part' => array()); if ($order == 'none') { return $access; } $order = $ini->variableArray('SiteAccessSettings', 'MatchOrder'); // Change the default type to eZSiteAccess::TYPE_URI if we're using URI MatchOrder. // This is to keep backward compatiblity with the ezurl operator. ezurl has since // rev 4949 added default siteaccess to generated URLs, even when there is // no siteaccess in the current URL. if (in_array('uri', $order)) { $access['type'] = eZSiteAccess::TYPE_URI; } foreach ($order as $matchprobe) { $name = ''; $type = ''; $match_type = ''; $uri_part = array(); switch ($matchprobe) { case 'servervar': if ($serversiteaccess = eZSys::serverVariable($ini->variable('SiteAccessSettings', 'ServerVariableName'), true)) { $access['name'] = $serversiteaccess; $access['type'] = eZSiteAccess::TYPE_SERVER_VAR; return $access; } else { continue; } break; case 'port': if ($ini->hasVariable('PortAccessSettings', $port)) { $access['name'] = $ini->variable('PortAccessSettings', $port); $access['type'] = eZSiteAccess::TYPE_PORT; return $access; } else { continue; } break; case 'uri': $type = eZSiteAccess::TYPE_URI; $match_type = $ini->variable('SiteAccessSettings', 'URIMatchType'); if ($match_type == 'map') { if ($ini->hasVariable('SiteAccessSettings', 'URIMatchMapItems')) { $match_item = $uri->element(0); $matchMapItems = $ini->variableArray('SiteAccessSettings', 'URIMatchMapItems'); foreach ($matchMapItems as $matchMapItem) { $matchMapURI = $matchMapItem[0]; $matchMapAccess = $matchMapItem[1]; if ($access['name'] == $matchMapAccess and in_array($matchMapAccess, $siteAccessList)) { $uri_part = array($matchMapURI); } if ($matchMapURI == $match_item and in_array($matchMapAccess, $siteAccessList)) { $uri->increase(1); $uri->dropBase(); $access['name'] = $matchMapAccess; $access['type'] = $type; $access['uri_part'] = array($matchMapURI); return $access; } } } } else { if ($match_type == 'element') { $match_index = $ini->variable('SiteAccessSettings', 'URIMatchElement'); $elements = $uri->elements(false); $elements = array_slice($elements, 0, $match_index); $name = implode('_', $elements); $uri_part = $elements; } else { if ($match_type == 'text') { $match_item = $uri->elements(); $matcher_pre = $ini->variable('SiteAccessSettings', 'URIMatchSubtextPre'); $matcher_post = $ini->variable('SiteAccessSettings', 'URIMatchSubtextPost'); } else { if ($match_type == 'regexp') { $match_item = $uri->elements(); $matcher = $ini->variable('SiteAccessSettings', 'URIMatchRegexp'); $match_num = $ini->variable('SiteAccessSettings', 'URIMatchRegexpItem'); } else { continue; } } } } break; case 'host': $type = eZSiteAccess::TYPE_HTTP_HOST; $match_type = $ini->variable('SiteAccessSettings', 'HostMatchType'); $match_item = $host; if ($match_type == 'map') { if ($ini->hasVariable('SiteAccessSettings', 'HostMatchMapItems')) { $matchMapItems = $ini->variableArray('SiteAccessSettings', 'HostMatchMapItems'); foreach ($matchMapItems as $matchMapItem) { $matchMapHost = $matchMapItem[0]; $matchMapAccess = $matchMapItem[1]; if ($matchMapHost == $host) { $access['name'] = $matchMapAccess; $access['type'] = $type; return $access; } } } } else { if ($match_type == 'element') { $match_index = $ini->variable('SiteAccessSettings', 'HostMatchElement'); $match_arr = explode('.', $match_item); $name = $match_arr[$match_index]; } else { if ($match_type == 'text') { $matcher_pre = $ini->variable('SiteAccessSettings', 'HostMatchSubtextPre'); $matcher_post = $ini->variable('SiteAccessSettings', 'HostMatchSubtextPost'); } else { if ($match_type == 'regexp') { $matcher = $ini->variable('SiteAccessSettings', 'HostMatchRegexp'); $match_num = $ini->variable('SiteAccessSettings', 'HostMatchRegexpItem'); } else { continue; } } } } break; case 'host_uri': $type = eZSiteAccess::TYPE_HTTP_HOST_URI; if ($ini->hasVariable('SiteAccessSettings', 'HostUriMatchMapItems')) { $uriString = $uri->elements(); $matchMapItems = $ini->variableArray('SiteAccessSettings', 'HostUriMatchMapItems'); $defaultHostMatchMethod = $ini->variable('SiteAccessSettings', 'HostUriMatchMethodDefault'); foreach ($matchMapItems as $matchMapItem) { $matchHost = $matchMapItem[0]; $matchURI = $matchMapItem[1]; $matchAccess = $matchMapItem[2]; $matchHostMethod = isset($matchMapItem[3]) ? $matchMapItem[3] : $defaultHostMatchMethod; if ($matchURI !== '' && !preg_match("@^{$matchURI}\\b@", $uriString)) { continue; } switch ($matchHostMethod) { case 'strict': $hasHostMatch = $matchHost === $host; break; case 'start': $hasHostMatch = strpos($host, $matchHost) === 0; break; case 'end': $hasHostMatch = strstr($host, $matchHost) === $matchHost; break; case 'part': $hasHostMatch = strpos($host, $matchHost) !== false; break; default: $hasHostMatch = false; eZDebug::writeError("Unknown host_uri host match: {$matchHostMethod}", "access"); break; } if ($hasHostMatch) { if ($matchURI !== '') { $matchURIFolders = explode('/', $matchURI); $uri->increase(count($matchURIFolders)); $uri->dropBase(); $access['uri_part'] = $matchURIFolders; } $access['name'] = $matchAccess; $access['type'] = $type; return $access; } } } break; case 'index': $type = eZSiteAccess::TYPE_INDEX_FILE; $match_type = $ini->variable('SiteAccessSettings', 'IndexMatchType'); $match_item = $file; if ($match_type == 'element') { $match_index = $ini->variable('SiteAccessSettings', 'IndexMatchElement'); $match_pos = strpos($match_item, '.php'); if ($match_pos !== false) { $match_item = substr($match_item, 0, $match_pos); $match_arr = explode('_', $match_item); $name = $match_arr[$match_index]; } } else { if ($match_type == 'text') { $matcher_pre = $ini->variable('SiteAccessSettings', 'IndexMatchSubtextPre'); $matcher_post = $ini->variable('SiteAccessSettings', 'IndexMatchSubtextPost'); } else { if ($match_type == 'regexp') { $matcher = $ini->variable('SiteAccessSettings', 'IndexMatchRegexp'); $match_num = $ini->variable('SiteAccessSettings', 'IndexMatchRegexpItem'); } else { continue; } } } break; default: eZDebug::writeError("Unknown access match: {$matchprobe}", "access"); break; } if ($match_type == 'regexp') { $name = self::matchRegexp($match_item, $matcher, $match_num); } else { if ($match_type == 'text') { $name = self::matchText($match_item, $matcher_pre, $matcher_post); } } if (isset($name) && $name != '') { $nameClean = self::washName($name); if (in_array($nameClean, $siteAccessList)) { if ($nameClean !== $name) { if (!$ini->hasVariable('SiteAccessSettings', 'NormalizeSANames') || $ini->variable('SiteAccessSettings', 'NormalizeSANames') == 'enabled') { $name = $nameClean; if ($ini->hasVariable('SiteAccessSettings', 'RedirectOnNormalize') && $ini->variable('SiteAccessSettings', 'RedirectOnNormalize') == 'enabled') { header($_SERVER['SERVER_PROTOCOL'] . " 301 Moved Permanently"); header("Status: 301 Moved Permanently"); $uriSlice = $uri->URIArray; array_shift($uriSlice); $newUri = $name . '/' . implode('/', $uriSlice); $location = eZSys::indexDir() . "/" . eZURI::encodeIRI($newUri); header("Location: " . $location); eZExecution::cleanExit(); } } } if ($type == eZSiteAccess::TYPE_URI) { if ($match_type == 'element') { $uri->increase($match_index); $uri->dropBase(); } else { if ($match_type == 'regexp') { $uri->setURIString($match_item); } else { if ($match_type == 'text') { $uri->setURIString($match_item); } } } } $access['type'] = $type; $access['name'] = $name; $access['uri_part'] = $uri_part; return $access; } } } return $access; }