PageRenderTime 43ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/ccds_library/xajax/xajax_core/xajaxArgumentManager.inc.php

http://ccds.googlecode.com/
PHP | 450 lines | 308 code | 54 blank | 88 comment | 67 complexity | 16040b1db024de55c83ad923eca0fef8 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0, LGPL-2.1
  1. <?php
  2. /*
  3. File: xajaxArgumentManager.inc.php
  4. Contains the xajaxArgumentManager class
  5. Title: xajaxArgumentManager class
  6. Please see <copyright.inc.php> for a detailed description, copyright
  7. and license information.
  8. */
  9. /*
  10. @package xajax
  11. @version $Id: xajaxArgumentManager.inc.php 362 2007-05-29 15:32:24Z calltoconstruct $
  12. @copyright Copyright (c) 2005-2006 by Jared White & J. Max Wilson
  13. @license http://www.xajaxproject.org/bsd_license.txt BSD License
  14. */
  15. if (!defined('XAJAX_METHOD_UNKNOWN')) define('XAJAX_METHOD_UNKNOWN', 0);
  16. if (!defined('XAJAX_METHOD_GET')) define('XAJAX_METHOD_GET', 1);
  17. if (!defined('XAJAX_METHOD_POST')) define('XAJAX_METHOD_POST', 2);
  18. /*
  19. Class: xajaxArgumentManager
  20. This class processes the input arguments from the GET or POST data of
  21. the request. If this is a request for the initial page load, no arguments
  22. will be processed. During a xajax request, any arguments found in the
  23. GET or POST will be converted to a PHP array.
  24. */
  25. class xajaxArgumentManager
  26. {
  27. /*
  28. Array: aArgs
  29. An array of arguments received via the GET or POST parameter
  30. xjxargs.
  31. */
  32. var $aArgs;
  33. /*
  34. Boolean: bDecodeUTF8Input
  35. A configuration option used to indicate whether input data should be
  36. UTF8 decoded automatically.
  37. */
  38. var $bDecodeUTF8Input;
  39. /*
  40. String: sCharacterEncoding
  41. The character encoding in which the input data will be received.
  42. */
  43. var $sCharacterEncoding;
  44. /*
  45. Integer: nMethod
  46. Stores the method that was used to send the arguments from the client. Will
  47. be one of: XAJAX_METHOD_UNKNOWN, XAJAX_METHOD_GET, XAJAX_METHOD_POST
  48. */
  49. var $nMethod;
  50. /*
  51. Array: aSequence
  52. Stores the decoding sequence table.
  53. */
  54. var $aSequence;
  55. function convertStringToBool($sValue)
  56. {
  57. if (0 == strcasecmp($sValue, 'true'))
  58. return true;
  59. if (0 == strcasecmp($sValue, 'false'))
  60. return false;
  61. if (is_numeric($sValue))
  62. {
  63. if (0 == $sValue)
  64. return false;
  65. return true;
  66. }
  67. return false;
  68. }
  69. function argumentStripSlashes(&$sArg)
  70. {
  71. if (false == is_string($sArg))
  72. return;
  73. $sArg = stripslashes($sArg);
  74. }
  75. function argumentDecodeXML(&$sArg)
  76. {
  77. if (false == is_string($sArg))
  78. return;
  79. if (0 == strlen($sArg))
  80. return;
  81. $nStackDepth = 0;
  82. $aStack = array();
  83. $aArg = array();
  84. $nCurrent = 0;
  85. $nLast = 0;
  86. $aExpecting = array();
  87. $nFound = 0;
  88. list($aExpecting, $nFound) = $this->aSequence['start'];
  89. $nLength = strlen($sArg);
  90. $sKey = '';
  91. $mValue = '';
  92. while ($nCurrent < $nLength)
  93. {
  94. $bFound = false;
  95. foreach ($aExpecting as $sExpecting => $nExpectedLength)
  96. {
  97. if ($sArg[$nCurrent] == $sExpecting[0])
  98. if ($sExpecting == substr($sArg, $nCurrent, $nExpectedLength))
  99. {
  100. list($aExpecting, $nFound) = $this->aSequence[$sExpecting];
  101. switch ($nFound)
  102. {
  103. case 3: // k
  104. $sKey = '';
  105. break;
  106. case 4: // /k
  107. $sKey = str_replace(
  108. array('<'.'![CDATA[', ']]>'),
  109. '',
  110. substr($sArg, $nLast, $nCurrent - $nLast)
  111. );
  112. break;
  113. case 5: // v
  114. $mValue = '';
  115. break;
  116. case 6: // /v
  117. if ($nLast < $nCurrent)
  118. {
  119. $mValue = str_replace(
  120. array('<'.'![CDATA[', ']]>'),
  121. '',
  122. substr($sArg, $nLast, $nCurrent - $nLast)
  123. );
  124. $cType = substr($mValue, 0, 1);
  125. $sValue = substr($mValue, 1);
  126. switch ($cType) {
  127. case 'S': $mValue = false === $sValue ? '' : $sValue; break;
  128. case 'B': $mValue = $this->convertStringToBool($sValue); break;
  129. case 'N': $mValue = floatval($sValue); break;
  130. case '*': $mValue = null; break;
  131. }
  132. }
  133. break;
  134. case 7: // /e
  135. $aArg[$sKey] = $mValue;
  136. break;
  137. case 1: // xjxobj
  138. ++$nStackDepth;
  139. array_push($aStack, $aArg);
  140. $aArg = array();
  141. array_push($aStack, $sKey);
  142. $sKey = '';
  143. break;
  144. case 8: // /xjxobj
  145. if (1 < $nStackDepth) {
  146. $mValue = $aArg;
  147. $sKey = array_pop($aStack);
  148. $aArg = array_pop($aStack);
  149. --$nStackDepth;
  150. } else {
  151. $sArg = $aArg;
  152. return;
  153. }
  154. break;
  155. }
  156. $nCurrent += $nExpectedLength;
  157. $nLast = $nCurrent;
  158. $bFound = true;
  159. break;
  160. }
  161. }
  162. if (false == $bFound)
  163. {
  164. if (0 == $nCurrent)
  165. {
  166. $sArg = str_replace(
  167. array('<'.'![CDATA[', ']]>'),
  168. '',
  169. $sArg
  170. );
  171. $cType = substr($sArg, 0, 1);
  172. $sValue = substr($sArg, 1);
  173. switch ($cType) {
  174. case 'S': $sArg = false === $sValue ? '' : $sValue; break;
  175. case 'B': $sArg = $this->convertStringToBool($sValue); break;
  176. case 'N': $sArg = floatval($sValue); break;
  177. case '*': $sArg = null; break;
  178. }
  179. return;
  180. }
  181. // for larger arg data, performance may suffer using concatenation
  182. // $sText .= $sArg[$nCurrent];
  183. $nCurrent++;
  184. }
  185. }
  186. $objLanguageManager =& xajaxLanguageManager::getInstance();
  187. trigger_error(
  188. $objLanguageManager->getText('ARGMGR:ERR:01')
  189. . $sExpected
  190. . $objLanguageManager->getText('ARGMGR:ERR:02')
  191. . $sChunk
  192. , E_USER_ERROR
  193. );
  194. }
  195. function argumentDecodeUTF8_iconv(&$mArg)
  196. {
  197. if (is_array($mArg))
  198. {
  199. foreach (array_keys($mArg) as $sKey)
  200. {
  201. $sNewKey = $sKey;
  202. $this->argumentDecodeUTF8_iconv($sNewKey);
  203. if ($sNewKey != $sKey)
  204. {
  205. $mArg[$sNewKey] = $mArg[$sKey];
  206. unset($mArg[$sKey]);
  207. $sKey = $sNewKey;
  208. }
  209. $this->argumentDecodeUTF8_iconv($mArg[$sKey]);
  210. }
  211. }
  212. else if (is_string($mArg))
  213. $mArg = iconv("UTF-8", $this->sCharacterEncoding.'//TRANSLIT', $mArg);
  214. }
  215. function argumentDecodeUTF8_mb_convert_encoding(&$mArg)
  216. {
  217. if (is_array($mArg))
  218. {
  219. foreach (array_keys($mArg) as $sKey)
  220. {
  221. $sNewKey = $sKey;
  222. $this->argumentDecodeUTF8_mb_convert_encoding($sNewKey);
  223. if ($sNewKey != $sKey)
  224. {
  225. $mArg[$sNewKey] = $mArg[$sKey];
  226. unset($mArg[$sKey]);
  227. $sKey = $sNewKey;
  228. }
  229. $this->argumentDecodeUTF8_mb_convert_encoding($mArg[$sKey]);
  230. }
  231. }
  232. else if (is_string($mArg))
  233. $mArg = mb_convert_encoding($mArg, $this->sCharacterEncoding, "UTF-8");
  234. }
  235. function argumentDecodeUTF8_utf8_decode(&$mArg)
  236. {
  237. if (is_array($mArg))
  238. {
  239. foreach (array_keys($mArg) as $sKey)
  240. {
  241. $sNewKey = $sKey;
  242. $this->argumentDecodeUTF8_utf8_decode($sNewKey);
  243. if ($sNewKey != $sKey)
  244. {
  245. $mArg[$sNewKey] = $mArg[$sKey];
  246. unset($mArg[$sKey]);
  247. $sKey = $sNewKey;
  248. }
  249. $this->argumentDecodeUTF8_utf8_decode($mArg[$sKey]);
  250. }
  251. }
  252. else if (is_string($mArg))
  253. $mArg = utf8_decode($mArg);
  254. }
  255. /*
  256. Constructor: xajaxArgumentManager
  257. Initializes configuration settings to their default values and reads
  258. the argument data from the GET or POST data.
  259. */
  260. function xajaxArgumentManager()
  261. {
  262. $this->aArgs = array();
  263. $this->bDecodeUTF8Input = false;
  264. $this->sCharacterEncoding = 'UTF-8';
  265. $this->nMethod = XAJAX_METHOD_UNKNOWN;
  266. $this->aSequence = array(
  267. '<'.'k'.'>' => array(array(
  268. '<'.'/k'.'>' => 4
  269. ), 3),
  270. '<'.'/k'.'>' => array(array(
  271. '<'.'v'.'>' => 3,
  272. '<'.'/e'.'>' => 4
  273. ), 4),
  274. '<'.'v'.'>' => array(array(
  275. '<'.'xjxobj'.'>' => 8,
  276. '<'.'/v'.'>' => 4
  277. ), 5),
  278. '<'.'/v'.'>' => array(array(
  279. '<'.'/e'.'>' => 4,
  280. '<'.'k'.'>' => 3
  281. ), 6),
  282. '<'.'e'.'>' => array(array(
  283. '<'.'k'.'>' => 3,
  284. '<'.'v'.'>' => 3,
  285. '<'.'/e'.'>' => 4
  286. ), 2),
  287. '<'.'/e'.'>' => array(array(
  288. '<'.'e'.'>' => 3,
  289. '<'.'/xjxobj'.'>' => 9
  290. ), 7),
  291. '<'.'xjxobj'.'>' => array(array(
  292. '<'.'e'.'>' => 3,
  293. '<'.'/xjxobj'.'>' => 9
  294. ), 1),
  295. '<'.'/xjxobj'.'>' => array(array(
  296. '<'.'/v'.'>' => 4
  297. ), 8),
  298. 'start' => array(array(
  299. '<'.'xjxobj'.'>' => 8
  300. ), 9)
  301. );
  302. if (isset($_POST['xjxargs'])) {
  303. $this->nMethod = XAJAX_METHOD_POST;
  304. $this->aArgs = $_POST['xjxargs'];
  305. } else if (isset($_GET['xjxargs'])) {
  306. $this->nMethod = XAJAX_METHOD_GET;
  307. $this->aArgs = $_GET['xjxargs'];
  308. }
  309. if (1 == get_magic_quotes_gpc())
  310. array_walk($this->aArgs, array(&$this, 'argumentStripSlashes'));
  311. array_walk($this->aArgs, array(&$this, 'argumentDecodeXML'));
  312. }
  313. /*
  314. Function: getInstance
  315. Returns:
  316. object - A reference to an instance of this class. This function is
  317. used to implement the singleton pattern.
  318. */
  319. function &getInstance()
  320. {
  321. static $obj;
  322. if (!$obj) {
  323. $obj = new xajaxArgumentManager();
  324. }
  325. return $obj;
  326. }
  327. /*
  328. Function: configure
  329. Accepts configuration settings from the main <xajax> object.
  330. The <xajaxArgumentManager> tracks the following configuration settings:
  331. <decodeUTF8Input> - (boolean): See <xajaxArgumentManager->bDecodeUTF8Input>
  332. <characterEncoding> - (string): See <xajaxArgumentManager->sCharacterEncoding>
  333. */
  334. function configure($sName, $mValue)
  335. {
  336. if ('decodeUTF8Input' == $sName) {
  337. if (true === $mValue || false === $mValue)
  338. $this->bDecodeUTF8Input = $mValue;
  339. } else if ('characterEncoding' == $sName) {
  340. $this->sCharacterEncoding = $mValue;
  341. }
  342. }
  343. /*
  344. Function: getRequestMethod
  345. Returns the method that was used to send the arguments from the client.
  346. */
  347. function getRequestMethod()
  348. {
  349. return $this->nMethod;
  350. }
  351. /*
  352. Function: process
  353. Returns the array of arguments that were extracted and parsed from
  354. the GET or POST data.
  355. */
  356. function process()
  357. {
  358. if ($this->bDecodeUTF8Input)
  359. {
  360. $sFunction = '';
  361. if (function_exists('iconv'))
  362. $sFunction = "iconv";
  363. else if (function_exists('mb_convert_encoding'))
  364. $sFunction = "mb_convert_encoding";
  365. else if ($this->sCharacterEncoding == "ISO-8859-1")
  366. $sFunction = "utf8_decode";
  367. else {
  368. $objLanguageManager =& xajaxLanguageManager::getInstance();
  369. trigger_error(
  370. $objLanguageManager->getText('ARGMGR:ERR:03')
  371. , E_USER_NOTICE
  372. );
  373. }
  374. $mFunction = array(&$this, 'argumentDecodeUTF8_' . $sFunction);
  375. array_walk($this->aArgs, $mFunction);
  376. $this->bDecodeUTF8Input = false;
  377. }
  378. return $this->aArgs;
  379. }
  380. }