<?php
/**
 * -----------------------------------------------------------------------------
 *
 * SyL - Web Application Framework for PHP
 *
 * PHP version 4 (>= 4.3.x) or 5
 *
 * Copyright (C) 2006 k.watanabe
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * -----------------------------------------------------------------------------
 * @package   SyL
 * @author    k.watanabe <k.watanabe@syl.jp>
 * @copyright 2006 k.watanabe
 * @license   http://www.opensource.org/licenses/lgpl-license.php
 * @version   CVS: $Id: SyL_DataManager.php,v 1.3 2007/01/03 11:17:37 seasonstream Exp $
 * @link      http://www.syl.jp/
 * -----------------------------------------------------------------------------
 */

/**
 * コンポーネントメソッドクラス
 */
require_once SYL_INCLUDE_DIR . '/framework/SyL_ComponentMethod.php';

/**
 * フレームワークデータ管理クラス
 *
 * @package   SyL
 * @author    k.watanabe <k.watanabe@syl.jp>
 * @copyright 2006 k.watanabe
 * @license   http://www.opensource.org/licenses/lgpl-license.php
 * @version   CVS: $Id: SyL_DataManager.php,v 1.3 2007/01/03 11:17:37 seasonstream Exp $
 * @link      http://www.syl.jp/
 */
class SyL_DataManager
{
    /**
     * テンプレートファイル
     * 
     * @access private
     * @var string
     */
    var $template_file = '';
    /**
     * ビューパラメータ
     * 
     * @access private
     * @var array
     */
    var $view_parameters = array();
    /**
     * パラメータ
     * 
     * @access private
     * @var string
     */
    var $parameters = array();
    /**
     * コントローラオブジェクト
     * 
     * @access private
     * @var object
     */
    var $controller = null;
    /**
     * ルータオブジェクト
     * 
     * @access private
     * @var object
     */
    var $router = null;
    /**
     * コンポーネントメソッドオブジェクト
     * 
     * @access private
     * @var object
     */
    var $cm = null;

    /**
     * コンストラクタ
     *
     * @access public
     * @param object コントローラオブジェクト
     */
    function SyL_DataManager(&$controller)
    {
        $this->cm =& new SyL_ComponentMethod($controller);
        $this->controller =& $controller;
    }

    /**
     * 遷移情報オブジェクトをセット
     *
     * @access public
     * @param object 遷移情報オブジェクト
     */
    function setRouter(&$router)
    {
        $this->router =& $router;
        // デバック - アクションの状態
        SyL_Loggers::debug("[DataManager] action info - name: " . $this->getActionName() . " dir: " . $this->getActionDir() . " file: " . $this->getActionFile() . " class: " . $this->getClassName());
    }

    /**
     * アクション名を取得
     *
     * @access public
     * @return string アクション名
     */
    function getActionName()
    {
        return is_object($this->router) ? $this->router->getActionName() : null;
    }

    /**
     * アクションディレクトリを取得
     *
     * @access public
     * @return string アクションディレクトリ
     */
    function getActionDir()
    {
        return $this->controller->getActionDir();
    }

    /**
     * アクションファイルを取得
     *
     * @access public
     * @return string アクションファイル
     */
    function getActionFile()
    {
        return is_object($this->router) ? $this->router->getActionFile() : null;
    }

    /**
     * クラス名を取得
     *
     * @access public
     * @return string クラス名
     */
    function getClassName()
    {
        return is_object($this->router) ? $this->router->getClassName() : null;
    }

    /**
     * PATH_INFO配列を取得
     *
     * @access public
     * @return array PATH_INFO配列
     */
    function getPathInfoArray()
    {
        return is_object($this->router) ? $this->router->getPathInfoArray() : null;
    }

    /**
     * テンプレートファイルをセット
     * 
     * @access public
     * @param string テンプレートファイル
     */
    function setTemplateFile($template_file)
    {
        $this->template_file = $template_file;
    }

    /**
     * テンプレートディレクトリを取得
     * 
     * @access public
     * @return string テンプレートディレクトリ
     */
    function getTemplateDir()
    {
        return $this->convertPath($this->controller->getTemplateDir(), true);
    }

    /**
     * テンプレートファイルを取得
     * 
     * @access public
     * @return string テンプレートファイル
     */
    function getTemplateFile()
    {
        $template_dir  = $this->getTemplateDir();
        $template_file = $this->convertPath($this->template_file, false);
        $real_path     = realpath($template_dir . $template_file);
        $reg           = '/^' . preg_quote($template_dir, '/') . '/';

        // デバック - テンプレートの状態
        SyL_Loggers::debug("[DataManager] template info  dir: {$template_dir} file: {$template_file}");

        // ファイル存在チェック
        if (!preg_match($reg, $real_path)) {
            SyL_Response::redirect404();
        }
        return $template_file;
    }

    /**
     * ビューパラメータセット
     * 
     * @access public
     * @param string ビューパラメータ名
     * @param string ビューパラメータ値
     */
    function setViewParameter($name, $value)
    {
        $this->view_parameters[$name] = $value;
    }

    /**
     * ビューパラメータを取得
     * 
     * @access public
     * @param string ビューパラメータ名
     * @return string ビューパラメータ値
     */
    function getViewParameter($name)
    {
        return isset($this->view_parameters[$name]) ? $this->view_parameters[$name] : '';
    }

    /**
     * パス補正
     * 
     * @access public
     * @param string 補正前パス
     * @return string 補正後パス
     */
    function convertPath($path, $is_dir_path=false)
    {
        if ($is_dir_path && !preg_match('/(\\\\|\/)$/', $path)) {
            $path .= '/';
        } else if (!$is_dir_path && preg_match('/^(\\\\|\/)/', $path)) {
            $path = substr($path, 1);
        }
        return $path;
    }

    /**
     * フィルタから値を取得する
     * 
     * @access public
     * @param string フィルタ名
     * @return mixed フィルタからの戻り値
     */
    function triggerFilter($name)
    {
        return $this->cm->triggerFilter($name);
    }

    /**
     * アプリケーションコンポーネントから値を取得する
     * 
     * @access public
     * @param string アプリケーションコンポーネント名
     * @return mixed アプリケーションコンポーネントからの戻り値
     */
    function triggerApp($name)
    {
        return $this->cm->triggerApp($name);
    }

    /**
     * アクション実行判定をセット
     * 
     * @access public
     * @param bool true: 実行する、false: 実行しない
     */
    function setExecuteAction($is_execute_action)
    {
        $this->controller->setExecuteAction($is_execute_action);
    }

    /**
     * コンポーネントオブジェクトをセット
     * 
     * @access public
     * @param string コンポーネント名
     * @return object コンポーネント
     */
    function &getComponent($name)
    {
        return $this->controller->container->getComponent($name);
    }


    /**
     * レイアウトパラメータをセット
     * 
     * @access public
     * @param string パラメータ名
     * @param mixed パラメータ値
     */
    function setParameter($name, $value)
    {
        $this->parameters[$name] = $value;
    }

    /**
     * レイアウトパラメータをセット（参照）
     *
     * @access public
     * @param string パラメータ名
     * @param mixed パラメータ値
     */
    function setParameterRef($name, &$value)
    {
        $this->parameters[$name] =& $value;
    }

    /**
     * 全パラメータを取得
     * 
     * @access public
     * @return array 全パラメータ
     */
    function &getParameters()
    {
        return $this->parameters;
    }

    /**
     * アクションオブジェクトをセット
     * 
     * @access public
     */
    function setActionValues()
    {
        if ($this->controller->container->isComponent(SYL_ACTION_KEY)) {
            $action =& $this->getComponent(SYL_ACTION_KEY);

            // アクションオブジェクトが存在する（アクション実行後）ならば、
            // プロパティを取得する
            foreach (get_object_vars($action) as $key => $value) {
                if (substr($key, 0, 1) != '_') {
                    if (is_object($value)) {
                        $this->setParameterRef($key, $value);
                    } else {
                        $this->setParameter($key, $value);
                    }
                }
            }

            // アプリケーションコンポネント削除
            $this->cm->deleteAppComponent();
            // アクションオブジェクト削除
            unset($action);
            $this->controller->container->deleteComponent(SYL_ACTION_KEY);
        } else {
            // アクションオブジェクトが存在しない（アクション実行無し）ならば、
            // アクションのクラスからデフォルトプロパティを取得する
            $action_file = $this->getActionDir() . $this->getActionFile();
            if (is_file($action_file)) {
                include_once $action_file;
                $action_class = $this->getClassName();
                if (class_exists($action_class)) {
                    foreach (get_class_vars($action_class) as $key => $value) {
                        $this->setParameter($key, $value);
                    }
                }
            }
        }
    }
}

?>
