Source for file UrlHandler.php

Documentation is available at UrlHandler.php

  1. <?php
  2. // vim: foldmethod=marker tabstop=4 shiftwidth=4 autoindent
  3. /**
  4.  *  UrlHandler.php
  5.  *
  6.  *  @author     Masaki Fujimoto <fujimoto@php.net>
  7.  *  @package    Ethna
  8.  *  @version    $Id: 15329bf269eadb0c7cf5769fdc47612386364a22 $
  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.     protected $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.     public function __construct()
  39.     {
  40.     }
  41.  
  42.     /**
  43.      *  Ethna_UrlHandlerクラスのインスタンスを取得する
  44.      *
  45.      *  $name がクラス名 ('_'を含む) の場合はそのクラスを、
  46.      *  そうでないときはプラグイン名とみなしてインスタンスを返す
  47.      *
  48.      *  @access public
  49.      */
  50.     public static 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[$namenew $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.     public 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.     public 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.             if (isset($value['path'])) {
  225.                 $match_length strlen($value['path']);
  226.  
  227.                 // check necessary match
  228.                 if (strncmp($path$value['path']$match_length!= 0{
  229.                     continue;
  230.                 }
  231.  
  232.                 // try exact match
  233.                 if ($path == $value['path']{
  234.                     $action $key;
  235.                     break;
  236.                 }
  237.  
  238.                 // continue in case w/ incomplete match
  239.                 if ($path != "" && $match_length && $path{$match_length!= "/"{
  240.                     continue;
  241.                 }
  242.                 if ($is_slash && $path{strlen($path)-1== "/"{
  243.                     continue;
  244.                 }
  245.             }
  246.  
  247.             if (isset($value['path_regexp']&& $value['path_regexp']{
  248.                 if (is_array($value['path_regexp'])) {
  249.                     foreach ($value['path_regexp'as $index => $regexp{
  250.                         if (preg_match($regexp$path$tmp)) {
  251.                             $action $key;
  252.                             $action_match $tmp;
  253.                             $action_regexp_index $index;
  254.                             break;
  255.                         }
  256.                     }
  257.                 else {
  258.                     if (preg_match($value['path_regexp']$path$tmp)) {
  259.                         $action $key;
  260.                         $action_match $tmp;
  261.                         break;
  262.                     }
  263.                 }
  264.             }
  265.  
  266.             // else, continue
  267.         }
  268.         if (is_null($action)) {
  269.             return array();
  270.         }
  271.         $action_value $action_map[$action];
  272.  
  273.         // build parameters
  274.         $http_vars $this->buildActionParameter($http_vars$action);
  275.  
  276.         // extra parameters
  277.         $path_ext is_null($action_regexp_index)
  278.                     ? $action_value['path_ext']
  279.                     : $action_value['path_ext'][$action_regexp_index];
  280.         if (is_array($path_ext&& is_array($action_match)) {
  281.             $n 1;
  282.             foreach ($path_ext as $key => $value{
  283.                 if (isset($action_match[$n]== false{
  284.                     break;
  285.                 }
  286.  
  287.                 // remove url (pre|suf)fix
  288.                 if (isset($value['url_prefix']&& $value['url_prefix'!= ""{
  289.                     $s $value['url_prefix'];
  290.                     if (substr($action_match[$n]0strlen($s)) == $s{
  291.                         $action_match[$nsubstr($action_match[$n]strlen($s));
  292.                     }
  293.                 }
  294.                 if (isset($value['url_suffix']&& $value['url_suffix'!= ""{
  295.                     $s $value['url_suffix'];
  296.                     if (substr($action_match[$n]-strlen($s)) == $s{
  297.                         $action_match[$nsubstr($action_match[$n]0-strlen($s));
  298.                     }
  299.                 }
  300.  
  301.                 // add form (pre|suf)fix
  302.                 if (isset($value['form_prefix']&& $value['form_prefix'!= ""{
  303.                     $action_match[$n$value['form_prefix'$action_match[$n];
  304.                 }
  305.                 if (isset($value['form_suffix']&& $value['form_suffix'!= ""{
  306.                     $action_match[$n$action_match[$n$value['form_suffix'];
  307.                 }
  308.  
  309.                 // input filter
  310.                 if (isset($value['input_filter']&& $value['input_filter'!= ""{
  311.                     $method $value['input_filter'];
  312.                     if (method_exists($this$method)) {
  313.                         $action_match[$n$this->$method($action_match[$n]);
  314.                     }
  315.                 }
  316.  
  317.                 $http_vars[$key$action_match[$n];
  318.                 $n++;
  319.             }
  320.         }
  321.  
  322.         return $http_vars;
  323.     }
  324.  
  325.     /**
  326.      *  ゲートウェイパスを正規化する
  327.      *
  328.      *  @access private
  329.      */
  330.     protected function _normalizePath($path)
  331.     {
  332.         if ($path == ""{
  333.             return array($pathfalse);
  334.         }
  335.  
  336.         $is_slash false;
  337.         $path preg_replace('|/+|''/'$path);
  338.  
  339.         if ($path{0== '/'{
  340.             $path substr($path1);
  341.         }
  342.         if ($path{strlen($path)-1== '/'{
  343.             $path substr($path0strlen($path)-1);
  344.             $is_slash true;
  345.         }
  346.  
  347.         return array($path$is_slash);
  348.     }
  349.  
  350.     /**
  351.      *  アクションをリクエストパラメータに変換する
  352.      *
  353.      *  @access public
  354.      */
  355.     public function buildActionParameter($http_vars$action)
  356.     {
  357.         if ($action == ""{
  358.             return $http_vars;
  359.         }
  360.         $key sprintf('action_%s'$action);
  361.         $http_vars[$key'true';
  362.         return $http_vars;
  363.     }
  364.  
  365.     /**
  366.      *  パラメータをURLに変換する
  367.      *
  368.      *  @access public
  369.      */
  370.     public function buildQueryParameter($query)
  371.     {
  372.         $param '';
  373.  
  374.         foreach ($query as $key => $value{
  375.             if (is_array($value)) {
  376.                 foreach ($value as $k => $v{
  377.                     if (is_numeric($k)) {
  378.                         $k '';
  379.                     }
  380.                     $param .= sprintf('%s=%s&',
  381.                                       urlencode(sprintf('%s[%s]'$key$k)),
  382.                                       urlencode($v));
  383.                 }
  384.             else if (is_null($value== false{
  385.                 $param .= sprintf('%s=%s&'urlencode($key)urlencode($value));
  386.             }
  387.         }
  388.  
  389.         return substr($param0-1);
  390.     }
  391.  
  392.     // {{{ ゲートウェイリクエスト正規化
  393.     // }}}
  394.  
  395.     // {{{ ゲートウェイパス生成
  396.     // }}}
  397.  
  398.     // {{{ フィルタ
  399.     // }}}
  400. }

Documentation generated on Fri, 11 Nov 2011 03:59:15 +0900 by phpDocumentor 1.4.3