/classes/superglobal.php

https://github.com/rynodivino/system · PHP · 265 lines · 163 code · 24 blank · 78 comment · 23 complexity · e64c250defd45e5430b112c5d6cdb661 MD5 · raw file

  1. <?php
  2. /**
  3. * @package Habari
  4. *
  5. */
  6. /**
  7. * SuperGlobals class
  8. *
  9. */
  10. class SuperGlobal extends ArrayIterator
  11. {
  12. protected $values = array();
  13. protected $raw_values = array();
  14. public function __construct( $array )
  15. {
  16. if ( !is_array( $array ) && !$array instanceof SuperGlobal ) {
  17. throw new Exception( 'Parameter must be array or SuperGlobal' );
  18. }
  19. parent::__construct( $array );
  20. }
  21. /**
  22. * Convert $_GET, $_POST and $_SERVER into SuperGlobal instances, also kill $_REQUEST
  23. *
  24. * @return
  25. */
  26. public static function process_gps()
  27. {
  28. /* We should only revert the magic quotes once per page hit */
  29. static $revert = true;
  30. if ( !$revert ) {
  31. // our work has already been done
  32. return;
  33. }
  34. if ( get_magic_quotes_gpc() ) {
  35. $_GET = Utils::stripslashes( $_GET );
  36. $_POST = Utils::stripslashes( $_POST );
  37. }
  38. $_GET = new SuperGlobal( $_GET );
  39. $_POST = new SuperGlobal( $_POST );
  40. $_SERVER = new SuperGlobal( $_SERVER );
  41. unset( $_REQUEST );
  42. $revert = false;
  43. }
  44. /**
  45. * Convert $_COOKIE into SuperGlobal instance
  46. *
  47. */
  48. public static function process_c()
  49. {
  50. /* We should only revert the magic quotes once per page hit */
  51. static $revert = true;
  52. if ( !$revert ) {
  53. // our work has already been done
  54. return;
  55. }
  56. if ( get_magic_quotes_gpc() ) {
  57. $_COOKIE = Utils::stripslashes( $_COOKIE );
  58. }
  59. $_COOKIE = new SuperGlobal( $_COOKIE );
  60. $revert = false;
  61. }
  62. /**
  63. * Return the raw, unfiltered value of the requested index
  64. *
  65. * @param mixed $index The index of the value
  66. * @return mixed The unfiltered value
  67. */
  68. public function raw( $index )
  69. {
  70. if ( isset( $this->raw_values[$index] ) ) {
  71. return $this->raw_values[$index];
  72. }
  73. $cp = $this->get_array_copy_raw();
  74. if ( isset( $cp[$index] ) ) {
  75. $this->raw_values[$index] = $cp[$index];
  76. return $this->raw_values[$index];
  77. }
  78. }
  79. /**
  80. * Return a copy of the filtered array. Implments ArrayIterator::getArrayCopy()
  81. */
  82. public function getArrayCopy()
  83. {
  84. return array_map( array( $this, 'base_filter' ), parent::getArrayCopy() );
  85. }
  86. /**
  87. * Return a copy of the unfiltered array.
  88. */
  89. public function get_array_copy_raw()
  90. {
  91. return parent::getArrayCopy();
  92. }
  93. /**
  94. * Return the current array element, filtered. Implements ArrayIterator::current()
  95. */
  96. public function current()
  97. {
  98. return $this->offsetGet( parent::key() );
  99. }
  100. /**
  101. * Return the value of an array offset. Allows the values to be filtered
  102. *
  103. * @param mixed $index The index of the array
  104. * @return mixed The filtered value at the array index
  105. */
  106. public function offsetGet( $index )
  107. {
  108. if ( isset( $this->values[$index] ) ) {
  109. return $this->values[$index];
  110. }
  111. $cp = $this->get_array_copy_raw();
  112. if ( isset( $cp[$index] ) ) {
  113. $this->values[$index] = $this->base_filter( $cp[$index] );
  114. return $this->values[$index];
  115. }
  116. }
  117. /**
  118. * Set the value of the array, clear caches for that index
  119. *
  120. * @param mixed $index The array index
  121. * @param mixed $value Tha value to store
  122. */
  123. public function offsetSet( $index, $value )
  124. {
  125. unset( $this->values[$index] );
  126. unset( $this->raw_values[$index] );
  127. parent::offsetSet( $index, $value );
  128. }
  129. /**
  130. * Recursively filter array values and strings using InputFilter::filter()
  131. *
  132. * @param mixed $value A value to filter
  133. * @return mixes The filtered value
  134. */
  135. protected function base_filter( $value )
  136. {
  137. if ( is_array( $value ) ) {
  138. return array_map( array( $this, 'base_filter' ), $value );
  139. }
  140. elseif ( is_string( $value ) ) {
  141. return InputFilter::filter( $value );
  142. }
  143. else {
  144. return $value;
  145. }
  146. }
  147. /**
  148. * Merges the contents of one or more arrays or ArrayObjects with this SuperGlobal
  149. *
  150. * @param mixed One or more array-like structures to merge into this array.
  151. * @return SuperGlobal The merged array
  152. */
  153. public function merge()
  154. {
  155. $args = func_get_args();
  156. $cp = $this->get_array_copy_raw();
  157. foreach ( $args as $ary ) {
  158. if ( is_array( $ary ) ) {
  159. foreach ( $ary as $key => $value ) {
  160. if ( is_numeric( $key ) ) {
  161. $cp[] = $value;
  162. }
  163. else {
  164. $cp[$key] = $value;
  165. }
  166. }
  167. }
  168. elseif ( $ary instanceof SuperGlobal ) {
  169. // loop to get raw data.
  170. while ( $ary->valid() ) {
  171. if ( is_numeric( $ary->key() ) ) {
  172. $cp[] = $ary->raw( $ary->key() );
  173. }
  174. else {
  175. $cp[$ary->key()] = $ary->raw( $ary->key() );
  176. }
  177. $ary->next();
  178. }
  179. }
  180. elseif ( $ary instanceof ArrayObject || $ary instanceof ArrayIterator ) {
  181. $arycp = $ary->getArrayCopy(); // Don't trigger offsetGet for ArrayObject
  182. foreach ( $arycp as $key => $value ) {
  183. if ( is_numeric( $key ) ) {
  184. $cp[] = $value;
  185. }
  186. else {
  187. $cp[$key] = $value;
  188. }
  189. }
  190. }
  191. else {
  192. $cp[] = $ary;
  193. }
  194. }
  195. return new SuperGlobal( $cp );
  196. }
  197. /**
  198. * Filters this SuperGlobal based on an array or arrays of keys
  199. *
  200. * @param mixed An array of key values that should be returned, or a string of a key value to be returned
  201. * @return SuperGlobal The values from this array that match the supplied keys
  202. */
  203. public function filter_keys()
  204. {
  205. $keys = array();
  206. $args = func_get_args();
  207. foreach ( $args as $ary ) {
  208. if ( !is_array( $ary ) ) {
  209. $ary = array( $ary );
  210. }
  211. $keys = array_merge( $keys, array_values( $ary ) );
  212. }
  213. $cp = $this->get_array_copy_raw();
  214. $cp = array_intersect_key( $cp, array_flip( $keys ) );
  215. return new SuperGlobal( $cp );
  216. }
  217. /**
  218. * Apply a map function to this array, like array_map()
  219. * @param callback $fn the name of the function to map through
  220. * @return SuperGlobal the result of the mapping
  221. **/
  222. public function map( $fn )
  223. {
  224. return new SuperGlobal( array_map( $fn, $this->get_array_copy_raw() ) );
  225. }
  226. /**
  227. * Use a regular expression replacement to change the keys in an array
  228. * @param string $replacement (optional) The regex replacement value
  229. * @param string $search_regex (optional) The regex search value
  230. * @return SuperGlobal The re-keyed array
  231. **/
  232. public function rekey( $replacement = '{\$$0}', $search_regex = '/^.*$/' )
  233. {
  234. $output = array();
  235. foreach ( $this->get_array_copy_raw() as $k => $v ) {
  236. $output[preg_replace( $search_regex, $replacement, $k )] = $v;
  237. }
  238. return new SuperGlobal( $output );
  239. }
  240. }
  241. ?>