PageRenderTime 24ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/league/uri/src/Components/Query.php

https://gitlab.com/itlboy/yii2-starter-installed
PHP | 377 lines | 153 code | 44 blank | 180 comment | 11 complexity | 3da9c1b26680e36522522a4ce31ff659 MD5 | raw file
  1. <?php
  2. /**
  3. * League.Uri (http://uri.thephpleague.com)
  4. *
  5. * @package League.uri
  6. * @author Ignace Nyamagana Butera <nyamsprod@gmail.com>
  7. * @copyright 2013-2015 Ignace Nyamagana Butera
  8. * @license https://github.com/thephpleague/uri/blob/master/LICENSE (MIT License)
  9. * @version 4.1.0
  10. * @link https://github.com/thephpleague/uri/
  11. */
  12. namespace League\Uri\Components;
  13. use InvalidArgumentException;
  14. use League\Uri\Interfaces\Query as QueryInterface;
  15. use League\Uri\QueryParser;
  16. use League\Uri\Types\ImmutableCollectionTrait;
  17. use League\Uri\Types\ImmutableComponentTrait;
  18. /**
  19. * Value object representing a URI query component.
  20. *
  21. * @package League.uri
  22. * @author Ignace Nyamagana Butera <nyamsprod@gmail.com>
  23. * @since 1.0.0
  24. */
  25. class Query implements QueryInterface
  26. {
  27. use ImmutableComponentTrait;
  28. use ImmutableCollectionTrait;
  29. /**
  30. * Key/pair separator character
  31. *
  32. * @var string
  33. */
  34. protected static $separator = '&';
  35. /**
  36. * Preserve the delimiter
  37. *
  38. * @var bool
  39. */
  40. protected $preserveDelimiter = false;
  41. /**
  42. * DEPRECATION WARNING! This method will be removed in the next major point release
  43. *
  44. * @deprecated deprecated since version 4.2
  45. *
  46. * return a new instance from an array or a traversable object
  47. *
  48. * @param \Traversable|array $data
  49. *
  50. * @return static
  51. */
  52. public static function createFromArray($data)
  53. {
  54. return self::createFromPairs($data);
  55. }
  56. /**
  57. * return a new Query instance from an Array or a traversable object
  58. *
  59. * @param \Traversable|array $data
  60. *
  61. * @return static
  62. */
  63. public static function createFromPairs($data)
  64. {
  65. $data = static::validateIterator($data);
  66. if (empty($data)) {
  67. return new static();
  68. }
  69. $query = (new QueryParser())->build($data, static::$separator);
  70. return new static($query);
  71. }
  72. /**
  73. * a new instance
  74. *
  75. * @param string $data
  76. */
  77. public function __construct($data = null)
  78. {
  79. $this->data = $this->validate($data);
  80. $this->preserveDelimiter = null !== $data;
  81. }
  82. /**
  83. * sanitize the submitted data
  84. *
  85. * @param string $str
  86. *
  87. * @return array
  88. */
  89. protected function validate($str)
  90. {
  91. if (null === $str) {
  92. return [];
  93. }
  94. $str = $this->filterEncodedQuery($this->validateString($str));
  95. return (new QueryParser())->parse($str, static::$separator, PHP_QUERY_RFC3986);
  96. }
  97. /**
  98. * Filter the encoded query string
  99. *
  100. * @param string $str the encoded query
  101. *
  102. * @throws InvalidArgumentException If the encoded query is invalid
  103. *
  104. * @return string
  105. */
  106. protected function filterEncodedQuery($str)
  107. {
  108. if (false === strpos($str, '#')) {
  109. return $str;
  110. }
  111. throw new InvalidArgumentException(sprintf(
  112. 'The encoded query `%s` contains invalid characters',
  113. $str
  114. ));
  115. }
  116. /**
  117. * @inheritdoc
  118. */
  119. public function __debugInfo()
  120. {
  121. return ['query' => $this->getContent()];
  122. }
  123. /**
  124. * @inheritdoc
  125. */
  126. public static function __set_state(array $properties)
  127. {
  128. $component = static::createFromPairs($properties['data']);
  129. $component->preserveDelimiter = $properties['preserveDelimiter'];
  130. return $component;
  131. }
  132. /**
  133. * Returns the component literal value.
  134. *
  135. * @return null|string
  136. */
  137. public function getContent()
  138. {
  139. if (!$this->preserveDelimiter) {
  140. return null;
  141. }
  142. return (new QueryParser())->build($this->data, static::$separator, PHP_QUERY_RFC3986);
  143. }
  144. /**
  145. * Returns the instance string representation; If the
  146. * instance is not defined an empty string is returned
  147. *
  148. * @return string
  149. */
  150. public function __toString()
  151. {
  152. return (string) $this->getContent();
  153. }
  154. /**
  155. * Returns the instance string representation
  156. * with its optional URI delimiters
  157. *
  158. * @return string
  159. */
  160. public function getUriComponent()
  161. {
  162. $query = $this->__toString();
  163. if ($this->preserveDelimiter) {
  164. return QueryInterface::DELIMITER.$query;
  165. }
  166. return $query;
  167. }
  168. /**
  169. * DEPRECATION WARNING! This method will be removed in the next major point release
  170. *
  171. * @deprecated deprecated since version 4.2
  172. *
  173. * Returns an array representation of the query
  174. *
  175. * @return array
  176. */
  177. public function toArray()
  178. {
  179. return $this->getPairs();
  180. }
  181. /**
  182. * Returns an array representation of the query
  183. *
  184. * @return array
  185. */
  186. public function getPairs()
  187. {
  188. return $this->data;
  189. }
  190. /**
  191. * Retrieves a single query parameter.
  192. *
  193. * Retrieves a single query parameter. If the parameter has not been set,
  194. * returns the default value provided.
  195. *
  196. * @param string $offset the parameter name
  197. * @param mixed $default Default value to return if the parameter does not exist.
  198. *
  199. * @return mixed
  200. */
  201. public function getValue($offset, $default = null)
  202. {
  203. $offset = $this->validateString($offset);
  204. $offset = $this->decodeComponent($offset);
  205. if (isset($this->data[$offset])) {
  206. return $this->data[$offset];
  207. }
  208. return $default;
  209. }
  210. /**
  211. * Returns an instance with the specified string
  212. *
  213. * This method MUST retain the state of the current instance, and return
  214. * an instance that contains the modified data
  215. *
  216. * @param string $value
  217. *
  218. * @return static
  219. */
  220. public function withContent($value = null)
  221. {
  222. if ($value === $this->getContent()) {
  223. return $this;
  224. }
  225. return new static($value);
  226. }
  227. /**
  228. * DEPRECATION WARNING! This method will be removed in the next major point release
  229. *
  230. * @deprecated deprecated since version 4.2
  231. *
  232. * @see withContent
  233. *
  234. * Returns an instance with the specified string
  235. *
  236. * This method MUST retain the state of the current instance, and return
  237. * an instance that contains the modified data
  238. *
  239. * @param string $value
  240. *
  241. * @return static
  242. */
  243. public function modify($value)
  244. {
  245. return $this->withContent($value);
  246. }
  247. /**
  248. * Returns an instance merge with the specified query
  249. *
  250. * This method MUST retain the state of the current instance, and return
  251. * an instance that contains the modified query
  252. *
  253. * @param QueryInterface|string $query the data to be merged
  254. *
  255. * @return static
  256. */
  257. public function merge($query)
  258. {
  259. $pairs = !$query instanceof QueryInterface ? $this->validate($query) : $query->getPairs();
  260. if ($this->data === $pairs) {
  261. return $this;
  262. }
  263. return static::createFromPairs(array_merge($this->data, $pairs));
  264. }
  265. /**
  266. * Sort the query string by offset, maintaining offset to data correlations.
  267. *
  268. * This method MUST retain the state of the current instance, and return
  269. * an instance that contains the modified query
  270. *
  271. * @param callable|int $sort a PHP sort flag constant or a comparaison function
  272. * which must return an integer less than, equal to,
  273. * or greater than zero if the first argument is
  274. * considered to be respectively less than, equal to,
  275. * or greater than the second.
  276. *
  277. * @return static
  278. */
  279. public function ksort($sort = SORT_REGULAR)
  280. {
  281. $func = is_callable($sort) ? 'uksort' : 'ksort';
  282. $data = $this->data;
  283. $func($data, $sort);
  284. if ($data === $this->data) {
  285. return $this;
  286. }
  287. return static::createFromPairs($data);
  288. }
  289. /**
  290. * @inheritdoc
  291. */
  292. public function hasKey($offset)
  293. {
  294. $offset = $this->validateString($offset);
  295. $offset = $this->decodeComponent($offset);
  296. return array_key_exists($offset, $this->data);
  297. }
  298. /**
  299. * @inheritdoc
  300. */
  301. public function keys()
  302. {
  303. if (0 === func_num_args()) {
  304. return array_keys($this->data);
  305. }
  306. return array_keys($this->data, $this->decodeComponent(func_get_arg(0)), true);
  307. }
  308. /**
  309. * @inheritdoc
  310. */
  311. public function without(array $offsets)
  312. {
  313. $data = $this->data;
  314. foreach ($offsets as $offset) {
  315. unset($data[$this->decodeComponent($offset)]);
  316. }
  317. return $this->newCollectionInstance($data);
  318. }
  319. /**
  320. * Return a new instance when needed
  321. *
  322. * @param array $data
  323. *
  324. * @return static
  325. */
  326. protected function newCollectionInstance(array $data)
  327. {
  328. if ($data === $this->data) {
  329. return $this;
  330. }
  331. return static::createFromPairs($data);
  332. }
  333. }