forked from extern/egroupware
467 lines
10 KiB
PHP
467 lines
10 KiB
PHP
|
<?php
|
||
|
/*
|
||
|
File: xajaxArgumentManager.inc.php
|
||
|
|
||
|
Contains the xajaxArgumentManager class
|
||
|
|
||
|
Title: xajaxArgumentManager class
|
||
|
|
||
|
Please see <copyright.inc.php> for a detailed description, copyright
|
||
|
and license information.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
@package xajax
|
||
|
@version $Id: xajaxArgumentManager.inc.php 362 2007-05-29 15:32:24Z calltoconstruct $
|
||
|
@copyright Copyright (c) 2005-2007 by Jared White & J. Max Wilson
|
||
|
@copyright Copyright (c) 2008-2009 by Joseph Woolley, Steffen Konerow, Jared White & J. Max Wilson
|
||
|
@license http://www.xajaxproject.org/bsd_license.txt BSD License
|
||
|
*/
|
||
|
|
||
|
if (!defined('XAJAX_METHOD_UNKNOWN')) define('XAJAX_METHOD_UNKNOWN', 0);
|
||
|
if (!defined('XAJAX_METHOD_GET')) define('XAJAX_METHOD_GET', 1);
|
||
|
if (!defined('XAJAX_METHOD_POST')) define('XAJAX_METHOD_POST', 2);
|
||
|
|
||
|
/*
|
||
|
Class: xajaxArgumentManager
|
||
|
|
||
|
This class processes the input arguments from the GET or POST data of
|
||
|
the request. If this is a request for the initial page load, no arguments
|
||
|
will be processed. During a xajax request, any arguments found in the
|
||
|
GET or POST will be converted to a PHP array.
|
||
|
*/
|
||
|
class xajaxArgumentManager
|
||
|
{
|
||
|
/*
|
||
|
Array: aArgs
|
||
|
|
||
|
An array of arguments received via the GET or POST parameter
|
||
|
xjxargs.
|
||
|
*/
|
||
|
var $aArgs;
|
||
|
|
||
|
/*
|
||
|
Boolean: bDecodeUTF8Input
|
||
|
|
||
|
A configuration option used to indicate whether input data should be
|
||
|
UTF8 decoded automatically.
|
||
|
*/
|
||
|
var $bDecodeUTF8Input;
|
||
|
|
||
|
/*
|
||
|
String: sCharacterEncoding
|
||
|
|
||
|
The character encoding in which the input data will be received.
|
||
|
*/
|
||
|
var $sCharacterEncoding;
|
||
|
|
||
|
/*
|
||
|
Integer: nMethod
|
||
|
|
||
|
Stores the method that was used to send the arguments from the client. Will
|
||
|
be one of: XAJAX_METHOD_UNKNOWN, XAJAX_METHOD_GET, XAJAX_METHOD_POST
|
||
|
*/
|
||
|
var $nMethod;
|
||
|
|
||
|
/*
|
||
|
Array: aSequence
|
||
|
|
||
|
Stores the decoding sequence table.
|
||
|
*/
|
||
|
var $aSequence;
|
||
|
|
||
|
/*
|
||
|
Function: convertStringToBool
|
||
|
|
||
|
Converts a string to a bool var.
|
||
|
|
||
|
Parameters:
|
||
|
$sValue - (string):
|
||
|
|
||
|
Returns:
|
||
|
(bool) : true / false
|
||
|
|
||
|
*/
|
||
|
|
||
|
function convertStringToBool($sValue)
|
||
|
{
|
||
|
if (0 == strcasecmp($sValue, 'true'))
|
||
|
return true;
|
||
|
if (0 == strcasecmp($sValue, 'false'))
|
||
|
return false;
|
||
|
if (is_numeric($sValue))
|
||
|
{
|
||
|
if (0 == $sValue)
|
||
|
return false;
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
function argumentStripSlashes(&$sArg)
|
||
|
{
|
||
|
if (false == is_string($sArg))
|
||
|
return;
|
||
|
|
||
|
$sArg = stripslashes($sArg);
|
||
|
}
|
||
|
|
||
|
function argumentDecodeXML(&$sArg)
|
||
|
{
|
||
|
if (false == is_string($sArg))
|
||
|
return;
|
||
|
|
||
|
if (0 == strlen($sArg))
|
||
|
return;
|
||
|
|
||
|
$nStackDepth = 0;
|
||
|
$aStack = array();
|
||
|
$aArg = array();
|
||
|
|
||
|
$nCurrent = 0;
|
||
|
$nLast = 0;
|
||
|
$aExpecting = array();
|
||
|
$nFound = 0;
|
||
|
list($aExpecting, $nFound) = $this->aSequence['start'];
|
||
|
|
||
|
$nLength = strlen($sArg);
|
||
|
|
||
|
$sKey = '';
|
||
|
$mValue = '';
|
||
|
|
||
|
while ($nCurrent < $nLength)
|
||
|
{
|
||
|
$bFound = false;
|
||
|
|
||
|
foreach ($aExpecting as $sExpecting => $nExpectedLength)
|
||
|
{
|
||
|
if ($sArg[$nCurrent] == $sExpecting[0])
|
||
|
{
|
||
|
if ($sExpecting == substr($sArg, $nCurrent, $nExpectedLength))
|
||
|
{
|
||
|
list($aExpecting, $nFound) = $this->aSequence[$sExpecting];
|
||
|
|
||
|
switch ($nFound)
|
||
|
{
|
||
|
case 3: // k
|
||
|
$sKey = '';
|
||
|
break;
|
||
|
case 4: // /k
|
||
|
$sKey = str_replace(
|
||
|
array('<'.'![CDATA[', ']]>'),
|
||
|
'',
|
||
|
substr($sArg, $nLast, $nCurrent - $nLast)
|
||
|
);
|
||
|
break;
|
||
|
case 5: // v
|
||
|
$mValue = '';
|
||
|
break;
|
||
|
case 6: // /v
|
||
|
if ($nLast < $nCurrent)
|
||
|
{
|
||
|
$mValue = str_replace(
|
||
|
array('<'.'![CDATA[', ']]>'),
|
||
|
'',
|
||
|
substr($sArg, $nLast, $nCurrent - $nLast)
|
||
|
);
|
||
|
|
||
|
$cType = substr($mValue, 0, 1);
|
||
|
$sValue = substr($mValue, 1);
|
||
|
switch ($cType) {
|
||
|
case 'S': $mValue = false === $sValue ? '' : $sValue; break;
|
||
|
case 'B': $mValue = $this->convertStringToBool($sValue); break;
|
||
|
case 'N': $mValue = floatval($sValue); break;
|
||
|
case '*': $mValue = null; break;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case 7: // /e
|
||
|
$aArg[$sKey] = $mValue;
|
||
|
break;
|
||
|
case 1: // xjxobj
|
||
|
++$nStackDepth;
|
||
|
array_push($aStack, $aArg);
|
||
|
$aArg = array();
|
||
|
array_push($aStack, $sKey);
|
||
|
$sKey = '';
|
||
|
break;
|
||
|
case 8: // /xjxobj
|
||
|
if (1 < $nStackDepth) {
|
||
|
$mValue = $aArg;
|
||
|
$sKey = array_pop($aStack);
|
||
|
$aArg = array_pop($aStack);
|
||
|
--$nStackDepth;
|
||
|
} else {
|
||
|
$sArg = $aArg;
|
||
|
return;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
$nCurrent += $nExpectedLength;
|
||
|
$nLast = $nCurrent;
|
||
|
$bFound = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (false == $bFound)
|
||
|
{
|
||
|
if (0 == $nCurrent)
|
||
|
{
|
||
|
$sArg = str_replace(
|
||
|
array('<'.'![CDATA[', ']]>'),
|
||
|
'',
|
||
|
$sArg
|
||
|
);
|
||
|
|
||
|
$cType = substr($sArg, 0, 1);
|
||
|
$sValue = substr($sArg, 1);
|
||
|
switch ($cType) {
|
||
|
case 'S': $sArg = false === $sValue ? '' : $sValue; break;
|
||
|
case 'B': $sArg = $this->convertStringToBool($sValue); break;
|
||
|
case 'N': $sArg = floatval($sValue); break;
|
||
|
case '*': $sArg = null; break;
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// for larger arg data, performance may suffer using concatenation
|
||
|
// $sText .= $sArg[$nCurrent];
|
||
|
$nCurrent++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$objLanguageManager =& xajaxLanguageManager::getInstance();
|
||
|
|
||
|
trigger_error(
|
||
|
$objLanguageManager->getText('ARGMGR:ERR:01')
|
||
|
. $sExpecting
|
||
|
. $objLanguageManager->getText('ARGMGR:ERR:02')
|
||
|
. $sArg
|
||
|
, E_USER_ERROR
|
||
|
);
|
||
|
}
|
||
|
|
||
|
function argumentDecodeUTF8_iconv(&$mArg)
|
||
|
{
|
||
|
if (is_array($mArg))
|
||
|
{
|
||
|
foreach (array_keys($mArg) as $sKey)
|
||
|
{
|
||
|
$sNewKey = $sKey;
|
||
|
$this->argumentDecodeUTF8_iconv($sNewKey);
|
||
|
|
||
|
if ($sNewKey != $sKey)
|
||
|
{
|
||
|
$mArg[$sNewKey] = $mArg[$sKey];
|
||
|
unset($mArg[$sKey]);
|
||
|
$sKey = $sNewKey;
|
||
|
}
|
||
|
|
||
|
$this->argumentDecodeUTF8_iconv($mArg[$sKey]);
|
||
|
}
|
||
|
}
|
||
|
else if (is_string($mArg))
|
||
|
$mArg = iconv("UTF-8", $this->sCharacterEncoding.'//TRANSLIT', $mArg);
|
||
|
}
|
||
|
|
||
|
function argumentDecodeUTF8_mb_convert_encoding(&$mArg)
|
||
|
{
|
||
|
if (is_array($mArg))
|
||
|
{
|
||
|
foreach (array_keys($mArg) as $sKey)
|
||
|
{
|
||
|
$sNewKey = $sKey;
|
||
|
$this->argumentDecodeUTF8_mb_convert_encoding($sNewKey);
|
||
|
|
||
|
if ($sNewKey != $sKey)
|
||
|
{
|
||
|
$mArg[$sNewKey] = $mArg[$sKey];
|
||
|
unset($mArg[$sKey]);
|
||
|
$sKey = $sNewKey;
|
||
|
}
|
||
|
|
||
|
$this->argumentDecodeUTF8_mb_convert_encoding($mArg[$sKey]);
|
||
|
}
|
||
|
}
|
||
|
else if (is_string($mArg))
|
||
|
$mArg = mb_convert_encoding($mArg, $this->sCharacterEncoding, "UTF-8");
|
||
|
}
|
||
|
|
||
|
function argumentDecodeUTF8_utf8_decode(&$mArg)
|
||
|
{
|
||
|
if (is_array($mArg))
|
||
|
{
|
||
|
foreach (array_keys($mArg) as $sKey)
|
||
|
{
|
||
|
$sNewKey = $sKey;
|
||
|
$this->argumentDecodeUTF8_utf8_decode($sNewKey);
|
||
|
|
||
|
if ($sNewKey != $sKey)
|
||
|
{
|
||
|
$mArg[$sNewKey] = $mArg[$sKey];
|
||
|
unset($mArg[$sKey]);
|
||
|
$sKey = $sNewKey;
|
||
|
}
|
||
|
|
||
|
$this->argumentDecodeUTF8_utf8_decode($mArg[$sKey]);
|
||
|
}
|
||
|
}
|
||
|
else if (is_string($mArg))
|
||
|
$mArg = utf8_decode($mArg);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
Constructor: xajaxArgumentManager
|
||
|
|
||
|
Initializes configuration settings to their default values and reads
|
||
|
the argument data from the GET or POST data.
|
||
|
*/
|
||
|
function xajaxArgumentManager()
|
||
|
{
|
||
|
$this->aArgs = array();
|
||
|
|
||
|
$this->bDecodeUTF8Input = false;
|
||
|
$this->sCharacterEncoding = 'UTF-8';
|
||
|
$this->nMethod = XAJAX_METHOD_UNKNOWN;
|
||
|
|
||
|
$this->aSequence = array(
|
||
|
'<'.'k'.'>' => array(array(
|
||
|
'<'.'/k'.'>' => 4
|
||
|
), 3),
|
||
|
'<'.'/k'.'>' => array(array(
|
||
|
'<'.'v'.'>' => 3,
|
||
|
'<'.'/e'.'>' => 4
|
||
|
), 4),
|
||
|
'<'.'v'.'>' => array(array(
|
||
|
'<'.'xjxobj'.'>' => 8,
|
||
|
'<'.'/v'.'>' => 4
|
||
|
), 5),
|
||
|
'<'.'/v'.'>' => array(array(
|
||
|
'<'.'/e'.'>' => 4,
|
||
|
'<'.'k'.'>' => 3
|
||
|
), 6),
|
||
|
'<'.'e'.'>' => array(array(
|
||
|
'<'.'k'.'>' => 3,
|
||
|
'<'.'v'.'>' => 3,
|
||
|
'<'.'/e'.'>' => 4
|
||
|
), 2),
|
||
|
'<'.'/e'.'>' => array(array(
|
||
|
'<'.'e'.'>' => 3,
|
||
|
'<'.'/xjxobj'.'>' => 9
|
||
|
), 7),
|
||
|
'<'.'xjxobj'.'>' => array(array(
|
||
|
'<'.'e'.'>' => 3,
|
||
|
'<'.'/xjxobj'.'>' => 9
|
||
|
), 1),
|
||
|
'<'.'/xjxobj'.'>' => array(array(
|
||
|
'<'.'/v'.'>' => 4
|
||
|
), 8),
|
||
|
'start' => array(array(
|
||
|
'<'.'xjxobj'.'>' => 8
|
||
|
), 9)
|
||
|
);
|
||
|
|
||
|
if (isset($_POST['xjxargs'])) {
|
||
|
$this->nMethod = XAJAX_METHOD_POST;
|
||
|
$this->aArgs = $_POST['xjxargs'];
|
||
|
} else if (isset($_GET['xjxargs'])) {
|
||
|
$this->nMethod = XAJAX_METHOD_GET;
|
||
|
$this->aArgs = $_GET['xjxargs'];
|
||
|
}
|
||
|
|
||
|
if (1 == get_magic_quotes_gpc())
|
||
|
array_walk($this->aArgs, array(&$this, 'argumentStripSlashes'));
|
||
|
|
||
|
array_walk($this->aArgs, array(&$this, 'argumentDecodeXML'));
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
Function: getInstance
|
||
|
|
||
|
Returns:
|
||
|
|
||
|
object - A reference to an instance of this class. This function is
|
||
|
used to implement the singleton pattern.
|
||
|
*/
|
||
|
function &getInstance()
|
||
|
{
|
||
|
static $obj;
|
||
|
if (!$obj) {
|
||
|
$obj = new xajaxArgumentManager();
|
||
|
}
|
||
|
return $obj;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
Function: configure
|
||
|
|
||
|
Accepts configuration settings from the main <xajax> object.
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
|
||
|
The <xajaxArgumentManager> tracks the following configuration settings:
|
||
|
|
||
|
<decodeUTF8Input> - (boolean): See <xajaxArgumentManager->bDecodeUTF8Input>
|
||
|
<characterEncoding> - (string): See <xajaxArgumentManager->sCharacterEncoding>
|
||
|
*/
|
||
|
function configure($sName, $mValue)
|
||
|
{
|
||
|
if ('decodeUTF8Input' == $sName) {
|
||
|
if (true === $mValue || false === $mValue)
|
||
|
$this->bDecodeUTF8Input = $mValue;
|
||
|
} else if ('characterEncoding' == $sName) {
|
||
|
$this->sCharacterEncoding = $mValue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
Function: getRequestMethod
|
||
|
|
||
|
Returns the method that was used to send the arguments from the client.
|
||
|
*/
|
||
|
function getRequestMethod()
|
||
|
{
|
||
|
return $this->nMethod;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
Function: process
|
||
|
|
||
|
Returns the array of arguments that were extracted and parsed from
|
||
|
the GET or POST data.
|
||
|
*/
|
||
|
function process()
|
||
|
{
|
||
|
if ($this->bDecodeUTF8Input)
|
||
|
{
|
||
|
$sFunction = '';
|
||
|
|
||
|
if (function_exists('iconv'))
|
||
|
$sFunction = "iconv";
|
||
|
else if (function_exists('mb_convert_encoding'))
|
||
|
$sFunction = "mb_convert_encoding";
|
||
|
else if ($this->sCharacterEncoding == "ISO-8859-1")
|
||
|
$sFunction = "utf8_decode";
|
||
|
else {
|
||
|
$objLanguageManager =& xajaxLanguageManager::getInstance();
|
||
|
trigger_error(
|
||
|
$objLanguageManager->getText('ARGMGR:ERR:03')
|
||
|
, E_USER_NOTICE
|
||
|
);
|
||
|
}
|
||
|
|
||
|
$mFunction = array(&$this, 'argumentDecodeUTF8_' . $sFunction);
|
||
|
|
||
|
array_walk($this->aArgs, $mFunction);
|
||
|
|
||
|
$this->bDecodeUTF8Input = false;
|
||
|
}
|
||
|
|
||
|
return $this->aArgs;
|
||
|
}
|
||
|
}
|