Ejemplo n.º 1
0
 public function getRequestTarget()
 {
     if ($this->requestTarget !== null) {
         return $this->requestTarget;
     }
     $target = $this->uri->getPath();
     if ($target == null) {
         $target = '/';
     }
     if ($this->uri->getQuery()) {
         $target .= '?' . $this->uri->getQuery();
     }
     return $target;
 }
Ejemplo n.º 2
0
 /**
  * Retrieves the message's request target.
  *
  * Retrieves the message's request-target either as it will appear (for
  * clients), as it appeared at request (for servers), or as it was
  * specified for the instance (see withRequestTarget()).
  *
  * In most cases, this will be the origin-form of the composed URI,
  * unless a value was provided to the concrete implementation (see
  * withRequestTarget() below).
  *
  * If no URI is available, and no request-target has been specifically
  * provided, this method will return the string "/".
  *
  * @return string
  */
 public function getRequestTarget()
 {
     // Use the explicitly set request target first.
     if (isset($this->requestTarget)) {
         return $this->requestTarget;
     }
     // Build the origin form from the composed URI.
     $target = $this->uri->getPath();
     $query = $this->uri->getQuery();
     if ($query) {
         $target .= "?" . $query;
     }
     // Return "/" if the origin form is empty.
     return $target ?: "/";
 }
Ejemplo n.º 3
0
 /**
  * Gets the request target from current URI
  *
  * @return string
  */
 private function targetFromUri()
 {
     $target = $this->uri->getPath();
     $target .= '' === $this->uri->getQuery() ? '' : '?' . $this->uri->getQuery();
     $target = empty($target) ? '/' : $target;
     return $target;
 }
 /**
  * @param AccessToken $accessToken
  * @param UriInterface $destination
  * @return Response
  */
 public function handle(AccessToken $accessToken, UriInterface $destination)
 {
     $claims = $this->userService->getUserClaims($accessToken)->toArray();
     $jwt = $this->encoderService->encode($claims);
     $q = $destination->getQuery();
     $q .= ($q ? '&' : '') . 'jwt=' . $jwt;
     return new RedirectResponse((string) $destination->withQuery($q));
 }
Ejemplo n.º 5
0
 /**
  * @return string
  */
 public function getRequestTarget()
 {
     if (isset($this->requestTarget) && $this->requestTarget !== '') {
         return $this->requestTarget;
     }
     if (!isset($this->uri)) {
         return '/';
     }
     $target = $this->uri->getPath();
     if ($this->uri->getQuery() !== '') {
         $target .= '?' . $this->uri->getQuery();
     }
     if ($target === '') {
         $target = '/';
     }
     return $target;
 }
Ejemplo n.º 6
0
 /**
  * @inheritdoc
  */
 public function getRequestTarget()
 {
     if ($this->requestTarget !== null) {
         return $this->requestTarget;
     }
     $this->requireUri();
     if ($this->uri === null) {
         return '/';
     }
     $target = $this->uri->getPath();
     $query = $this->uri->getQuery();
     if ($query !== '') {
         $target .= '?' . $query;
     }
     $this->requestTarget = $target;
     return $this->requestTarget;
 }
Ejemplo n.º 7
0
 /**
  * {@inheritdoc}
  */
 public function getRequestTarget()
 {
     if ($this->requestTarget !== null) {
         return $this->requestTarget;
     }
     if (!$this->uri instanceof UriInterface) {
         return '/';
     }
     $this->requestTarget = $this->uri->getPath();
     if (!$this->requestTarget) {
         $this->requestTarget = '/';
     }
     if ($this->uri->getQuery()) {
         $this->requestTarget .= '?' . $this->uri->getQuery();
     }
     return $this->requestTarget;
 }
Ejemplo n.º 8
0
 private function createRtmpUrl(UriInterface $uri)
 {
     // Use a relative URL when creating Flash player URLs
     $result = ltrim($uri->getPath(), '/');
     if ($query = $uri->getQuery()) {
         $result .= '?' . $query;
     }
     return $result;
 }
 /**
  * Merges additional query parameters with current query parameters (possibly overwriting (some of) them)
  *
  * @param UriInterface $uri
  * @param array $queryParameters Query parameters to add / overwrite
  * @return UriInterface
  */
 public static function addQueryParameters(UriInterface $uri, array $queryParameters)
 {
     $originalQuery = $uri->getQuery();
     $originalQueryParameters = [];
     parse_str($originalQuery, $originalQueryParameters);
     $newQueryParameters = array_replace_recursive($originalQueryParameters, $queryParameters);
     $newQuery = http_build_query($newQueryParameters);
     $newUri = $uri->withQuery($newQuery);
     return $newUri;
 }
Ejemplo n.º 10
0
 /**
  * Gets the query parameters as an array from a ``UriInterface`` instance.
  *
  * @param UriInterface $uri
  * @param array $exclude
  * @param array $params
  *
  * @return array
  */
 public function getQueryParams(UriInterface $uri, $exclude = ['sig'], $params = [])
 {
     parse_str($uri->getQuery(), $params);
     foreach ($exclude as $excludedParam) {
         if (array_key_exists($excludedParam, $params)) {
             unset($params[$excludedParam]);
         }
     }
     return $params;
 }
Ejemplo n.º 11
0
 /**
  * Get a query parameter from a PSR-7 UriInterface
  *
  * @param UriInterface $uri
  * @param string $param
  *
  * @return string|array|null
  */
 public function getQueryParam(UriInterface $uri, $param)
 {
     if (!($query = $uri->getQuery())) {
         return null;
     }
     parse_str($query, $params);
     if (!array_key_exists($param, $params)) {
         return null;
     }
     return $params[$param];
 }
Ejemplo n.º 12
0
 /**
  * {@inheritdoc}
  */
 public function getRequestTarget()
 {
     if ($this->requestTarget) {
         return $this->requestTarget;
     }
     $target = $this->uri->getPath();
     $target = $target ? $target : '/';
     $query = $this->uri->getQuery();
     $target .= $query ? '?' . $query : '';
     return $target;
 }
Ejemplo n.º 13
0
 /**
  * Retrieve query string arguments.
  *
  * Retrieves the deserialized query string arguments, if any.
  *
  * Note: the query params might not be in sync with the URI or server
  * params. If you need to ensure you are only getting the original
  * values, you may need to parse the query string from `getUri()->getQuery()`
  * or from the `QUERY_STRING` server param.
  *
  * @return array
  */
 public function getQueryParams()
 {
     if ($this->queryParams) {
         return $this->queryParams;
     }
     if ($this->uri === null) {
         return [];
     }
     parse_str($this->uri->getQuery(), $this->queryParams);
     // <-- URL decodes data
     return $this->queryParams;
 }
Ejemplo n.º 14
0
 public function getSelectedValues(UriInterface $uri)
 {
     $queryParams = Psr7\parse_query($uri->getQuery());
     $selectedValues = [];
     foreach ($queryParams as $paramName => $params) {
         if (!isset($this->paramFacets[$paramName])) {
             continue;
         }
         $facetName = $this->paramFacets[$paramName];
         $selectedValues[$facetName] = $params;
     }
     return $selectedValues;
 }
Ejemplo n.º 15
0
 /**
  * Converts the relative URI into a new URI that is resolved against the base URI.
  *
  * @param UriInterface $base Base URI
  * @param UriInterface $rel  Relative URI
  *
  * @return UriInterface
  * @link http://tools.ietf.org/html/rfc3986#section-5.2
  */
 public static function resolve(UriInterface $base, UriInterface $rel)
 {
     if ((string) $rel === '') {
         // we can simply return the same base URI instance for this same-document reference
         return $base;
     }
     if ($rel->getScheme() != '') {
         return $rel->withPath(self::removeDotSegments($rel->getPath()));
     }
     if ($rel->getAuthority() != '') {
         $targetAuthority = $rel->getAuthority();
         $targetPath = self::removeDotSegments($rel->getPath());
         $targetQuery = $rel->getQuery();
     } else {
         $targetAuthority = $base->getAuthority();
         if ($rel->getPath() === '') {
             $targetPath = $base->getPath();
             $targetQuery = $rel->getQuery() != '' ? $rel->getQuery() : $base->getQuery();
         } else {
             if ($rel->getPath()[0] === '/') {
                 $targetPath = $rel->getPath();
             } else {
                 if ($targetAuthority != '' && $base->getPath() === '') {
                     $targetPath = '/' . $rel->getPath();
                 } else {
                     $lastSlashPos = strrpos($base->getPath(), '/');
                     if ($lastSlashPos === false) {
                         $targetPath = $rel->getPath();
                     } else {
                         $targetPath = substr($base->getPath(), 0, $lastSlashPos + 1) . $rel->getPath();
                     }
                 }
             }
             $targetPath = self::removeDotSegments($targetPath);
             $targetQuery = $rel->getQuery();
         }
     }
     return new Uri(Uri::composeComponents($base->getScheme(), $targetAuthority, $targetPath, $targetQuery, $rel->getFragment()));
 }
Ejemplo n.º 16
0
 /**
  * Retrieves the message's request target.
  *
  * Retrieves the message's request-target either as it will appear (for
  * clients), as it appeared at request (for servers), or as it was
  * specified for the instance (see withRequestTarget()).
  *
  * In most cases, this will be the origin-form of the composed URI,
  * unless a value was provided to the concrete implementation (see
  * withRequestTarget() below).
  *
  * If no URI is available, and no request-target has been specifically
  * provided, this method MUST return the string "/".
  *
  * @return string
  */
 public function getRequestTarget()
 {
     if (null !== $this->requestTarget) {
         return $this->requestTarget;
     }
     if (!$this->uri) {
         return '/';
     }
     $target = $this->uri->getPath();
     if ($this->uri->getQuery()) {
         $target .= '?' . $this->uri->getQuery();
     }
     if (empty($target)) {
         $target = '/';
     }
     return $target;
 }
Ejemplo n.º 17
0
 /**
  * Create a new URI with a specific query string value.
  *
  * Any existing query string values that exactly match the provided key are
  * removed and replaced with the given key value pair.
  *
  * Note: this function will convert "=" to "%3D" and "&" to "%26".
  *
  * @param UriInterface $uri URI to use as a base.
  * @param string $key   Key to set.
  * @param string $value Value to set.
  *
  * @return UriInterface
  */
 public static function withQueryValue(UriInterface $uri, $key, $value)
 {
     $current = $uri->getQuery();
     $key = strtr($key, self::$replaceQuery);
     if (!$current) {
         $result = [];
     } else {
         $result = [];
         foreach (explode('&', $current) as $part) {
             if (explode('=', $part)[0] !== $key) {
                 $result[] = $part;
             }
         }
     }
     if ($value !== null) {
         $result[] = $key . '=' . strtr($value, self::$replaceQuery);
     } else {
         $result[] = $key;
     }
     return $uri->withQuery(implode('&', $result));
 }
/**
 * 
 * Adds a query string parameter key/value pair to a uri object.
 * 
 * Given a uri object $uri1 representing http://someserver.com/controller/action?param1=val1 
 * s3MVC_addQueryStrParamToUri($uri1, 'param2', 'val2') will return a new uri object representing
 * http://someserver.com/controller/action?param1=val1&param2=val2
 * 
 * @param \Psr\Http\Message\UriInterface $uri
 * @param string $param_name
 * @param string $param_value
 * 
 * @return \Psr\Http\Message\UriInterface
 */
function s3MVC_addQueryStrParamToUri(\Psr\Http\Message\UriInterface $uri, $param_name, $param_value)
{
    $query_params = [];
    parse_str($uri->getQuery(), $query_params);
    // Extract existing query string params to an array
    $query_params[$param_name] = $param_value;
    // Add new param the query string params array
    return $uri->withQuery(http_build_query($query_params));
    // return a uri object with updated query params
}
Ejemplo n.º 19
0
 /**
  * @param $urlString
  * @param UriInterface $originUrl
  * @return UriInterface
  */
 private function createAbsoulteUrl(UriInterface $uri, UriInterface $originUrl)
 {
     // @example href=""
     if ((string) $uri == "" || strpos((string) $uri, "#") === 0) {
         return $originUrl;
     }
     // @example href="?cat=1"
     if (strpos((string) $uri, "?") === 0) {
         return new Uri($originUrl->getScheme() . "://" . $originUrl->getHost() . $originUrl->getPath() . (string) $uri);
     }
     if ($uri->getScheme() === '') {
         if ($uri->getQuery() !== '') {
             $query = '?' . $uri->getQuery();
         } else {
             $query = '';
         }
         if ($uri->getHost() !== '') {
             $uriString = $originUrl->getScheme() . '://' . $uri->getHost() . $uri->getPath() . $query;
         } else {
             if (strpos($uri->getPath(), '/') === 0) {
                 // absolute path
                 $uriString = $originUrl->getScheme() . '://' . $originUrl->getHost() . $uri->getPath() . $query;
             } else {
                 // relative path
                 $pathParts = pathinfo($originUrl->getPath());
                 if (array_key_exists('dirname', $pathParts)) {
                     $dirname = $pathParts['dirname'];
                     if ($dirname != "/") {
                         $dirname .= "/";
                     }
                 } else {
                     $dirname = "/";
                 }
                 $uriString = $originUrl->getScheme() . '://' . $originUrl->getHost() . $dirname . $uri->getPath() . $query;
             }
         }
         $resultUri = new Uri($uriString);
     } else {
         $resultUri = $uri;
     }
     return $resultUri;
 }
Ejemplo n.º 20
0
 /**
  * Create a new URI with a specific query string value removed.
  *
  * Any existing query string values that exactly match the provided key are removed.
  *
  * Note: this function will convert "=" to "%3D" and "&" to "%26".
  *
  * @param UriInterface $uri URI to use as a base.
  * @param string       $key Query string key value pair to remove.
  *
  * @throws \InvalidArgumentException
  *
  * @return UriInterface
  */
 public static function withoutQueryValue(UriInterface $uri, $key)
 {
     if ($uri->getQuery() === null) {
         return $uri;
     }
     $result = [];
     foreach (explode('&', $uri->getQuery()) as $part) {
         if (explode('=', $part)[0] !== $key) {
             $result[] = $part;
         }
     }
     return $uri->withQuery(implode('&', $result));
 }
Ejemplo n.º 21
0
 private static function decodeUnreservedCharacters(UriInterface $uri)
 {
     $regex = '/%(?:2D|2E|5F|7E|3[0-9]|[46][1-9A-F]|[57][0-9A])/i';
     $callback = function (array $match) {
         return rawurldecode($match[0]);
     };
     return $uri->withPath(preg_replace_callback($regex, $callback, $uri->getPath()))->withQuery(preg_replace_callback($regex, $callback, $uri->getQuery()));
 }
Ejemplo n.º 22
0
 /**
  * Returns an instance with the provided URI.
  *
  * This method MUST update the Host header of the returned request by
  * default if the URI contains a host component. If the URI does not
  * contain a host component, any pre-existing Host header MUST be carried
  * over to the returned request.
  *
  * You can opt-in to preserving the original state of the Host header by
  * setting `$preserveHost` to `true`. When `$preserveHost` is set to
  * `true`, this method interacts with the Host header in the following ways:
  *
  * - If the the Host header is missing or empty, and the new URI contains
  *   a host component, this method MUST update the Host header in the returned
  *   request.
  * - If the Host header is missing or empty, and the new URI does not contain a
  *   host component, this method MUST NOT update the Host header in the returned
  *   request.
  * - If a Host header is present and non-empty, this method MUST NOT update
  *   the Host header in the returned request.
  *
  * @link http://tools.ietf.org/html/rfc3986#section-4.3
  *
  * @param  UriInterface $uri          New request URI to use.
  * @param  bool         $preserveHost Preserve the original state of the Host header.
  * @return self
  */
 public function withUri(UriInterface $uri, $preserveHost = false)
 {
     $request = clone $this;
     $request->scheme($uri->getScheme());
     $userInfo = $uri->getUserInfo();
     $parts = explode(':', $userInfo);
     $request->username($parts[0] ?: null);
     $request->password(!empty($parts[1]) ? $parts[1] : null);
     $request->port($uri->getPort());
     if ($preserveHost) {
         $host = $request->headers['Host'];
         $request->host($uri->getHost());
         $request->headers['Host'] = $host;
     } else {
         $request->host($uri->getHost());
     }
     $request->path($uri->getPath());
     $request->query($uri->getQuery());
     $request->fragment($uri->getFragment());
     return $request;
 }
Ejemplo n.º 23
0
 /**
  * Format a URI Query component according to the Formatter properties
  *
  * @param UriInterface|Uri $uri
  *
  * @return string
  */
 protected function formatQuery($uri)
 {
     $query = $this->formatUriPart(new Query($uri->getQuery()));
     if ($this->preserveQuery || '' !== $query) {
         $query = '?' . $query;
     }
     return $query;
 }
Ejemplo n.º 24
0
 public static function withAddedQueryValues(UriInterface $uri, array $queryValues) : UriInterface
 {
     $current = $uri->getQuery();
     if (false === empty($current)) {
         parse_str($current, $values);
         foreach ($values as $key => $value) {
             if (false === isset($queryValues[$key])) {
                 $queryValues[$key] = $value;
             }
         }
     }
     $result = [];
     foreach ($queryValues as $key => $value) {
         $result[] = $key . '=' . $value;
     }
     return $uri->withQuery(implode('&', $result));
 }
Ejemplo n.º 25
0
 protected function runMatches(UriInterface $uri)
 {
     return $uri->getQuery() == $this->expected;
 }
Ejemplo n.º 26
0
 /**
  * Format a Interfaces\Schemes\Uri according to the Formatter properties
  *
  * @param Uri|UriInterface $uri
  *
  * @return string
  */
 protected function formatUri($uri)
 {
     $scheme = $uri->getScheme();
     if ('' !== $scheme) {
         $scheme .= ':';
     }
     $query = $this->formatUriPart(new Query($uri->getQuery()));
     if ('' !== $query) {
         $query = '?' . $query;
     }
     $fragment = $uri->getFragment();
     if ('' !== $fragment) {
         $fragment = '#' . $fragment;
     }
     $auth = $this->formatAuthority($uri);
     return $scheme . $auth . $this->formatPath($uri->getPath(), $auth) . $query . $fragment;
 }
 protected function getCategoriesFacet(Category $selectedCategory = null, UriInterface $uri)
 {
     $cache = $this->get('app.cache');
     $categoryFacet = $this->facets->getByName('categories');
     /**
      * @var CategoryCollection $categoryData
      */
     $categoryData = $this->get('app.repository.category')->getCategories();
     $cacheKey = 'category-facet-tree-' . $this->locale;
     if (!$cache->has($cacheKey)) {
         $categoryTree = [];
         /**
          * @var Category $category
          */
         foreach ($categoryData as $category) {
             $categoryEntry = new ViewData();
             //                $categoryEntry->uri = $category->getId();
             $categoryEntry->value = $this->generateUrl('category', ['category' => (string) $category->getSlug()]);
             $categoryEntry->id = (string) $category->getId();
             $categoryEntry->label = (string) $category->getName();
             $categoryEntry->count = 0;
             $ancestors = $category->getAncestors();
             $categoryEntry->ancestors = [];
             if (!is_null($ancestors)) {
                 foreach ($ancestors as $ancestor) {
                     $categoryEntry->ancestors[] = $ancestor->getId();
                 }
             }
             $categoryTree[$category->getId()] = $categoryEntry;
         }
         foreach ($categoryTree as $entry) {
             $children = array_keys($categoryData->getByParent($entry->id));
             if ($children) {
                 $entry->children = new ViewDataCollection();
             }
             foreach ($children as $id) {
                 $entry->children->add($categoryTree[$id], $id);
             }
         }
         $cache->store($cacheKey, serialize($categoryTree));
     } else {
         $categoryTree = unserialize($cache->fetch($cacheKey));
     }
     foreach ($categoryFacet->getTerms() as $term) {
         $categoryId = $term->getTerm();
         $categoryEntry = $categoryTree[$categoryId];
         $categoryEntry->count = $term->getCount();
     }
     $limitedOptions = new ViewDataCollection();
     if (is_null($selectedCategory)) {
         $categories = $categoryData->getRoots();
         foreach ($categories as $category) {
             $entry = $categoryTree[$category->getId()];
             unset($entry->children);
             $limitedOptions->add($entry);
         }
     } else {
         $this->addToCollection($selectedCategory->getId(), $limitedOptions, $categoryTree[$selectedCategory->getId()]->ancestors, $categoryTree);
     }
     $queryParams = \GuzzleHttp\Psr7\parse_query($uri->getQuery());
     $categories = new ViewData();
     $categories->hierarchicalSelectFacet = true;
     $categories->facet = new ViewData();
     $categories->facet->clearUri = $this->generateUrl('pop', $queryParams);
     $categories->facet->countHidden = true;
     $categories->facet->available = true;
     $categories->facet->label = $this->trans('filters.productType', [], 'catalog');
     $categories->facet->key = 'product-type';
     $categories->facet->limitedOptions = $limitedOptions;
     return $categories;
 }
Ejemplo n.º 28
0
 /**
  * @param $nodes
  * @param $uri
  * @return mixed
  * @throws UnableToDetermineNodesException
  * @throws UnknownNodeTypeException
  */
 protected function fetchNode(array $nodes, UriInterface $uri)
 {
     foreach ($nodes as $nodeId => $node) {
         if (!isset($node['type']) || !isset($node['pattern'])) {
             continue;
         }
         if (strpos($node['type'], 'url') !== 0) {
             continue;
         }
         if (strpos($uri->getScheme(), 'http') !== 0) {
             continue;
         }
         $type = $node['type'];
         $pattern = $node['pattern'];
         $subject = NULL;
         //check if https is required
         if (isset($node['secure'])) {
             if ($node['secure'] && strpos($uri->getScheme(), 'https') !== 0) {
                 continue;
             }
         }
         //determine url part by type
         switch ($type) {
             case "url":
                 $subject = $uri;
                 break;
             case "url_path":
                 $subject = $uri->getPath();
                 break;
             case "url_host":
                 $subject = $uri->getHost();
                 break;
             case "url_query":
                 $subject = $uri->getQuery();
                 break;
             default:
                 throw new UnknownNodeTypeException($type);
         }
         if (preg_match_all('#' . $pattern . '#i', $subject)) {
             return [$nodeId, $node];
         }
     }
     throw new UnableToDetermineNodesException();
 }
Ejemplo n.º 29
0
 /**
  * Resolve a base URI with a relative URI and return a new URI.
  *
  * @param UriInterface $base Base URI
  * @param UriInterface $rel  Relative URI
  *
  * @return UriInterface
  */
 public static function resolve(UriInterface $base, UriInterface $rel)
 {
     // Return the relative uri as-is if it has a scheme.
     if ($rel->getScheme()) {
         return $rel->withPath(static::removeDotSegments($rel->getPath()));
     }
     $relParts = ['scheme' => $rel->getScheme(), 'authority' => $rel->getAuthority(), 'path' => $rel->getPath(), 'query' => $rel->getQuery(), 'fragment' => $rel->getFragment()];
     $parts = ['scheme' => $base->getScheme(), 'authority' => $base->getAuthority(), 'path' => $base->getPath(), 'query' => $base->getQuery(), 'fragment' => $base->getFragment()];
     if (!empty($relParts['authority'])) {
         $parts['authority'] = $relParts['authority'];
         $parts['path'] = self::removeDotSegments($relParts['path']);
         $parts['query'] = $relParts['query'];
         $parts['fragment'] = $relParts['fragment'];
     } elseif (!empty($relParts['path'])) {
         if (substr($relParts['path'], 0, 1) == '/') {
             $parts['path'] = self::removeDotSegments($relParts['path']);
             $parts['query'] = $relParts['query'];
             $parts['fragment'] = $relParts['fragment'];
         } else {
             if (!empty($parts['authority']) && empty($parts['path'])) {
                 $mergedPath = '/';
             } else {
                 $mergedPath = substr($parts['path'], 0, strrpos($parts['path'], '/') + 1);
             }
             $parts['path'] = self::removeDotSegments($mergedPath . $relParts['path']);
             $parts['query'] = $relParts['query'];
             $parts['fragment'] = $relParts['fragment'];
         }
     } elseif (!empty($relParts['query'])) {
         $parts['query'] = $relParts['query'];
     } elseif ($relParts['fragment']) {
         $parts['fragment'] = $relParts['fragment'];
     }
     return new Uri(static::createUriString($parts['scheme'], $parts['authority'], $parts['path'], $parts['query'], $parts['fragment']));
 }
Ejemplo n.º 30
0
 /**
  * Creates a new URI with a specific query string value.
  *
  * Any existing query string values that exactly match the provided key are
  * removed and replaced with the given key value pair.
  *
  * A value of null will set the query string key without a value, e.g. "key"
  * instead of "key=value".
  *
  * @param UriInterface $uri   URI to use as a base.
  * @param string       $key   Key to set.
  * @param string|null  $value Value to set
  *
  * @return UriInterface
  */
 public static function withQueryValue(UriInterface $uri, $key, $value)
 {
     $current = $uri->getQuery();
     if ($current === '') {
         $result = [];
     } else {
         $decodedKey = rawurldecode($key);
         $result = array_filter(explode('&', $current), function ($part) use($decodedKey) {
             return rawurldecode(explode('=', $part)[0]) !== $decodedKey;
         });
     }
     // Query string separators ("=", "&") within the key or value need to be encoded
     // (while preventing double-encoding) before setting the query string. All other
     // chars that need percent-encoding will be encoded by withQuery().
     $key = strtr($key, self::$replaceQuery);
     if ($value !== null) {
         $result[] = $key . '=' . strtr($value, self::$replaceQuery);
     } else {
         $result[] = $key;
     }
     return $uri->withQuery(implode('&', $result));
 }