/** * Checks if path segments are valid * @param array $elements * @return bool */ private function isValid(array $elements) : bool { $matcher = new Matcher(new Pattern(UriFactory::PATH_REGEX)); foreach ($elements as $segment) { if (!$matcher->match($segment)) { return false; } } return true; }
/** * Sets valid hostname in ASCII format * @param string $address Host name to set */ protected function setAddress(string $address) { if (empty($address)) { throw new InvalidArgumentException('Empty hostname given'); } $matcher = new Matcher(new Pattern('^((^[\\s\\.:/])|([\\s\\.:/]$)|(.*[\\s:/].*))$')); if ($matcher->match($address)) { throw new InvalidArgumentException("Invalid hostname, given: {$address}"); } $this->address = $this->getPunnycode()->encode($address); }
/** * Checks if password is valid * @param string $password * @return bool */ public function isValidPassword(string $password) : bool { $matcher = new Matcher(new Pattern("^(" . UriFactory::USERINFO_CHARS_REGEX . "*)\$")); return !empty($matcher->match($password)); }
/** * Parse query string into Query * @param string $queryString String with query to parse * @param int $mode Parse mode {@see self::MODE_QUERY_DUPLICATE_LAST} * @throws UnexpectedValueException On unsupported mode * @return Query */ protected function parseQuery(string $queryString, int $mode = self::MODE_QUERY_DUPLICATE_LAST) : Query { $query = new Query(); $bracketsMatcher = new Matcher(new Pattern('^[^\\[\\]]+(\\[[^\\]]*\\])+$')); // When duplicate detected replace with duplicate value if (!(self::MODE_QUERY_DUPLICATE_AS_ARRAY & $mode) && !(self::MODE_QUERY_DUPLICATE_WITH_COLON & $mode)) { parse_str($queryString, $parameters); foreach ($parameters as $name => $value) { $query->add(new Parameter($name, $value)); } return $query; } // When duplicate detected turn value into an array or concatenated with colon when duplicate exists $matcher = new Matcher($this->queryPattern); $matches = $matcher->matchAll($queryString, PREG_SET_ORDER); foreach ($matches as $match) { $name = $match['name']; $value = $match['value']; if ($bracketsMatcher->match($name) && self::MODE_QUERY_DUPLICATE_AS_ARRAY & $mode) { parse_str($match[1], $parsedParameter); if (sizeof($parsedParameter) === 1) { $name = key($parsedParameter); $value = reset($parsedParameter); } } // If parameter already exists append value otherwise add parameter to Query if ($query->exists(function (Parameter $parameter) use($name) { return $parameter->getName() == $name; })) { /** @var Parameter $parameter */ foreach ($query as $parameter) { if ($parameter->getName() == $name) { $currentValue = $parameter->getValue(); // Decode urlencoded value $value = is_array($value) ? $this->decodeUrlArrayValue($value) : $this->decodeUrlValue($value); switch (true) { // When duplicate detected turn value into an array case self::MODE_QUERY_DUPLICATE_AS_ARRAY & $mode: // Decide how to merge existing value with parsed one if (is_array($currentValue) && is_array($value)) { $currentValue = array_merge($currentValue, $value); } elseif (is_array($currentValue) && !is_array($value)) { $currentValue[] = $value; } elseif (!is_array($currentValue) && is_array($value)) { $currentValue = array_merge([$currentValue], $value); } else { $currentValue = [$currentValue, $value]; } break; // When duplicate detected concatenate colon and duplicate value // When duplicate detected concatenate colon and duplicate value case self::MODE_QUERY_DUPLICATE_WITH_COLON & $mode: $currentValue .= ",{$value}"; break; } $query->remove($parameter); $query->add(new Parameter($name, $currentValue)); } } } else { $value = is_array($value) ? $this->decodeUrlArrayValue($value) : $this->decodeUrlValue($value); $query->add(new Parameter($name, $value)); } } return $query; }