<?php
/**
 * 處理外部請求變量的類
 *
 * 禁止此文件以外的文件出現 $_POST、$_GET、$_FILES變量及eval函數(用request::myeval )
 * 以便於對主要黑客攻擊進行防範
 *
 * @version        $Id: request.class.php 1 12:03 2010-10-28 tianya $
 * @package        DedeCMS.Libraries
 * @copyright      Copyright (c) 2007 - 2010, DesDev, Inc.
 * @license        http://help.dedecms.com/usersguide/license.html
 * @link           http://www.dedecms.com
 */
// REQUEST常量,用於判斷是否啟用REQUEST類
define('DEDEREQUEST', TRUE);

//簡化 cls_request::item() 函數
function Request($key, $df='')
{
    $GLOBALS['request'] = isset($GLOBALS['request'])? $GLOBALS['request'] : new Request;
    if (!$GLOBALS['request']->isinit)
    {
        $GLOBALS['request']->Init();
    }
    return $GLOBALS['request']->Item($key, $df);
}
class Request
{

    var $isinit = false;
    //用戶的cookie
    var $cookies = array();

    //把GET、POST的變量合併一塊，相當於 _REQUEST
    var $forms = array();
    
    //_GET 變量
    var $gets = array();

    //_POST 變量
    var $posts = array();

    //用戶的請求模式 GET 或 POST
    var $request_type = 'GET';

    //文件變量
    var $files = array();
    
    //嚴禁保存的文件名
    var $filter_filename = '/\.(php|pl|sh|js)$/i';

   /**
    * 初始化用戶請求
    * 對於 post、get 的數據，會轉到 selfforms 數組， 並刪除原來數組
    * 對於 cookie 的數據，會轉到 cookies 數組，但不刪除原來數組
    */
    function Init()
    {
        global $_POST,$_GET;
        //處理post、get
        $formarr = array('p' => $_POST, 'g' => $_GET);
        foreach($formarr as $_k => $_r)
        {
            if( count($_r) > 0 )
            {
                foreach($_r as $k=>$v)
                {
                    if( preg_match('/^cfg_(.*?)/i', $k) )
                    {
                        continue;
                    }
                    $this->forms[$k] = $v;
                    if( $_k=='p' )
                    {
                        $this->posts[$k] = $v;
                    } else {
                        $this->gets[$k] = $v;
                    }
                }
            }
        }
        unset($_POST);
        unset($_GET);
        unset($_REQUEST);
        
        //處理cookie
        if( count($_COOKIE) > 0 )
        {
            foreach($_COOKIE as $k=>$v)
            {
                if( preg_match('/^config/i', $k) )
                {
                    continue;
                }
                $this->cookies[$k] = $v;
            }
        }
        //unset($_POST, $_GET);
        
        //上傳的文件處理
        if( isset($_FILES) && count($_FILES) > 0 )
        {
            $this->filter_files($_FILES);
        }
        $this->isinit = TRUE;
        
        //global變量
        //self::$forms['_global'] = $GLOBALS;
    }

   /**
    * 把 eval 重命名為 myeval
    */
    function MyEval( $phpcode )
    {
        return eval( $phpcode );
    }

   /**
    * 獲得指定表單值
    */
    function Item( $formname, $defaultvalue = '' )
    {
        return isset($this->forms[$formname]) ? $this->forms[$formname] :  $defaultvalue;
    }

   /**
    * 獲得指定臨時文件名值
    */
    function Upfile( $formname, $defaultvalue = '' )
    {
        return isset($this->files[$formname]['tmp_name']) ? $this->files[$formname]['tmp_name'] :  $defaultvalue;
    }

   /**
    * 過濾文件相關
    */
    function FilterFiles( &$files )
    {
        foreach($files as $k=>$v)
        {
            $this->$files[$k] = $v;
        }
        unset($_FILES);
    }

   /**
    * 移動上傳的文件
    */
    function MoveUploadFile( $formname, $filename, $filetype = '' )
    {
        if( $this->is_upload_file( $formname ) )
        {
            if( preg_match($this->filter_filename, $filename) )
            {
                return FALSE;
            }
            else
            {
                return move_uploaded_file($this->files[$formname]['tmp_name'], $filename);
            }
        }
    }

   /**
    * 獲得文件的擴展名
    */
    function GetShortname( $formname )
    {
        $filetype = strtolower(isset($this->files[$formname]['type']) ? $this->files[$formname]['type'] : '');
        $shortname = '';
        switch($filetype)
        {
            case 'image/jpeg':
                $shortname = 'jpg';
                break;
            case 'image/pjpeg':
                $shortname = 'jpg';
                break;
            case 'image/gif':
                $shortname = 'gif';
                break;
            case 'image/png':
                $shortname = 'png';
                break;
            case 'image/xpng':
                $shortname = 'png';
                break;
            case 'image/wbmp':
                $shortname = 'bmp';
                break;
            default:
                $filename = isset($this->files[$formname]['name']) ? $this->files[$formname]['name'] : '';
                if( preg_match("/\./", $filename) )
                {
                    $fs = explode('.', $filename);
                    $shortname = strtolower($fs[ count($fs)-1 ]);
                }
                break;
        }
        return $shortname;
    }

   /**
    * 獲得指定文件表單的文件詳細信息
    */
    function GetFileInfo( $formname, $item = '' )
    {
        if( !isset( $this->files[$formname]['tmp_name'] ) )
        {
            return FALSE;
        }
        else
        {
            if($item=='')
            {
                return $this->files[$formname];
            }
            else
            {
                return (isset($this->files[$formname][$item]) ? $this->files[$formname][$item] : '');
            }
        }
    }

   /**
    * 判斷是否存在上傳的文件
    */
    function IsUploadFile( $formname )
    {
        if( !isset( $this->files[$formname]['tmp_name'] ) )
        {
            return FALSE;
        }
        else
        {
            return is_uploaded_file( $this->files[$formname]['tmp_name'] );
        }
    }
    
    /**
     * 檢查文件後綴是否為指定值
     *
     * @param  string  $subfix
     * @return boolean
     */
     function CheckSubfix($formname, $subfix = 'csv')
    {
        if( $this->get_shortname( $formname ) != $subfix)
        {
            return FALSE;
        }
        return TRUE;
    }
}