|
eZ Publish
[4.0]
|
00001 <?php 00002 /** 00003 * File containing the eZNamePatternResolver class 00004 * 00005 * @copyright Copyright (C) 2005-2008 eZ Systems AS. All rights reserved. 00006 * @license http://ez.no/licenses/gnu_gpl GNU GPL v2 00007 * @version //autogentag// 00008 * @package kernel 00009 * 00010 */ 00011 00012 /** 00013 * eZNamePatternResolver is a utility class for resolving object name and url alias patterns. 00014 * This code supports object name pattern groups. 00015 * 00016 * Syntax: 00017 * <code> 00018 * <attribute_identifier> 00019 * <attribute_identifier> <2nd-identifier> 00020 * User text <attribute_identifier>|(<2nd-identifier><3rd-identifier>) 00021 * </code> 00022 * 00023 * Example: 00024 * <code> 00025 * <nickname|(<firstname> <lastname>)> 00026 * </code> 00027 * 00028 * Tokens are looked up from left to right. If a match is found for the 00029 * leftmost token, the 2nd token will not be used. Tokens are representations 00030 * of atttributes. So a match means that that the current attribute has data. 00031 * 00032 * tokens are the class attribute identifiers which are used in the class 00033 * edit-interface. 00034 * 00035 * @package kernel 00036 * @version //autogentag// 00037 */ 00038 class eZNamePatternResolver 00039 { 00040 /** 00041 * Holds token groups 00042 * 00043 * @var array 00044 */ 00045 private $groupLookupTable; 00046 00047 /** 00048 * Contains the original name pattern entered 00049 * 00050 * @var string 00051 */ 00052 private $origNamePattern; 00053 00054 /** 00055 * Holds the filtered name pattern where token groups are replaced with 00056 * meta strings 00057 * 00058 * @var string 00059 */ 00060 private $namePattern; 00061 00062 /** 00063 * The content object which holds the attributes used to resolve name pattern. 00064 * 00065 * @var eZContentObject 00066 */ 00067 private $contentObject; 00068 00069 /** 00070 * Version number of the content object to fetch attributes from. 00071 * 00072 * @var int 00073 */ 00074 private $version; 00075 00076 /** 00077 * Contains the language locale for which to fetch attributes. 00078 * 00079 * @var string 00080 */ 00081 private $translation; 00082 00083 /** 00084 * Holds data fetched from content object attributes 00085 * 00086 * @var array(string=>string) 00087 */ 00088 private $attributeArray; 00089 00090 00091 /** 00092 * The string to use to signify group tokens. 00093 * 00094 * @var string 00095 */ 00096 private $metaString = 'EZMETAGROUP_'; 00097 00098 /** 00099 * Constructs a object to resolve $namePattern. $contentVersion and 00100 * $contentTranslation specify which version and translation respectively 00101 * of the content object to use. 00102 * 00103 * @param string $namePattern 00104 * @param eZContentObject $contentObject 00105 * @param int $contentVersion 00106 * @param string $contentTranslation 00107 */ 00108 public function __construct( $namePattern, $contentObject, $contentVersion = false, $contentTranslation = false ) 00109 { 00110 $this->origNamePattern = $namePattern; 00111 $this->contentObject = $contentObject; 00112 $this->version = $contentVersion; 00113 $this->translation = $contentTranslation; 00114 00115 $this->namePattern = $this->filterNamePattern( $namePattern); 00116 } 00117 00118 /** 00119 * Return the real name for an object name pattern 00120 * 00121 * @param string $namePattern 00122 * @return string 00123 */ 00124 public function resolveNamePattern() 00125 { 00126 // Fetch attributes for present identifiers 00127 $this->fetchContentAttributes(); 00128 00129 // Replace tokens with real values 00130 $objectName = $this->translatePattern(); 00131 00132 return $objectName; 00133 } 00134 00135 /** 00136 * Fetches the list of available class-identifiers in the token, and it 00137 * will only fetch the attributes which appear amongst the identifiers 00138 * found in tokens. 00139 * 00140 * @return void 00141 */ 00142 private function fetchContentAttributes() 00143 { 00144 $returnAttributeArray = array(); 00145 00146 $identifierArray = $this->getIdentifiers( $this->origNamePattern ); 00147 00148 $attributes = $this->contentObject->fetchAttributesByIdentifier( $identifierArray, $this->version, array( $this->translation ) ); 00149 00150 if ( is_array( $attributes ) ) 00151 { 00152 foreach ( $attributes as $attribute ) 00153 { 00154 $identifier = $attribute->contentClassAttributeIdentifier(); 00155 $returnAttributeArray[$identifier] = $attribute->title(); 00156 } 00157 } 00158 else 00159 { 00160 $returnAttributeArray = array(); 00161 } 00162 $this->attributeArray = $returnAttributeArray; 00163 } 00164 00165 00166 /** 00167 * Replaces tokens in the name pattern with their resolved values. 00168 * 00169 * @return string 00170 */ 00171 private function translatePattern() 00172 { 00173 $tokenArray = $this->extractTokens( $this->namePattern ); 00174 $objectName = $this->namePattern; 00175 00176 foreach( $tokenArray as $token ) 00177 { 00178 $string = $this->resolveToken( $token ); 00179 $objectName = str_replace( $token, $string, $objectName ); 00180 } 00181 00182 return $objectName; 00183 } 00184 00185 /** 00186 * Extract all tokens from $namePattern 00187 * 00188 * Example: 00189 * <code> 00190 * Text <token> more text ==> <token> 00191 * </code> 00192 * 00193 * @param string $namePattern 00194 * @return array 00195 */ 00196 private function extractTokens( $namePattern ) 00197 { 00198 $foundTokens = preg_match_all( "|<([^>]+)>|U", $namePattern, 00199 $tokenArray ); 00200 00201 return $tokenArray[0]; 00202 } 00203 00204 /** 00205 * Looks up the value $token should be replaced with and returns this as 00206 * a string. Meta strings denothing token groups are automatically 00207 * inferred. 00208 * 00209 * @param string $token 00210 * @return string 00211 */ 00212 private function resolveToken( $token ) 00213 { 00214 $replaceString = ""; 00215 $tokenParts = $this->tokenParts( $token ); 00216 00217 foreach ( $tokenParts as $tokenPart ) 00218 { 00219 if ( $this->isTokenGroup( $tokenPart ) ) 00220 { 00221 $groupTokenArray = $this->extractTokens( $this->groupLookupTable[$tokenPart] ); 00222 $replaceString = $this->groupLookupTable[$tokenPart]; 00223 00224 foreach ( $groupTokenArray as $groupToken ) 00225 { 00226 $replaceString = str_replace( $groupToken, $this->resolveToken( $groupToken ), $replaceString ); 00227 } 00228 // We want to stop after the first matching token part / identifier is found 00229 // <id1|id2> if id1 has a value, id2 will not be used. 00230 // In this case id1 or id1 is a token group. 00231 break; 00232 } 00233 else 00234 { 00235 if ( array_key_exists( $tokenPart, $this->attributeArray ) and $this->attributeArray[$tokenPart] !== '' and $this->attributeArray[$tokenPart] !== NULL ) 00236 { 00237 $replaceString = $this->attributeArray[$tokenPart]; 00238 // We want to stop after the first matching token part / identifier is found 00239 // <id1|id2> if id1 has a value, id2 will not be used. 00240 break; 00241 } 00242 } 00243 } 00244 return $replaceString; 00245 } 00246 00247 00248 /** 00249 * Checks whether $identifier is a placeholder for a token group. 00250 * 00251 * @param string $identifier 00252 * @return void 00253 */ 00254 private function isTokenGroup( $identifier ) 00255 { 00256 if ( strpos( $identifier, $this->metaString ) === false ) 00257 { 00258 return false; 00259 } 00260 return true; 00261 } 00262 00263 /** 00264 * Return the different constituents of $token in an array. 00265 * The normal case here is that the different identifiers within one token 00266 * will be tokenized and returned. 00267 * 00268 * Example: 00269 * <code> 00270 * "<title|text>" ==> array( 'title', 'text' ) 00271 * </code> 00272 * 00273 * @param string $token 00274 * @return array 00275 */ 00276 private function tokenParts( $token ) 00277 { 00278 $tokenParts = preg_split( '#\W#', $token, -1, PREG_SPLIT_NO_EMPTY ); 00279 return $tokenParts; 00280 } 00281 00282 /** 00283 * Builds a lookup / translation table for groups in the $namePattern. 00284 * The groups are referenced with a generated meta-token in the original 00285 * name pattern. 00286 * 00287 * Returns intermediate name pattern where groups are replaced with meta- 00288 * tokens. 00289 * 00290 * @param string $namePattern 00291 * @return string 00292 */ 00293 private function filterNamePattern( $namePattern ) 00294 { 00295 $retNamePattern = ""; 00296 $foundGroups = preg_match_all( "/[<|\|](\(.+\))[\||>]/U", $namePattern, $groupArray ); 00297 00298 if ( $foundGroups ) 00299 { 00300 $i = 0; 00301 foreach ( $groupArray[1] as $group ) 00302 { 00303 // Create meta-token for group 00304 $metaToken = $this->metaString . $i; 00305 00306 // Insert the group with its placeholder token 00307 $retNamePattern = str_replace( $group, $metaToken, $namePattern ); 00308 00309 // Remove the pattern "(" ")" from the tokens 00310 $group = str_replace( array( '(', ')' ), '', $group ); 00311 00312 $this->groupLookupTable[$metaToken] = $group; 00313 ++$i; 00314 } 00315 return $retNamePattern; 00316 } 00317 return $namePattern; 00318 00319 } 00320 00321 /** 00322 * Returns all identifiers from all tokens in the name pattern. 00323 * 00324 * @param string $patternString 00325 * @return array 00326 */ 00327 private function getIdentifiers( $patternString ) 00328 { 00329 $allTokens = '#<(.*)>#U'; 00330 $identifiers = '#\W#'; 00331 00332 $tmpArray = array(); 00333 preg_match_all( $allTokens, $patternString, $matches ); 00334 00335 foreach ( $matches[1] as $match ) 00336 { 00337 $tmpArray[] = preg_split( $identifiers, $match, -1, PREG_SPLIT_NO_EMPTY ); 00338 } 00339 00340 $retArray = array(); 00341 foreach ( $tmpArray as $matchGroup ) 00342 { 00343 if ( is_array( $matchGroup ) ) 00344 { 00345 foreach ( $matchGroup as $item ) 00346 { 00347 $retArray[] = $item; 00348 } 00349 } 00350 else 00351 { 00352 $retArray[] = $matchGroup; 00353 } 00354 } 00355 return $retArray; 00356 } 00357 } 00358 ?>