Source for file ActionChain.php

Documentation is available at ActionChain.php

  1. <?php
  2. /**
  3.  * Teeple2 - PHP5 Web Application Framework inspired by Seasar2
  4.  *
  5.  * PHP versions 5
  6.  *
  7.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  8.  * that is available through the world-wide-web at the following URI:
  9.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  10.  * the PHP License and are unable to obtain it through the web, please
  11.  * send a note to license@php.net so we can mail you a copy immediately.
  12.  *
  13.  * @package     teeple
  14.  * @author      Mitsutaka Sato <miztaka@gmail.com>
  15.  * @license     http://www.php.net/license/3_0.txt  PHP License 3.0
  16.  */
  17.  
  18. /**
  19.  * Actionを管理するクラス。
  20.  * このクラスを使ってActionのForwardに対応する。
  21.  * @package     teeple
  22.  */
  23. {
  24.     /**
  25.      * Actionのリスト
  26.      * @var array 
  27.      */
  28.     protected $_list = array();
  29.  
  30.     /**
  31.      * @var 現在実行されているActionの位置を保持する 
  32.      */
  33.     protected $_index = 0;
  34.     
  35.     /**
  36.      * @var Logger 
  37.      */
  38.     protected $log;
  39.     
  40.     /**
  41.      * @var Teeple_Request 
  42.      */
  43.     private $request;
  44.     public function setComponent_Teeple_Request($c{
  45.         $this->request $c;
  46.     }
  47.     
  48.     /**
  49.      * @var Teeple_Container 
  50.      */
  51.     private $container;
  52.     public function setComponent_container($c{
  53.         $this->container $c;
  54.     }
  55.     
  56.     /**
  57.      * @var Teeple_Response 
  58.      */
  59.     private $response;
  60.     public function setComponent_Teeple_Response($c{
  61.         $this->response $c;
  62.     }
  63.     
  64.     /**
  65.      * @var Teeple_ValidatorManager 
  66.      */
  67.     private $validatorManager;
  68.     public function setComponent_Teeple_ValidatorManager($c{
  69.         $this->validatorManager $c;
  70.     }
  71.  
  72.     /**
  73.      * @var Teeple_ConverterManager 
  74.      */
  75.     private $converterManager;
  76.     public function setComponent_Teeple_ConverterManager($c{
  77.         $this->converterManager $c;
  78.     }
  79.     
  80.     /**
  81.      * コンストラクター
  82.      */
  83.     public function __construct({
  84.         $this->log = LoggerManager::getLogger(get_class($this));
  85.     }
  86.  
  87.     /**
  88.      * Actionを追加する
  89.      *
  90.      * @param   string  $name   Actionのクラス名
  91.      */
  92.     public function add($name{
  93.  
  94.         // Actionのクラス名をチェック
  95.         if (!preg_match("/^[0-9a-zA-Z_]+$/"$name)) {
  96.             throw new Teeple_Exception("Actionクラス名が不正です。");
  97.         }
  98.  
  99.         // Actionクラスのインスタンス化
  100.         $className Teeple_Util::capitalizedClassName($name);
  101.         $action $this->container->getPrototype($className);
  102.         if (!is_object($action)) {
  103.             throw new Teeple_Exception("Actionクラスの生成に失敗しました。({$className})");
  104.         }
  105.  
  106.         array_push($this->_list$action);
  107.         return;
  108.     }
  109.  
  110.     /**
  111.      * ActionChainをクリアする。
  112.      *
  113.      */
  114.     public function clear({
  115.         $this->_list = array();
  116.         $this->_index     = 0;
  117.     }
  118.  
  119.     /**
  120.      * ActionChainに次のActionがあるかどうか?
  121.      * @return boolean 
  122.      */
  123.     public function hasNext({
  124.         return ($this->_index < (count($this->_list1));
  125.     }
  126.  
  127.     /**
  128.      * ActionChainを次に進める
  129.      *
  130.      */
  131.     public function next({
  132.         
  133.         if ($this->_index >= count($this->_list)) {
  134.             throw new Teeple_Exception("次のアクションはありません。");
  135.         }
  136.         $this->_index++;
  137.         return;
  138.     }
  139.  
  140.     /**
  141.      * 現在のAction名を返却
  142.      *
  143.      * @return  string  Actionの名前
  144.      */
  145.     public function getCurActionName({
  146.         return strtolower(get_class($this->getCurAction()));
  147.     }
  148.     
  149.     /**
  150.      * リストの先頭のActionのインスタンスを返却
  151.      *
  152.      * @return Teeple_ActionBase 
  153.      */
  154.     public function getCurAction({
  155.         return $this->_list[$this->_index];
  156.     }
  157.     
  158.     /**
  159.      * ActionChainを実行します。
  160.      *
  161.      */
  162.     public function execute({
  163.         
  164.         if (count($this->_list== 0{
  165.             throw new Teeple_Exception("Actionが1つも登録されていません。");
  166.         }
  167.         
  168.         while (true{
  169.             // Actionを実行する
  170.             $view $this->executeAction();
  171.             if ($view == ""{
  172.                 $actionName $this->getCurActionName();
  173.                 $view str_replace('_','/',$actionName).".html";
  174.             }
  175.             // Actionへのフォワードの場合
  176.             if (preg_match("/^action:/"$view)) {
  177.                 $action preg_replace("/action:/"""$view);
  178.                 $this->add(trim($action));
  179.                 $this->request->setFilterError(NULL);
  180.             else {
  181.                 $this->response->setView($view);
  182.             }
  183.             // 次へ進む
  184.             if ($this->hasNext()) {
  185.                 break;
  186.             }
  187.             $this->next();
  188.         }
  189.         return;
  190.     }
  191.  
  192.     /**
  193.      * Actionを実行
  194.      *
  195.      * @return string viewのパス
  196.      */
  197.     private function executeAction({
  198.  
  199.         // 現在のアクションを取得
  200.         $action $this->getCurAction();
  201.         if (!is_object($action)) {
  202.             throw new Teeple_Exception("Actionオブジェクトが取得できません。");
  203.         }
  204.         $className get_class($action);
  205.         $this->log->info("アクション {$className} を実行します。");
  206.         
  207.         // メソッド名
  208.         $methodName $this->request->getActionMethod();
  209.         if (method_exists($action$methodName)) {
  210.             $methodName 'execute';
  211.         }
  212.         
  213.         // Converterの実行
  214.         $params $this->request->getParameters();
  215.         $this->doConverter($action$params);
  216.         
  217.         // Requestの値をActionに移す
  218.         if (count($params0{
  219.             foreach($params as $name => $value{
  220.                 if (preg_match('/^__/'$name)) {
  221.                     continue;
  222.                 }
  223.                 $action->$name $params[$name];
  224.             }
  225.         }
  226.         
  227.         if ($this->request->isFilterError()) {
  228.             // Validatorの実行
  229.             $this->doValidation($action$methodName);
  230.         }
  231.         
  232.         // エラーが発生している場合は、onXXError()メソッドを実行する。
  233.         if ($this->request->isFilterError()) {
  234.             $type $this->request->getFilterError();
  235.             $this->log->debug("errortype: $type");
  236.             if ($type != ""{
  237.                 $methodName 'on'.$type.'Error';
  238.                 $this->log->info("メソッド {$methodName} を実行します。");
  239.                 if (method_exists($action$methodName)) {
  240.                     return $action->$methodName();
  241.                 }
  242.                 $this->log->warn("メソッド {$methodName} が存在しません。");
  243.                 return NULL;
  244.             }
  245.         }
  246.         
  247.         // Actionメソッドを実行する。
  248.         $this->log->info("メソッド {$methodName} を実行します。");
  249.         return $action->$methodName();
  250.     }
  251.     
  252.     /**
  253.      * バリデーションを実行します。
  254.      *
  255.      * @param Teeple_ActionBase $action 
  256.      * @param string $methodName 
  257.      */
  258.     private function doValidation($action$methodName{
  259.         
  260.         $className get_class($action);
  261.         if (defined($className."::VALIDATION_CONFIG")) {
  262.             return;
  263.         }
  264.         if (defined($className."::VALIDATION_TARGET")) {
  265.             $targets explode(','constant($className."::VALIDATION_TARGET"));
  266.             array_walk($targets'trim');
  267.             if (in_array($methodName$targets)) {
  268.                 $this->log->info("メソッド{$methodName}はValidation対象ではありません。");
  269.                 return;
  270.             }
  271.         }
  272.         
  273.         $validationConfig $this->validatorManager->parseYAML(constant($className."::VALIDATION_CONFIG"));
  274.         if ($this->validatorManager->execute($action$validationConfig)) {
  275.             $this->request->setFilterError('Validate');
  276.         }
  277.         
  278.         return;
  279.     }
  280.     
  281.     /**
  282.      * Converterを実行します。
  283.      *
  284.      * @param Teeple_ActionBase $action 
  285.      * @param array $params 
  286.      */
  287.     private function doConverter($action&$params{
  288.         
  289.         $className get_class($action);
  290.         if (defined($className."::CONVERTER_CONFIG")) {
  291.             return;
  292.         }
  293.         
  294.         $yamlConfig Horde_Yaml::load(constant($className."::CONVERTER_CONFIG"));
  295.         if (is_array($yamlConfig)) {
  296.             throw new Teeple_Exception("Converterの設定を解析できませんでした。");
  297.         }
  298.         //$this->log->debug(var_export($yamlConfig, true));
  299.         
  300.         $this->converterManager->execute($params$yamlConfig);
  301.     }
  302.  
  303. }
  304. ?>

Documentation generated on Mon, 26 Apr 2010 08:59:28 +0900 by phpDocumentor 1.4.3