/lib/horde/framework/Horde/Variables.php

https://github.com/markn86/moodle · PHP · 403 lines · 181 code · 44 blank · 178 comment · 21 complexity · 70a1c2188fba53a9a4a6c65a6eae1815 MD5 · raw file

  1. <?php
  2. /**
  3. * Copyright 2009-2017 Horde LLC (http://www.horde.org/)
  4. *
  5. * See the enclosed file LICENSE for license information (LGPL). If you
  6. * did not receive this file, see http://www.horde.org/licenses/lgpl21.
  7. *
  8. * @category Horde
  9. * @copyright 2009-2017 Horde LLC
  10. * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
  11. * @package Util
  12. */
  13. /**
  14. * An OO-way to access form variables.
  15. *
  16. * @todo $_expected and $_vars are used inconsistently. $_expected is used in
  17. * exists(), but not in getExists(). And both are expected to be of the same
  18. * format, while Horde_Form submits $_expected as a flat list and $_vars as a
  19. * multi-dimensional array, if the the form elements are or array type (like
  20. * object[] in Turba).
  21. * @todo The sanitized feature doesn't seem to be used anywhere at all.
  22. *
  23. * @author Robert E. Coyle <robertecoyle@hotmail.com>
  24. * @author Chuck Hagenbuch <chuck@horde.org>
  25. * @author Michael Slusarz <slusarz@horde.org>
  26. * @category Horde
  27. * @copyright 2009-2017 Horde LLC
  28. * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
  29. * @package Util
  30. */
  31. class Horde_Variables implements ArrayAccess, Countable, IteratorAggregate
  32. {
  33. /**
  34. * The list of expected variables.
  35. *
  36. * @var array
  37. */
  38. protected $_expected = array();
  39. /**
  40. * Has the input been sanitized?
  41. *
  42. * @var boolean
  43. */
  44. protected $_sanitized = false;
  45. /**
  46. * Array of form variables.
  47. *
  48. * @var array
  49. */
  50. protected $_vars;
  51. /**
  52. * Returns a Horde_Variables object populated with the form input.
  53. *
  54. * @param string $sanitize Sanitize the input variables?
  55. *
  56. * @return Horde_Variables Variables object.
  57. */
  58. public static function getDefaultVariables($sanitize = false)
  59. {
  60. return new self(null, $sanitize);
  61. }
  62. /**
  63. * Constructor.
  64. *
  65. * @param array $vars The list of form variables (if null, defaults
  66. * to PHP's $_REQUEST value). If '_formvars'
  67. * exists, it must be a JSON encoded array that
  68. * contains the list of allowed form variables.
  69. * @param string $sanitize Sanitize the input variables?
  70. */
  71. public function __construct($vars = array(), $sanitize = false)
  72. {
  73. if (is_null($vars)) {
  74. $request_copy = $_REQUEST;
  75. $vars = Horde_Util::dispelMagicQuotes($request_copy);
  76. }
  77. if (isset($vars['_formvars'])) {
  78. $this->_expected = @json_decode($vars['_formvars'], true);
  79. unset($vars['_formvars']);
  80. }
  81. $this->_vars = $vars;
  82. if ($sanitize) {
  83. $this->sanitize();
  84. }
  85. }
  86. /**
  87. * Sanitize the form input.
  88. */
  89. public function sanitize()
  90. {
  91. if (!$this->_sanitized) {
  92. foreach (array_keys($this->_vars) as $key) {
  93. $this->$key = $this->filter($key);
  94. }
  95. $this->_sanitized = true;
  96. }
  97. }
  98. /**
  99. * Alias of isset().
  100. *
  101. * @see __isset()
  102. */
  103. public function exists($varname)
  104. {
  105. return $this->__isset($varname);
  106. }
  107. /**
  108. * isset() implementation.
  109. *
  110. * @param string $varname The form variable name.
  111. *
  112. * @return boolean Does $varname form variable exist?
  113. */
  114. public function __isset($varname)
  115. {
  116. return count($this->_expected)
  117. ? $this->_getExists($this->_expected, $varname, $value)
  118. : $this->_getExists($this->_vars, $varname, $value);
  119. }
  120. /**
  121. * Implements isset() for ArrayAccess interface.
  122. *
  123. * @see __isset()
  124. */
  125. public function offsetExists($field)
  126. {
  127. return $this->__isset($field);
  128. }
  129. /**
  130. * Returns the value of a given form variable.
  131. *
  132. * @param string $varname The form variable name.
  133. * @param string $default The default form variable value.
  134. *
  135. * @return mixed The form variable, or $default if it doesn't exist.
  136. */
  137. public function get($varname, $default = null)
  138. {
  139. return $this->_getExists($this->_vars, $varname, $value)
  140. ? $value
  141. : $default;
  142. }
  143. /**
  144. * Returns the value of a given form variable.
  145. *
  146. * @param string $varname The form variable name.
  147. *
  148. * @return mixed The form variable, or null if it doesn't exist.
  149. */
  150. public function __get($varname)
  151. {
  152. $this->_getExists($this->_vars, $varname, $value);
  153. return $value;
  154. }
  155. /**
  156. * Implements getter for ArrayAccess interface.
  157. *
  158. * @see __get()
  159. */
  160. public function offsetGet($field)
  161. {
  162. return $this->__get($field);
  163. }
  164. /**
  165. * Given a variable name, returns the value and sets a variable indicating
  166. * whether the value exists in the form data.
  167. *
  168. * @param string $varname The form variable name.
  169. * @param boolean &$exists Reference to variable that will indicate
  170. * whether $varname existed in form data.
  171. *
  172. * @return mixed The form variable, or null if it doesn't exist.
  173. */
  174. public function getExists($varname, &$exists)
  175. {
  176. $exists = $this->_getExists($this->_vars, $varname, $value);
  177. return $value;
  178. }
  179. /**
  180. * Sets the value of a given form variable.
  181. *
  182. * @see __set()
  183. */
  184. public function set($varname, $value)
  185. {
  186. $this->$varname = $value;
  187. }
  188. /**
  189. * Sets the value of a given form variable.
  190. *
  191. * @param string $varname The form variable name.
  192. * @param mixed $value The value to set.
  193. */
  194. public function __set($varname, $value)
  195. {
  196. $keys = array();
  197. if (Horde_Array::getArrayParts($varname, $base, $keys)) {
  198. array_unshift($keys, $base);
  199. $place = &$this->_vars;
  200. $i = count($keys);
  201. while ($i--) {
  202. $key = array_shift($keys);
  203. if (!isset($place[$key])) {
  204. $place[$key] = array();
  205. }
  206. $place = &$place[$key];
  207. }
  208. $place = $value;
  209. } else {
  210. $this->_vars[$varname] = $value;
  211. }
  212. }
  213. /**
  214. * Implements setter for ArrayAccess interface.
  215. *
  216. * @see __set()
  217. */
  218. public function offsetSet($field, $value)
  219. {
  220. $this->__set($field, $value);
  221. }
  222. /**
  223. * Deletes a given form variable.
  224. *
  225. * @see __unset()
  226. */
  227. public function remove($varname)
  228. {
  229. unset($this->$varname);
  230. }
  231. /**
  232. * Deletes a given form variable.
  233. *
  234. * @param string $varname The form variable name.
  235. */
  236. public function __unset($varname)
  237. {
  238. Horde_Array::getArrayParts($varname, $base, $keys);
  239. if (is_null($base)) {
  240. unset($this->_vars[$varname]);
  241. } else {
  242. $ptr = &$this->_vars[$base];
  243. $end = count($keys) - 1;
  244. foreach ($keys as $key => $val) {
  245. if (!isset($ptr[$val])) {
  246. break;
  247. }
  248. if ($end == $key) {
  249. array_splice($ptr, array_search($val, array_keys($ptr)), 1);
  250. } else {
  251. $ptr = &$ptr[$val];
  252. }
  253. }
  254. }
  255. }
  256. /**
  257. * Implements unset() for ArrayAccess interface.
  258. *
  259. * @see __unset()
  260. */
  261. public function offsetUnset($field)
  262. {
  263. $this->__unset($field);
  264. }
  265. /**
  266. * Merges a list of variables into the current form variable list.
  267. *
  268. * @param array $vars Form variables.
  269. */
  270. public function merge($vars)
  271. {
  272. foreach ($vars as $varname => $value) {
  273. $this->$varname = $value;
  274. }
  275. }
  276. /**
  277. * Set $varname to $value ONLY if it's not already present.
  278. *
  279. * @param string $varname The form variable name.
  280. * @param mixed $value The value to set.
  281. *
  282. * @return boolean True if the value was altered.
  283. */
  284. public function add($varname, $value)
  285. {
  286. if ($this->exists($varname)) {
  287. return false;
  288. }
  289. $this->_vars[$varname] = $value;
  290. return true;
  291. }
  292. /**
  293. * Filters a form value so that it can be used in HTML output.
  294. *
  295. * @param string $varname The form variable name.
  296. *
  297. * @return mixed The filtered variable, or null if it doesn't exist.
  298. */
  299. public function filter($varname)
  300. {
  301. $val = $this->$varname;
  302. if (is_null($val) || $this->_sanitized) {
  303. return $val;
  304. }
  305. return is_array($val)
  306. ? filter_var_array($val, FILTER_SANITIZE_STRING)
  307. : filter_var($val, FILTER_SANITIZE_STRING);
  308. }
  309. /* Protected methods. */
  310. /**
  311. * Fetch the requested variable ($varname) into $value, and return
  312. * whether or not the variable was set in $array.
  313. *
  314. * @param array $array The array to search in (usually either
  315. * $this->_vars or $this->_expected).
  316. * @param string $varname The name of the variable to look for.
  317. * @param mixed &$value $varname's value gets assigned to this variable.
  318. *
  319. * @return boolean Whether or not the variable was set (or, if we've
  320. * checked $this->_expected, should have been set).
  321. */
  322. protected function _getExists($array, $varname, &$value)
  323. {
  324. if (Horde_Array::getArrayParts($varname, $base, $keys)) {
  325. if (!isset($array[$base])) {
  326. $value = null;
  327. return false;
  328. }
  329. $searchspace = &$array[$base];
  330. $i = count($keys);
  331. while ($i--) {
  332. $key = array_shift($keys);
  333. if (!isset($searchspace[$key])) {
  334. $value = null;
  335. return false;
  336. }
  337. $searchspace = &$searchspace[$key];
  338. }
  339. $value = $searchspace;
  340. return true;
  341. }
  342. $value = isset($array[$varname])
  343. ? $array[$varname]
  344. : null;
  345. return !is_null($value);
  346. }
  347. /* Countable methods. */
  348. /**
  349. */
  350. public function count()
  351. {
  352. return count($this->_vars);
  353. }
  354. /* IteratorAggregate method. */
  355. public function getIterator()
  356. {
  357. return new ArrayIterator($this->_vars);
  358. }
  359. }