<?php
/* SVN FILE: $Id: rkt_request.php 365 2008-05-13 04:31:00Z bb_yujiro $ */
/**
 * リクエストデータの取得
 *
 * PHP versions 5
 *
 *      hitSuji : Social Network Service <http://rakuto.net/rktSNS/>
 *      Copyright (c) 2007 Yujiro Takahashi
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @filesource
 * @package         hitSuji
 * @copyright       Copyright (c) 2007 Yujiro Takahashi
 * @link            http://rakuto.net/
 * @author          Yujiro Takahashi <yujiro@rakuto.net>
 * @version         $Revision: 365 $
 * @modifiedby      $LastChangedBy: bb_yujiro $
 * @lastmodified    $Date: 2008-05-13 13:31:00 +0900 (火, 13 5 2008) $
 * @license         http://opensource.org/licenses/mit-license.php The MIT License
 */

require LIB_DIR.'rktRequest/StripAttributes.php';
require LIB_DIR.'PEAR/Validator/Validate.php';

/**
 * リクエストデータクラス
 *
 * @category        Request
 * @package         hitSuji
 * @copyright       Copyright (c) 2007 Yujiro Takahashi
 * @link            http://rakuto.net/
 * @author          Yujiro Takahashi <yujiro@rakuto.net>
 * @version         $Revision: 365 $
 * @modifiedby      $LastChangedBy: bb_yujiro $
 * @lastmodified    $Date: 2008-05-13 13:31:00 +0900 (火, 13 5 2008) $
 * @license         http://opensource.org/licenses/mit-license.php The MIT License
 */
class RKT_Request extends Validate
{
    /**
     * 取得したグローバルスコープ値格納用
     * @access public
     * @var string
     */
    public $requests =  array();

    /**
     * Singleton用インスタンス
     * @var object
     */
    private static $_instance;

    /**
     * グローバルスコープ名
     * @access private
     * @var string
     */
    private $_request_type = '_REQUEST';

    /**
     * 個別警告フラグ格納用
     * @access private
     * @var array
     */
    private $_alerts = array();

    /**
     * PathInfo引数格納用
     * @access private
     * @var array
     */
    private $_path_args = array();

    /**
     * PathInfo引数カーソル
     * @access private
     * @var integer
     */
    private $_arg_cursor = 0;

    /**
     * 正当性フラグ
     * @access private
     * @var integer
     */
    private $_validated = true;

    /**
     * コンストラクタ
     *
     * @access public
     * @param array $request グローバルスコープ名
     */
    private function __construct($request_type = '_REQUEST')
    {
        $this->_request_type = $request_type;
        $this->_validated    = true;

        $path_info = empty($_SERVER[PATH_INFO_KEY])?'':$_SERVER[PATH_INFO_KEY];
        $this->_path_args  = explode('/', $path_info);
        $this->_arg_cursor = PATH_INFO_START;
    }

    /**
     * Singleton メソッド
     *
     * @access public
     * @return object
     */
    public static function &getInstance($request_type = '_REQUEST')
    {
        if (!isset(self::$_instance)) {
            $classname = __CLASS__;
            self::$_instance = new $classname($request_type);
        }
        return self::$_instance;
    }

    /**
     * 入力方法の設定
     *
     * @access public
     * @param string $request グローバルスコープ名
     */
    public function setRequestType($request_type = '_REQUEST')
    {
        $this->_request_type = $request_type;
    }

    /**
     * 対象のグローバル格納値の取得
     *
     * @access public
     * @param string $key
     * @return mixed グローバル格納値
     */
    public function getRequest($key)
    {
        return isSet($this->requests[$key])? $this->requests[$key]:null;
    }

    /**
     * グローバル格納配列の取得
     *
     * @access public
     * @return array グローバル格納配列
     */
    public function getRequests()
    {
        return $this->requests;
    }

    /**
     * 警告格納配列の取得
     *
     * @access public
     * @return array 警告格納配列
     */
    public function getAlerts()
    {
        return $this->_alerts;
    }

    /**
     * 警告配列の設定
     *
     * @access public
     * @param string $key 入力キー
     * @param string $alert 警告文字列
     */
    public function setAlert($key)
    {
        $this->_alerts[$key] = true;
        $this->_validated = false;
    }

    /**
     * 正当性状態を初期状態に戻す
     *
     * @access public
     * @return void
     */
    public function resetValidated()
    {
        $this->_alerts = array();
        $this->_validated = true;
    }

    /**
     * 正当性状態の取得
     *
     * @access public
     * @return integer チェック結果
     */
    public function getValidate()
    {
        return $this->_validated;
    }

    /**
     * ダミー
     *
     * @access public
     * @parmas mixed $value
     * @param mixed $option オプション
     * @return boolean 真:正常 偽:エラー
     */
    public static function dummy($value, $option=null)
    {
        return true;
    }

    /**
     * 配列対応で属性のストリップ
     *
     * @access public
     * @param mixed $value
     * @param mixed $option ダミー
     * @retrun mixed
     */
    public static function multiStripAttribute($values, $option=null)
    {
        if (!is_array($values)){
            $value = trim($values);
            if (get_magic_quotes_gpc()) {
                $value = stripslashes($value);
            }

            $objsatr = Request_StripAttributes::getInstance(STRIP_ATTR_DRIVER);
            $objsatr->setAllowable(ALLOWABLE_ATTRIBUTES);
            $objsatr->setStripScript(false);
            return $objsatr->getParsed($value);
        }
        $result = array();
        foreach ($values as $key=>$value){
            $result[$key] = self::multiStripAttribute($value);
        }
        return $result;
    }

    /**
     * 配列対応でJavaScriptのストリップ
     *
     * @access public
     * @param mixed $value
     * @param mixed $option ダミー
     * @retrun mixed
     */
    public static function multiStripJavaScript($values, $option=null)
    {
        if (!is_array($values)){
            $value = trim($values);
            if (get_magic_quotes_gpc()) {
                $value = stripslashes($value);
            }
            $objsatr = Request_StripAttributes::getInstance(STRIP_ATTR_DRIVER);
            $objsatr->setAllowable(ALLOWABLE_ATTRIBUTES);
            $objsatr->setStripScript(true);
            $value = $objsatr->getParsed($value);
            
            return str_replace('javascript:', '', $value);
        }
        $result = array();
        foreach ($values as $key=>$value){
            $result[$key] = self::multiStripJavaScript($value);
        }
        return $result;
    }

    /**
     * 配列対応のストリップスラッシュ
     *
     * @access public
     * @param mixed $value
     * @param mixed $option ダミー
     * @retrun mixed
     */
    public static function multiStripSlashes($values, $option=null)
    {
        if (!is_array($values)){
            $value = trim($values);
            if (get_magic_quotes_gpc()) {
                $value = stripslashes($value);
            }
            return $value;
        }
        $result = array();
        foreach ($values as $key=>$value){
            $result[$key] = self::multiStripSlashes($value);
        }
        return $result;
    }

    /**
     * 配列対応のストリップタグ
     *
     * @access public
     * @parmas mixed $value
     * @param mixed $option オプション
     * @return mixed ストリップタグ
     */
    public static function multiStripTags($value, $option)
    {
        extract($option);
        $tags = empty($tags) ?null:$tags;

        if (!is_array($value)){
            return strip_tags($value, $tags);
        }
        foreach ($value as $key=>$row){
            $value[$key] = self::multiStripTags($row, $option);
        }
        return $value;
    }

    /**
     * HTML BODY用エフェクト
     *
     * @access public
     * @parmas mixed $value
     * @param mixed $option オプション
     * @return mixed
     */
    public static function htmlBody($value, $option=null)
    {
        $value = self::multiStripAttribute($value);

        /* 各種プラグイン処理 */
        $value = loadPlugin::exec()->requestHtmlBody($value);
        return $value;
    }

    /**
     * 年齢の出力
     *
     * @access public
     * @parmas mixed $value
     * @param mixed $option オプション
     * @return string
     */
    public function ageToDate($value, $option=null) 
    {
        if (empty($value)){
            return null;
        }
        $value = intval($value);
        if (!is_int($value)){
            return null;
        }

        if (empty($option['left'])){
            $year = intval(date('Y')) - $value;
        } else {
            $year = intval(date('Y')) - $value -1;
        }
        return date($year.'-m-d');
    }

    /**
     * 日付フォーマット変換
     *
     * @access public
     * @parmas mixed $value
     * @param mixed $option オプション
     * @return string
     */
    public function strToDate($value, $option) 
    {
        extract($option);
        $format = empty($format) ?'Y-m-d':$format;
        
        if (is_numeric($value)){
            $value = date($format, $value);
        } else {
            $value = fDate($value, $format);
        }

        return $value;
    }

    /**
     * 配列対応の数値検閲
     *
     * @access public
     * @parmas mixed $value
     * @param array $option
     * @return boolean
     */
    public function multiNumber($value, $option=null)
    {
        if (!is_array($value)){
            return parent::number($value, $option);
        }
        $result = true;
        foreach ($value as $row){
            $result &= self::multiNumber($row, $option);
        }
        return $result;
    }

    /**
     * 必須項目
     *
     * @access public
     * @parma mixed $value
     * @param mixed $option オプション
     * @return boolean 真:正常 偽:エラー
     */
    public function required($value, $option=null)
    {
        if ($value == '') {
            return false;
        }
        return true;
    }

    /**
     * カーソル位置の設定
     *
     * @access public
     * @param integer $cursor 
     */
    public function setArgCursor($cursor)
    {
        $this->_arg_cursor = $cursor;
    }

    /**
     * フォームからの値の正当性を確認
     *
     * <code><pre>
     * $conditions = array (
     *      'type'=>     'nunber',
     *      'option'=>   array(),
     *      'required'=> true,
     *      'effect'=>   array('RKT_Request', 'multiStripTags'),
     *      'pic_up'=>   'Ooutside',
     * );
     * $object->catchValidate('input', $conditions);
     * </pre></code>
     *
     * @access public
     * @param string $key 確認対象情報
     * @param array $conditions 実行条件
     * @return boolean 真:正常 偽:エラー
     */
    public function catchValidate($key, $conditions)
    {
        extract($conditions);

        $source   = null;
        $required = empty($required) ?false:$required;
        $require  = $required ?'required':'dummy';
        $effect   = empty($effect)? array(__CLASS__, 'multiStripTags'):$effect;
        $pic_up   = empty($pic_up) ?'OoutSide':$pic_up;

        $func   = array(&$this, '_get'.$pic_up);
        $source = call_user_func($func, $key);

        $this->requests[$key] = call_user_func($effect, $source, $option);
        $this->_alerts[$key]  = null;

        /* 対象が日付型の場合 */
        if ($type == 'date'){
            $source = joinDate($source);
        }
        /* validateの対象を配列に */
        $values = is_array($source) ? $source : array($source);
        foreach ($values as $value){
            $method = empty($value)? $require:$type;
            $func = array(__CLASS__, $method);

            $result = call_user_func($func, $value, $option);
            if (!$result)   break;
        }

        /* 正当性結果の保存 */
        if (!$result && isSet($input)){
            $this->_validated      = false;
            $this->_alerts[$key]   = true;
            $this->requests[$key] = null;
        } elseif ($this->_request_type === '_POST') {
            /* 各種プラグイン処理 */
            $this->requests[$key] = loadPlugin::exec()->requestFilter($this->requests[$key], $type);
        }

        return $result;
    }

    /**
     * PHPの外部から来る変数の取得
     *
     * @access private
     * @parma string $key
     * @return mixed
     */
    private function _getOoutSide($key)
    {
        $value = null;
        eval('$request = isSet($'.$this->_request_type.'[$key]);');
        if (!$request){
            return false;
        }
        eval('$value = $'.$this->_request_type.'[$key];');
        return $value;
    }

    /**
     * PathInfo変数の取得
     *
     * @access private
     * @parma string $key
     * @return mixed
     */
    private function _getPathArgs($key)
    {
        $value = null;
        if (isSet($this->_path_args[$this->_arg_cursor])){
            $value = $this->_path_args[$this->_arg_cursor];
        }
        $this->_arg_cursor++;

        return $value;
    }
} // RKT_Request
?>
