# ApplicationUrl.class.php

Go to the documentation of this file.

    00001 <?php
    00002 /***************************************************************************
    00003  *   Copyright (C) 2007-2009 by Ivan Y. Khvostishkov                       *
    00004  *                                                                         *
    00005  *   This program is free software; you can redistribute it and/or modify  *
    00006  *   it under the terms of the GNU Lesser General Public License as        *
    00007  *   published by the Free Software Foundation; either version 3 of the    *
    00008  *   License, or (at your option) any later version.                       *
    00009  *                                                                         *
    00010  ***************************************************************************/
    00011
    00017     class ApplicationUrl
    00018     {
    00019         protected $base             = null;
    00020
    00021         protected $applicationScope = array();
    00022         protected $userScope            = array();
    00023         protected $navigationScope  = array();
    00024
    00025         protected $argSeparator     = null;
    00026
    00027         protected $navigationSchema = null;
    00028
    00029         protected $absolute         = false;
    00030
    00034         public static function create()
    00035         {
    00036             return new self;
    00037         }
    00038
    00042         public function setBase(HttpUrl $base)
    00043         {
    00044             $this->base = $base;
    00045
    00046             return $this;
    00047         }
    00048
    00052         public function getBase()
    00053         {
    00054             return $this->base;
    00055         }
    00056
    00060         public function setAbsolute($absolute)
    00061         {
    00062             $this->absolute = $absolute;
    00063
    00064             return $this;
    00065         }
    00066
    00067         public function isAbsolute()
    00068         {
    00069             return $this->absolute;
    00070         }
    00071
    00075         public function setNavigationSchema(ScopeNavigationSchema $schema)
    00076         {
    00077             $this->navigationSchema = $schema;
    00078
    00079             return $this;
    00080         }
    00081
    00085         public function getNavigationSchema()
    00086         {
    00087             return $this->navigationSchema;
    00088         }
    00089
    00093         public function addApplicationScope($scope)
    00094         {
    00095             Assert::isArray($scope);
    00096
    00097             $this->applicationScope = ArrayUtils::mergeRecursiveUnique(
    00098                 $this->applicationScope, $scope
    00099             );
    00100
    00101             return $this;
    00102         }
    00103
    00107         public function addUserScope($userScope)
    00108         {
    00109             Assert::isArray($userScope);
    00110
    00111             $this->userScope = ArrayUtils::mergeRecursiveUnique(
    00112                 $this->userScope, $userScope
    00113             );
    00114
    00115             return $this;
    00116         }
    00117
    00121         public function dropFromUserScope($key)
    00122         {
    00123             if (isset($this->userScope[$key]))
    00124                 $this->userScope[$key] = null;
    00125
    00126             return $this;
    00127         }
    00128
    00129         public function getUserScope()
    00130         {
    00131             return $this->userScope;
    00132         }
    00133
    00137         public function setPath($path)
    00138         {
    00139             if (!$this->navigationSchema)
    00140                 throw new WrongStateException(
    00141                     'charly says always set navigation schema'
    00142                     .' before you go off somewhere'
    00143                 );
    00144
    00145             $scope = $this->navigationSchema->getScope($path);
    00146
    00147             if ($scope === null)
    00148                 throw new WrongArgumentException(
    00149                     '404: not found'
    00150                 );
    00151
    00152             $this->navigationScope = $scope;
    00153
    00154             return $this;
    00155         }
    00156
    00160         public function setPathByRequestUri($requestUri, $normalize = true)
    00161         {
    00162             if (!$this->base)
    00163                 throw new WrongStateException(
    00164                     'base url must be set first'
    00165                 );
    00166
    00167             $currentUrl = GenericUri::create()->
    00168                 parse($requestUri);
    00169
    00170             if (!$currentUrl->isValid())
    00171                 throw new WrongArgumentException(
    00172                     'wtf? request uri is invalid'
    00173                 );
    00174
    00175             if ($normalize)
    00176                 $currentUrl->normalize();
    00177
    00178             $path = $currentUrl->getPath();
    00179
    00180             // paranoia
    00181             if (!$path || ($path[0] !== '/'))
    00182                 $path = '/'.$path;
    00183
    00184             if (strpos($path, $this->base->getPath()) !== 0)
    00185                 throw new WrongArgumentException(
    00186                     'left parts of path and base url does not match: '
    00187                     ."$path vs. ".$this->base->getPath()
    00188                 );
    00189
    00190             $actualPath = substr($path, strlen($this->base->getPath()));
    00191
    00192             return $this->setPath($actualPath);
    00193         }
    00194
    00195         public function getNavigationScope()
    00196         {
    00197             return $this->navigationScope;
    00198         }
    00199
    00200         public function getArgSeparator()
    00201         {
    00202             if (!$this->argSeparator)
    00203                 return ini_get('arg_separator.output');
    00204             else
    00205                 return $this->argSeparator;
    00206         }
    00207
    00211         public function setArgSeparator($argSeparator)
    00212         {
    00213             $this->argSeparator = $argSeparator;
    00214
    00215             return $this;
    00216         }
    00217
    00218         public function currentHref(
    00219             $additionalScope = array(),
    00220             $absolute = null
    00221         )
    00222         {
    00223             return $this->scopeHref(
    00224                 ArrayUtils::mergeRecursiveUnique(
    00225                     $this->userScope, $additionalScope
    00226                 ),
    00227                 $absolute
    00228             );
    00229         }
    00230
    00231         public function scopeHref($scope, $absolute = null)
    00232         {
    00233             Assert::isArray($scope);
    00234
    00235             // href scope may override navigation scope
    00236             $actualScope = ArrayUtils::mergeRecursiveUnique(
    00237                 $this->navigationScope, $scope
    00238             );
    00239
    00240             return $this->cleanHref($actualScope, $absolute);
    00241         }
    00242
    00243         public function cleanHref($scope, $absolute = null)
    00244         {
    00245             Assert::isArray($scope);
    00246
    00247             $path = $this->navigationSchema
    00248                 ? $this->navigationSchema->extractPath($scope)
    00249                 : null;
    00250
    00251             return $this->href($path.'?'.$this->buildQuery($scope), $absolute);
    00252         }
    00253
    00254         public function baseHref($absolute = null)
    00255         {
    00256             return $this->href(null, $absolute);
    00257         }
    00258
    00259         public function poorReference($url)
    00260         {
    00261             Assert::isNotNull($this->base, 'set base url first');
    00262
    00263             $parsedUrl = HttpUrl::create()->parse($url);
    00264
    00265             return $this->base->transform($parsedUrl);
    00266         }
    00267
    00268         public function href($url, $absolute = null)
    00269         {
    00270             if ($absolute === null)
    00271                 $absolute = $this->absolute;
    00272
    00273             $result = $this->poorReference($url);
    00274
    00275             if ($this->applicationScope)
    00276                 $result->appendQuery(
    00277                     $this->buildQuery($this->applicationScope),
    00278                     $this->getArgSeparator()
    00279                 );
    00280
    00281             $result->normalize();
    00282
    00283             if ($result->getQuery() === '')
    00284                 $result->setQuery(null);
    00285
    00286             if ($absolute)
    00287                 return $result->toString();
    00288             else
    00289                 return $result->toStringFromRoot();
    00290         }
    00291
    00292         public function absoluteHref($url)
    00293         {
    00294             return $this->href($url, true);
    00295         }
    00296
    00297         public function getUserQueryVars()
    00298         {
    00299             return $this->getQueryVars($this->userScope);
    00300         }
    00301
    00302         public function getApplicationQueryVars()
    00303         {
    00304             return $this->getQueryVars($this->applicationScope);
    00305         }
    00306
    00307         protected function getQueryVars($scope)
    00308         {
    00309             $queryParts = explode(
    00310                 $this->getArgSeparator(),
    00311                 $this->buildQuery($scope)
    00312             );
    00313
    00314             $result = array();
    00315
    00316             foreach ($queryParts as $queryPart) {
    00317                 if (!$queryPart)
    00318                     continue;
    00319
    00320                 list($key, $value) = explode('=', $queryPart, 2);
    00321
    00322                 $result[$key] = $value;
    00323             }
    00324
    00325             return $result;
    00326         }
    00327
    00328         protected function buildQuery($scope)
    00329         {
    00330             return http_build_query(
    00331                 $scope, null, $this->getArgSeparator()
    00332             );
    00333         }
    00334     }
    00335 ?>