|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // Definition of eZURI class 00004 // 00005 // Created on: <10-Apr-2002 13:47:41 amos> 00006 // 00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00008 // SOFTWARE NAME: eZ Publish 00009 // SOFTWARE RELEASE: 4.0.x 00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS 00011 // SOFTWARE LICENSE: GNU General Public License v2.0 00012 // NOTICE: > 00013 // This program is free software; you can redistribute it and/or 00014 // modify it under the terms of version 2.0 of the GNU General 00015 // Public License as published by the Free Software Foundation. 00016 // 00017 // This program is distributed in the hope that it will be useful, 00018 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 // GNU General Public License for more details. 00021 // 00022 // You should have received a copy of version 2.0 of the GNU General 00023 // Public License along with this program; if not, write to the Free 00024 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00025 // MA 02110-1301, USA. 00026 // 00027 // 00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00029 // 00030 00031 /*! 00032 \class eZURI ezuri.php 00033 \ingroup eZHTTP 00034 \brief Provides access to the HTTP uri 00035 00036 The URI can be accessed one element at a time with element() and elements() and 00037 can be iterated with increase() and the current index returned with index(). Moving 00038 the beginning and end is done with toBeginning() and toEnd(). 00039 The base can be retrieved with base() and the elements with elements(). 00040 00041 This class also supports the attribute system. 00042 00043 \note The index starts at 0 00044 */ 00045 00046 class eZURI 00047 { 00048 /*! 00049 Initializes with the URI string $uri. The URI string is split on / into an array. 00050 */ 00051 function eZURI( $uri ) 00052 { 00053 $this->setURIString( $uri ); 00054 } 00055 00056 /*! 00057 \static 00058 Decodes a path string which is in IRI format and returns the new path in the internal encoding. 00059 00060 More info on IRI here: http://www.w3.org/International/O-URL-and-ident.html 00061 */ 00062 static function decodeIRI( $str ) 00063 { 00064 $str = urldecode( $str ); // Decode %xx entries, we now have a utf-8 string 00065 $codec = eZTextCodec::instance( 'utf-8' ); // Make sure string is converted from utf-8 to internal encoding 00066 return $codec->convertString( $str ); 00067 } 00068 00069 /*! 00070 \static 00071 Encodes path string in internal encoding to a new string which conforms to the IRI specification. 00072 00073 More info on IRI here: http://www.w3.org/International/O-URL-and-ident.html 00074 */ 00075 static function encodeIRI( $str ) 00076 { 00077 $codec = eZTextCodec::instance( false, 'utf-8' ); 00078 $str = $codec->convertString( $str ); // Make sure the string is in utf-8 00079 $out = explode( "/", $str ); // Don't encode the slashes 00080 foreach ( $out as $i => $o ) 00081 { 00082 if ( preg_match( "#^[\(]([a-zA-Z0-9_]+)[\)]#", $o, $m ) ) 00083 { 00084 // Don't encode '(' and ')' in user parameters 00085 $out[$i] = '(' . urlencode( $m[1] ) . ')'; 00086 } 00087 else 00088 { 00089 $out[$i] = urlencode( $o ); // Let PHP do the rest 00090 } 00091 } 00092 $tmp = join( "/", $out ); 00093 // Don't encode '~' in URLs 00094 $tmp = str_replace( '%7E', '~', $tmp ); 00095 return $tmp; 00096 } 00097 00098 /*! 00099 \static 00100 Parse URL and encode/decode its path string. 00101 */ 00102 static function codecURL( $url, $encode ) 00103 { 00104 $originalLocale = setlocale( LC_CTYPE, "0" ); 00105 setlocale( LC_CTYPE, 'C' ); 00106 // Parse URL and encode the path. 00107 $data = parse_url( $url ); 00108 setlocale( LC_CTYPE, $originalLocale ); 00109 00110 if ( isset( $data['path'] ) ) 00111 { 00112 if ( $encode ) 00113 $data['path'] = eZURI::encodeIRI( $data['path'] ); // Make sure it is encoded to IRI format 00114 else 00115 $data['path'] = eZURI::decodeIRI( $data['path'] ); // Make sure it is dencoded to internal encoding 00116 } 00117 00118 // Reconstruct the URL 00119 $host = ''; 00120 $preHost = ''; 00121 if ( isset( $data['user'] ) ) 00122 { 00123 if ( isset( $data['pass'] ) ) 00124 $preHost .= $data['user'] . ':' . $data['pass'] . '@'; 00125 else 00126 $preHost .= $data['user'] . '@'; 00127 } 00128 if ( isset( $data['host'] ) ) 00129 { 00130 if ( isset( $data['port'] ) ) 00131 $host = $preHost . $data['host'] . ':' . $data['port']; 00132 else 00133 $host = $preHost . $data['host']; 00134 } 00135 $url = ''; 00136 if ( isset( $data['scheme'] ) ) 00137 $url = $data['scheme'] . '://' . $host; 00138 else if ( strlen( $host ) > 0 ) 00139 $url = '//' . $host; 00140 if ( isset( $data['path'] ) ) 00141 { 00142 $url .= $data['path']; 00143 } 00144 if ( isset( $data['query'] ) ) 00145 { 00146 $url .= '?' . $data['query']; 00147 } 00148 if ( isset( $data['fragment'] ) ) 00149 { 00150 $url .= '#' . $data['fragment']; 00151 } 00152 00153 return $url; 00154 } 00155 00156 /*! 00157 \static 00158 Encodes path string of URL in internal encoding to a new string which conforms to the IRI specification. 00159 */ 00160 static function encodeURL( $url ) 00161 { 00162 return eZURI::codecURL( $url, true ); 00163 } 00164 00165 /*! 00166 Decodes URL which has path string is in IRI format and returns the new URL with path in the internal encoding. 00167 */ 00168 static function decodeURL( $url ) 00169 { 00170 return eZURI::codecURL( $url, false ); 00171 } 00172 00173 /*! 00174 Sets the current URI string to $uri, the URI is then split into array elements 00175 and index reset to 1. 00176 */ 00177 function setURIString( $uri, $fullInitialize = true ) 00178 { 00179 if ( strlen( $uri ) > 0 and 00180 $uri[0] == '/' ) 00181 $uri = substr( $uri, 1 ); 00182 00183 $uri = eZURI::decodeIRI( $uri ); 00184 00185 $this->URI = $uri; 00186 $this->URIArray = explode( '/', $uri ); 00187 $this->Index = 0; 00188 00189 if ( $fullInitialize ) 00190 { 00191 $this->OriginalURI = $uri; 00192 $this->UserArray = array(); 00193 00194 //include_once( 'lib/ezutils/classes/ezini.php' ); 00195 $ini = eZINI::instance( 'template.ini' ); 00196 00197 if ( $ini->variable( 'ControlSettings', 'OldStyleUserVariables' ) == 'enabled' ) 00198 { 00199 foreach( array_keys( $this->URIArray ) as $key ) 00200 { 00201 if ( isset( $this->URIArray[$key] ) && preg_match( "(^[\(][a-zA-Z0-9_]+[\)])", $this->URIArray[$key] ) ) 00202 { 00203 $this->UserArray[substr( $this->URIArray[$key], 1, strlen( $this->URIArray[$key] ) - 2 )] = $this->URIArray[$key+1]; 00204 unset( $this->URIArray[$key] ); 00205 unset( $this->URIArray[$key+1] ); 00206 } 00207 } 00208 } 00209 else 00210 { 00211 unset( $paramName ); 00212 unset( $paramValue ); 00213 foreach( array_keys( $this->URIArray ) as $key ) 00214 { 00215 if ( isset( $this->URIArray[$key] ) ) 00216 { 00217 if ( preg_match( "/^[\(][a-zA-Z0-9_]+[\)]/", $this->URIArray[$key] ) ) 00218 { 00219 if ( isset( $paramName ) and isset( $paramValue ) ) 00220 { 00221 $this->UserArray[ $paramName ] = $paramValue; 00222 unset( $paramName ); 00223 unset( $paramValue ); 00224 } 00225 $paramName = substr( $this->URIArray[$key], 1, strlen( $this->URIArray[$key] ) - 2 ); 00226 if ( isset( $this->URIArray[$key+1] ) ) 00227 { 00228 $this->UserArray[ $paramName ] = $this->URIArray[$key+1]; 00229 unset( $this->URIArray[$key+1] ); 00230 } 00231 else 00232 $this->UserArray[ $paramName ] = ""; 00233 unset( $this->URIArray[$key] ); 00234 } 00235 else 00236 { 00237 if ( isset( $paramName ) ) 00238 { 00239 if ( !empty( $this->URIArray[$key] ) ) 00240 $this->UserArray[ $paramName ] .= '/' . $this->URIArray[$key]; 00241 unset( $this->URIArray[$key] ); 00242 } 00243 } 00244 } 00245 } 00246 } 00247 00248 // Remake the URI without any user parameters 00249 $this->URI = implode( '/', $this->URIArray ); 00250 00251 //include_once( 'lib/ezutils/classes/ezini.php' ); 00252 $ini = eZINI::instance( 'template.ini' ); 00253 if ( $ini->variable( 'ControlSettings', 'AllowUserVariables' ) == 'false' ) 00254 { 00255 $this->UserArray = array(); 00256 } 00257 // Convert filter string to current locale 00258 $this->convertFilterString(); 00259 } 00260 } 00261 00262 /*! 00263 \return the URI passed as to the object. 00264 \note the URI will not include the leading \c / if \a $withLeadingSlash is \c true. 00265 */ 00266 function uriString( $withLeadingSlash = false ) 00267 { 00268 $uri = $this->URI; 00269 if ( $withLeadingSlash ) 00270 $uri = "/$uri"; 00271 return $uri; 00272 } 00273 00274 /*! 00275 \return the URI passed to the object with user parameters (if any). 00276 \note the URI will not include the leading \c / if \a $withLeadingSlash is \c true. 00277 */ 00278 function originalURIString( $withLeadingSlash = false ) 00279 { 00280 $uri = $this->OriginalURI; 00281 if ( $withLeadingSlash ) 00282 $uri = "/$uri"; 00283 return $uri; 00284 } 00285 00286 /*! 00287 \return true if the URI is empty, ie it's equal to / or empty string. 00288 */ 00289 function isEmpty() 00290 { 00291 return $this->URI == '' or $this->URI == '/'; 00292 } 00293 00294 /*! 00295 \return the element at $index. 00296 If $relative is true the index is relative to the current index(). 00297 */ 00298 function element( $index = 0, $relative = true ) 00299 { 00300 $pos = $index; 00301 if ( $relative ) 00302 $pos += $this->Index; 00303 if ( isset( $this->URIArray[$pos] ) ) 00304 return $this->URIArray[$pos]; 00305 $ret = null; 00306 return $ret; 00307 } 00308 00309 /*! 00310 \return all elements as a string, this is all elements after the current index. 00311 If $as_text is false the returned item is an array. 00312 */ 00313 function elements( $as_text = true ) 00314 { 00315 $elements = array_slice( $this->URIArray, $this->Index ); 00316 if ( $as_text ) 00317 { 00318 $retValue = implode( '/', $elements ); 00319 return $retValue; 00320 } 00321 else 00322 return $elements; 00323 } 00324 00325 /*! 00326 Converts filter string to current locale. 00327 When an user types in browser url like: 00328 "/content/view/full/2/(namefilter)/a" 00329 'a' letter should be urldecoded and converted from utf-8 to current locale. 00330 */ 00331 function convertFilterString() 00332 { 00333 foreach ( array_keys( $this->UserArray ) as $paramKey ) 00334 { 00335 if ( $paramKey == 'namefilter' ) 00336 { 00337 $char = $this->UserArray[$paramKey]; 00338 $char = urldecode( $char ); 00339 00340 //include_once( 'lib/ezi18n/classes/eztextcodec.php' ); 00341 $codec = eZTextCodec::instance( 'utf-8', false ); 00342 if ( $codec ) 00343 $char = $codec->convertString( $char ); 00344 } 00345 } 00346 } 00347 00348 /* 00349 \return all user defined variables 00350 */ 00351 function userParameters() 00352 { 00353 return $this->UserArray; 00354 } 00355 00356 /*! 00357 Moves the index to the beginning. 00358 */ 00359 function toBeginning() 00360 { 00361 $this->Index = 0; 00362 } 00363 00364 /*! 00365 Moves the index to the end. 00366 */ 00367 function toEnd() 00368 { 00369 $this->Index = count( $this->URIArray ); 00370 } 00371 00372 /*! 00373 Moves the index 1 step up or $num if specified. 00374 */ 00375 function increase( $num = 1 ) 00376 { 00377 $this->Index += $num; 00378 if ( $this->Index < 0 ) 00379 $this->Index = 0; 00380 } 00381 00382 /*! 00383 Removes all elements below the current index, recreates the URI string 00384 and sets index to 0. 00385 */ 00386 function dropBase() 00387 { 00388 $elements = array_slice( $this->URIArray, $this->Index ); 00389 $this->URIArray = $elements; 00390 $this->URI = implode( '/', $this->URIArray ); 00391 $uri = $this->URI; 00392 foreach ( $this->UserArray as $name => $value ) 00393 { 00394 $uri .= '/(' . $name . ')/' . $value; 00395 } 00396 $this->OriginalURI = $uri; 00397 $this->Index = 0; 00398 } 00399 00400 /*! 00401 \return the current index. 00402 */ 00403 function index() 00404 { 00405 return $this->Index; 00406 } 00407 00408 /*! 00409 \return the base string or the base elements as an array if $as_text is true. 00410 \sa elements 00411 */ 00412 function base( $as_text = true ) 00413 { 00414 $elements = array_slice( $this->URIArray, 0, $this->Index ); 00415 if ( $as_text ) 00416 { 00417 $baseAsText = '/' . implode( '/', $elements ); 00418 return $baseAsText; 00419 } 00420 else 00421 return $elements; 00422 } 00423 00424 /*! 00425 Tries to match the base of $uri against this base and returns the result. 00426 A match is made if all elements of this object match the base elements of 00427 the $uri object, this means that $uri's base may be longer than this base but 00428 not shorter. 00429 \note $uri must be a eZURI object 00430 */ 00431 function matchBase( $uri ) 00432 { 00433 if ( !( $uri instanceof eZURI ) ) 00434 { 00435 return false; 00436 } 00437 if ( count( $this->URIArray ) == 0 or 00438 count( $uri->URIArray ) == 0 ) 00439 { 00440 return false; 00441 } 00442 for ( $i = 0; $i < count( $this->URIArray ); ++$i ) 00443 { 00444 if ( $this->URIArray[$i] != $uri->URIArray[$i] ) 00445 { 00446 return false; 00447 } 00448 } 00449 return true; 00450 } 00451 00452 /*! 00453 \return the attributes for this object. 00454 */ 00455 function attributes() 00456 { 00457 return array( 'element', 00458 'base', 00459 'tail', 00460 'index', 00461 'uri', 00462 'original_uri' ); 00463 } 00464 00465 /*! 00466 \return true if the attribute $attr exist. 00467 */ 00468 function hasAttribute( $attr ) 00469 { 00470 return in_array( $attr, $this->attributes() ); 00471 } 00472 00473 /*! 00474 \return the value for attribute $attr or null if it does not exist. 00475 */ 00476 function attribute( $attr ) 00477 { 00478 switch ( $attr ) 00479 { 00480 case 'element': 00481 return $this->element(); 00482 break; 00483 case 'tail': 00484 return $this->elements(); 00485 break; 00486 case 'base': 00487 return $this->base(); 00488 break; 00489 case 'index': 00490 return $this->index(); 00491 break; 00492 case 'uri': 00493 return $this->uriString(); 00494 break; 00495 case 'original_uri': 00496 return $this->originalURIString(); 00497 break; 00498 default: 00499 { 00500 eZDebug::writeError( "Attribute '$attr' does not exist", 'eZURI::attribute' ); 00501 return null; 00502 } break; 00503 } 00504 } 00505 00506 /*! 00507 \return the unique instance for the URI, if $uri is supplied it used as the global URI value. 00508 */ 00509 static function instance( $uri = false ) 00510 { 00511 // If $uri is false we assume the caller wants eZSys::requestURI() 00512 if ( $uri === false or $uri == eZSys::requestURI() ) 00513 { 00514 if ( !isset( $GLOBALS['eZURIRequestInstance'] ) ) 00515 { 00516 $GLOBALS['eZURIRequestInstance'] = new eZURI( eZSys::requestURI() ); 00517 } 00518 return $GLOBALS['eZURIRequestInstance']; 00519 } 00520 00521 return new eZURI( $uri ); 00522 } 00523 00524 /*! 00525 Implementation of an 'ezurl' template operator. 00526 Makes valid ez publish urls to use in links. 00527 */ 00528 static function transformURI( &$href, $ignoreIndexDir = false, $serverURL = 'relative' ) 00529 { 00530 if ( preg_match( "#^[a-zA-Z0-9]+:#", $href ) || substr( $href, 0, 2 ) == '//' ) 00531 return false; 00532 00533 if ( strlen( $href ) == 0 ) 00534 $href = '/'; 00535 else if ( $href[0] == '#' ) 00536 { 00537 $href = htmlspecialchars( $href ); 00538 return true; 00539 } 00540 else if ( $href[0] != '/' ) 00541 { 00542 $href = '/' . $href; 00543 } 00544 00545 //include_once( 'lib/ezutils/classes/ezsys.php' ); 00546 $sys = eZSys::instance(); 00547 $dir = !$ignoreIndexDir ? $sys->indexDir() : $sys->wwwDir(); 00548 $serverURL = $serverURL === 'full' ? $sys->serverURL() : '' ; 00549 $href = $serverURL . $dir . $href; 00550 if ( !$ignoreIndexDir ) 00551 { 00552 $href = preg_replace( "#^(//)#", "/", $href ); 00553 $href = preg_replace( "#(^.*)(/+)$#", "\$1", $href ); 00554 } 00555 $href = htmlspecialchars( $href ); 00556 00557 if ( $href == "" ) 00558 $href = "/"; 00559 00560 return true; 00561 } 00562 00563 /// The original URI string 00564 public $URI; 00565 /// The URI array 00566 public $URIArray; 00567 /// The current index 00568 public $Index; 00569 /// User defined template variables 00570 public $UserArray; 00571 }; 00572 00573 ?>