[ Index ]

PHP Cross Reference of Akelos Framework

title

Body

[close]

/ -> AkRouter.php (source)

   1  <?php
   2  /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
   3  
   4  // +----------------------------------------------------------------------+
   5  // | Akelos Framework - http://www.akelos.org                             |
   6  // +----------------------------------------------------------------------+
   7  // | Copyright (c) 2002-2006, Akelos Media, S.L.  & Bermi Ferrer Martinez |
   8  // | Released under the GNU Lesser General Public License, see LICENSE.txt|
   9  // +----------------------------------------------------------------------+
  10  
  11  ak_compat('http_build_query');
  12  
  13  /**
  14   * Native PHP URL rewriting for the Akelos Framework.
  15   * 
  16   * @package ActionController
  17   * @subpackage Request
  18   * @author Bermi Ferrer <bermi a.t akelos c.om>
  19   * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
  20   * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
  21   */
  22  
  23  
  24  if(!defined('OPTIONAL')){
  25      define('OPTIONAL', false);
  26  }
  27  
  28  if(!defined('COMPULSORY')){
  29      define('COMPULSORY', true);
  30  }
  31  
  32  if(!defined('COMPULSORY_REGEX')){
  33      define('COMPULSORY_REGEX', '([^\/]+){1}');
  34  }
  35  
  36  
  37  
  38  
  39  /**
  40  * Native PHP URL rewriting for the Akelos Framework
  41  *
  42  * This class implements PHP based URL rewriting for the Akelos Framework, thus shifting the responsibility of URL parsing from the webserver to the Akelos Framework itself. This has been a requested feature for two primary reasons.
  43  *
  44  * - Not all webservers support rewriting. By moving this code to the core, the framework is able to function out of the box on almost all webservers.
  45  *
  46  * - A rewriting implementation in the Akelos Framework can also be used to generate custom URLs by linking it to the standard URL helpers such as url_for, link_to, and redirect_to.
  47  *
  48  * @author Bermi Ferrer <bermi a.t akelos d.t c.om>
  49  * @copyright Copyright (c) 2002-2005, Akelos Media, S.L. http://www.akelos.org
  50  * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
  51  */
  52  class AkRouter extends AkObject
  53  {
  54  
  55      /**
  56      * Routes setting container
  57      *
  58      * @see getRoutes
  59      * @access private
  60      * @var array $_loaded_routes
  61      */
  62      var $_loaded_routes = array();
  63  
  64  
  65      function __construct()
  66      {
  67          /**
  68          * We will try to guess if mod_rewrite is enabled.
  69          * Set AK_ENABLE_URL_REWRITE in your config 
  70          * to avoid the overhead this function causes
  71          */
  72          if(!defined('AK_ENABLE_URL_REWRITE') || (defined('AK_ENABLE_URL_REWRITE') && AK_ENABLE_URL_REWRITE !== false)){
  73              $this->_loadUrlRewriteSettings();
  74          }
  75      }
  76  
  77      /**
  78      * $this->_loaded_routes getter
  79      *
  80      * Use this method to get $this->_loaded_routes value
  81      *
  82      * @access public
  83      * @return array Returns Loaded Routes array.
  84      */
  85      function getRoutes()
  86      {
  87          return $this->_loaded_routes;
  88      }
  89  
  90  
  91      /**
  92      * Generates a custom URL, depending on current rewrite rules.
  93      *
  94      * Generates a custom URL, depending on current rewrite rules.
  95      *
  96      * @access public
  97      * @param    array    $params    An array with parameters to include in the url.
  98      * - <code>array('controller'=>'post','action'=>'view','id'=>'10')</code>
  99      * - <code>array('controller'=>'page','action'=>'view_page','webpage'=>'contact_us')</code>
 100      * @return string Having the following rewrite rules:
 101      * <code>
 102      * $Router =& new AkRouter();
 103      *
 104      * $Router->map('/setup/*config_settings',array('controller'=>'setup'));
 105      * $Router->map('/customize/*options/:action',array('controller'=>'themes','options'=>3));
 106      * $Router->map('/blog/:action/:id',array('controller'=>'post','action'=>'list','id'=>OPTIONAL),array('id'=>'/\d{1,}/'));
 107      * $Router->map('/:year/:month/:day', array('controller' => 'articles','action' => 'view_headlines','year' => COMPULSORY,'month' => 'all','day' => OPTIONAL) , array('year'=>'/(20){1}\d{2}/','month'=>'/((1)?\d{1,2}){2}/','day'=>'/(([1-3])?\d{1,2}){2}/'));
 108      * $Router->map('/:webpage', array('controller' => 'page', 'action' => 'view_page', 'webpage' => 'index'),array('webpage'=>'/(\w|_)+/'));
 109      * $Router->map('/', array('controller' => 'page', 'action' => 'view_page', 'webpage'=>'index'));
 110      * $Router->map('/:controller/:action/:id');
 111      * </code>
 112      *
 113      * We get the following results:
 114      *
 115      * <code>$Router->toUrl(array('controller'=>'page','action'=>'view_page','webpage'=>'contact_us'));</code>
 116      * Produces: /contact_us/
 117      *
 118      * <code>$Router->toUrl(array('controller'=>'page','action'=>'view_page','webpage'=>'index'));</code>
 119      * Produces: /
 120      *
 121      * <code>$Router->toUrl(array('controller'=>'post','action'=>'list','id'=>null));</code>
 122      * Produces: /blog/
 123      *
 124      * <code>$Router->toUrl(array('controller'=>'post','action'=>'view','id'=>null));</code>
 125      * Produces: /blog/view/
 126      *
 127      * <code>$Router->toUrl(array('controller'=>'post','action'=>'view','id'=>'10'));</code>
 128      * Produces: /blog/view/10/
 129      *
 130      * <code>$Router->toUrl(array('controller'=>'blog','action'=>'view','id'=>'newest'));</code>
 131      * Produces: /blog/view/newest/
 132      *
 133      * <code>$Router->toUrl(array('controller' => 'articles','action' => 'view_headlines','year' => '2005','month' => '10', 'day' => null));</code>
 134      * Produces: /2005/10/
 135      *
 136      * <code>$Router->toUrl(array('controller'</code> => 'articles','action' => 'view_headlines','year' => '2006','month' => 'all', 'day' => null));</code>
 137      * Produces: /2006/
 138      *
 139      * <code>$Router->toUrl(array('controller' => 'user','action' => 'list','id' => '12'));</code>
 140      * Produces: /user/list/12/
 141      *
 142      * <code>$Router->toUrl(array('controller' => 'setup','config_settings' => array('themes','clone','12')));</code>
 143      * Produces: /setup/themes/clone/12/
 144      *
 145      * <code>$Router->toUrl(array('controller' => 'themes','options' => array('blue','css','sans_serif'), 'action'=>'clone'));</code>
 146      * Produces: /customize/blue/css/sans_serif/clone/
 147      */
 148      function toUrl($params=array())
 149      {
 150          static $_cache;
 151          $_cache_key = md5(serialize($params));
 152          if(!isset($_cache[$_cache_key])){
 153              $_parsed = '';
 154  
 155              if(isset($params[AK_SESSION_NAME]) && isset($_COOKIE)){
 156                  unset($params[AK_SESSION_NAME]);
 157              }
 158  
 159              $params = array_map(array(&$this, '_urlEncode'), $params);
 160  
 161              foreach ($this->_loaded_routes as $_route){
 162                  $params_copy = $params;
 163                  $_parsed = '';
 164                  $_controller = '';
 165                  foreach ($params_copy as $_k=>$_v){
 166                      if(isset($$_k)){
 167                          unset($$_k);
 168                      }
 169                  }
 170                  extract($params);
 171  
 172                  if(isset($_route['options'])){
 173                      foreach ($_route['options'] as $_option=>$_value){
 174                          if(
 175                          !empty($_route['url_pieces']) &&
 176                          isset($_route['options'][$_option]) &&
 177                          array_search(':'.$_option, $_route['url_pieces']) === false &&
 178                          array_search('*'.$_option, $_route['url_pieces']) === false &&
 179                          (
 180                          is_string($_value) ||
 181                          is_integer($_value)) &&
 182                          (
 183                          !isset($params_copy[$_option]
 184                          ) ||
 185                          $params_copy[$_option] != $_value
 186                          )
 187                          )
 188                          {
 189                              continue 2;
 190                          }
 191                          if(isset($params_copy[$_option]) &&
 192                          $_value == $params_copy[$_option] &&
 193                          $_value !== OPTIONAL &&
 194                          $_value !== COMPULSORY)
 195                          {
 196                              if($_option == 'controller'){
 197                                  $_controller = $_value;
 198                              }
 199                              unset($params_copy[$_option]);
 200                              unset($$_option);
 201                          }
 202                      }
 203                  }
 204  
 205  
 206                  foreach ($_route['arr_params'] as $arr_route){
 207                      if(isset($$arr_route) && is_array($$arr_route)){
 208                          $$arr_route = join('/',$$arr_route);
 209                      }
 210                  }
 211  
 212                  $_url_pieces = array();
 213                  foreach (array_reverse($_route['url_pieces']) as $_v){
 214                      if(strstr($_v,':') || strstr($_v,'*')){
 215                          $_v = substr($_v,1);
 216                          if(isset($params[$_v])){
 217                              if (count($_url_pieces) || isset($_route['options'][$_v]) && $params[$_v] != $_route['options'][$_v] || !isset($_route['options'][$_v]) || isset($_route['options'][$_v]) && $_route['options'][$_v] === COMPULSORY){
 218                                  $_url_pieces[] = is_array($params[$_v]) ? join('/',$params[$_v]) : $params[$_v];
 219                              }
 220                          }
 221                      }else{
 222                          $_url_pieces[] = is_array($_v) ? join('/',$_v) : $_v;
 223                      }
 224                  }
 225  
 226                  $_parsed = str_replace('//','/','/'.join('/',array_reverse($_url_pieces)).'/');
 227  
 228                  // This might be faster but using eval here might cause security issues
 229                  //@eval('$_parsed = "/".trim(str_replace("//","/","'.str_replace(array('/:','/*'),'/$','/'.join('/',$_route['url_pieces']).'/').'"),"/")."/";');
 230  
 231                  if($_parsed == '//'){
 232                      $_parsed = '/';
 233                  }
 234  
 235                  if(is_string($_parsed)){
 236                      if($_parsed_arr = $this->toParams($_parsed)){
 237  
 238                          if($_parsed == '/' && count(array_diff($params,$_parsed_arr)) == 0){
 239                              $_cache[$_cache_key] = '/';
 240                              return $_cache[$_cache_key];
 241                          }
 242  
 243                          if( isset($_parsed_arr['controller']) &&
 244                          ((isset($controller) && $_parsed_arr['controller'] == $controller) ||
 245                          (isset($_controller) && $_parsed_arr['controller'] == $_controller))){
 246  
 247  
 248                              if( isset($_route['options']['controller']) &&
 249                              $_route['options']['controller'] !== OPTIONAL &&
 250                              $_route['options']['controller'] !== COMPULSORY &&
 251                              $_parsed_arr['controller'] != $_route['options']['controller'] &&
 252                              count(array_diff(array_keys($_route['options']),array_keys($_parsed_arr))) > 0){
 253                                  continue;
 254                              }
 255  
 256                              $url_params = array_merge($_parsed_arr, $params_copy);
 257  
 258                              if($_parsed != '/'){
 259                                  foreach ($_parsed_arr as $_k=>$_v){
 260                                      if(isset($url_params[$_k]) && $url_params[$_k] == $_v){
 261                                          unset($url_params[$_k]);
 262                                      }
 263                                  }
 264                              }
 265  
 266                              foreach (array_reverse($_route['url_pieces'], true) as $position => $piece){
 267                                  $piece = str_replace(array(':','*'),'', $piece);
 268                                  if(isset($$piece)){
 269                                      if(strstr($_parsed,'/'.$$piece.'/')){
 270                                          unset($url_params[$piece]);
 271                                      }
 272                                  }
 273                              }
 274  
 275                              foreach ($url_params as $_k=>$_v){
 276                                  if($_v == null){
 277                                      unset($url_params[$_k]);
 278                                  }
 279                              }
 280  
 281                              if($_parsed == '/' && !empty($url_params['controller'])){
 282                                  $_parsed = '/'.join('/',array_diff(array($url_params['controller'],@$url_params['action'],@$url_params['id']),array('')));
 283                                  unset($url_params['controller'],$url_params['action'],$url_params['id']);
 284                              }
 285  
 286                              if(defined('AK_URL_REWRITE_ENABLED') && AK_URL_REWRITE_ENABLED === true){
 287                                  if(isset($url_params['ak'])){
 288                                      unset($url_params['ak']);
 289                                  }
 290                                  if(isset($url_params['lang'])){
 291                                      $_parsed = '/'.$url_params['lang'].$_parsed;
 292                                      unset($url_params['lang']);
 293                                  }
 294                                  $_parsed .= count($url_params) ? '?'.http_build_query($url_params) : '';
 295                              }else{
 296                                  $_parsed = count($url_params) ? '/?ak='.$_parsed.'&'.http_build_query($url_params) : '/?ak='.$_parsed;
 297                              }
 298                              $_cache[$_cache_key] = $_parsed;
 299                              return $_parsed;
 300                          }
 301                      }
 302                  }
 303              }
 304  
 305              (array)$extra_parameters = @array_diff($params_copy,$_parsed_arr);
 306  
 307  
 308              if($_parsed == '' && is_array($params)){
 309                  $_parsed = '?'.http_build_query(array_merge($params,(array)$extra_parameters));
 310              }
 311              if($_parsed == '//'){
 312                  $_parsed = '/';
 313              }
 314  
 315              if(defined('AK_URL_REWRITE_ENABLED') && AK_URL_REWRITE_ENABLED === false && $_parsed{0} != '?'){
 316                  $_parsed = '?ak='.trim($_parsed,'/');
 317              }
 318  
 319              $_parsed .= empty($extra_parameters) ? '' : (strstr($_parsed,'?') ? '&' : '?').http_build_query($extra_parameters);
 320              $_cache[$_cache_key] = $_parsed;
 321          }
 322          return $_cache[$_cache_key];
 323      }
 324  
 325      /**
 326      * Gets the parameters from a Akelos Framework friendly URL.
 327      *
 328      * This method returns the parameters found in an Akelos Framework friendly URL.
 329      *
 330      * This function will inspect the rewrite rules and will return the params that match the first one.
 331      *
 332      * @access public
 333      * @param    string    $url    URL to get params from.
 334      * @return mixed Having the following rewrite rules:
 335      * <code>
 336      * $Router =& new AkRouter();
 337      *
 338      * $Router->map('/setup/*config_settings',array('controller'=>'setup'));
 339      * $Router->map('/customize/*options/:action',array('controller'=>'themes','options'=>3));
 340      * $Router->map('/blog/:action/:id',array('controller'=>'post','action'=>'list','id'=>OPTIONAL),array('id'=>'/\d{1,}/'));
 341      * $Router->map('/:year/:month/:day', array('controller' => 'articles','action' => 'view_headlines','year' => COMPULSORY,'month' => 'all','day' => OPTIONAL) , array('year'=>'/(20){1}\d{2}/','month'=>'/((1)?\d{1,2}){2}/','day'=>'/(([1-3])?\d{1,2}){2}/'));
 342      * $Router->map('/:webpage', array('controller' => 'page', 'action' => 'view_page', 'webpage' => 'index'),array('webpage'=>'/(\w|_)+/'));
 343      * $Router->map('/', array('controller' => 'page', 'action' => 'view_page', 'webpage'=>'index'));
 344      * $Router->map('/:controller/:action/:id');
 345      * </code>
 346      *
 347      * We get the following results:
 348      *
 349      * <code>$Router->toParams('/contact_us');</code>
 350      * Produces: array('controller'=>'page','action'=>'view_page','webpage'=>'contact_us');
 351      *
 352      * <code>$Router->toParams('/');</code>
 353      * Produces: array('controller'=>'page','action'=>'view_page','webpage'=>'index');
 354      *
 355      * <code>$Router->toParams('');</code>
 356      * Produces: array('controller'=>'page','action'=>'view_page','webpage'=>'index');
 357      *
 358      * <code>$Router->toParams('/blog/');</code>
 359      * Produces: array('controller'=>'post','action'=>'list','id'=>null);
 360      *
 361      * <code>$Router->toParams('/blog/view');</code>
 362      * Produces: array('controller'=>'post','action'=>'view','id'=>null);
 363      *
 364      * <code>$Router->toParams('/blog/view/10/');</code>
 365      * Produces: array('controller'=>'post','action'=>'view','id'=>'10');
 366      *
 367      * <code>$Router->toParams('/blog/view/newest/');</code>
 368      * Produces: array('controller'=>'blog','action'=>'view','id'=>'newest');
 369      *
 370      * <code>$Router->toParams('/2005/10/');</code>
 371      * Produces: array('controller' => 'articles','action' => 'view_headlines','year' => '2005','month' => '10', 'day' => null);
 372      *
 373      * <code>$Router->toParams('/2006/');</code>
 374      * Produces: array('controller' => 'articles','action' => 'view_headlines','year' => '2006','month' => 'all', 'day' => null);
 375      *
 376      * <code>$Router->toParams('/user/list/12');</code>
 377      * Produces: array('controller' => 'user','action' => 'list','id' => '12');
 378      *
 379      * <code>$Router->toParams('/setup/themes/clone/12/');</code>
 380      * Produces: array('controller' => 'setup','config_settings' => array('themes','clone','12'));
 381      *
 382      * <code>$Router->toParams('/customize/blue/css/sans_serif/clone/');</code>
 383      * Produces: array('controller' => 'themes','options' => array('blue','css','sans_serif'), 'action'=>'clone');
 384      *
 385      * This function returns false in case no rule is found for selected URL
 386      */
 387      function toParams($url)
 388      {
 389          $url = $url == '/' || $url == '' ? '/' : '/'.trim($url,'/').'/';
 390          $nurl = $url;
 391  
 392          foreach ($this->_loaded_routes as $_route){
 393              $params = array();
 394  
 395              if(preg_match($_route['regex'], $url)){
 396                  foreach ($_route['regex_array'] as $single_regex_arr){
 397  
 398                      $k = key($single_regex_arr);
 399  
 400                      $single_regex = $single_regex_arr[$k];
 401                      $single_regex = '/^(\/'.$single_regex.'){1}/';
 402                      preg_match($single_regex, $url, $got);
 403  
 404                      if(in_array($k,$_route['arr_params'])){
 405                          $url_parts = strstr(trim($url,'/'),'/') ? explode('/',trim($url,'/')) : array(trim($url,'/'));
 406  
 407                          $pieces = (isset($_route['options'][$k]) && $_route['options'][$k] > 0) ? $_route['options'][$k] : count($url_parts);
 408                          while ($pieces>0) {
 409                              $pieces--;
 410                              $url_part = array_shift($url_parts);
 411                              $url = substr_replace($url,'',1,strlen($url_part)+1);
 412  
 413                              if(preg_match($single_regex, '/'.$url_part)){
 414                                  $params[$k][] = $url_part;
 415                              }
 416                          }
 417                      }elseif(!empty($got[0])){
 418                          $url = substr_replace($url,'',1,strlen($got[0]));
 419                          if(in_array($k,$_route['var_params'] )){
 420                              $param = trim($got[0],'/');
 421                              $params[$k] = $param;
 422                          }
 423                      }
 424                      if(isset($_route['options'][$k])){
 425  
 426                          if($_route['options'][$k] !== COMPULSORY &&
 427                          $_route['options'][$k] !== OPTIONAL &&
 428                          $_route['options'][$k] != '' &&
 429                          ((!isset($params[$k]))||(isset($params[$k]) && $params[$k] == ''))){
 430                              $params[$k] = $_route['options'][$k];
 431                          }
 432                      }
 433                  }
 434  
 435                  if(isset($_route['options'])){
 436                      foreach ($_route['options'] as $_option => $_value){
 437                          if($_value !== COMPULSORY && $_value !== OPTIONAL && $_value != '' && !isset($params[$_option])){
 438                              $params[$_option] = $_value;
 439                          }
 440                      }
 441                  }
 442              }
 443              if(count($params)){
 444                  $params = array_map(array(&$this,'_urlDecode'), $params);
 445                  return $params;
 446              }
 447          }
 448          return false;
 449      }
 450  
 451      /**
 452      * Add a rewrite rule
 453      *
 454      * Rewrite rules are defined on the file <code>config/routes.php</code>
 455      *
 456      * Rules that are defined first take precedence over the rest.
 457      *
 458      * @access public
 459      * @param    string    $url_pattern    URL patterns have the following format:
 460      *
 461      * - <b>/static_text</b>
 462      * - <b>/:variable</b>  (will load $variable)
 463      * - <b>/*array</b> (will load $array as an array)
 464      * @param    array    $options    Options is an array with and array pair of field=>value
 465      * The following example <code>array('controller' => 'page')</code> sets var 'controler' to 'page' if no 'controller' is specified in the $url_pattern param this value will be used.
 466      *
 467      * The following constants can be used as values:
 468      * <code>
 469      * OPTIONAL // 'var_name'=> OPTIONAL, will set 'var_name' as an option
 470      * COMPULSORY // 'var_name'=> COMPULSORY, will require 'var_name' to be set
 471      * </code>
 472      * @param    array    $requirements    $requirements holds an array with and array pair of field=>value where value is a perl compatible regular expression that will be used to validate rewrite rules
 473      * The following example <code>array('id'=>'/\d+/')</code> will require that var 'id' must be a numeric field.
 474      *
 475      * NOTE:If option <b>'id'=>OPTIONAL</b> this requirement will be used in case 'id' is set to something
 476      * @return void
 477      */
 478      function connect($url_pattern, $options = array(), $requirements = null)
 479      {
 480  
 481          if(!empty($options['requirements'])){
 482              $requirements = empty($requirements) ? $options['requirements'] : array_merge($options['requirements'],$requirements);
 483              unset($options['requirements']);
 484          }
 485  
 486          preg_match_all('/(([^\/]){1}(\/\/)?){1,}/',$url_pattern,$found);
 487          $url_pieces = $found[0];
 488  
 489          $regex_arr = array();
 490          $optional_pieces = array();
 491          $var_params = array();
 492          $arr_params = array();
 493          foreach ($url_pieces as $piece){
 494              $is_var = $piece[0] == ':';
 495              $is_arr = $piece[0] == '*';
 496              $is_constant = !$is_var && !$is_arr;
 497  
 498              $piece = $is_constant ? $piece : substr($piece,1);
 499  
 500              if($is_var && !isset($options[$piece])){
 501                  $options[$piece] = OPTIONAL;
 502              }
 503  
 504              if($is_arr && !isset($options[$piece])){
 505                  $options[$piece] = OPTIONAL;
 506              }
 507  
 508              if(($is_arr || $is_var) && $piece == 'this'){
 509                  trigger_error(Ak::t('You can\'t use the reserved word this for mapping URLs'), E_USER_ERROR);
 510              }
 511  
 512              //COMPULSORY
 513  
 514              if($is_constant){
 515                  $regex_arr[] = array('_constant_'.$piece => '('.$piece.'(?=(\/|$))){1}');
 516              }elseif(isset($requirements[$piece])){
 517                  if (isset($options[$piece]) && $options[$piece] !== COMPULSORY){
 518                      $regex_arr[] = array($piece=> '(('.trim($requirements[$piece],'/').'){1})?');
 519                  }elseif(isset($options[$piece]) && $options[$piece] !== OPTIONAL){
 520                      $regex_arr[] = array($piece=> '(('.trim($requirements[$piece],'/').'){1}|('.$options[$piece].'){1}){1}');
 521                  }else{
 522                      $regex_arr[] = array($piece=> '('.trim($requirements[$piece],'/').'){1}');
 523                  }
 524              }elseif(isset($options[$piece])){
 525                  if($options[$piece] === OPTIONAL){
 526                      $regex_arr[] = array($piece=>'[^\/]*');
 527                  }elseif ($options[$piece] === COMPULSORY){
 528                      $regex_arr[] = array($piece=> COMPULSORY_REGEX);
 529                  }elseif(is_string($options[$piece]) && $options[$piece][0] == '/' &&
 530                  ($_tmp_close_char = strlen($options[$piece])-1 || $options[$piece][$_tmp_close_char] == '/')){
 531                      $regex_arr[] = array($piece=> substr($options[$piece],1,$_tmp_close_char*-1));
 532                  }elseif ($options[$piece] != ''){
 533                      $regex_arr[] = array($piece=>'[^\/]*');
 534                      $optional_pieces[$piece] = $piece;
 535                  }
 536              }else{
 537                  $regex_arr[] = array($piece => $piece);
 538              }
 539  
 540  
 541              if($is_var){
 542                  $var_params[] = $piece;
 543              }
 544              if($is_arr){
 545                  $arr_params[] = $piece;
 546              }
 547  
 548              if(isset($options[$piece]) && $options[$piece] === OPTIONAL){
 549                  $optional_pieces[$piece] = $piece;
 550              }
 551          }
 552  
 553          foreach (array_reverse($regex_arr) as $pos=>$single_regex_arr){
 554              $var_name = key($single_regex_arr);
 555              if((isset($options[$var_name]) && $options[$var_name] === COMPULSORY) || (isset($requirements[$var_name]) && $requirements[$var_name] === COMPULSORY)){
 556                  $last_optional_var = $pos;
 557                  break;
 558              }
 559          }
 560  
 561          $regex = '/^((\/)?';
 562          $pieces_count = count($regex_arr);
 563  
 564          foreach ($regex_arr as $pos=>$single_regex_arr){
 565              $k = key($single_regex_arr);
 566              $single_regex = $single_regex_arr[$k];
 567  
 568              $slash_delimiter = isset($last_optional_var) && ($last_optional_var <= $pos) ? '{1}' : '?';
 569  
 570              if(isset($optional_pieces[$k])){
 571                  $terminal = (is_numeric($options[$k]) && $options[$k] > 0 && in_array($k,$arr_params)) ? '{'.$options[$k].'}' : ($pieces_count == $pos+1 ? '?' : '{1}');
 572                  $regex .= $is_arr ? '('.$single_regex.'\/'.$slash_delimiter.')+' : '('.$single_regex.'\/'.$slash_delimiter.')'.$terminal;
 573              }else{
 574                  $regex .= $is_arr ? $single_regex.'\/+' : $single_regex.'\/'.($pieces_count == $pos+1 ? '?' : $slash_delimiter);
 575              }
 576          }
 577          $regex = rtrim($regex ,'/').'){1}$/';
 578          $regex = str_replace('/^\$/','/^\\/?$/',$regex);
 579  
 580  
 581          $this->_loaded_routes[] = array(
 582          'url_path' => $url_pattern,
 583          'options' => $options,
 584          'requirements' => $requirements,
 585          'url_pieces' => $url_pieces,
 586          'regex' => $regex,
 587          'regex_array' => $regex_arr,
 588          'optional_params' => $optional_pieces,
 589          'var_params' => $var_params,
 590          'arr_params' => $arr_params
 591          );
 592  
 593      }
 594  
 595  
 596      /**
 597      * Alias for map
 598      * 
 599      * @see map
 600      */
 601      function map($url_pattern, $options = array(), $requirements = null)
 602      {
 603          return $this->connect($url_pattern, $options, $requirements);
 604      }
 605  
 606      /**
 607      * Url decode a string or an array of strings
 608      */
 609      function _urlDecode($input)
 610      {
 611          if(!empty($input)){
 612              if (is_scalar($input)){
 613                  return urldecode($input);
 614              }elseif (is_array($input)){
 615                  return array_map(array(&$this,'_urlDecode'),$input);
 616              }
 617          }
 618          return '';
 619      }
 620  
 621      /**
 622      * Url encodes a string or an array of strings
 623      */
 624      function _urlEncode($input)
 625      {
 626          if(!empty($input)){
 627              if (is_scalar($input)){
 628                  return urlencode($input);
 629              }elseif (is_array($input)){
 630                  return array_map(array(&$this,'_urlEncode'),$input);
 631              }
 632          }
 633          return '';
 634      }
 635  
 636      /**
 637      * This method tries to determine if url rewrite is enabled on this server.
 638      * It has only been tested on apache.
 639      * It is strongly recomended that you manually define the constant 
 640      * AK_URL_REWRITE_ENABLED on your config file to the avoid overload
 641      * this function causes and to prevent from missfunctioning
 642      */
 643      function _loadUrlRewriteSettings()
 644      {
 645          static $result;
 646          if(isset($result)){
 647              return $result;
 648          }
 649  
 650          if(defined('AK_URL_REWRITE_ENABLED')){
 651              $result = AK_URL_REWRITE_ENABLED;
 652              return AK_URL_REWRITE_ENABLED;
 653          }
 654          if(AK_DESKTOP){
 655              if(!defined('AK_URL_REWRITE_ENABLED')){
 656                  define('AK_URL_REWRITE_ENABLED',false);
 657                  $result = AK_URL_REWRITE_ENABLED;
 658                  return false;
 659              }
 660          }
 661          if(defined('AK_ENABLE_URL_REWRITE') && AK_ENABLE_URL_REWRITE == false){
 662              if(!defined('AK_URL_REWRITE_ENABLED')){
 663                  define('AK_URL_REWRITE_ENABLED',false);
 664              }
 665              $result = AK_URL_REWRITE_ENABLED;
 666              return false;
 667          }
 668  
 669          $url_rewrite_status = false;
 670  
 671          //echo '<pre>'.print_r(get_defined_functions(), true).'</pre>';
 672  
 673          if( isset($_SERVER['REDIRECT_STATUS'])
 674          && $_SERVER['REDIRECT_STATUS'] == 200
 675          && isset($_SERVER['REDIRECT_QUERY_STRING'])
 676          && strstr($_SERVER['REDIRECT_QUERY_STRING'],'ak=')){
 677  
 678              if(strstr($_SERVER['REDIRECT_QUERY_STRING'],'&')){
 679                  $tmp_arr = explode('&',$_SERVER['REDIRECT_QUERY_STRING']);
 680                  $ak_request = $tmp_arr[0];
 681              }else{
 682                  $ak_request = $_SERVER['REDIRECT_QUERY_STRING'];
 683              }
 684              $ak_request = trim(str_replace('ak=','',$ak_request),'/');
 685  
 686              if(strstr($_SERVER['REDIRECT_URL'],$ak_request)){
 687                  $url_rewrite_status = true;
 688              }else {
 689                  $url_rewrite_status = false;
 690              }
 691          }
 692  
 693          // We check if available by investigating the .htaccess file if no query has been set yet
 694          elseif(function_exists('apache_get_modules')){
 695  
 696              $available_modules = apache_get_modules();
 697  
 698              if(in_array('mod_rewrite',(array)$available_modules)){
 699  
 700                  // Local session name is changed intentionally from .htaccess
 701                  // So we can see if the file has been loaded.
 702                  // if so, we restore the session.name to its original
 703                  // value
 704                  if(ini_get('session.name') == 'AK_SESSID'){
 705                      $session_name = defined('AK_SESSION_NAME') ? AK_SESSION_NAME : get_cfg_var('session.name');
 706                      ini_set('session.name',$session_name);
 707                      $url_rewrite_status = true;
 708  
 709                      // In some cases where session.name cant be set up by htaccess file,
 710                      // we can check for modrewrite status on this file
 711                  }elseif (file_exists(AK_BASE_DIR.DS.'.htaccess')){
 712                      $htaccess_file = Ak::file_get_contents(AK_BASE_DIR.DS.'.htaccess');
 713                      if(stristr($htaccess_file,'RewriteEngine on')){
 714                          $url_rewrite_status = true;
 715                      }
 716                  }
 717              }
 718  
 719              // If none of the above works we try to fetch a file that should be remaped
 720          }elseif (isset($_SERVER['REDIRECT_URL']) && $_SERVER['REDIRECT_URL'] == '/' && isset($_SERVER['REDIRECT_STATUS']) && $_SERVER['REDIRECT_STATUS'] == 200){
 721              $url_rewrite_test_url = AK_URL.'mod_rewrite_test';
 722              if(!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])){
 723                  $url_rewrite_test_url = AK_PROTOCOL.$_SERVER['PHP_AUTH_USER'].':'.$_SERVER['PHP_AUTH_PW'].'@'.AK_HOST.'/mod_rewrite_test';
 724              }
 725  
 726              $url_rewrite_status = strstr(@file_get_contents($url_rewrite_test_url), 'AK_URL_REWRITE_ENABLED');
 727              $AK_URL_REWRITE_ENABLED = "define(\\'AK_URL_REWRITE_ENABLED\\', ".($url_rewrite_status ? 'true' : 'false').");\n";
 728  
 729              register_shutdown_function(create_function('',"Ak::file_put_contents(AK_CONFIG_DIR.DS.'config.php',
 730              str_replace('<?php\n','<?php\n\n$AK_URL_REWRITE_ENABLED',Ak::file_get_contents(AK_CONFIG_DIR.DS.'config.php')));"));
 731          }
 732  
 733  
 734  
 735          if(!defined('AK_URL_REWRITE_ENABLED')){
 736              define('AK_URL_REWRITE_ENABLED', $url_rewrite_status);
 737          }
 738          $result = AK_URL_REWRITE_ENABLED;
 739          return AK_URL_REWRITE_ENABLED;
 740      }
 741  }
 742  
 743  
 744  function &AkRouter()
 745  {
 746      $null = null;
 747      $AkRouter =& Ak::singleton('AkRouter', $null);
 748      return $AkRouter;
 749  }
 750  
 751  ?>


Generated: Mon Oct 27 12:43:49 2008 Cross-referenced by PHPXref 0.6