Source for file Simple.php

Documentation is available at Simple.php

  1. <?php
  2. /**
  3.  *  Simple.php
  4.  *
  5.  *  @author     Keisuke SATO <riaf@me.com>
  6.  *  @package    Ethna
  7.  *  @version    $Id: b05bd254b9b40e0c2f998380421e86bf7868467c $
  8.  */
  9.  
  10. /**
  11.  *  URLハンドラクラス
  12.  *
  13.  *  @author     Keisuke SATO <riaf@me.com>
  14.  *  @access     public
  15.  *  @package    Ethna
  16.  */
  17. {
  18.     /** @var    array   アクションマッピング */
  19.     protected $action_map = array(
  20.         // 'index' => '/',
  21.         // 'wozozo_index' => '/wozozo',
  22.         // 'wozozo_message' => '/wozozo/{message}',
  23.         // 'message_show' => array(
  24.         //     'path' => '/message/{id}',
  25.         //     'patterns' => array(
  26.         //         'id' => '\d+',
  27.         //     ),
  28.         //     'defaults' => array(
  29.         //         'id' => 123,
  30.         //     ),
  31.         // ),
  32.     );
  33.  
  34.     /**
  35.      *  アクションをユーザリクエストに変換する
  36.      *
  37.      *  @access public
  38.      */
  39.     public function actionToRequest($action$param=array())
  40.     {
  41.         $ret null;
  42.         $action_map $this->getActionMap();
  43.  
  44.         if (isset($action_map[$action])) {
  45.             $def $action_map[$action];
  46.  
  47.             $paths $this->sortPaths($def['path']SORT_DESC);
  48.  
  49.             foreach ($paths as $path{
  50.                 if (strpos($path'{'&& preg_match_all('/\{(.*?)\}/'$path$matches)) {
  51.                     $keys array_unique($matches[1]);
  52.                     $replaces array();
  53.  
  54.                     foreach ($keys as $key{
  55.                         $val null;
  56.                         if (isset($param[$key])) {
  57.                             $val $param[$key];
  58.                         else if (isset($def['defaults']&& isset($def['defaults'][$key])) {
  59.                             $val $def['defaults'][$key];
  60.                         }
  61.  
  62.                         if (!is_null($val)) {
  63.                             $replaces['{'.$key.'}'$val;
  64.                         else {
  65.                             continue 2;
  66.                         }
  67.                     }
  68.  
  69.                     $ret array(str_replace(array_keys($replaces)array_values($replaces)$path)$keys);
  70.                     break;
  71.                 else {
  72.                     $ret array($patharray());
  73.                     break;
  74.                 }
  75.             }
  76.         }
  77.  
  78.         return $ret;
  79.     }
  80.  
  81.     /**
  82.      * ユーザリクエストをアクションに変換する
  83.      *
  84.      * @param array $http_vars 
  85.      */
  86.     public function requestToAction($http_vars)
  87.     {
  88.         $path '/';
  89.         $detected_action null;
  90.  
  91.         if (isset($http_vars['__url_info__'])) {
  92.             $path $this->normalizePath($http_vars['__url_info__']);
  93.         }
  94.  
  95.         foreach ($this->getActionMap(as $action => $def{
  96.             foreach ($def['path'as $pattern{
  97.                 if (strpos($pattern'{')) {
  98.                     $action $this->getActionByRegex($path$action$def$http_vars);
  99.  
  100.                     if (!is_null($action)) {
  101.                         $detected_action $action;
  102.                         break;
  103.                     }
  104.                 else {
  105.                     if ($path === $pattern{
  106.                         $detected_action $action;
  107.                         break;
  108.                     }
  109.                 }
  110.             }
  111.         }
  112.  
  113.         if (is_null($detected_action)) {
  114.             $http_vars array();
  115.         else {
  116.             $http_vars $this->buildActionParameter($http_vars$detected_action);
  117.         }
  118.  
  119.         return $http_vars;
  120.     }
  121.  
  122.     /**
  123.      * 正規表現でマッチさせる
  124.      *
  125.      * @param string $path 
  126.      * @param string $action 
  127.      * @param array $def 
  128.      * @param array $http_vars 
  129.      */
  130.     protected function getActionByRegex($path$action$def&$http_vars)
  131.     {
  132.         $ret_action null;
  133.         $regex_pattern array();
  134.         $request_keys array();
  135.  
  136.         foreach ($def['path'as $pattern{
  137.             if (preg_match_all('/\{(.*?)\}/'$pattern$matches)) {
  138.                 $request_keys $matches[1];
  139.  
  140.                 $replaces array();
  141.                 foreach ($matches[0as $i => $from{
  142.                     $key $matches[1][$i];
  143.                     $to '([^\/]+?)';
  144.  
  145.                     if (isset($def['patterns']&& isset($def['patterns'][$key])) {
  146.                         $to '('.$def['patterns'][$key].')';
  147.                     }
  148.  
  149.                     $replaces[preg_quote($from'/')$to;
  150.                 }
  151.  
  152.                 $regex_pattern '/^'.str_replace(array_keys($replaces)array_values($replaces)preg_quote($pattern'/')).'$/';
  153.  
  154.                 if (preg_match($regex_pattern$path$match)) {
  155.                     $ret_action $action;
  156.  
  157.                     foreach ($request_keys as $i => $key{
  158.                         if (isset($match[$i+1])) {
  159.                             $http_vars[$key$match[$i+1];
  160.                         }
  161.                     }
  162.                 }
  163.             }
  164.         }
  165.  
  166.         return $ret_action;
  167.     }
  168.  
  169.     /**
  170.      *  Ethna_UrlHandlerクラスのインスタンスを取得する
  171.      *
  172.      *  $name がクラス名 ('_'を含む) の場合はそのクラスを、
  173.      *  そうでないときはプラグイン名とみなしてインスタンスを返す
  174.      *
  175.      *  @access public
  176.      */
  177.     public static function getInstance($name null)
  178.     {
  179.         static $instance array();
  180.         if ($name === null{
  181.             $name = __CLASS__;
  182.         }
  183.         if (isset($instance[$name])) {
  184.             return $instance[$name];
  185.         }
  186.  
  187.         if (strpos($name'_'!== false{
  188.             $instance[$namenew $name();
  189.         else {
  190.             // get instance with plugin
  191.             $ctl Ethna_Controller::getInstance();
  192.             $plugin $ctl->getPlugin();
  193.             $instance[$name$plugin->getPlugin('Urlhandler'$name);
  194.         }
  195.  
  196.         return $instance[$name];
  197.     }
  198.  
  199.     /**
  200.      * get action_map
  201.      * より複雑な定義などを行うときはこれをオーバーライドする
  202.      *
  203.      * @return array 
  204.      */
  205.     protected function getActionMap()
  206.     {
  207.         foreach ($this->action_map as &$def{
  208.             if (is_string($def)) {
  209.                 $def array(
  210.                     'path' => array($def),
  211.                 );
  212.             else if (is_array($def&& isset($def['path']&& is_string($def['path'])) {
  213.                 $def['path'array($def['path']);
  214.             }
  215.         }
  216.  
  217.         return $this->action_map;
  218.     }
  219.  
  220.     /**
  221.      *  ゲートウェイパスを正規化する
  222.      *
  223.      *  @access protected
  224.      */
  225.     protected function normalizePath($path)
  226.     {
  227.         if ($path == ""{
  228.             return array($pathfalse);
  229.         }
  230.  
  231.         $path preg_replace('|/+|''/'$path);
  232.         $path '/'.trim($path'/');
  233.  
  234.         return $path;
  235.     }
  236.  
  237.     /**
  238.      * 引数順にソートする
  239.      *
  240.      * @access protected
  241.      */
  242.     protected function sortPaths(array $paths$sort SORT_ASC)
  243.     {
  244.         $counts array();
  245.         foreach ($paths as $path{
  246.             $counts[substr_count($path'{');
  247.         }
  248.  
  249.         array_multisort($paths$sort$counts);
  250.  
  251.         return $paths;
  252.     }
  253.  
  254.     /**
  255.      *  アクションをリクエストパラメータに変換する
  256.      *
  257.      *  @access protected
  258.      */
  259.     protected function buildActionParameter($http_vars$action)
  260.     {
  261.         if ($action == ""{
  262.             return $http_vars;
  263.         }
  264.  
  265.         $key sprintf('action_%s'$action);
  266.         $http_vars[$key'true';
  267.  
  268.         return $http_vars;
  269.     }
  270. }

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