Source for file Ethna_UrlHandler.php

Documentation is available at Ethna_UrlHandler.php

  1. <?php
  2. // vim: foldmethod=marker tabstop=4 shiftwidth=4 autoindent
  3. /**
  4.  *  Ethna_UrlHandler.php
  5.  *
  6.  *  @author     Masaki Fujimoto <fujimoto@php.net>
  7.  *  @package    Ethna
  8.  *  @version    $Id$
  9.  */
  10.  
  11. /**
  12.  *  URLハンドラクラス
  13.  *
  14.  *  @author     Masaki Fujimoto <fujimoto@php.net>
  15.  *  @access     public
  16.  *  @package    Ethna
  17.  */
  18. {
  19.     /** @var    array   アクションマッピング */
  20.     var $action_map = array(
  21.         /*
  22.          * 'user'   => array(
  23.          *  'user_login' => array(
  24.          *      'path'          => 'login',
  25.          *      'path_regexp'   => false,
  26.          *      'path_ext'      => false,
  27.          *      'option'        => array(),
  28.          *  ),
  29.          * ),
  30.          */
  31.     );
  32.  
  33.     /**
  34.      *  Ethna_UrlHandlerクラスのコンストラクタ
  35.      *
  36.      *  @access public
  37.      */
  38.     function Ethna_UrlHandler()
  39.     {
  40.     }
  41.  
  42.     /**
  43.      *  Ethna_UrlHandlerクラスのインスタンスを取得する
  44.      *
  45.      *  $name がクラス名 ('_'を含む) の場合はそのクラスを、
  46.      *  そうでないときはプラグイン名とみなしてインスタンスを返す
  47.      *
  48.      *  @access public
  49.      */
  50.     function &getInstance($name null)
  51.     {
  52.         static $instance array();
  53.         if ($name === null{
  54.             $name = __CLASS__;
  55.         }
  56.         if (isset($instance[$name])) {
  57.             return $instance[$name];
  58.         }
  59.  
  60.         if (strpos($name'_'!== false{
  61.             $instance[$name&new $name();
  62.         else {
  63.             // get instance with plugin
  64.             $ctl &Ethna_Controller::getInstance();
  65.             $plugin &$ctl->getPlugin();
  66.             $instance[$name&$plugin->getPlugin('Urlhandler'$name);
  67.         }
  68.  
  69.         return $instance[$name];
  70.     }
  71.  
  72.     /**
  73.      *  アクションをユーザリクエストに変換する
  74.      *
  75.      *  @access public
  76.      */
  77.     function actionToRequest($action$param)
  78.     {
  79.         $url_handler null;
  80.         $action_value null;
  81.         foreach ($this->action_map as $key => $value{
  82.             if (isset($value[$action])) {
  83.                 $url_handler $key;
  84.                 $action_value $value[$action];
  85.                 break;
  86.             }
  87.         }
  88.         if (is_null($url_handler)) {
  89.             return null;
  90.         }
  91.  
  92.         // url_handler specific path
  93.         $method sprintf("_getPath_%s"ucfirst($url_handler));
  94.         if (method_exists($this$method=== false{
  95.             return null;
  96.         }
  97.         list($path$path_key$this->$method($action$param);
  98.         if ($path == ""{
  99.             return null;
  100.         }
  101.  
  102.         // append action path
  103.         if ($action_value['path']{
  104.             $path .= "/" $action_value['path'];
  105.         }
  106.  
  107.         // path_ext candidate list
  108.         if (is_array($action_value['path_regexp'])) {
  109.             // try most matcher
  110.             $tmp array_map('count'$action_value['path_ext']);
  111.             arsort($tmp);
  112.             $path_ext_list_indices array_keys($tmp);
  113.             $path_ext_list $action_value['path_ext'];
  114.         else {
  115.             $path_ext_list_indices array(0);
  116.             $path_ext_list array(=> $action_value['path_ext']);
  117.         }
  118.  
  119.         // fix path_ext to use
  120.         foreach ($path_ext_list_indices as $index{
  121.             if (is_array($path_ext_list[$index]=== false{
  122.                 // no parameters needed.
  123.                 $path_ext $path_ext_list[$index];
  124.                 break;
  125.             }
  126.             $path_ext_match true;
  127.             foreach ($path_ext_list[$indexas $key => $value{
  128.                 if (isset($param[$key]=== false{
  129.                     $path_ext_match false;
  130.                     break;
  131.                 }
  132.             }
  133.             if ($path_ext_match{
  134.                 $path_ext $path_ext_list[$index];
  135.                 break;
  136.             }
  137.         }
  138.         if (isset($path_ext=== false{
  139.             return null;
  140.         }
  141.  
  142.         // append extra parameters to path.
  143.         if (is_array($path_ext)) {
  144.             foreach ($path_ext as $key => $value{
  145.                 $path_key[$key;
  146.                 $ext_param $param[$key];
  147.  
  148.                 // output filter
  149.                 if (isset($value['output_filter']&& $value['output_filter'!= ""{
  150.                     $method $value['output_filter'];
  151.                     if (method_exists($this$method)) {
  152.                         $ext_param $this->$method($ext_param);
  153.                     }
  154.                 }
  155.  
  156.                 // remove form (pre|suf)fix
  157.                 if (isset($value['form_prefix']&& $value['form_prefix'!= ""{
  158.                     $s $value['form_prefix'];
  159.                     if (substr($ext_param0strlen($s)) == $s{
  160.                         $ext_param substr($ext_paramstrlen($s));
  161.                     }
  162.                 }
  163.                 if (isset($value['form_suffix']&& $value['form_suffix'!= ""{
  164.                     $s $value['form_suffix'];
  165.                     if (substr($ext_param-strlen($s)) == $s{
  166.                         $ext_param substr($ext_param0-strlen($s));
  167.                     }
  168.                 }
  169.  
  170.                 // rawurlencode (url (pre|suf)fixes need not to be encoded.)
  171.                 $ext_param rawurlencode($ext_param);
  172.  
  173.                 // add url (pre|suf)fix
  174.                 if (isset($value['url_prefix']&& $value['url_prefix'!= ""{
  175.                     $ext_param $value['url_prefix'$ext_param;
  176.                 }
  177.                 if (isset($value['url_suffix']&& $value['url_suffix'!= ""{
  178.                     $ext_param $ext_param $value['url_suffix'];
  179.                 }
  180.  
  181.                 $path .= '/' $ext_param;
  182.             }
  183.         }
  184.  
  185.         list($path$is_slash$this->_normalizePath($path);
  186.         return array($path$path_key);
  187.     }
  188.  
  189.     /**
  190.      *  ユーザリクエストをアクションに変換する
  191.      *
  192.      *  @access public
  193.      */
  194.     function requestToAction($http_vars)
  195.     {
  196.         if (isset($http_vars['__url_handler__']== false
  197.             || isset($this->action_map[$http_vars['__url_handler__']]== false{
  198.             return array();
  199.         }
  200.  
  201.         $url_handler $http_vars['__url_handler__'];
  202.         $action_map $this->action_map[$url_handler];
  203.  
  204.         // parameter fix
  205.         $method sprintf("_normalizeRequest_%s"ucfirst($url_handler));
  206.         if (method_exists($this$method)) {
  207.             $http_vars $this->$method($http_vars);
  208.         }
  209.  
  210.         // normalize
  211.         if (isset($http_vars['__url_info__'])) {
  212.             $path $http_vars['__url_info__'];
  213.         else {
  214.             $path "";
  215.         }
  216.         list($path$is_slash$this->_normalizePath($path);
  217.  
  218.         // match
  219.         $action null;
  220.         $action_value null;
  221.         $action_match null;
  222.         $action_regexp_index null;
  223.         foreach ($action_map as $key => $value{
  224.             $match_length strlen($value['path']);
  225.  
  226.             // check necessary match
  227.             if (strncmp($path$value['path']$match_length!= 0{
  228.                 continue;
  229.             }
  230.  
  231.             // try exact match
  232.             if ($path == $value['path']{
  233.                 $action $key;
  234.                 break;
  235.             }
  236.  
  237.             // continue in case w/ incomplete match
  238.             if ($path != "" && $match_length && $path{$match_length!= "/"{
  239.                 continue;
  240.             }
  241.             if ($is_slash && $path{strlen($path)-1== "/"{
  242.                 continue;
  243.             }
  244.  
  245.             // try regexp
  246.             if ($value['path_regexp']{
  247.                 if (is_array($value['path_regexp'])) {
  248.                     foreach ($value['path_regexp'as $index => $regexp{
  249.                         if (preg_match($regexp$path$tmp)) {
  250.                             $action $key;
  251.                             $action_match $tmp;
  252.                             $action_regexp_index $index;
  253.                             break;
  254.                         }
  255.                     }
  256.                 else {
  257.                     if (preg_match($value['path_regexp']$path$tmp)) {
  258.                         $action $key;
  259.                         $action_match $tmp;
  260.                         break;
  261.                     }
  262.                 }
  263.             }
  264.         }
  265.         if (is_null($action)) {
  266.             return array();
  267.         }
  268.         $action_value $action_map[$action];
  269.  
  270.         // build parameters
  271.         $http_vars $this->buildActionParameter($http_vars$action);
  272.  
  273.         // extra parameters
  274.         $path_ext is_null($action_regexp_index)
  275.                     ? $action_value['path_ext']
  276.                     : $action_value['path_ext'][$action_regexp_index];
  277.         if (is_array($path_ext&& is_array($action_match)) {
  278.             $n 1;
  279.             foreach ($path_ext as $key => $value{
  280.                 if (isset($action_match[$n]== false{
  281.                     break;
  282.                 }
  283.  
  284.                 // remove url (pre|suf)fix
  285.                 if (isset($value['url_prefix']&& $value['url_prefix'!= ""{
  286.                     $s $value['url_prefix'];
  287.                     if (substr($action_match[$n]0strlen($s)) == $s{
  288.                         $action_match[$nsubstr($action_match[$n]strlen($s));
  289.                     }
  290.                 }
  291.                 if (isset($value['url_suffix']&& $value['url_suffix'!= ""{
  292.                     $s $value['url_suffix'];
  293.                     if (substr($action_match[$n]-strlen($s)) == $s{
  294.                         $action_match[$nsubstr($action_match[$n]0-strlen($s));
  295.                     }
  296.                 }
  297.  
  298.                 // add form (pre|suf)fix
  299.                 if (isset($value['form_prefix']&& $value['form_prefix'!= ""{
  300.                     $action_match[$n$value['form_prefix'$action_match[$n];
  301.                 }
  302.                 if (isset($value['form_suffix']&& $value['form_suffix'!= ""{
  303.                     $action_match[$n$action_match[$n$value['form_suffix'];
  304.                 }
  305.  
  306.                 // input filter
  307.                 if (isset($value['input_filter']&& $value['input_filter'!= ""{
  308.                     $method $value['input_filter'];
  309.                     if (method_exists($this$method)) {
  310.                         $action_match[$n$this->$method($action_match[$n]);
  311.                     }
  312.                 }
  313.  
  314.                 $http_vars[$key$action_match[$n];
  315.                 $n++;
  316.             }
  317.         }
  318.  
  319.         return $http_vars;
  320.     }
  321.  
  322.     /**
  323.      *  ゲートウェイパスを正規化する
  324.      *
  325.      *  @access private
  326.      */
  327.     function _normalizePath($path)
  328.     {
  329.         if ($path == ""{
  330.             return array($pathfalse);
  331.         }
  332.  
  333.         $is_slash false;
  334.         $path preg_replace('|/+|''/'$path);
  335.  
  336.         if ($path{0== '/'{
  337.             $path substr($path1);
  338.         }
  339.         if ($path{strlen($path)-1== '/'{
  340.             $path substr($path0strlen($path)-1);
  341.             $is_slash true;
  342.         }
  343.  
  344.         return array($path$is_slash);
  345.     }
  346.  
  347.     /**
  348.      *  アクションをリクエストパラメータに変換する
  349.      *
  350.      *  @access public
  351.      */
  352.     function buildActionParameter($http_vars$action)
  353.     {
  354.         if ($action == ""{
  355.             return $http_vars;
  356.         }
  357.         $key sprintf('action_%s'$action);
  358.         $http_vars[$key'true';
  359.         return $http_vars;
  360.     }
  361.  
  362.     /**
  363.      *  パラメータをURLに変換する
  364.      *
  365.      *  @access public
  366.      */
  367.     function buildQueryParameter($query)
  368.     {
  369.         $param '';
  370.  
  371.         foreach ($query as $key => $value{
  372.             if (is_array($value)) {
  373.                 foreach ($value as $k => $v{
  374.                     if (is_numeric($k)) {
  375.                         $k '';
  376.                     }
  377.                     $param .= sprintf('%s=%s&',
  378.                                       urlencode(sprintf('%s[%s]'$key$k)),
  379.                                       urlencode($v));
  380.                 }
  381.             else if (is_null($value== false{
  382.                 $param .= sprintf('%s=%s&'urlencode($key)urlencode($value));
  383.             }
  384.         }
  385.  
  386.         return substr($param0-1);
  387.     }
  388.  
  389.     // {{{ ゲートウェイリクエスト正規化
  390.     // }}}
  391.  
  392.     // {{{ ゲートウェイパス生成
  393.     // }}}
  394.  
  395.     // {{{ フィルタ
  396.     // }}}
  397. }
  398.  
  399. ?>

Documentation generated on Fri, 11 Nov 2011 04:01:02 +0900 by phpDocumentor 1.4.3