diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/IssueBoards.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/IssueBoards.php new file mode 100644 index 0000000000000000000000000000000000000000..e5d460bc553ba866d77057bd4baa355553dc7290 --- /dev/null +++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/IssueBoards.php @@ -0,0 +1,88 @@ +<?php namespace Gitlab\Api; + +class IssueBoards extends AbstractApi +{ + /** + * @param int $project_id + * @param array $parameters + * + * @return mixed + */ + public function all($project_id = null, array $parameters = []) + { + $resolver = $this->createOptionsResolver(); + + $path = $project_id === null ? 'boards' : $this->getProjectPath($project_id, 'boards'); + + return $this->get($path, $resolver->resolve($parameters)); + } + + /** + * @param int $project_id + * @param int $board_id + * @return mixed + */ + public function allLists($project_id, $board_id) + { + return $this->get($this->getProjectPath($project_id, 'boards/'.$this->encodePath($board_id).'/lists')); + } + + + /** + * @param int $project_id + * @param int $board_id + * @param int $list_id + * @return mixed + */ + public function showList($project_id, $board_id, $list_id) + { + return $this->get($this->getProjectPath($project_id, 'boards/'.$this->encodePath($board_id).'/lists'.$this->encodePath($list_id))); + } + + /** + * @param int $project_id + * @param int $board_id + * @param int $label_id + * @return mixed + */ + public function createList($project_id, $board_id, $label_id) + { + $params = array( + 'id' => $project_id, + 'board_id' => $board_id, + 'label_id' => $label_id + ); + + return $this->get($this->getProjectPath($project_id, 'boards/'.$this->encodePath($board_id).'/lists'), $params); + } + + /** + * @param int $project_id + * @param int $board_id + * @param int $list_id + * @param int $position + * @return mixed + */ + public function updateList($project_id, $board_id, $list_id, $position) + { + $params = array( + 'id' => $project_id, + 'board_id' => $board_id, + 'list_id' => $list_id, + 'position' => $position + ); + + return $this->put($this->getProjectPath($project_id, 'boards/'.$this->encodePath($board_id).'/lists/'.$this->encodePath($list_id)), $params); + } + + /** + * @param int $project_id + * @param int $board_id + * @param int $list_id + * @return mixed + */ + public function deleteList($project_id, $board_id, $list_id) + { + return $this->delete($this->getProjectPath($project_id, 'boards/'.$this->encodePath($board_id).'/lists/'.$this->encodePath($list_id))); + } +} diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/Jobs.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/Jobs.php new file mode 100644 index 0000000000000000000000000000000000000000..2bec5679621145ff75b0b1bc56c55672ec0732d4 --- /dev/null +++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/Jobs.php @@ -0,0 +1,178 @@ +<?php namespace Gitlab\Api; + +use Psr\Http\Message\StreamInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; + +class Jobs extends AbstractApi +{ + const SCOPE_CREATED = 'created'; + const SCOPE_PENDING = 'pending'; + const SCOPE_RUNNING = 'running'; + const SCOPE_FAILED = 'failed'; + const SCOPE_SUCCESS = 'success'; + const SCOPE_CANCELED = 'canceled'; + const SCOPE_SKIPPED = 'skipped'; + const SCOPE_MANUAL = 'manual'; + + /** + * @param int|string $project_id + * @param array $parameters ( + * + * @var string|string[] $scope The scope of jobs to show, one or array of: created, pending, running, failed, + * success, canceled, skipped, manual; showing all jobs if none provided. + * ) + * + * @return mixed + */ + public function all($project_id, array $parameters = []) + { + $resolver = $this->createOptionsResolver(); + + return $this->get("projects/".$this->encodePath($project_id)."/jobs", $resolver->resolve($parameters)); + } + + /** + * @param int|string $project_id + * @param int $pipeline_id + * @param array $parameters ( + * + * @var string|string[] $scope The scope of jobs to show, one or array of: created, pending, running, failed, + * success, canceled, skipped, manual; showing all jobs if none provided. + * ) + * + * @return mixed + */ + public function pipelineJobs($project_id, $pipeline_id, array $parameters = []) + { + $resolver = $this->createOptionsResolver(); + + return $this->get( + $this->getProjectPath($project_id, 'pipelines/').$this->encodePath($pipeline_id)."/jobs", + $resolver->resolve($parameters) + ); + } + + /** + * @param int|string $project_id + * @param int $job_id + * @return mixed + */ + public function show($project_id, $job_id) + { + return $this->get("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)); + } + + /** + * @param int|string $project_id + * @param int $job_id + * @return StreamInterface + */ + public function artifacts($project_id, $job_id) + { + return $this->getAsResponse("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/artifacts")->getBody(); + } + + /** + * @param int|string $project_id + * @param string $ref_name + * @param string $job_name + * @return StreamInterface + */ + public function artifactsByRefName($project_id, $ref_name, $job_name) + { + return $this->getAsResponse("projects/".$this->encodePath($project_id)."/jobs/artifacts/".$this->encodePath($ref_name)."/download", array( + 'job' => $job_name + ))->getBody(); + } + + /** + * @param int|string $project_id + * @param int $job_id + * @return string + */ + public function trace($project_id, $job_id) + { + return $this->get("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/trace"); + } + + /** + * @param int|string $project_id + * @param int $job_id + * @return mixed + */ + public function cancel($project_id, $job_id) + { + return $this->post("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/cancel"); + } + + /** + * @param int|string $project_id + * @param int $job_id + * @return mixed + */ + public function retry($project_id, $job_id) + { + return $this->post("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/retry"); + } + + /** + * @param int|string $project_id + * @param int $job_id + * @return mixed + */ + public function erase($project_id, $job_id) + { + return $this->post("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/erase"); + } + + /** + * @param int|string $project_id + * @param int $job_id + * @return mixed + */ + public function keepArtifacts($project_id, $job_id) + { + return $this->post("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/artifacts/keep"); + } + + /** + * @param int|string $project_id + * @param int $job_id + * @return mixed + */ + public function play($project_id, $job_id) + { + return $this->post("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/play"); + } + + /** + * {@inheritdoc} + */ + protected function createOptionsResolver() + { + $allowedScopeValues = [ + self::SCOPE_CANCELED, + self::SCOPE_CREATED, + self::SCOPE_FAILED, + self::SCOPE_MANUAL, + self::SCOPE_PENDING, + self::SCOPE_RUNNING, + self::SCOPE_SKIPPED, + self::SCOPE_SUCCESS, + ]; + + $resolver = parent::createOptionsResolver(); + $resolver->setDefined('scope') + ->setAllowedTypes('scope', ['string', 'array']) + ->setAllowedValues('scope', $allowedScopeValues) + ->addAllowedValues('scope', function ($value) use ($allowedScopeValues) { + return is_array($value) && empty(array_diff($value, $allowedScopeValues)); + }) + ->setNormalizer('scope', function (OptionsResolver $resolver, $value) { + return (array) $value; + }) + ; + + return $resolver; + } +} diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/RepositoryFiles.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/RepositoryFiles.php new file mode 100644 index 0000000000000000000000000000000000000000..bc20c00f0d8604756353474517e7dbfe84e4e7c7 --- /dev/null +++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Api/RepositoryFiles.php @@ -0,0 +1,135 @@ +<?php + +namespace Gitlab\Api; + +use Symfony\Component\OptionsResolver\OptionsResolver; + +class RepositoryFiles extends AbstractApi +{ + /** + * @param int $project_id + * @param string $file_path + * @param string $ref + * @return mixed + */ + public function getFile($project_id, $file_path, $ref) + { + return $this->get($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($file_path)), array( + 'ref' => $ref + )); + } + + /** + * @param int $project_id + * @param string $file_path + * @param string $ref + * @return mixed + */ + public function getRawFile($project_id, $file_path, $ref) + { + return $this->get($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($file_path).'/raw'), array( + 'ref' => $ref, + )); + } + + /** + * @param int $project_id + * @param array $parameters ( + * + * @var string $file_path Url encoded full path to new file. Ex. lib%2Fclass%2Erb. + * @var string $branch Name of the branch. + * @var string $start_branch Name of the branch to start the new commit from. + * @var string $encoding Change encoding to 'base64'. Default is text. + * @var string $author_email Specify the commit author's email address. + * @var string $author_name Specify the commit author's name. + * @var string $content File content. + * @var string $commit_message Commit message. + * ) + * + * @return mixed + */ + public function createFile($project_id, array $parameters = []) + { + $resolver = new OptionsResolver(); + $resolver->setRequired('file_path'); + $resolver->setRequired('branch'); + $resolver->setDefined('start_branch'); + $resolver->setDefined('encoding') + ->setAllowedValues('encoding', ['text', 'base64']) + ; + $resolver->setDefined('author_email'); + $resolver->setDefined('author_name'); + $resolver->setRequired('content'); + $resolver->setRequired('commit_message'); + + $resolved = $resolver->resolve($parameters); + + return $this->post($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($resolved['file_path'])), $resolved); + } + + /** + * @param int $project_id + * @param array $parameters ( + * + * @var string $file_path Url encoded full path to new file. Ex. lib%2Fclass%2Erb. + * @var string $branch Name of the branch. + * @var string $start_branch Name of the branch to start the new commit from. + * @var string $encoding Change encoding to 'base64'. Default is text. + * @var string $author_email Specify the commit author's email address. + * @var string $author_name Specify the commit author's name. + * @var string $content File content. + * @var string $commit_message Commit message. + * @var string $last_commit_id Last known file commit id. + * ) + * + * @return mixed + */ + public function updateFile($project_id, array $parameters = []) + { + $resolver = new OptionsResolver(); + $resolver->setRequired('file_path'); + $resolver->setRequired('branch'); + $resolver->setDefined('start_branch'); + $resolver->setDefined('encoding') + ->setAllowedValues('encoding', ['text', 'base64']) + ; + $resolver->setDefined('author_email'); + $resolver->setDefined('author_name'); + $resolver->setRequired('content'); + $resolver->setRequired('commit_message'); + $resolver->setDefined('last_commit_id'); + + $resolved = $resolver->resolve($parameters); + + return $this->put($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($resolved['file_path'])), $resolved); + } + + /** + * @param int $project_id + * @param array $parameters ( + * + * @var string $file_path Url encoded full path to new file. Ex. lib%2Fclass%2Erb. + * @var string $branch Name of the branch. + * @var string $start_branch Name of the branch to start the new commit from. + * @var string $author_email Specify the commit author's email address. + * @var string $author_name Specify the commit author's name. + * @var string $commit_message Commit message. + * ) + * + * @return mixed + */ + public function deleteFile($project_id, array $parameters = []) + { + $resolver = new OptionsResolver(); + $resolver->setRequired('file_path'); + $resolver->setRequired('branch'); + $resolver->setDefined('start_branch'); + $resolver->setDefined('author_email'); + $resolver->setDefined('author_name'); + $resolver->setRequired('commit_message'); + + $resolved = $resolver->resolve($parameters); + + return $this->delete($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($resolved['file_path'])), $resolved); + } +} diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Builder.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Builder.php new file mode 100644 index 0000000000000000000000000000000000000000..15be1ff12bb8e04fcd85fa65122440cf1bf430b5 --- /dev/null +++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Builder.php @@ -0,0 +1,117 @@ +<?php + +namespace Gitlab\HttpClient; + +use Http\Client\Common\HttpMethodsClient; +use Http\Client\Common\Plugin; +use Http\Client\Common\PluginClient; +use Http\Client\HttpClient; +use Http\Discovery\HttpClientDiscovery; +use Http\Discovery\MessageFactoryDiscovery; +use Http\Discovery\StreamFactoryDiscovery; +use Http\Message\MessageFactory; +use Http\Message\RequestFactory; +use Http\Message\StreamFactory; + +/** + * A builder that builds the API client. + * This will allow you to fluently add and remove plugins. + * + * @author Tobias Nyholm <tobias.nyholm@gmail.com> + */ +class Builder +{ + /** + * The object that sends HTTP messages. + * + * @var HttpClient + */ + private $httpClient; + + /** + * A HTTP client with all our plugins. + * + * @var HttpMethodsClient + */ + private $pluginClient; + + /** + * @var MessageFactory + */ + private $requestFactory; + + /** + * @var StreamFactory + */ + private $streamFactory; + + /** + * True if we should create a new Plugin client at next request. + * + * @var bool + */ + private $httpClientModified = true; + + /** + * @var Plugin[] + */ + private $plugins = []; + + /** + * @param HttpClient $httpClient + * @param RequestFactory $requestFactory + * @param StreamFactory $streamFactory + */ + public function __construct( + HttpClient $httpClient = null, + RequestFactory $requestFactory = null, + StreamFactory $streamFactory = null + ) { + $this->httpClient = $httpClient ?: HttpClientDiscovery::find(); + $this->requestFactory = $requestFactory ?: MessageFactoryDiscovery::find(); + $this->streamFactory = $streamFactory ?: StreamFactoryDiscovery::find(); + } + + /** + * @return HttpMethodsClient + */ + public function getHttpClient() + { + if ($this->httpClientModified) { + $this->httpClientModified = false; + + $this->pluginClient = new HttpMethodsClient( + new PluginClient($this->httpClient, $this->plugins), + $this->requestFactory + ); + } + + return $this->pluginClient; + } + + /** + * Add a new plugin to the end of the plugin chain. + * + * @param Plugin $plugin + */ + public function addPlugin(Plugin $plugin) + { + $this->plugins[] = $plugin; + $this->httpClientModified = true; + } + + /** + * Remove a plugin by its fully qualified class name (FQCN). + * + * @param string $fqcn + */ + public function removePlugin($fqcn) + { + foreach ($this->plugins as $idx => $plugin) { + if ($plugin instanceof $fqcn) { + unset($this->plugins[$idx]); + $this->httpClientModified = true; + } + } + } +} diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Message/QueryStringBuilder.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Message/QueryStringBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..03e16a32610668223fe1d467c637fb74d65845cb --- /dev/null +++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Message/QueryStringBuilder.php @@ -0,0 +1,76 @@ +<?php + +namespace Gitlab\HttpClient\Message; + +final class QueryStringBuilder +{ + /** + * Encode a query as a query string according to RFC 3986. Indexed arrays are encoded using + * empty squared brackets ([]) unlike http_build_query. + * + * @param mixed $query + * + * @return string + */ + public static function build($query) + { + if (!is_array($query)) { + return static::rawurlencode($query); + } + return implode('&', array_map(function ($value, $key) { + return static::encode($value, $key); + }, $query, array_keys($query))); + } + + /** + * Encode a value + * @param mixed $query + * @param string $prefix + * + * @return string + */ + private static function encode($query, $prefix) + { + if (!is_array($query)) { + return static::rawurlencode($prefix).'='.static::rawurlencode($query); + } + + $isIndexedArray = static::isIndexedArray($query); + return implode('&', array_map(function ($value, $key) use ($prefix, $isIndexedArray) { + $prefix = $isIndexedArray ? $prefix.'[]' : $prefix.'['.$key.']'; + return static::encode($value, $prefix); + }, $query, array_keys($query))); + } + + /** + * Tell if the given array is an indexed one (i.e. contains only sequential integer keys starting from 0). + * + * @param array $query + * + * @return bool + */ + public static function isIndexedArray(array $query) + { + if (empty($query) || !isset($query[0])) { + return false; + } + + return array_keys($query) === range(0, count($query) - 1); + } + + /** + * Encode a value like rawurlencode, but return "0" when false is given. + * + * @param mixed $value + * + * @return string + */ + private static function rawurlencode($value) + { + if ($value === false) { + return '0'; + } + + return rawurlencode($value); + } +} diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Message/ResponseMediator.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Message/ResponseMediator.php new file mode 100644 index 0000000000000000000000000000000000000000..16bd781f07f7179bc93d508e262724da8cddc4a6 --- /dev/null +++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Message/ResponseMediator.php @@ -0,0 +1,73 @@ +<?php + +namespace Gitlab\HttpClient\Message; + +use Psr\Http\Message\ResponseInterface; + +/** + * Utilities to parse response headers and content. + */ +class ResponseMediator +{ + /** + * Return the response body as a string or json array if content type is application/json. + *. + * @param ResponseInterface $response + * + * @return array|string + */ + public static function getContent(ResponseInterface $response) + { + $body = $response->getBody()->__toString(); + if (strpos($response->getHeaderLine('Content-Type'), 'application/json') === 0) { + $content = json_decode($body, true); + if (JSON_ERROR_NONE === json_last_error()) { + return $content; + } + } + + return $body; + } + + /** + * Extract pagination URIs from Link header. + * + * @param ResponseInterface $response + * + * @return array|null + */ + public static function getPagination(ResponseInterface $response) + { + if (!$response->hasHeader('Link')) { + return null; + } + + $header = self::getHeader($response, 'Link'); + $pagination = array(); + foreach (explode(',', $header) as $link) { + preg_match('/<(.*)>; rel="(.*)"/i', trim($link, ','), $match); + + if (3 === count($match)) { + $pagination[$match[2]] = $match[1]; + } + } + + return $pagination; + } + + + /** + * Get the value for a single header. + * + * @param ResponseInterface $response + * @param string $name + * + * @return string|null + */ + private static function getHeader(ResponseInterface $response, $name) + { + $headers = $response->getHeader($name); + + return array_shift($headers); + } +} diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/ApiVersion.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/ApiVersion.php new file mode 100644 index 0000000000000000000000000000000000000000..46b20e402284357dd3ee81eee9f76b1dfd854d6d --- /dev/null +++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/ApiVersion.php @@ -0,0 +1,29 @@ +<?php + + +namespace Gitlab\HttpClient\Plugin; + +use Http\Client\Common\Plugin; +use Psr\Http\Message\RequestInterface; + +/** + * Prefix requests path with /api/v4/ if required. + * + * @author Fabien Bourigault <bourigaultfabien@gmail.com> + */ +class ApiVersion implements Plugin +{ + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + $uri = $request->getUri(); + + if (substr($uri->getPath(), 0, 8) !== '/api/v4/') { + $request = $request->withUri($uri->withPath('/api/v4/'.$uri->getPath())); + } + + return $next($request); + } +} diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/Authentication.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/Authentication.php new file mode 100644 index 0000000000000000000000000000000000000000..aac0acc4a2e0c5a3a3cb585398bafa8dc68f6c66 --- /dev/null +++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/Authentication.php @@ -0,0 +1,86 @@ +<?php + +namespace Gitlab\HttpClient\Plugin; + +use Gitlab\Client; +use Http\Client\Common\Plugin; +use Psr\Http\Message\RequestInterface; + +/** + * Add authentication to the request. + * + * @author Tobias Nyholm <tobias.nyholm@gmail.com> + * @author Fabien Bourigault <bourigaultfabien@gmail.com> + */ +class Authentication implements Plugin +{ + /** + * @var string + */ + private $method; + + /** + * @var string + */ + private $token; + + /** + * @var string|null + */ + private $sudo; + + /** + * @param string $method + * @param string $token + * @param string|null $sudo + */ + public function __construct($method, $token, $sudo = null) + { + $this->method = $method; + $this->token = $token; + $this->sudo = $sudo; + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + switch ($this->method) { + case Client::AUTH_HTTP_TOKEN: + $request = $request->withHeader('PRIVATE-TOKEN', $this->token); + if (!is_null($this->sudo)) { + $request = $request->withHeader('SUDO', $this->sudo); + } + break; + + case Client::AUTH_URL_TOKEN: + $uri = $request->getUri(); + $query = $uri->getQuery(); + + $parameters = [ + 'private_token' => $this->token, + ]; + + if (!is_null($this->sudo)) { + $parameters['sudo'] = $this->sudo; + } + + $query .= empty($query) ? '' : '&'; + $query .= utf8_encode(http_build_query($parameters, '', '&')); + + $uri = $uri->withQuery($query); + $request = $request->withUri($uri); + break; + + case Client::AUTH_OAUTH_TOKEN: + $request = $request->withHeader('Authorization', 'Bearer '.$this->token); + if (!is_null($this->sudo)) { + $request = $request->withHeader('SUDO', $this->sudo); + } + break; + } + + return $next($request); + } +} diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/GitlabExceptionThrower.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/GitlabExceptionThrower.php new file mode 100644 index 0000000000000000000000000000000000000000..bb61e31219f9650a90e8e52980c1e94d666c1bf3 --- /dev/null +++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/GitlabExceptionThrower.php @@ -0,0 +1,86 @@ +<?php + +namespace Gitlab\HttpClient\Plugin; + +use Gitlab\Exception\ErrorException; +use Gitlab\Exception\RuntimeException; +use Gitlab\HttpClient\Message\ResponseMediator; +use Http\Client\Common\Plugin; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; + +/** + * A plugin to remember the last response. + * + * @author Tobias Nyholm <tobias.nyholm@gmail.com> + * @author Fabien Bourigault <bourigaultfabien@gmail.com> + */ +class GitlabExceptionThrower implements Plugin +{ + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + return $next($request)->then(function (ResponseInterface $response) { + if ($response->getStatusCode() >= 400 && $response->getStatusCode() < 600) { + $content = ResponseMediator::getContent($response); + if (is_array($content) && isset($content['message'])) { + if (400 == $response->getStatusCode()) { + $message = $this->parseMessage($content['message']); + + throw new ErrorException($message, 400); + } + } + + $errorMessage = null; + if (isset($content['error'])) { + $errorMessage = $content['error']; + if (is_array($content['error'])) { + $errorMessage = implode("\n", $content['error']); + } + } elseif (isset($content['message'])) { + $errorMessage = $this->parseMessage($content['message']); + } else { + $errorMessage = $content; + } + + throw new RuntimeException($errorMessage, $response->getStatusCode()); + } + + return $response; + }); + } + + /** + * @param mixed $message + * + * @return string + */ + private function parseMessage($message) + { + $string = $message; + + if (is_array($message)) { + $format = '"%s" %s'; + $errors = array(); + + foreach ($message as $field => $messages) { + if (is_array($messages)) { + $messages = array_unique($messages); + foreach ($messages as $error) { + $errors[] = sprintf($format, $field, $error); + } + } elseif (is_integer($field)) { + $errors[] = $messages; + } else { + $errors[] = sprintf($format, $field, $messages); + } + } + + $string = implode(', ', $errors); + } + + return $string; + } +} diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/History.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/History.php new file mode 100644 index 0000000000000000000000000000000000000000..8412356fdae09fea78832a5593bba3f3c187ddf9 --- /dev/null +++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/HttpClient/Plugin/History.php @@ -0,0 +1,44 @@ +<?php + +namespace Gitlab\HttpClient\Plugin; + +use Http\Client\Common\Plugin\Journal; +use Http\Client\Exception; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; + +/** + * A plugin to remember the last response. + * + * @author Tobias Nyholm <tobias.nyholm@gmail.com> + */ +class History implements Journal +{ + /** + * @var ResponseInterface + */ + private $lastResponse; + + /** + * @return ResponseInterface|null + */ + public function getLastResponse() + { + return $this->lastResponse; + } + + /** + * {@inheritdoc} + */ + public function addSuccess(RequestInterface $request, ResponseInterface $response) + { + $this->lastResponse = $response; + } + + /** + * {@inheritdoc} + */ + public function addFailure(RequestInterface $request, Exception $exception) + { + } +} diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Model/Job.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Model/Job.php new file mode 100644 index 0000000000000000000000000000000000000000..586e3a31185baf94ec1ef05b5edc5bf087446084 --- /dev/null +++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Model/Job.php @@ -0,0 +1,83 @@ +<?php namespace Gitlab\Model; + +use Gitlab\Client; + +/** + * Class Commit + * + * @property-read Commit $commit + * @property-read int $id + * @property-read string $coverage + * @property-read string $created_at + * @property-read string $artifacts_file + * @property-read string $finished_at + * @property-read string $name + * @property-read Pipeline $pipeline + * @property-read string $ref + * @property-read string $runner + * @property-read string $stage + * @property-read string $started_at + * @property-read string $status + * @property-read string|bool $tag + * @property-read User $user + */ +class Job extends AbstractModel +{ + /** + * @var array + */ + protected static $properties = array( + 'id', + 'commit', + 'coverage', + 'created_at', + 'artifacts_file', + 'finished_at', + 'name', + 'pipeline', + 'ref', + 'runner', + 'stage', + 'started_at', + 'status', + 'tag', + 'user' + ); + + /** + * @param Client $client + * @param Project $project + * @param array $data + * @return Job + */ + public static function fromArray(Client $client, Project $project, array $data) + { + $job = new static($project, $data['id'], $client); + + if (isset($data['user'])) { + $data['user'] = User::fromArray($client, $data['user']); + } + + if (isset($data['commit'])) { + $data['commit'] = Commit::fromArray($client, $project, $data['commit']); + } + + if (isset($data['pipeline'])) { + $data['pipeline'] = Pipeline::fromArray($client, $project, $data['pipeline']); + } + + return $job->hydrate($data); + } + + /** + * @param Project $project + * @param int $id + * @param Client $client + */ + public function __construct(Project $project, $id = null, Client $client = null) + { + $this->setClient($client); + $this->setData('project', $project); + $this->setData('id', $id); + } +} diff --git a/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Model/Pipeline.php b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Model/Pipeline.php new file mode 100644 index 0000000000000000000000000000000000000000..efeccbc9879f78fe2a50df6b51ba0987c6c1ed22 --- /dev/null +++ b/vendor/m4tthumphrey/php-gitlab-api/lib/Gitlab/Model/Pipeline.php @@ -0,0 +1,49 @@ +<?php namespace Gitlab\Model; + +use Gitlab\Client; + +/** + * Class Commit + * + * @property-read int $id + * @property-read string $ref + * @property-read string $sha + * @property-read string $status + */ +class Pipeline extends AbstractModel +{ + /** + * @var array + */ + protected static $properties = array( + 'id', + 'ref', + 'sha', + 'status' + ); + + /** + * @param Client $client + * @param Project $project + * @param array $data + * @return Pipeline + */ + public static function fromArray(Client $client, Project $project, array $data) + { + $pipeline = new static($project, $data['id'], $client); + + return $pipeline->hydrate($data); + } + + /** + * @param Project $project + * @param int $id + * @param Client $client + */ + public function __construct(Project $project, $id = null, Client $client = null) + { + $this->setClient($client); + $this->setData('project', $project); + $this->setData('id', $id); + } +} diff --git a/vendor/php-http/client-common/CHANGELOG.md b/vendor/php-http/client-common/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..3031720c6d59e8b3362a4eda3370af07f98f56d9 --- /dev/null +++ b/vendor/php-http/client-common/CHANGELOG.md @@ -0,0 +1,137 @@ +# Change Log + +## 1.7.0 - 2017-11-30 + +### Added + +- Symfony 4 support + +### Changed + +- Strict comparison in DecoderPlugin + +## 1.6.0 - 2017-10-16 + +### Added + +- Add HttpClientPool client to leverage load balancing and fallback mechanism [see the documentation](http://docs.php-http.org/en/latest/components/client-common.html) for more details. +- `PluginClientFactory` to create `PluginClient` instances. +- Added new option 'delay' for `RetryPlugin`. +- Added new option 'decider' for `RetryPlugin`. +- Supports more cookie date formats in the Cookie Plugin + +### Changed + +- The `RetryPlugin` does now wait between retries. To disable/change this feature you must write something like: + +```php +$plugin = new RetryPlugin(['delay' => function(RequestInterface $request, Exception $e, $retries) { + return 0; +}); +``` + +### Deprecated + +- The `debug_plugins` option for `PluginClient` is deprecated and will be removed in 2.0. Use the decorator design pattern instead like in [ProfilePlugin](https://github.com/php-http/HttplugBundle/blob/de33f9c14252f22093a5ec7d84f17535ab31a384/Collector/ProfilePlugin.php). + +## 1.5.0 - 2017-03-30 + +### Added + +- `QueryDefaultsPlugin` to add default query parameters. + +## 1.4.2 - 2017-03-18 + +### Deprecated + +- `DecoderPlugin` does not longer claim to support `compress` content encoding + +### Fixed + +- `CookiePlugin` allows main domain cookies to be sent/stored for subdomains +- `DecoderPlugin` uses the right `FilteredStream` to handle `deflate` content encoding + + +## 1.4.1 - 2017-02-20 + +### Fixed + +- Cast return value of `StreamInterface::getSize` to string in `ContentLengthPlugin` + + +## 1.4.0 - 2016-11-04 + +### Added + +- Add Path plugin +- Base URI plugin that combines Add Host and Add Path plugins + + +## 1.3.0 - 2016-10-16 + +### Changed + +- Fix Emulated Trait to use Http based promise which respect the HttpAsyncClient interface +- Require Httplug 1.1 where we use HTTP specific promises. +- RedirectPlugin: use the full URL instead of the URI to properly keep track of redirects +- Add AddPathPlugin for API URLs with base path +- Add BaseUriPlugin that combines AddHostPlugin and AddPathPlugin + + +## 1.2.1 - 2016-07-26 + +### Changed + +- AddHostPlugin also sets the port if specified + + +## 1.2.0 - 2016-07-14 + +### Added + +- Suggest separate plugins in composer.json +- Introduced `debug_plugins` option for `PluginClient` + + +## 1.1.0 - 2016-05-04 + +### Added + +- Add a flexible http client providing both contract, and only emulating what's necessary +- HTTP Client Router: route requests to underlying clients +- Plugin client and core plugins moved here from `php-http/plugins` + +### Deprecated + +- Extending client classes, they will be made final in version 2.0 + + +## 1.0.0 - 2016-01-27 + +### Changed + +- Remove useless interface in BatchException + + +## 0.2.0 - 2016-01-12 + +### Changed + +- Updated package files +- Updated HTTPlug to RC1 + + +## 0.1.1 - 2015-12-26 + +### Added + +- Emulated clients + + +## 0.1.0 - 2015-12-25 + +### Added + +- Batch client from utils +- Methods client from utils +- Emulators and decorators from client-tools diff --git a/vendor/php-http/client-common/LICENSE b/vendor/php-http/client-common/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..4558d6f06306fce15add8bc10e29152bc4ad5355 --- /dev/null +++ b/vendor/php-http/client-common/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015-2016 PHP HTTP Team <team@php-http.org> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/php-http/client-common/README.md b/vendor/php-http/client-common/README.md new file mode 100644 index 0000000000000000000000000000000000000000..017bfcec93b5f7d436bffaade7e051ec0570ccb1 --- /dev/null +++ b/vendor/php-http/client-common/README.md @@ -0,0 +1,55 @@ +# HTTP Client Common + +[](https://github.com/php-http/client-common/releases) +[](LICENSE) +[](https://travis-ci.org/php-http/client-common) +[](https://scrutinizer-ci.com/g/php-http/client-common) +[](https://scrutinizer-ci.com/g/php-http/client-common) +[](https://packagist.org/packages/php-http/client-common) + +**Common HTTP Client implementations and tools for HTTPlug.** + + +## Install + +Via Composer + +``` bash +$ composer require php-http/client-common +``` + + +## Usage + +This package provides common tools for HTTP Clients: + +- BatchClient to handle sending requests in parallel +- A convenience client with HTTP method names as class methods +- Emulator, decorator layers for sync/async clients + + +## Documentation + +Please see the [official documentation](http://docs.php-http.org/en/latest/components/client-common.html). + + +## Testing + +``` bash +$ composer test +``` + + +## Contributing + +Please see our [contributing guide](http://docs.php-http.org/en/latest/development/contributing.html). + + +## Security + +If you discover any security related issues, please contact us at [security@php-http.org](mailto:security@php-http.org). + + +## License + +The MIT License (MIT). Please see [License File](LICENSE) for more information. diff --git a/vendor/php-http/client-common/composer.json b/vendor/php-http/client-common/composer.json new file mode 100644 index 0000000000000000000000000000000000000000..fc5fc5fb4ea5e4927b72b29e406b5b47f3f691fa --- /dev/null +++ b/vendor/php-http/client-common/composer.json @@ -0,0 +1,43 @@ +{ + "name": "php-http/client-common", + "description": "Common HTTP Client implementations and tools for HTTPlug", + "license": "MIT", + "keywords": ["http", "client", "httplug", "common"], + "homepage": "http://httplug.io", + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "require": { + "php": "^5.4 || ^7.0", + "php-http/httplug": "^1.1", + "php-http/message-factory": "^1.0", + "php-http/message": "^1.6", + "symfony/options-resolver": "^2.6 || ^3.0 || ^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5 || ^3.4 || ^4.2", + "guzzlehttp/psr7": "^1.4" + }, + "suggest": { + "php-http/logger-plugin": "PSR-3 Logger plugin", + "php-http/cache-plugin": "PSR-6 Cache plugin", + "php-http/stopwatch-plugin": "Symfony Stopwatch plugin" + }, + "autoload": { + "psr-4": { + "Http\\Client\\Common\\": "src/" + } + }, + "scripts": { + "test": "vendor/bin/phpspec run", + "test-ci": "vendor/bin/phpspec run -c phpspec.ci.yml" + }, + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } + } +} diff --git a/vendor/php-http/client-common/src/BatchClient.php b/vendor/php-http/client-common/src/BatchClient.php new file mode 100644 index 0000000000000000000000000000000000000000..2036355b604746ea942b0c69a95ba768723ae0e5 --- /dev/null +++ b/vendor/php-http/client-common/src/BatchClient.php @@ -0,0 +1,73 @@ +<?php + +namespace Http\Client\Common; + +use Http\Client\Exception; +use Http\Client\HttpClient; +use Http\Client\Common\Exception\BatchException; +use Psr\Http\Message\RequestInterface; + +/** + * BatchClient allow to sends multiple request and retrieve a Batch Result. + * + * This implementation simply loops over the requests and uses sendRequest with each of them. + * + * @author Joel Wurtz <jwurtz@jolicode.com> + */ +class BatchClient implements HttpClient +{ + /** + * @var HttpClient + */ + private $client; + + /** + * @param HttpClient $client + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * {@inheritdoc} + */ + public function sendRequest(RequestInterface $request) + { + return $this->client->sendRequest($request); + } + + /** + * Send several requests. + * + * You may not assume that the requests are executed in a particular order. If the order matters + * for your application, use sendRequest sequentially. + * + * @param RequestInterface[] The requests to send + * + * @return BatchResult Containing one result per request + * + * @throws BatchException If one or more requests fails. The exception gives access to the + * BatchResult with a map of request to result for success, request to + * exception for failures + */ + public function sendRequests(array $requests) + { + $batchResult = new BatchResult(); + + foreach ($requests as $request) { + try { + $response = $this->sendRequest($request); + $batchResult = $batchResult->addResponse($request, $response); + } catch (Exception $e) { + $batchResult = $batchResult->addException($request, $e); + } + } + + if ($batchResult->hasExceptions()) { + throw new BatchException($batchResult); + } + + return $batchResult; + } +} diff --git a/vendor/php-http/client-common/src/BatchResult.php b/vendor/php-http/client-common/src/BatchResult.php new file mode 100644 index 0000000000000000000000000000000000000000..710611d6d00ff6b3069eff19a26f2daab6ec1e7e --- /dev/null +++ b/vendor/php-http/client-common/src/BatchResult.php @@ -0,0 +1,181 @@ +<?php + +namespace Http\Client\Common; + +use Http\Client\Exception; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; + +/** + * Responses and exceptions returned from parallel request execution. + * + * @author Márk Sági-Kazár <mark.sagikazar@gmail.com> + */ +final class BatchResult +{ + /** + * @var \SplObjectStorage + */ + private $responses; + + /** + * @var \SplObjectStorage + */ + private $exceptions; + + public function __construct() + { + $this->responses = new \SplObjectStorage(); + $this->exceptions = new \SplObjectStorage(); + } + + /** + * Checks if there are any successful responses at all. + * + * @return bool + */ + public function hasResponses() + { + return $this->responses->count() > 0; + } + + /** + * Returns all successful responses. + * + * @return ResponseInterface[] + */ + public function getResponses() + { + $responses = []; + + foreach ($this->responses as $request) { + $responses[] = $this->responses[$request]; + } + + return $responses; + } + + /** + * Checks if there is a successful response for a request. + * + * @param RequestInterface $request + * + * @return bool + */ + public function isSuccessful(RequestInterface $request) + { + return $this->responses->contains($request); + } + + /** + * Returns the response for a successful request. + * + * @param RequestInterface $request + * + * @return ResponseInterface + * + * @throws \UnexpectedValueException If request was not part of the batch or failed + */ + public function getResponseFor(RequestInterface $request) + { + try { + return $this->responses[$request]; + } catch (\UnexpectedValueException $e) { + throw new \UnexpectedValueException('Request not found', $e->getCode(), $e); + } + } + + /** + * Adds a response in an immutable way. + * + * @param RequestInterface $request + * @param ResponseInterface $response + * + * @return BatchResult the new BatchResult with this request-response pair added to it + */ + public function addResponse(RequestInterface $request, ResponseInterface $response) + { + $new = clone $this; + $new->responses->attach($request, $response); + + return $new; + } + + /** + * Checks if there are any unsuccessful requests at all. + * + * @return bool + */ + public function hasExceptions() + { + return $this->exceptions->count() > 0; + } + + /** + * Returns all exceptions for the unsuccessful requests. + * + * @return Exception[] + */ + public function getExceptions() + { + $exceptions = []; + + foreach ($this->exceptions as $request) { + $exceptions[] = $this->exceptions[$request]; + } + + return $exceptions; + } + + /** + * Checks if there is an exception for a request, meaning the request failed. + * + * @param RequestInterface $request + * + * @return bool + */ + public function isFailed(RequestInterface $request) + { + return $this->exceptions->contains($request); + } + + /** + * Returns the exception for a failed request. + * + * @param RequestInterface $request + * + * @return Exception + * + * @throws \UnexpectedValueException If request was not part of the batch or was successful + */ + public function getExceptionFor(RequestInterface $request) + { + try { + return $this->exceptions[$request]; + } catch (\UnexpectedValueException $e) { + throw new \UnexpectedValueException('Request not found', $e->getCode(), $e); + } + } + + /** + * Adds an exception in an immutable way. + * + * @param RequestInterface $request + * @param Exception $exception + * + * @return BatchResult the new BatchResult with this request-exception pair added to it + */ + public function addException(RequestInterface $request, Exception $exception) + { + $new = clone $this; + $new->exceptions->attach($request, $exception); + + return $new; + } + + public function __clone() + { + $this->responses = clone $this->responses; + $this->exceptions = clone $this->exceptions; + } +} diff --git a/vendor/php-http/client-common/src/EmulatedHttpAsyncClient.php b/vendor/php-http/client-common/src/EmulatedHttpAsyncClient.php new file mode 100644 index 0000000000000000000000000000000000000000..1b163167e6dfcfb23076e3a9ad4a19b96a86abfe --- /dev/null +++ b/vendor/php-http/client-common/src/EmulatedHttpAsyncClient.php @@ -0,0 +1,27 @@ +<?php + +namespace Http\Client\Common; + +use Http\Client\HttpAsyncClient; +use Http\Client\HttpClient; + +/** + * Emulates an async HTTP client. + * + * This should be replaced by an anonymous class in PHP 7. + * + * @author Márk Sági-Kazár <mark.sagikazar@gmail.com> + */ +class EmulatedHttpAsyncClient implements HttpClient, HttpAsyncClient +{ + use HttpAsyncClientEmulator; + use HttpClientDecorator; + + /** + * @param HttpClient $httpClient + */ + public function __construct(HttpClient $httpClient) + { + $this->httpClient = $httpClient; + } +} diff --git a/vendor/php-http/client-common/src/EmulatedHttpClient.php b/vendor/php-http/client-common/src/EmulatedHttpClient.php new file mode 100644 index 0000000000000000000000000000000000000000..01046c83e4c29a0578e6132da47ce378e8e71698 --- /dev/null +++ b/vendor/php-http/client-common/src/EmulatedHttpClient.php @@ -0,0 +1,27 @@ +<?php + +namespace Http\Client\Common; + +use Http\Client\HttpAsyncClient; +use Http\Client\HttpClient; + +/** + * Emulates an HTTP client. + * + * This should be replaced by an anonymous class in PHP 7. + * + * @author Márk Sági-Kazár <mark.sagikazar@gmail.com> + */ +class EmulatedHttpClient implements HttpClient, HttpAsyncClient +{ + use HttpAsyncClientDecorator; + use HttpClientEmulator; + + /** + * @param HttpAsyncClient $httpAsyncClient + */ + public function __construct(HttpAsyncClient $httpAsyncClient) + { + $this->httpAsyncClient = $httpAsyncClient; + } +} diff --git a/vendor/php-http/client-common/src/Exception/BatchException.php b/vendor/php-http/client-common/src/Exception/BatchException.php new file mode 100644 index 0000000000000000000000000000000000000000..66a92719e4ae05be21567ce08d5ecb84c716e808 --- /dev/null +++ b/vendor/php-http/client-common/src/Exception/BatchException.php @@ -0,0 +1,39 @@ +<?php + +namespace Http\Client\Common\Exception; + +use Http\Client\Exception\TransferException; +use Http\Client\Common\BatchResult; + +/** + * This exception is thrown when HttpClient::sendRequests led to at least one failure. + * + * It gives access to a BatchResult with the request-exception and request-response pairs. + * + * @author Márk Sági-Kazár <mark.sagikazar@gmail.com> + */ +final class BatchException extends TransferException +{ + /** + * @var BatchResult + */ + private $result; + + /** + * @param BatchResult $result + */ + public function __construct(BatchResult $result) + { + $this->result = $result; + } + + /** + * Returns the BatchResult that contains all responses and exceptions. + * + * @return BatchResult + */ + public function getResult() + { + return $this->result; + } +} diff --git a/vendor/php-http/client-common/src/Exception/CircularRedirectionException.php b/vendor/php-http/client-common/src/Exception/CircularRedirectionException.php new file mode 100644 index 0000000000000000000000000000000000000000..73ec521e17348e898ff895a172947e68bce93fce --- /dev/null +++ b/vendor/php-http/client-common/src/Exception/CircularRedirectionException.php @@ -0,0 +1,14 @@ +<?php + +namespace Http\Client\Common\Exception; + +use Http\Client\Exception\HttpException; + +/** + * Thrown when circular redirection is detected. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +class CircularRedirectionException extends HttpException +{ +} diff --git a/vendor/php-http/client-common/src/Exception/ClientErrorException.php b/vendor/php-http/client-common/src/Exception/ClientErrorException.php new file mode 100644 index 0000000000000000000000000000000000000000..b1f6cc855eba0e100f9701f6d7d66269984661e2 --- /dev/null +++ b/vendor/php-http/client-common/src/Exception/ClientErrorException.php @@ -0,0 +1,14 @@ +<?php + +namespace Http\Client\Common\Exception; + +use Http\Client\Exception\HttpException; + +/** + * Thrown when there is a client error (4xx). + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +class ClientErrorException extends HttpException +{ +} diff --git a/vendor/php-http/client-common/src/Exception/HttpClientNotFoundException.php b/vendor/php-http/client-common/src/Exception/HttpClientNotFoundException.php new file mode 100644 index 0000000000000000000000000000000000000000..5d33f9838360395298b9e8ca3ecfbc155f6b9b3f --- /dev/null +++ b/vendor/php-http/client-common/src/Exception/HttpClientNotFoundException.php @@ -0,0 +1,14 @@ +<?php + +namespace Http\Client\Common\Exception; + +use Http\Client\Exception\TransferException; + +/** + * Thrown when a http client cannot be chosen in a pool. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +class HttpClientNotFoundException extends TransferException +{ +} diff --git a/vendor/php-http/client-common/src/Exception/LoopException.php b/vendor/php-http/client-common/src/Exception/LoopException.php new file mode 100644 index 0000000000000000000000000000000000000000..e834124df607bbe10f381cb432598e668771ca7e --- /dev/null +++ b/vendor/php-http/client-common/src/Exception/LoopException.php @@ -0,0 +1,14 @@ +<?php + +namespace Http\Client\Common\Exception; + +use Http\Client\Exception\RequestException; + +/** + * Thrown when the Plugin Client detects an endless loop. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +class LoopException extends RequestException +{ +} diff --git a/vendor/php-http/client-common/src/Exception/MultipleRedirectionException.php b/vendor/php-http/client-common/src/Exception/MultipleRedirectionException.php new file mode 100644 index 0000000000000000000000000000000000000000..ae514cd738c64fa063284a5823e31e06124bdc45 --- /dev/null +++ b/vendor/php-http/client-common/src/Exception/MultipleRedirectionException.php @@ -0,0 +1,14 @@ +<?php + +namespace Http\Client\Common\Exception; + +use Http\Client\Exception\HttpException; + +/** + * Redirect location cannot be chosen. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +class MultipleRedirectionException extends HttpException +{ +} diff --git a/vendor/php-http/client-common/src/Exception/ServerErrorException.php b/vendor/php-http/client-common/src/Exception/ServerErrorException.php new file mode 100644 index 0000000000000000000000000000000000000000..665d72418b0b71403da4f8e8e6ce48c37bf38022 --- /dev/null +++ b/vendor/php-http/client-common/src/Exception/ServerErrorException.php @@ -0,0 +1,14 @@ +<?php + +namespace Http\Client\Common\Exception; + +use Http\Client\Exception\HttpException; + +/** + * Thrown when there is a server error (5xx). + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +class ServerErrorException extends HttpException +{ +} diff --git a/vendor/php-http/client-common/src/FlexibleHttpClient.php b/vendor/php-http/client-common/src/FlexibleHttpClient.php new file mode 100644 index 0000000000000000000000000000000000000000..58f88132d26f185881bf3bbf6e0b1f45b19842e7 --- /dev/null +++ b/vendor/php-http/client-common/src/FlexibleHttpClient.php @@ -0,0 +1,39 @@ +<?php + +namespace Http\Client\Common; + +use Http\Client\HttpAsyncClient; +use Http\Client\HttpClient; + +/** + * A flexible http client, which implements both interface and will emulate + * one contract, the other, or none at all depending on the injected client contract. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +final class FlexibleHttpClient implements HttpClient, HttpAsyncClient +{ + use HttpClientDecorator; + use HttpAsyncClientDecorator; + + /** + * @param HttpClient|HttpAsyncClient $client + */ + public function __construct($client) + { + if (!($client instanceof HttpClient) && !($client instanceof HttpAsyncClient)) { + throw new \LogicException('Client must be an instance of Http\\Client\\HttpClient or Http\\Client\\HttpAsyncClient'); + } + + $this->httpClient = $client; + $this->httpAsyncClient = $client; + + if (!($this->httpClient instanceof HttpClient)) { + $this->httpClient = new EmulatedHttpClient($this->httpClient); + } + + if (!($this->httpAsyncClient instanceof HttpAsyncClient)) { + $this->httpAsyncClient = new EmulatedHttpAsyncClient($this->httpAsyncClient); + } + } +} diff --git a/vendor/php-http/client-common/src/HttpAsyncClientDecorator.php b/vendor/php-http/client-common/src/HttpAsyncClientDecorator.php new file mode 100644 index 0000000000000000000000000000000000000000..6eb576cdb154bb59098cece31e8e0508aad5bdc6 --- /dev/null +++ b/vendor/php-http/client-common/src/HttpAsyncClientDecorator.php @@ -0,0 +1,29 @@ +<?php + +namespace Http\Client\Common; + +use Http\Client\HttpAsyncClient; +use Psr\Http\Message\RequestInterface; + +/** + * Decorates an HTTP Async Client. + * + * @author Márk Sági-Kazár <mark.sagikazar@gmail.com> + */ +trait HttpAsyncClientDecorator +{ + /** + * @var HttpAsyncClient + */ + protected $httpAsyncClient; + + /** + * {@inheritdoc} + * + * @see HttpAsyncClient::sendAsyncRequest + */ + public function sendAsyncRequest(RequestInterface $request) + { + return $this->httpAsyncClient->sendAsyncRequest($request); + } +} diff --git a/vendor/php-http/client-common/src/HttpAsyncClientEmulator.php b/vendor/php-http/client-common/src/HttpAsyncClientEmulator.php new file mode 100644 index 0000000000000000000000000000000000000000..c0ba354f87c401d2e70c13cefcceb00e153d018f --- /dev/null +++ b/vendor/php-http/client-common/src/HttpAsyncClientEmulator.php @@ -0,0 +1,36 @@ +<?php + +namespace Http\Client\Common; + +use Http\Client\Exception; +use Http\Client\Promise; +use Psr\Http\Message\RequestInterface; + +/** + * Emulates an HTTP Async Client in an HTTP Client. + * + * @author Márk Sági-Kazár <mark.sagikazar@gmail.com> + */ +trait HttpAsyncClientEmulator +{ + /** + * {@inheritdoc} + * + * @see HttpClient::sendRequest + */ + abstract public function sendRequest(RequestInterface $request); + + /** + * {@inheritdoc} + * + * @see HttpAsyncClient::sendAsyncRequest + */ + public function sendAsyncRequest(RequestInterface $request) + { + try { + return new Promise\HttpFulfilledPromise($this->sendRequest($request)); + } catch (Exception $e) { + return new Promise\HttpRejectedPromise($e); + } + } +} diff --git a/vendor/php-http/client-common/src/HttpClientDecorator.php b/vendor/php-http/client-common/src/HttpClientDecorator.php new file mode 100644 index 0000000000000000000000000000000000000000..a33d5efd79eb717d8c55f237c48068672d715fde --- /dev/null +++ b/vendor/php-http/client-common/src/HttpClientDecorator.php @@ -0,0 +1,29 @@ +<?php + +namespace Http\Client\Common; + +use Http\Client\HttpClient; +use Psr\Http\Message\RequestInterface; + +/** + * Decorates an HTTP Client. + * + * @author Márk Sági-Kazár <mark.sagikazar@gmail.com> + */ +trait HttpClientDecorator +{ + /** + * @var HttpClient + */ + protected $httpClient; + + /** + * {@inheritdoc} + * + * @see HttpClient::sendRequest + */ + public function sendRequest(RequestInterface $request) + { + return $this->httpClient->sendRequest($request); + } +} diff --git a/vendor/php-http/client-common/src/HttpClientEmulator.php b/vendor/php-http/client-common/src/HttpClientEmulator.php new file mode 100644 index 0000000000000000000000000000000000000000..dbec1aba330324dde3cb758ad79cb8f6cedb091f --- /dev/null +++ b/vendor/php-http/client-common/src/HttpClientEmulator.php @@ -0,0 +1,32 @@ +<?php + +namespace Http\Client\Common; + +use Psr\Http\Message\RequestInterface; + +/** + * Emulates an HTTP Client in an HTTP Async Client. + * + * @author Márk Sági-Kazár <mark.sagikazar@gmail.com> + */ +trait HttpClientEmulator +{ + /** + * {@inheritdoc} + * + * @see HttpClient::sendRequest + */ + public function sendRequest(RequestInterface $request) + { + $promise = $this->sendAsyncRequest($request); + + return $promise->wait(); + } + + /** + * {@inheritdoc} + * + * @see HttpAsyncClient::sendAsyncRequest + */ + abstract public function sendAsyncRequest(RequestInterface $request); +} diff --git a/vendor/php-http/client-common/src/HttpClientPool.php b/vendor/php-http/client-common/src/HttpClientPool.php new file mode 100644 index 0000000000000000000000000000000000000000..7ac292ca138fe31b4830268607e451bc6adfd5a4 --- /dev/null +++ b/vendor/php-http/client-common/src/HttpClientPool.php @@ -0,0 +1,59 @@ +<?php + +namespace Http\Client\Common; + +use Http\Client\Common\Exception\HttpClientNotFoundException; +use Http\Client\HttpAsyncClient; +use Http\Client\HttpClient; +use Psr\Http\Message\RequestInterface; + +/** + * A http client pool allows to send requests on a pool of different http client using a specific strategy (least used, + * round robin, ...). + */ +abstract class HttpClientPool implements HttpAsyncClient, HttpClient +{ + /** + * @var HttpClientPoolItem[] + */ + protected $clientPool = []; + + /** + * Add a client to the pool. + * + * @param HttpClient|HttpAsyncClient|HttpClientPoolItem $client + */ + public function addHttpClient($client) + { + if (!$client instanceof HttpClientPoolItem) { + $client = new HttpClientPoolItem($client); + } + + $this->clientPool[] = $client; + } + + /** + * Return an http client given a specific strategy. + * + * @throws HttpClientNotFoundException When no http client has been found into the pool + * + * @return HttpClientPoolItem Return a http client that can do both sync or async + */ + abstract protected function chooseHttpClient(); + + /** + * {@inheritdoc} + */ + public function sendAsyncRequest(RequestInterface $request) + { + return $this->chooseHttpClient()->sendAsyncRequest($request); + } + + /** + * {@inheritdoc} + */ + public function sendRequest(RequestInterface $request) + { + return $this->chooseHttpClient()->sendRequest($request); + } +} diff --git a/vendor/php-http/client-common/src/HttpClientPool/LeastUsedClientPool.php b/vendor/php-http/client-common/src/HttpClientPool/LeastUsedClientPool.php new file mode 100644 index 0000000000000000000000000000000000000000..6299cceb60fafb9f70e89ea0323f2ba0d38f7647 --- /dev/null +++ b/vendor/php-http/client-common/src/HttpClientPool/LeastUsedClientPool.php @@ -0,0 +1,45 @@ +<?php + +namespace Http\Client\Common\HttpClientPool; + +use Http\Client\Common\Exception\HttpClientNotFoundException; +use Http\Client\Common\HttpClientPool; +use Http\Client\Common\HttpClientPoolItem; + +/** + * LeastUsedClientPool will choose the client with the less current request in the pool. + * + * This strategy is only useful when doing async request + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +final class LeastUsedClientPool extends HttpClientPool +{ + /** + * {@inheritdoc} + */ + protected function chooseHttpClient() + { + $clientPool = array_filter($this->clientPool, function (HttpClientPoolItem $clientPoolItem) { + return !$clientPoolItem->isDisabled(); + }); + + if (0 === count($clientPool)) { + throw new HttpClientNotFoundException('Cannot choose a http client as there is no one present in the pool'); + } + + usort($clientPool, function (HttpClientPoolItem $clientA, HttpClientPoolItem $clientB) { + if ($clientA->getSendingRequestCount() === $clientB->getSendingRequestCount()) { + return 0; + } + + if ($clientA->getSendingRequestCount() < $clientB->getSendingRequestCount()) { + return -1; + } + + return 1; + }); + + return reset($clientPool); + } +} diff --git a/vendor/php-http/client-common/src/HttpClientPool/RandomClientPool.php b/vendor/php-http/client-common/src/HttpClientPool/RandomClientPool.php new file mode 100644 index 0000000000000000000000000000000000000000..3255f865df369dfb2a6d388d28a3705390048274 --- /dev/null +++ b/vendor/php-http/client-common/src/HttpClientPool/RandomClientPool.php @@ -0,0 +1,31 @@ +<?php + +namespace Http\Client\Common\HttpClientPool; + +use Http\Client\Common\Exception\HttpClientNotFoundException; +use Http\Client\Common\HttpClientPool; +use Http\Client\Common\HttpClientPoolItem; + +/** + * RoundRobinClientPool will choose the next client in the pool. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +final class RandomClientPool extends HttpClientPool +{ + /** + * {@inheritdoc} + */ + protected function chooseHttpClient() + { + $clientPool = array_filter($this->clientPool, function (HttpClientPoolItem $clientPoolItem) { + return !$clientPoolItem->isDisabled(); + }); + + if (0 === count($clientPool)) { + throw new HttpClientNotFoundException('Cannot choose a http client as there is no one present in the pool'); + } + + return $clientPool[array_rand($clientPool)]; + } +} diff --git a/vendor/php-http/client-common/src/HttpClientPool/RoundRobinClientPool.php b/vendor/php-http/client-common/src/HttpClientPool/RoundRobinClientPool.php new file mode 100644 index 0000000000000000000000000000000000000000..8d8e40a013b036621ae0a9ef6729e7812bc04f3f --- /dev/null +++ b/vendor/php-http/client-common/src/HttpClientPool/RoundRobinClientPool.php @@ -0,0 +1,41 @@ +<?php + +namespace Http\Client\Common\HttpClientPool; + +use Http\Client\Common\Exception\HttpClientNotFoundException; +use Http\Client\Common\HttpClientPool; + +/** + * RoundRobinClientPool will choose the next client in the pool. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +final class RoundRobinClientPool extends HttpClientPool +{ + /** + * {@inheritdoc} + */ + protected function chooseHttpClient() + { + $last = current($this->clientPool); + + do { + $client = next($this->clientPool); + + if (false === $client) { + $client = reset($this->clientPool); + + if (false === $client) { + throw new HttpClientNotFoundException('Cannot choose a http client as there is no one present in the pool'); + } + } + + // Case when there is only one and the last one has been disabled + if ($last === $client && $client->isDisabled()) { + throw new HttpClientNotFoundException('Cannot choose a http client as there is no one enabled in the pool'); + } + } while ($client->isDisabled()); + + return $client; + } +} diff --git a/vendor/php-http/client-common/src/HttpClientPoolItem.php b/vendor/php-http/client-common/src/HttpClientPoolItem.php new file mode 100644 index 0000000000000000000000000000000000000000..09cd6ddf1c96f4bea9817b25c2d1544497dcc617 --- /dev/null +++ b/vendor/php-http/client-common/src/HttpClientPoolItem.php @@ -0,0 +1,178 @@ +<?php + +namespace Http\Client\Common; + +use Http\Client\HttpAsyncClient; +use Http\Client\HttpClient; +use Psr\Http\Message\RequestInterface; +use Http\Client\Exception; + +/** + * A HttpClientPoolItem represent a HttpClient inside a Pool. + * + * It is disabled when a request failed and can be reenable after a certain number of seconds + * It also keep tracks of the current number of request the client is currently sending (only usable for async method) + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +class HttpClientPoolItem implements HttpClient, HttpAsyncClient +{ + /** + * @var int Number of request this client is currently sending + */ + private $sendingRequestCount = 0; + + /** + * @var \DateTime|null Time when this client has been disabled or null if enable + */ + private $disabledAt; + + /** + * @var int|null Number of seconds after this client is reenable, by default null: never reenable this client + */ + private $reenableAfter; + + /** + * @var FlexibleHttpClient A http client responding to async and sync request + */ + private $client; + + /** + * @param HttpClient|HttpAsyncClient $client + * @param null|int $reenableAfter Number of seconds after this client is reenable + */ + public function __construct($client, $reenableAfter = null) + { + $this->client = new FlexibleHttpClient($client); + $this->reenableAfter = $reenableAfter; + } + + /** + * {@inheritdoc} + */ + public function sendRequest(RequestInterface $request) + { + if ($this->isDisabled()) { + throw new Exception\RequestException('Cannot send the request as this client has been disabled', $request); + } + + try { + $this->incrementRequestCount(); + $response = $this->client->sendRequest($request); + $this->decrementRequestCount(); + } catch (Exception $e) { + $this->disable(); + $this->decrementRequestCount(); + + throw $e; + } + + return $response; + } + + /** + * {@inheritdoc} + */ + public function sendAsyncRequest(RequestInterface $request) + { + if ($this->isDisabled()) { + throw new Exception\RequestException('Cannot send the request as this client has been disabled', $request); + } + + $this->incrementRequestCount(); + + return $this->client->sendAsyncRequest($request)->then(function ($response) { + $this->decrementRequestCount(); + + return $response; + }, function ($exception) { + $this->disable(); + $this->decrementRequestCount(); + + throw $exception; + }); + } + + /** + * Whether this client is disabled or not. + * + * Will also reactivate this client if possible + * + * @internal + * + * @return bool + */ + public function isDisabled() + { + $disabledAt = $this->getDisabledAt(); + + if (null !== $this->reenableAfter && null !== $disabledAt) { + // Reenable after a certain time + $now = new \DateTime(); + + if (($now->getTimestamp() - $disabledAt->getTimestamp()) >= $this->reenableAfter) { + $this->enable(); + + return false; + } + + return true; + } + + return null !== $disabledAt; + } + + /** + * Get current number of request that is send by the underlying http client. + * + * @internal + * + * @return int + */ + public function getSendingRequestCount() + { + return $this->sendingRequestCount; + } + + /** + * Return when this client has been disabled or null if it's enabled. + * + * @return \DateTime|null + */ + private function getDisabledAt() + { + return $this->disabledAt; + } + + /** + * Increment the request count. + */ + private function incrementRequestCount() + { + ++$this->sendingRequestCount; + } + + /** + * Decrement the request count. + */ + private function decrementRequestCount() + { + --$this->sendingRequestCount; + } + + /** + * Enable the current client. + */ + private function enable() + { + $this->disabledAt = null; + } + + /** + * Disable the current client. + */ + private function disable() + { + $this->disabledAt = new \DateTime('now'); + } +} diff --git a/vendor/php-http/client-common/src/HttpClientRouter.php b/vendor/php-http/client-common/src/HttpClientRouter.php new file mode 100644 index 0000000000000000000000000000000000000000..9f721336a172a5ab3f75fe70899a9081503f4618 --- /dev/null +++ b/vendor/php-http/client-common/src/HttpClientRouter.php @@ -0,0 +1,74 @@ +<?php + +namespace Http\Client\Common; + +use Http\Client\Exception\RequestException; +use Http\Client\HttpAsyncClient; +use Http\Client\HttpClient; +use Http\Message\RequestMatcher; +use Psr\Http\Message\RequestInterface; + +/** + * Route a request to a specific client in the stack based using a RequestMatcher. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +final class HttpClientRouter implements HttpClient, HttpAsyncClient +{ + /** + * @var array + */ + private $clients = []; + + /** + * {@inheritdoc} + */ + public function sendRequest(RequestInterface $request) + { + $client = $this->chooseHttpClient($request); + + return $client->sendRequest($request); + } + + /** + * {@inheritdoc} + */ + public function sendAsyncRequest(RequestInterface $request) + { + $client = $this->chooseHttpClient($request); + + return $client->sendAsyncRequest($request); + } + + /** + * Add a client to the router. + * + * @param HttpClient|HttpAsyncClient $client + * @param RequestMatcher $requestMatcher + */ + public function addClient($client, RequestMatcher $requestMatcher) + { + $this->clients[] = [ + 'matcher' => $requestMatcher, + 'client' => new FlexibleHttpClient($client), + ]; + } + + /** + * Choose an HTTP client given a specific request. + * + * @param RequestInterface $request + * + * @return HttpClient|HttpAsyncClient + */ + protected function chooseHttpClient(RequestInterface $request) + { + foreach ($this->clients as $client) { + if ($client['matcher']->matches($request)) { + return $client['client']; + } + } + + throw new RequestException('No client found for the specified request', $request); + } +} diff --git a/vendor/php-http/client-common/src/HttpMethodsClient.php b/vendor/php-http/client-common/src/HttpMethodsClient.php new file mode 100644 index 0000000000000000000000000000000000000000..58804fc243f89c9a3a78d16fa0d3200c66c020d6 --- /dev/null +++ b/vendor/php-http/client-common/src/HttpMethodsClient.php @@ -0,0 +1,205 @@ +<?php + +namespace Http\Client\Common; + +use Http\Client\Exception; +use Http\Client\HttpClient; +use Http\Message\RequestFactory; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\StreamInterface; +use Psr\Http\Message\UriInterface; + +/** + * Convenience HTTP client that integrates the MessageFactory in order to send + * requests in the following form:. + * + * $client + * ->get('/foo') + * ->post('/bar') + * ; + * + * The client also exposes the sendRequest methods of the wrapped HttpClient. + * + * @author Márk Sági-Kazár <mark.sagikazar@gmail.com> + * @author David Buchmann <mail@davidbu.ch> + */ +class HttpMethodsClient implements HttpClient +{ + /** + * @var HttpClient + */ + private $httpClient; + + /** + * @var RequestFactory + */ + private $requestFactory; + + /** + * @param HttpClient $httpClient The client to send requests with + * @param RequestFactory $requestFactory The message factory to create requests + */ + public function __construct(HttpClient $httpClient, RequestFactory $requestFactory) + { + $this->httpClient = $httpClient; + $this->requestFactory = $requestFactory; + } + + /** + * Sends a GET request. + * + * @param string|UriInterface $uri + * @param array $headers + * + * @throws Exception + * + * @return ResponseInterface + */ + public function get($uri, array $headers = []) + { + return $this->send('GET', $uri, $headers, null); + } + + /** + * Sends an HEAD request. + * + * @param string|UriInterface $uri + * @param array $headers + * + * @throws Exception + * + * @return ResponseInterface + */ + public function head($uri, array $headers = []) + { + return $this->send('HEAD', $uri, $headers, null); + } + + /** + * Sends a TRACE request. + * + * @param string|UriInterface $uri + * @param array $headers + * + * @throws Exception + * + * @return ResponseInterface + */ + public function trace($uri, array $headers = []) + { + return $this->send('TRACE', $uri, $headers, null); + } + + /** + * Sends a POST request. + * + * @param string|UriInterface $uri + * @param array $headers + * @param string|StreamInterface|null $body + * + * @throws Exception + * + * @return ResponseInterface + */ + public function post($uri, array $headers = [], $body = null) + { + return $this->send('POST', $uri, $headers, $body); + } + + /** + * Sends a PUT request. + * + * @param string|UriInterface $uri + * @param array $headers + * @param string|StreamInterface|null $body + * + * @throws Exception + * + * @return ResponseInterface + */ + public function put($uri, array $headers = [], $body = null) + { + return $this->send('PUT', $uri, $headers, $body); + } + + /** + * Sends a PATCH request. + * + * @param string|UriInterface $uri + * @param array $headers + * @param string|StreamInterface|null $body + * + * @throws Exception + * + * @return ResponseInterface + */ + public function patch($uri, array $headers = [], $body = null) + { + return $this->send('PATCH', $uri, $headers, $body); + } + + /** + * Sends a DELETE request. + * + * @param string|UriInterface $uri + * @param array $headers + * @param string|StreamInterface|null $body + * + * @throws Exception + * + * @return ResponseInterface + */ + public function delete($uri, array $headers = [], $body = null) + { + return $this->send('DELETE', $uri, $headers, $body); + } + + /** + * Sends an OPTIONS request. + * + * @param string|UriInterface $uri + * @param array $headers + * @param string|StreamInterface|null $body + * + * @throws Exception + * + * @return ResponseInterface + */ + public function options($uri, array $headers = [], $body = null) + { + return $this->send('OPTIONS', $uri, $headers, $body); + } + + /** + * Sends a request with any HTTP method. + * + * @param string $method HTTP method to use + * @param string|UriInterface $uri + * @param array $headers + * @param string|StreamInterface|null $body + * + * @throws Exception + * + * @return ResponseInterface + */ + public function send($method, $uri, array $headers = [], $body = null) + { + return $this->sendRequest($this->requestFactory->createRequest( + $method, + $uri, + $headers, + $body + )); + } + + /** + * Forward to the underlying HttpClient. + * + * {@inheritdoc} + */ + public function sendRequest(RequestInterface $request) + { + return $this->httpClient->sendRequest($request); + } +} diff --git a/vendor/php-http/client-common/src/Plugin.php b/vendor/php-http/client-common/src/Plugin.php new file mode 100644 index 0000000000000000000000000000000000000000..89a2a622d46c69f9a7ffb47042c4667e46ef556f --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin.php @@ -0,0 +1,32 @@ +<?php + +namespace Http\Client\Common; + +use Http\Promise\Promise; +use Psr\Http\Message\RequestInterface; + +/** + * A plugin is a middleware to transform the request and/or the response. + * + * The plugin can: + * - break the chain and return a response + * - dispatch the request to the next middleware + * - restart the request + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +interface Plugin +{ + /** + * Handle the request and return the response coming from the next callable. + * + * @see http://docs.php-http.org/en/latest/plugins/build-your-own.html + * + * @param RequestInterface $request + * @param callable $next Next middleware in the chain, the request is passed as the first argument + * @param callable $first First middleware in the chain, used to to restart a request + * + * @return Promise Resolves a PSR-7 Response or fails with an Http\Client\Exception (The same as HttpAsyncClient). + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first); +} diff --git a/vendor/php-http/client-common/src/Plugin/AddHostPlugin.php b/vendor/php-http/client-common/src/Plugin/AddHostPlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..29ab8ae84097e9c6ad748d0acba3db2f3911a8b4 --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/AddHostPlugin.php @@ -0,0 +1,77 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Plugin; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\UriInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; + +/** + * Add schema, host and port to a request. Can be set to overwrite the schema and host if desired. + * + * @author Tobias Nyholm <tobias.nyholm@gmail.com> + */ +final class AddHostPlugin implements Plugin +{ + /** + * @var UriInterface + */ + private $host; + + /** + * @var bool + */ + private $replace; + + /** + * @param UriInterface $host + * @param array $config { + * + * @var bool $replace True will replace all hosts, false will only add host when none is specified. + * } + */ + public function __construct(UriInterface $host, array $config = []) + { + if ('' === $host->getHost()) { + throw new \LogicException('Host can not be empty'); + } + + $this->host = $host; + + $resolver = new OptionsResolver(); + $this->configureOptions($resolver); + $options = $resolver->resolve($config); + + $this->replace = $options['replace']; + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + if ($this->replace || '' === $request->getUri()->getHost()) { + $uri = $request->getUri() + ->withHost($this->host->getHost()) + ->withScheme($this->host->getScheme()) + ->withPort($this->host->getPort()) + ; + + $request = $request->withUri($uri); + } + + return $next($request); + } + + /** + * @param OptionsResolver $resolver + */ + private function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'replace' => false, + ]); + $resolver->setAllowedTypes('replace', 'bool'); + } +} diff --git a/vendor/php-http/client-common/src/Plugin/AddPathPlugin.php b/vendor/php-http/client-common/src/Plugin/AddPathPlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..e24d61a4e42a89c60e4ed07c54c93e31b949533d --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/AddPathPlugin.php @@ -0,0 +1,48 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Plugin; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\UriInterface; + +/** + * Prepend a base path to the request URI. Useful for base API URLs like http://domain.com/api. + * + * @author Sullivan Senechal <soullivaneuh@gmail.com> + */ +final class AddPathPlugin implements Plugin +{ + /** + * @var UriInterface + */ + private $uri; + + /** + * @param UriInterface $uri + */ + public function __construct(UriInterface $uri) + { + if ('' === $uri->getPath()) { + throw new \LogicException('URI path cannot be empty'); + } + + if ('/' === substr($uri->getPath(), -1)) { + throw new \LogicException('URI path cannot end with a slash.'); + } + + $this->uri = $uri; + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + $request = $request->withUri($request->getUri() + ->withPath($this->uri->getPath().$request->getUri()->getPath()) + ); + + return $next($request); + } +} diff --git a/vendor/php-http/client-common/src/Plugin/AuthenticationPlugin.php b/vendor/php-http/client-common/src/Plugin/AuthenticationPlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..194712fcde024fa81991162084fa041c6fae2827 --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/AuthenticationPlugin.php @@ -0,0 +1,38 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Plugin; +use Http\Message\Authentication; +use Psr\Http\Message\RequestInterface; + +/** + * Send an authenticated request. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +final class AuthenticationPlugin implements Plugin +{ + /** + * @var Authentication An authentication system + */ + private $authentication; + + /** + * @param Authentication $authentication + */ + public function __construct(Authentication $authentication) + { + $this->authentication = $authentication; + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + $request = $this->authentication->authenticate($request); + + return $next($request); + } +} diff --git a/vendor/php-http/client-common/src/Plugin/BaseUriPlugin.php b/vendor/php-http/client-common/src/Plugin/BaseUriPlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..2c2a7752cf466b2a8061dd1093970c59687317b3 --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/BaseUriPlugin.php @@ -0,0 +1,54 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Plugin; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\UriInterface; + +/** + * Combines the AddHostPlugin and AddPathPlugin. + * + * @author Sullivan Senechal <soullivaneuh@gmail.com> + */ +final class BaseUriPlugin implements Plugin +{ + /** + * @var AddHostPlugin + */ + private $addHostPlugin; + + /** + * @var AddPathPlugin|null + */ + private $addPathPlugin = null; + + /** + * @param UriInterface $uri Has to contain a host name and cans have a path. + * @param array $hostConfig Config for AddHostPlugin. @see AddHostPlugin::configureOptions + */ + public function __construct(UriInterface $uri, array $hostConfig = []) + { + $this->addHostPlugin = new AddHostPlugin($uri, $hostConfig); + + if (rtrim($uri->getPath(), '/')) { + $this->addPathPlugin = new AddPathPlugin($uri); + } + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + $addHostNext = function (RequestInterface $request) use ($next, $first) { + return $this->addHostPlugin->handleRequest($request, $next, $first); + }; + + if ($this->addPathPlugin) { + return $this->addPathPlugin->handleRequest($request, $addHostNext, $first); + } + + return $addHostNext($request); + } +} diff --git a/vendor/php-http/client-common/src/Plugin/ContentLengthPlugin.php b/vendor/php-http/client-common/src/Plugin/ContentLengthPlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..0f7aafaeda3197f4571dabd6996b22e2f4e26eec --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/ContentLengthPlugin.php @@ -0,0 +1,36 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Plugin; +use Http\Message\Encoding\ChunkStream; +use Psr\Http\Message\RequestInterface; + +/** + * Allow to set the correct content length header on the request or to transfer it as a chunk if not possible. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +final class ContentLengthPlugin implements Plugin +{ + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + if (!$request->hasHeader('Content-Length')) { + $stream = $request->getBody(); + + // Cannot determine the size so we use a chunk stream + if (null === $stream->getSize()) { + $stream = new ChunkStream($stream); + $request = $request->withBody($stream); + $request = $request->withAddedHeader('Transfer-Encoding', 'chunked'); + } else { + $request = $request->withHeader('Content-Length', (string) $stream->getSize()); + } + } + + return $next($request); + } +} diff --git a/vendor/php-http/client-common/src/Plugin/ContentTypePlugin.php b/vendor/php-http/client-common/src/Plugin/ContentTypePlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..8ef1d62b34b0dd36cbf21769fda7b4d8de37088b --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/ContentTypePlugin.php @@ -0,0 +1,123 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Plugin; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\StreamInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; + +/** + * Allow to set the correct content type header on the request automatically only if it is not set. + * + * @author Karim Pinchon <karim.pinchon@gmail.com> + */ +final class ContentTypePlugin implements Plugin +{ + /** + * Allow to disable the content type detection when stream is too large (as it can consume a lot of resource). + * + * @var bool + * + * true skip the content type detection + * false detect the content type (default value) + */ + protected $skipDetection; + + /** + * Determine the size stream limit for which the detection as to be skipped (default to 16Mb). + * + * @var int + */ + protected $sizeLimit; + + /** + * @param array $config { + * + * @var bool $skip_detection True skip detection if stream size is bigger than $size_limit. + * @var int $size_limit size stream limit for which the detection as to be skipped. + * } + */ + public function __construct(array $config = []) + { + $resolver = new OptionsResolver(); + $resolver->setDefaults([ + 'skip_detection' => false, + 'size_limit' => 16000000, + ]); + $resolver->setAllowedTypes('skip_detection', 'bool'); + $resolver->setAllowedTypes('size_limit', 'int'); + + $options = $resolver->resolve($config); + + $this->skipDetection = $options['skip_detection']; + $this->sizeLimit = $options['size_limit']; + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + if (!$request->hasHeader('Content-Type')) { + $stream = $request->getBody(); + $streamSize = $stream->getSize(); + + if (!$stream->isSeekable()) { + return $next($request); + } + + if (0 === $streamSize) { + return $next($request); + } + + if ($this->skipDetection && (null === $streamSize || $streamSize >= $this->sizeLimit)) { + return $next($request); + } + + if ($this->isJson($stream)) { + $request = $request->withHeader('Content-Type', 'application/json'); + + return $next($request); + } + + if ($this->isXml($stream)) { + $request = $request->withHeader('Content-Type', 'application/xml'); + + return $next($request); + } + } + + return $next($request); + } + + /** + * @param $stream StreamInterface + * + * @return bool + */ + private function isJson($stream) + { + $stream->rewind(); + + json_decode($stream->getContents()); + + return JSON_ERROR_NONE === json_last_error(); + } + + /** + * @param $stream StreamInterface + * + * @return \SimpleXMLElement|false + */ + private function isXml($stream) + { + $stream->rewind(); + + $previousValue = libxml_use_internal_errors(true); + $isXml = simplexml_load_string($stream->getContents()); + libxml_use_internal_errors($previousValue); + + return $isXml; + } +} diff --git a/vendor/php-http/client-common/src/Plugin/CookiePlugin.php b/vendor/php-http/client-common/src/Plugin/CookiePlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..59ee90da19d21ea442596a95fa427c630bc41874 --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/CookiePlugin.php @@ -0,0 +1,180 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Plugin; +use Http\Client\Exception\TransferException; +use Http\Message\Cookie; +use Http\Message\CookieJar; +use Http\Message\CookieUtil; +use Http\Message\Exception\UnexpectedValueException; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; + +/** + * Handle request cookies. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +final class CookiePlugin implements Plugin +{ + /** + * Cookie storage. + * + * @var CookieJar + */ + private $cookieJar; + + /** + * @param CookieJar $cookieJar + */ + public function __construct(CookieJar $cookieJar) + { + $this->cookieJar = $cookieJar; + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + foreach ($this->cookieJar->getCookies() as $cookie) { + if ($cookie->isExpired()) { + continue; + } + + if (!$cookie->matchDomain($request->getUri()->getHost())) { + continue; + } + + if (!$cookie->matchPath($request->getUri()->getPath())) { + continue; + } + + if ($cookie->isSecure() && ('https' !== $request->getUri()->getScheme())) { + continue; + } + + $request = $request->withAddedHeader('Cookie', sprintf('%s=%s', $cookie->getName(), $cookie->getValue())); + } + + return $next($request)->then(function (ResponseInterface $response) use ($request) { + if ($response->hasHeader('Set-Cookie')) { + $setCookies = $response->getHeader('Set-Cookie'); + + foreach ($setCookies as $setCookie) { + $cookie = $this->createCookie($request, $setCookie); + + // Cookie invalid do not use it + if (null === $cookie) { + continue; + } + + // Restrict setting cookie from another domain + if (!preg_match("/\.{$cookie->getDomain()}$/", '.'.$request->getUri()->getHost())) { + continue; + } + + $this->cookieJar->addCookie($cookie); + } + } + + return $response; + }); + } + + /** + * Creates a cookie from a string. + * + * @param RequestInterface $request + * @param $setCookie + * + * @return Cookie|null + * + * @throws TransferException + */ + private function createCookie(RequestInterface $request, $setCookie) + { + $parts = array_map('trim', explode(';', $setCookie)); + + if (empty($parts) || !strpos($parts[0], '=')) { + return; + } + + list($name, $cookieValue) = $this->createValueKey(array_shift($parts)); + + $maxAge = null; + $expires = null; + $domain = $request->getUri()->getHost(); + $path = $request->getUri()->getPath(); + $secure = false; + $httpOnly = false; + + // Add the cookie pieces into the parsed data array + foreach ($parts as $part) { + list($key, $value) = $this->createValueKey($part); + + switch (strtolower($key)) { + case 'expires': + try { + $expires = CookieUtil::parseDate($value); + } catch (UnexpectedValueException $e) { + throw new TransferException( + sprintf( + 'Cookie header `%s` expires value `%s` could not be converted to date', + $name, + $value + ), + null, + $e + ); + } + + break; + + case 'max-age': + $maxAge = (int) $value; + + break; + + case 'domain': + $domain = $value; + + break; + + case 'path': + $path = $value; + + break; + + case 'secure': + $secure = true; + + break; + + case 'httponly': + $httpOnly = true; + + break; + } + } + + return new Cookie($name, $cookieValue, $maxAge, $domain, $path, $secure, $httpOnly, $expires); + } + + /** + * Separates key/value pair from cookie. + * + * @param $part + * + * @return array + */ + private function createValueKey($part) + { + $parts = explode('=', $part, 2); + $key = trim($parts[0]); + $value = isset($parts[1]) ? trim($parts[1]) : true; + + return [$key, $value]; + } +} diff --git a/vendor/php-http/client-common/src/Plugin/DecoderPlugin.php b/vendor/php-http/client-common/src/Plugin/DecoderPlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..b661b613ac72a6235f272bdcfb8a5660a95a24e0 --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/DecoderPlugin.php @@ -0,0 +1,140 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Plugin; +use Http\Message\Encoding; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\StreamInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; + +/** + * Allow to decode response body with a chunk, deflate, compress or gzip encoding. + * + * If zlib is not installed, only chunked encoding can be handled. + * + * If Content-Encoding is not disabled, the plugin will add an Accept-Encoding header for the encoding methods it supports. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +final class DecoderPlugin implements Plugin +{ + /** + * @var bool Whether this plugin decode stream with value in the Content-Encoding header (default to true). + * + * If set to false only the Transfer-Encoding header will be used + */ + private $useContentEncoding; + + /** + * @param array $config { + * + * @var bool $use_content_encoding Whether this plugin should look at the Content-Encoding header first or only at the Transfer-Encoding (defaults to true). + * } + */ + public function __construct(array $config = []) + { + $resolver = new OptionsResolver(); + $resolver->setDefaults([ + 'use_content_encoding' => true, + ]); + $resolver->setAllowedTypes('use_content_encoding', 'bool'); + $options = $resolver->resolve($config); + + $this->useContentEncoding = $options['use_content_encoding']; + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + $encodings = extension_loaded('zlib') ? ['gzip', 'deflate'] : ['identity']; + + if ($this->useContentEncoding) { + $request = $request->withHeader('Accept-Encoding', $encodings); + } + $encodings[] = 'chunked'; + $request = $request->withHeader('TE', $encodings); + + return $next($request)->then(function (ResponseInterface $response) { + return $this->decodeResponse($response); + }); + } + + /** + * Decode a response body given its Transfer-Encoding or Content-Encoding value. + * + * @param ResponseInterface $response Response to decode + * + * @return ResponseInterface New response decoded + */ + private function decodeResponse(ResponseInterface $response) + { + $response = $this->decodeOnEncodingHeader('Transfer-Encoding', $response); + + if ($this->useContentEncoding) { + $response = $this->decodeOnEncodingHeader('Content-Encoding', $response); + } + + return $response; + } + + /** + * Decode a response on a specific header (content encoding or transfer encoding mainly). + * + * @param string $headerName Name of the header + * @param ResponseInterface $response Response + * + * @return ResponseInterface A new instance of the response decoded + */ + private function decodeOnEncodingHeader($headerName, ResponseInterface $response) + { + if ($response->hasHeader($headerName)) { + $encodings = $response->getHeader($headerName); + $newEncodings = []; + + while ($encoding = array_pop($encodings)) { + $stream = $this->decorateStream($encoding, $response->getBody()); + + if (false === $stream) { + array_unshift($newEncodings, $encoding); + + continue; + } + + $response = $response->withBody($stream); + } + + $response = $response->withHeader($headerName, $newEncodings); + } + + return $response; + } + + /** + * Decorate a stream given an encoding. + * + * @param string $encoding + * @param StreamInterface $stream + * + * @return StreamInterface|false A new stream interface or false if encoding is not supported + */ + private function decorateStream($encoding, StreamInterface $stream) + { + if ('chunked' === strtolower($encoding)) { + return new Encoding\DechunkStream($stream); + } + + if ('deflate' === strtolower($encoding)) { + return new Encoding\DecompressStream($stream); + } + + if ('gzip' === strtolower($encoding)) { + return new Encoding\GzipDecodeStream($stream); + } + + return false; + } +} diff --git a/vendor/php-http/client-common/src/Plugin/ErrorPlugin.php b/vendor/php-http/client-common/src/Plugin/ErrorPlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..f09d3b161a8883947e2ba6458a46a20c676ba38f --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/ErrorPlugin.php @@ -0,0 +1,55 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Exception\ClientErrorException; +use Http\Client\Common\Exception\ServerErrorException; +use Http\Client\Common\Plugin; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; + +/** + * Throw exception when the response of a request is not acceptable. + * + * Status codes 400-499 lead to a ClientErrorException, status 500-599 to a ServerErrorException. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +final class ErrorPlugin implements Plugin +{ + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + $promise = $next($request); + + return $promise->then(function (ResponseInterface $response) use ($request) { + return $this->transformResponseToException($request, $response); + }); + } + + /** + * Transform response to an error if possible. + * + * @param RequestInterface $request Request of the call + * @param ResponseInterface $response Response of the call + * + * @throws ClientErrorException If response status code is a 4xx + * @throws ServerErrorException If response status code is a 5xx + * + * @return ResponseInterface If status code is not in 4xx or 5xx return response + */ + protected function transformResponseToException(RequestInterface $request, ResponseInterface $response) + { + if ($response->getStatusCode() >= 400 && $response->getStatusCode() < 500) { + throw new ClientErrorException($response->getReasonPhrase(), $request, $response); + } + + if ($response->getStatusCode() >= 500 && $response->getStatusCode() < 600) { + throw new ServerErrorException($response->getReasonPhrase(), $request, $response); + } + + return $response; + } +} diff --git a/vendor/php-http/client-common/src/Plugin/HeaderAppendPlugin.php b/vendor/php-http/client-common/src/Plugin/HeaderAppendPlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..26fd813458564a612d2730ec0735a9ca3930b362 --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/HeaderAppendPlugin.php @@ -0,0 +1,45 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Plugin; +use Psr\Http\Message\RequestInterface; + +/** + * Append headers to the request. + * + * If the header already exists the value will be appended to the current value. + * + * This only makes sense for headers that can have multiple values like 'Forwarded' + * + * @see https://en.wikipedia.org/wiki/List_of_HTTP_header_fields + * + * @author Soufiane Ghzal <sghzal@gmail.com> + */ +final class HeaderAppendPlugin implements Plugin +{ + /** + * @var array + */ + private $headers = []; + + /** + * @param array $headers Hashmap of header name to header value + */ + public function __construct(array $headers) + { + $this->headers = $headers; + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + foreach ($this->headers as $header => $headerValue) { + $request = $request->withAddedHeader($header, $headerValue); + } + + return $next($request); + } +} diff --git a/vendor/php-http/client-common/src/Plugin/HeaderDefaultsPlugin.php b/vendor/php-http/client-common/src/Plugin/HeaderDefaultsPlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..6dfc1115a06a099d641b90aa2eb1e9357f2d5d71 --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/HeaderDefaultsPlugin.php @@ -0,0 +1,43 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Plugin; +use Psr\Http\Message\RequestInterface; + +/** + * Set header to default value if it does not exist. + * + * If a given header already exists the value wont be replaced and the request wont be changed. + * + * @author Soufiane Ghzal <sghzal@gmail.com> + */ +final class HeaderDefaultsPlugin implements Plugin +{ + /** + * @var array + */ + private $headers = []; + + /** + * @param array $headers Hashmap of header name to header value + */ + public function __construct(array $headers) + { + $this->headers = $headers; + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + foreach ($this->headers as $header => $headerValue) { + if (!$request->hasHeader($header)) { + $request = $request->withHeader($header, $headerValue); + } + } + + return $next($request); + } +} diff --git a/vendor/php-http/client-common/src/Plugin/HeaderRemovePlugin.php b/vendor/php-http/client-common/src/Plugin/HeaderRemovePlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..fc9c19d1aadabf34c1287a9ed97b78f78ebbbc74 --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/HeaderRemovePlugin.php @@ -0,0 +1,41 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Plugin; +use Psr\Http\Message\RequestInterface; + +/** + * Removes headers from the request. + * + * @author Soufiane Ghzal <sghzal@gmail.com> + */ +final class HeaderRemovePlugin implements Plugin +{ + /** + * @var array + */ + private $headers = []; + + /** + * @param array $headers List of header names to remove from the request + */ + public function __construct(array $headers) + { + $this->headers = $headers; + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + foreach ($this->headers as $header) { + if ($request->hasHeader($header)) { + $request = $request->withoutHeader($header); + } + } + + return $next($request); + } +} diff --git a/vendor/php-http/client-common/src/Plugin/HeaderSetPlugin.php b/vendor/php-http/client-common/src/Plugin/HeaderSetPlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..75f11d40aaae9c7ded7edf960b1dcc99deae9bd8 --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/HeaderSetPlugin.php @@ -0,0 +1,41 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Plugin; +use Psr\Http\Message\RequestInterface; + +/** + * Set headers on the request. + * + * If the header does not exist it wil be set, if the header already exists it will be replaced. + * + * @author Soufiane Ghzal <sghzal@gmail.com> + */ +final class HeaderSetPlugin implements Plugin +{ + /** + * @var array + */ + private $headers = []; + + /** + * @param array $headers Hashmap of header name to header value + */ + public function __construct(array $headers) + { + $this->headers = $headers; + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + foreach ($this->headers as $header => $headerValue) { + $request = $request->withHeader($header, $headerValue); + } + + return $next($request); + } +} diff --git a/vendor/php-http/client-common/src/Plugin/HistoryPlugin.php b/vendor/php-http/client-common/src/Plugin/HistoryPlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..5abddbd84128d6a95617ed2410d3b6817736a884 --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/HistoryPlugin.php @@ -0,0 +1,49 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Plugin; +use Http\Client\Exception; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; + +/** + * Record HTTP calls. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +final class HistoryPlugin implements Plugin +{ + /** + * Journal use to store request / responses / exception. + * + * @var Journal + */ + private $journal; + + /** + * @param Journal $journal + */ + public function __construct(Journal $journal) + { + $this->journal = $journal; + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + $journal = $this->journal; + + return $next($request)->then(function (ResponseInterface $response) use ($request, $journal) { + $journal->addSuccess($request, $response); + + return $response; + }, function (Exception $exception) use ($request, $journal) { + $journal->addFailure($request, $exception); + + throw $exception; + }); + } +} diff --git a/vendor/php-http/client-common/src/Plugin/Journal.php b/vendor/php-http/client-common/src/Plugin/Journal.php new file mode 100644 index 0000000000000000000000000000000000000000..15f309569fb9842a58ed0c13feb27374f26de40f --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/Journal.php @@ -0,0 +1,31 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Exception; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; + +/** + * Records history of HTTP calls. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +interface Journal +{ + /** + * Record a successful call. + * + * @param RequestInterface $request Request use to make the call + * @param ResponseInterface $response Response returned by the call + */ + public function addSuccess(RequestInterface $request, ResponseInterface $response); + + /** + * Record a failed call. + * + * @param RequestInterface $request Request use to make the call + * @param Exception $exception Exception returned by the call + */ + public function addFailure(RequestInterface $request, Exception $exception); +} diff --git a/vendor/php-http/client-common/src/Plugin/QueryDefaultsPlugin.php b/vendor/php-http/client-common/src/Plugin/QueryDefaultsPlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..6c1e32cd307fefe0960c80bf1e6ce57dab518d34 --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/QueryDefaultsPlugin.php @@ -0,0 +1,54 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Plugin; +use Psr\Http\Message\RequestInterface; + +/** + * Set query to default value if it does not exist. + * + * If a given query parameter already exists the value wont be replaced and the request wont be changed. + * + * @author Tobias Nyholm <tobias.nyholm@gmail.com> + */ +final class QueryDefaultsPlugin implements Plugin +{ + /** + * @var array + */ + private $queryParams = []; + + /** + * @param array $queryParams Hashmap of query name to query value. Names and values must not be url encoded as + * this plugin will encode them + */ + public function __construct(array $queryParams) + { + $this->queryParams = $queryParams; + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + foreach ($this->queryParams as $name => $value) { + $uri = $request->getUri(); + $array = []; + parse_str($uri->getQuery(), $array); + + // If query value is not found + if (!isset($array[$name])) { + $array[$name] = $value; + + // Create a new request with the new URI with the added query param + $request = $request->withUri( + $uri->withQuery(http_build_query($array)) + ); + } + } + + return $next($request); + } +} diff --git a/vendor/php-http/client-common/src/Plugin/RedirectPlugin.php b/vendor/php-http/client-common/src/Plugin/RedirectPlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..d2f442edb8fe95cc9676ef0295e64e2427df9748 --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/RedirectPlugin.php @@ -0,0 +1,270 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Exception\CircularRedirectionException; +use Http\Client\Common\Exception\MultipleRedirectionException; +use Http\Client\Common\Plugin; +use Http\Client\Exception\HttpException; +use Psr\Http\Message\MessageInterface; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\UriInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; + +/** + * Follow redirections. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +class RedirectPlugin implements Plugin +{ + /** + * Rule on how to redirect, change method for the new request. + * + * @var array + */ + protected $redirectCodes = [ + 300 => [ + 'switch' => [ + 'unless' => ['GET', 'HEAD'], + 'to' => 'GET', + ], + 'multiple' => true, + 'permanent' => false, + ], + 301 => [ + 'switch' => [ + 'unless' => ['GET', 'HEAD'], + 'to' => 'GET', + ], + 'multiple' => false, + 'permanent' => true, + ], + 302 => [ + 'switch' => [ + 'unless' => ['GET', 'HEAD'], + 'to' => 'GET', + ], + 'multiple' => false, + 'permanent' => false, + ], + 303 => [ + 'switch' => [ + 'unless' => ['GET', 'HEAD'], + 'to' => 'GET', + ], + 'multiple' => false, + 'permanent' => false, + ], + 307 => [ + 'switch' => false, + 'multiple' => false, + 'permanent' => false, + ], + 308 => [ + 'switch' => false, + 'multiple' => false, + 'permanent' => true, + ], + ]; + + /** + * Determine how header should be preserved from old request. + * + * @var bool|array + * + * true will keep all previous headers (default value) + * false will ditch all previous headers + * string[] will keep only headers with the specified names + */ + protected $preserveHeader; + + /** + * Store all previous redirect from 301 / 308 status code. + * + * @var array + */ + protected $redirectStorage = []; + + /** + * Whether the location header must be directly used for a multiple redirection status code (300). + * + * @var bool + */ + protected $useDefaultForMultiple; + + /** + * @var array + */ + protected $circularDetection = []; + + /** + * @param array $config { + * + * @var bool|string[] $preserve_header True keeps all headers, false remove all of them, an array is interpreted as a list of header names to keep + * @var bool $use_default_for_multiple Whether the location header must be directly used for a multiple redirection status code (300). + * } + */ + public function __construct(array $config = []) + { + $resolver = new OptionsResolver(); + $resolver->setDefaults([ + 'preserve_header' => true, + 'use_default_for_multiple' => true, + ]); + $resolver->setAllowedTypes('preserve_header', ['bool', 'array']); + $resolver->setAllowedTypes('use_default_for_multiple', 'bool'); + $resolver->setNormalizer('preserve_header', function (OptionsResolver $resolver, $value) { + if (is_bool($value) && false === $value) { + return []; + } + + return $value; + }); + $options = $resolver->resolve($config); + + $this->preserveHeader = $options['preserve_header']; + $this->useDefaultForMultiple = $options['use_default_for_multiple']; + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + // Check in storage + if (array_key_exists((string) $request->getUri(), $this->redirectStorage)) { + $uri = $this->redirectStorage[(string) $request->getUri()]['uri']; + $statusCode = $this->redirectStorage[(string) $request->getUri()]['status']; + $redirectRequest = $this->buildRedirectRequest($request, $uri, $statusCode); + + return $first($redirectRequest); + } + + return $next($request)->then(function (ResponseInterface $response) use ($request, $first) { + $statusCode = $response->getStatusCode(); + + if (!array_key_exists($statusCode, $this->redirectCodes)) { + return $response; + } + + $uri = $this->createUri($response, $request); + $redirectRequest = $this->buildRedirectRequest($request, $uri, $statusCode); + $chainIdentifier = spl_object_hash((object) $first); + + if (!array_key_exists($chainIdentifier, $this->circularDetection)) { + $this->circularDetection[$chainIdentifier] = []; + } + + $this->circularDetection[$chainIdentifier][] = (string) $request->getUri(); + + if (in_array((string) $redirectRequest->getUri(), $this->circularDetection[$chainIdentifier])) { + throw new CircularRedirectionException('Circular redirection detected', $request, $response); + } + + if ($this->redirectCodes[$statusCode]['permanent']) { + $this->redirectStorage[(string) $request->getUri()] = [ + 'uri' => $uri, + 'status' => $statusCode, + ]; + } + + // Call redirect request in synchrone + $redirectPromise = $first($redirectRequest); + + return $redirectPromise->wait(); + }); + } + + /** + * Builds the redirect request. + * + * @param RequestInterface $request Original request + * @param UriInterface $uri New uri + * @param int $statusCode Status code from the redirect response + * + * @return MessageInterface|RequestInterface + */ + protected function buildRedirectRequest(RequestInterface $request, UriInterface $uri, $statusCode) + { + $request = $request->withUri($uri); + + if (false !== $this->redirectCodes[$statusCode]['switch'] && !in_array($request->getMethod(), $this->redirectCodes[$statusCode]['switch']['unless'])) { + $request = $request->withMethod($this->redirectCodes[$statusCode]['switch']['to']); + } + + if (is_array($this->preserveHeader)) { + $headers = array_keys($request->getHeaders()); + + foreach ($headers as $name) { + if (!in_array($name, $this->preserveHeader)) { + $request = $request->withoutHeader($name); + } + } + } + + return $request; + } + + /** + * Creates a new Uri from the old request and the location header. + * + * @param ResponseInterface $response The redirect response + * @param RequestInterface $request The original request + * + * @throws HttpException If location header is not usable (missing or incorrect) + * @throws MultipleRedirectionException If a 300 status code is received and default location cannot be resolved (doesn't use the location header or not present) + * + * @return UriInterface + */ + private function createUri(ResponseInterface $response, RequestInterface $request) + { + if ($this->redirectCodes[$response->getStatusCode()]['multiple'] && (!$this->useDefaultForMultiple || !$response->hasHeader('Location'))) { + throw new MultipleRedirectionException('Cannot choose a redirection', $request, $response); + } + + if (!$response->hasHeader('Location')) { + throw new HttpException('Redirect status code, but no location header present in the response', $request, $response); + } + + $location = $response->getHeaderLine('Location'); + $parsedLocation = parse_url($location); + + if (false === $parsedLocation) { + throw new HttpException(sprintf('Location %s could not be parsed', $location), $request, $response); + } + + $uri = $request->getUri(); + + if (array_key_exists('scheme', $parsedLocation)) { + $uri = $uri->withScheme($parsedLocation['scheme']); + } + + if (array_key_exists('host', $parsedLocation)) { + $uri = $uri->withHost($parsedLocation['host']); + } + + if (array_key_exists('port', $parsedLocation)) { + $uri = $uri->withPort($parsedLocation['port']); + } + + if (array_key_exists('path', $parsedLocation)) { + $uri = $uri->withPath($parsedLocation['path']); + } + + if (array_key_exists('query', $parsedLocation)) { + $uri = $uri->withQuery($parsedLocation['query']); + } else { + $uri = $uri->withQuery(''); + } + + if (array_key_exists('fragment', $parsedLocation)) { + $uri = $uri->withFragment($parsedLocation['fragment']); + } else { + $uri = $uri->withFragment(''); + } + + return $uri; + } +} diff --git a/vendor/php-http/client-common/src/Plugin/RequestMatcherPlugin.php b/vendor/php-http/client-common/src/Plugin/RequestMatcherPlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..5f72b02d8ac6973ba659ab9d4bf1f7f1eaf97eba --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/RequestMatcherPlugin.php @@ -0,0 +1,47 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Plugin; +use Http\Message\RequestMatcher; +use Psr\Http\Message\RequestInterface; + +/** + * Apply a delegated plugin based on a request match. + * + * @author Márk Sági-Kazár <mark.sagikazar@gmail.com> + */ +final class RequestMatcherPlugin implements Plugin +{ + /** + * @var RequestMatcher + */ + private $requestMatcher; + + /** + * @var Plugin + */ + private $delegatedPlugin; + + /** + * @param RequestMatcher $requestMatcher + * @param Plugin $delegatedPlugin + */ + public function __construct(RequestMatcher $requestMatcher, Plugin $delegatedPlugin) + { + $this->requestMatcher = $requestMatcher; + $this->delegatedPlugin = $delegatedPlugin; + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + if ($this->requestMatcher->matches($request)) { + return $this->delegatedPlugin->handleRequest($request, $next, $first); + } + + return $next($request); + } +} diff --git a/vendor/php-http/client-common/src/Plugin/RetryPlugin.php b/vendor/php-http/client-common/src/Plugin/RetryPlugin.php new file mode 100644 index 0000000000000000000000000000000000000000..8446246e673c4cab2cb3685f894a18220b14f385 --- /dev/null +++ b/vendor/php-http/client-common/src/Plugin/RetryPlugin.php @@ -0,0 +1,122 @@ +<?php + +namespace Http\Client\Common\Plugin; + +use Http\Client\Common\Plugin; +use Http\Client\Exception; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; + +/** + * Retry the request if an exception is thrown. + * + * By default will retry only one time. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +final class RetryPlugin implements Plugin +{ + /** + * Number of retry before sending an exception. + * + * @var int + */ + private $retry; + + /** + * @var callable + */ + private $delay; + + /** + * @var callable + */ + private $decider; + + /** + * Store the retry counter for each request. + * + * @var array + */ + private $retryStorage = []; + + /** + * @param array $config { + * + * @var int $retries Number of retries to attempt if an exception occurs before letting the exception bubble up. + * @var callable $decider A callback that gets a request and an exception to decide after a failure whether the request should be retried. + * @var callable $delay A callback that gets a request, an exception and the number of retries and returns how many microseconds we should wait before trying again. + * } + */ + public function __construct(array $config = []) + { + $resolver = new OptionsResolver(); + $resolver->setDefaults([ + 'retries' => 1, + 'decider' => function (RequestInterface $request, Exception $e) { + return true; + }, + 'delay' => __CLASS__.'::defaultDelay', + ]); + $resolver->setAllowedTypes('retries', 'int'); + $resolver->setAllowedTypes('decider', 'callable'); + $resolver->setAllowedTypes('delay', 'callable'); + $options = $resolver->resolve($config); + + $this->retry = $options['retries']; + $this->decider = $options['decider']; + $this->delay = $options['delay']; + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + $chainIdentifier = spl_object_hash((object) $first); + + return $next($request)->then(function (ResponseInterface $response) use ($request, $chainIdentifier) { + if (array_key_exists($chainIdentifier, $this->retryStorage)) { + unset($this->retryStorage[$chainIdentifier]); + } + + return $response; + }, function (Exception $exception) use ($request, $next, $first, $chainIdentifier) { + if (!array_key_exists($chainIdentifier, $this->retryStorage)) { + $this->retryStorage[$chainIdentifier] = 0; + } + + if ($this->retryStorage[$chainIdentifier] >= $this->retry) { + unset($this->retryStorage[$chainIdentifier]); + + throw $exception; + } + + if (!call_user_func($this->decider, $request, $exception)) { + throw $exception; + } + + $time = call_user_func($this->delay, $request, $exception, $this->retryStorage[$chainIdentifier]); + usleep($time); + + // Retry in synchrone + ++$this->retryStorage[$chainIdentifier]; + $promise = $this->handleRequest($request, $next, $first); + + return $promise->wait(); + }); + } + + /** + * @param RequestInterface $request + * @param Exception $e + * @param int $retries The number of retries we made before. First time this get called it will be 0. + * + * @return int + */ + public static function defaultDelay(RequestInterface $request, Exception $e, $retries) + { + return pow(2, $retries) * 500000; + } +} diff --git a/vendor/php-http/client-common/src/PluginClient.php b/vendor/php-http/client-common/src/PluginClient.php new file mode 100644 index 0000000000000000000000000000000000000000..93aea8f2fda0c2ead27a5de67006a43a7a0c51d5 --- /dev/null +++ b/vendor/php-http/client-common/src/PluginClient.php @@ -0,0 +1,179 @@ +<?php + +namespace Http\Client\Common; + +use Http\Client\Common\Exception\LoopException; +use Http\Client\Exception as HttplugException; +use Http\Client\HttpAsyncClient; +use Http\Client\HttpClient; +use Http\Client\Promise\HttpFulfilledPromise; +use Http\Client\Promise\HttpRejectedPromise; +use Psr\Http\Message\RequestInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; + +/** + * The client managing plugins and providing a decorator around HTTP Clients. + * + * @author Joel Wurtz <joel.wurtz@gmail.com> + */ +final class PluginClient implements HttpClient, HttpAsyncClient +{ + /** + * An HTTP async client. + * + * @var HttpAsyncClient + */ + private $client; + + /** + * The plugin chain. + * + * @var Plugin[] + */ + private $plugins; + + /** + * A list of options. + * + * @var array + */ + private $options; + + /** + * @param HttpClient|HttpAsyncClient $client + * @param Plugin[] $plugins + * @param array $options { + * + * @var int $max_restarts + * @var Plugin[] $debug_plugins an array of plugins that are injected between each normal plugin + * } + * + * @throws \RuntimeException if client is not an instance of HttpClient or HttpAsyncClient + */ + public function __construct($client, array $plugins = [], array $options = []) + { + if ($client instanceof HttpAsyncClient) { + $this->client = $client; + } elseif ($client instanceof HttpClient) { + $this->client = new EmulatedHttpAsyncClient($client); + } else { + throw new \RuntimeException('Client must be an instance of Http\\Client\\HttpClient or Http\\Client\\HttpAsyncClient'); + } + + $this->plugins = $plugins; + $this->options = $this->configure($options); + } + + /** + * {@inheritdoc} + */ + public function sendRequest(RequestInterface $request) + { + // If we don't have an http client, use the async call + if (!($this->client instanceof HttpClient)) { + return $this->sendAsyncRequest($request)->wait(); + } + + // Else we want to use the synchronous call of the underlying client, and not the async one in the case + // we have both an async and sync call + $pluginChain = $this->createPluginChain($this->plugins, function (RequestInterface $request) { + try { + return new HttpFulfilledPromise($this->client->sendRequest($request)); + } catch (HttplugException $exception) { + return new HttpRejectedPromise($exception); + } + }); + + return $pluginChain($request)->wait(); + } + + /** + * {@inheritdoc} + */ + public function sendAsyncRequest(RequestInterface $request) + { + $pluginChain = $this->createPluginChain($this->plugins, function (RequestInterface $request) { + return $this->client->sendAsyncRequest($request); + }); + + return $pluginChain($request); + } + + /** + * Configure the plugin client. + * + * @param array $options + * + * @return array + */ + private function configure(array $options = []) + { + if (isset($options['debug_plugins'])) { + @trigger_error('The "debug_plugins" option is deprecated since 1.5 and will be removed in 2.0.', E_USER_DEPRECATED); + } + + $resolver = new OptionsResolver(); + $resolver->setDefaults([ + 'max_restarts' => 10, + 'debug_plugins' => [], + ]); + + $resolver + ->setAllowedTypes('debug_plugins', 'array') + ->setAllowedValues('debug_plugins', function (array $plugins) { + foreach ($plugins as $plugin) { + // Make sure each object passed with the `debug_plugins` is an instance of Plugin. + if (!$plugin instanceof Plugin) { + return false; + } + } + + return true; + }); + + return $resolver->resolve($options); + } + + /** + * Create the plugin chain. + * + * @param Plugin[] $pluginList A list of plugins + * @param callable $clientCallable Callable making the HTTP call + * + * @return callable + */ + private function createPluginChain($pluginList, callable $clientCallable) + { + $firstCallable = $lastCallable = $clientCallable; + + /* + * Inject debug plugins between each plugin. + */ + $pluginListWithDebug = $this->options['debug_plugins']; + foreach ($pluginList as $plugin) { + $pluginListWithDebug[] = $plugin; + $pluginListWithDebug = array_merge($pluginListWithDebug, $this->options['debug_plugins']); + } + + while ($plugin = array_pop($pluginListWithDebug)) { + $lastCallable = function (RequestInterface $request) use ($plugin, $lastCallable, &$firstCallable) { + return $plugin->handleRequest($request, $lastCallable, $firstCallable); + }; + + $firstCallable = $lastCallable; + } + + $firstCalls = 0; + $firstCallable = function (RequestInterface $request) use ($lastCallable, &$firstCalls) { + if ($firstCalls > $this->options['max_restarts']) { + throw new LoopException('Too many restarts in plugin client', $request); + } + + ++$firstCalls; + + return $lastCallable($request); + }; + + return $firstCallable; + } +} diff --git a/vendor/php-http/client-common/src/PluginClientFactory.php b/vendor/php-http/client-common/src/PluginClientFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..bd4c08f9a62530a792022e7830a0ecd681e7c828 --- /dev/null +++ b/vendor/php-http/client-common/src/PluginClientFactory.php @@ -0,0 +1,62 @@ +<?php + +namespace Http\Client\Common; + +use Http\Client\HttpAsyncClient; +use Http\Client\HttpClient; + +/** + * Factory to create PluginClient instances. Using this factory instead of calling PluginClient constructor will enable + * the Symfony profiling without any configuration. + * + * @author Fabien Bourigault <bourigaultfabien@gmail.com> + */ +final class PluginClientFactory +{ + /** + * @var callable + */ + private static $factory; + + /** + * Set the factory to use. + * The callable to provide must have the same arguments and return type as PluginClientFactory::createClient. + * This is used by the HTTPlugBundle to provide a better Symfony integration. + * Unlike the createClient method, this one is static to allow zero configuration profiling by hooking into early + * application execution. + * + * @internal + * + * @param callable $factory + */ + public static function setFactory(callable $factory) + { + static::$factory = $factory; + } + + /** + * @param HttpClient|HttpAsyncClient $client + * @param Plugin[] $plugins + * @param array $options { + * + * @var string $client_name to give client a name which may be used when displaying client information like in + * the HTTPlugBundle profiler. + * } + * + * @see PluginClient constructor for PluginClient specific $options. + * + * @return PluginClient + */ + public function createClient($client, array $plugins = [], array $options = []) + { + if (static::$factory) { + $factory = static::$factory; + + return $factory($client, $plugins, $options); + } + + unset($options['client_name']); + + return new PluginClient($client, $plugins, $options); + } +} diff --git a/vendor/php-http/multipart-stream-builder/CHANGELOG.md b/vendor/php-http/multipart-stream-builder/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..1f0ee3d7f32e2bc04227bb2988081ba0fbd2af08 --- /dev/null +++ b/vendor/php-http/multipart-stream-builder/CHANGELOG.md @@ -0,0 +1,60 @@ +# Change Log + +## 1.0.0 - 2017-05-21 + +No changes from 0.2.0. + +## 0.2.0 - 2017-02-20 + +You may do a BC update to version 0.2.0 if you are sure that you are not adding +multiple resources with the same name to the Builder. + +### Fixed + +- Make sure one can add resources with same name without overwrite. + +## 0.1.6 - 2017-02-16 + +### Fixed + +- Performance improvements by avoid using `uniqid()`. + +## 0.1.5 - 2017-02-14 + +### Fixed + +- Support for non-readable streams. This fix was needed because flaws in Guzzle, Zend and Slims implementations of PSR-7. + +## 0.1.4 - 2016-12-31 + +### Added + +- Added support for resetting the builder + +## 0.1.3 - 2016-12-22 + +### Added + +- Added `CustomMimetypeHelper` to allow you to configure custom mimetypes. + +### Changed + +- Using regular expression instead of `basename($filename)` because basename is depending on locale. + +## 0.1.2 - 2016-08-31 + +### Added + +- Support for Outlook msg files. + +## 0.1.1 - 2016-08-10 + +### Added + +- Support for Apple passbook. + +## 0.1.0 - 2016-07-19 + +### Added + +- Initial release diff --git a/vendor/php-http/multipart-stream-builder/LICENSE b/vendor/php-http/multipart-stream-builder/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..8e2c4a0b85c31bf132105920cc90ba371025eb8a --- /dev/null +++ b/vendor/php-http/multipart-stream-builder/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015 PHP HTTP Team <team@php-http.org> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/php-http/multipart-stream-builder/README.md b/vendor/php-http/multipart-stream-builder/README.md new file mode 100644 index 0000000000000000000000000000000000000000..10ad0588b4b7e9a43e9eaced1ecda28c7b4cf372 --- /dev/null +++ b/vendor/php-http/multipart-stream-builder/README.md @@ -0,0 +1,37 @@ +# PSR-7 Multipart Stream Builder + +[](https://github.com/php-http/multipart-stream-builder/releases) +[](https://travis-ci.org/php-http/multipart-stream-builder) +[](https://scrutinizer-ci.com/g/php-http/multipart-stream-builder) +[](https://scrutinizer-ci.com/g/php-http/multipart-stream-builder) +[](https://packagist.org/packages/php-http/multipart-stream-builder) + +**A builder for Multipart PSR-7 Streams. The builder create streams independenly form any PSR-7 implementation.** + + +## Install + +Via Composer + +``` bash +$ composer require php-http/multipart-stream-builder +``` + +## Documentation + +Please see the [official documentation](http://php-http.readthedocs.org/en/latest/components/multipart-stream-builder.html). + + +## Contributing + +Please see [CONTRIBUTING](CONTRIBUTING.md) and [CONDUCT](CONDUCT.md) for details. + + +## Security + +If you discover any security related issues, please contact us at [security@php-http.org](mailto:security@php-http.org). + + +## License + +The MIT License (MIT). Please see [License File](LICENSE) for more information. diff --git a/vendor/php-http/multipart-stream-builder/appveyor.yml b/vendor/php-http/multipart-stream-builder/appveyor.yml new file mode 100644 index 0000000000000000000000000000000000000000..8d7af73f722812a369260d79a9078c2b01a02393 --- /dev/null +++ b/vendor/php-http/multipart-stream-builder/appveyor.yml @@ -0,0 +1,39 @@ +build: false +platform: + - x86 + - x64 + +clone_folder: c:\projects\php-http\multipart-stream-builder + +cache: + - c:\tools\php -> appveyor.yml + +init: + - SET PATH=c:\php;%PATH% + - SET COMPOSER_NO_INTERACTION=1 + - SET PHP=1 + + +install: + - IF EXIST c:\php (SET PHP=0) ELSE (mkdir c:\php) + - cd c:\php + - IF %PHP%==1 appveyor DownloadFile http://windows.php.net/downloads/releases/archives/php-7.0.0-nts-Win32-VC14-x86.zip + - IF %PHP%==1 7z x php-7.0.0-nts-Win32-VC14-x86.zip -y >nul + - IF %PHP%==1 del /Q *.zip + - IF %PHP%==1 echo @php %%~dp0composer.phar %%* > composer.bat + - IF %PHP%==1 copy /Y php.ini-development php.ini + - IF %PHP%==1 echo max_execution_time=1200 >> php.ini + - IF %PHP%==1 echo date.timezone="UTC" >> php.ini + - IF %PHP%==1 echo extension_dir=ext >> php.ini + - IF %PHP%==1 echo extension=php_openssl.dll >> php.ini + - IF %PHP%==1 echo extension=php_mbstring.dll >> php.ini + - IF %PHP%==1 echo extension=php_fileinfo.dll >> php.ini + - appveyor DownloadFile https://getcomposer.org/composer.phar + - cd c:\projects\php-http\multipart-stream-builder + - mkdir %APPDATA%\Composer + - composer update --prefer-dist --no-progress --ansi + +test_script: + - cd c:\projects\php-http\multipart-stream-builder + - vendor\bin\phpunit.bat --verbose + diff --git a/vendor/php-http/multipart-stream-builder/composer.json b/vendor/php-http/multipart-stream-builder/composer.json new file mode 100644 index 0000000000000000000000000000000000000000..1ada3605c54bd13ede3523d86fd9ac8a4cb31fbd --- /dev/null +++ b/vendor/php-http/multipart-stream-builder/composer.json @@ -0,0 +1,43 @@ +{ + "name": "php-http/multipart-stream-builder", + "description": "A builder class that help you create a multipart stream", + "license": "MIT", + "keywords": ["http", "factory", "message", "stream", "multipart stream"], + "homepage": "http://php-http.org", + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + } + ], + "require": { + "php": "^5.5 || ^7.0", + "psr/http-message": "^1.0", + "php-http/message-factory": "^1.0.2", + "php-http/discovery": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.4", + "php-http/message": "^1.5", + "zendframework/zend-diactoros": "^1.3.5" + }, + "autoload": { + "psr-4": { + "Http\\Message\\MultipartStream\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "tests\\Http\\Message\\MultipartStream\\": "tests/" + } + }, + "scripts": { + "test": "vendor/bin/phpunit", + "test-ci": "vendor/bin/phpunit --coverage-text --coverage-clover=build/coverage.xml" + }, + "extra": { + "branch-alias": { + "dev-master": "0.3-dev" + } + } +} diff --git a/vendor/php-http/multipart-stream-builder/src/ApacheMimetypeHelper.php b/vendor/php-http/multipart-stream-builder/src/ApacheMimetypeHelper.php new file mode 100644 index 0000000000000000000000000000000000000000..6e4ca660246f5fdc929ca455e3e30b1ddc6c639b --- /dev/null +++ b/vendor/php-http/multipart-stream-builder/src/ApacheMimetypeHelper.php @@ -0,0 +1,142 @@ +<?php + +namespace Http\Message\MultipartStream; + +/** + * This class helps to find the proper mime types. The source of this file is taken + * from Guzzle. + * + * @author Michael Dowling and contributors to guzzlehttp/psr7 + * @author Tobias Nyholm <tobias.nyholm@gmail.com> + */ +class ApacheMimetypeHelper implements MimetypeHelper +{ + /** + * {@inheritdoc} + * + * @see http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types + */ + public function getMimetypeFromFilename($filename) + { + return $this->getMimetypeFromExtension(pathinfo($filename, PATHINFO_EXTENSION)); + } + + /** + * {@inheritdoc} + * + * @see http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types + */ + public function getMimetypeFromExtension($extension) + { + static $mimetypes = [ + '7z' => 'application/x-7z-compressed', + 'aac' => 'audio/x-aac', + 'ai' => 'application/postscript', + 'aif' => 'audio/x-aiff', + 'asc' => 'text/plain', + 'asf' => 'video/x-ms-asf', + 'atom' => 'application/atom+xml', + 'avi' => 'video/x-msvideo', + 'bmp' => 'image/bmp', + 'bz2' => 'application/x-bzip2', + 'cer' => 'application/pkix-cert', + 'crl' => 'application/pkix-crl', + 'crt' => 'application/x-x509-ca-cert', + 'css' => 'text/css', + 'csv' => 'text/csv', + 'cu' => 'application/cu-seeme', + 'deb' => 'application/x-debian-package', + 'doc' => 'application/msword', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dvi' => 'application/x-dvi', + 'eot' => 'application/vnd.ms-fontobject', + 'eps' => 'application/postscript', + 'epub' => 'application/epub+zip', + 'etx' => 'text/x-setext', + 'flac' => 'audio/flac', + 'flv' => 'video/x-flv', + 'gif' => 'image/gif', + 'gz' => 'application/gzip', + 'htm' => 'text/html', + 'html' => 'text/html', + 'ico' => 'image/x-icon', + 'ics' => 'text/calendar', + 'ini' => 'text/plain', + 'iso' => 'application/x-iso9660-image', + 'jar' => 'application/java-archive', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'js' => 'text/javascript', + 'json' => 'application/json', + 'latex' => 'application/x-latex', + 'log' => 'text/plain', + 'm4a' => 'audio/mp4', + 'm4v' => 'video/mp4', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mov' => 'video/quicktime', + 'mp3' => 'audio/mpeg', + 'mp4' => 'video/mp4', + 'mp4a' => 'audio/mp4', + 'mp4v' => 'video/mp4', + 'mpe' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpg4' => 'video/mp4', + 'oga' => 'audio/ogg', + 'ogg' => 'audio/ogg', + 'ogv' => 'video/ogg', + 'ogx' => 'application/ogg', + 'pbm' => 'image/x-portable-bitmap', + 'pdf' => 'application/pdf', + 'pgm' => 'image/x-portable-graymap', + 'png' => 'image/png', + 'pnm' => 'image/x-portable-anymap', + 'ppm' => 'image/x-portable-pixmap', + 'ppt' => 'application/vnd.ms-powerpoint', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'ps' => 'application/postscript', + 'qt' => 'video/quicktime', + 'rar' => 'application/x-rar-compressed', + 'ras' => 'image/x-cmu-raster', + 'rss' => 'application/rss+xml', + 'rtf' => 'application/rtf', + 'sgm' => 'text/sgml', + 'sgml' => 'text/sgml', + 'svg' => 'image/svg+xml', + 'swf' => 'application/x-shockwave-flash', + 'tar' => 'application/x-tar', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'torrent' => 'application/x-bittorrent', + 'ttf' => 'application/x-font-ttf', + 'txt' => 'text/plain', + 'wav' => 'audio/x-wav', + 'webm' => 'video/webm', + 'wma' => 'audio/x-ms-wma', + 'wmv' => 'video/x-ms-wmv', + 'woff' => 'application/x-font-woff', + 'wsdl' => 'application/wsdl+xml', + 'xbm' => 'image/x-xbitmap', + 'xls' => 'application/vnd.ms-excel', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xml' => 'application/xml', + 'xpm' => 'image/x-xpixmap', + 'xwd' => 'image/x-xwindowdump', + 'yaml' => 'text/yaml', + 'yml' => 'text/yaml', + 'zip' => 'application/zip', + + // Non-Apache standard + 'pkpass' => 'application/vnd.apple.pkpass', + 'msg' => 'application/vnd.ms-outlook', + ]; + + $extension = strtolower($extension); + + return isset($mimetypes[$extension]) + ? $mimetypes[$extension] + : null; + } +} diff --git a/vendor/php-http/multipart-stream-builder/src/CustomMimetypeHelper.php b/vendor/php-http/multipart-stream-builder/src/CustomMimetypeHelper.php new file mode 100644 index 0000000000000000000000000000000000000000..9f3f0d9211e563aeabcb59b6e34912de7ae1779e --- /dev/null +++ b/vendor/php-http/multipart-stream-builder/src/CustomMimetypeHelper.php @@ -0,0 +1,51 @@ +<?php + +namespace Http\Message\MultipartStream; + +/** + * Let you add your own mimetypes. The mimetype lookup will fallback on the ApacheMimeTypeHelper. + * + * @author Tobias Nyholm <tobias.nyholm@gmail.com> + */ +class CustomMimetypeHelper extends ApacheMimetypeHelper +{ + /** + * @var array + */ + private $mimetypes = []; + + /** + * @param array $mimetypes should be of type extension => mimetype + */ + public function __construct(array $mimetypes = []) + { + $this->mimetypes = $mimetypes; + } + + /** + * @param string $extension + * @param string $mimetype + * + * @return $this + */ + public function addMimetype($extension, $mimetype) + { + $this->mimetypes[$extension] = $mimetype; + + return $this; + } + + /** + * {@inheritdoc} + * + * Check if we have any defined mimetypes and of not fallback to ApacheMimetypeHelper + */ + public function getMimetypeFromExtension($extension) + { + $extension = strtolower($extension); + + return isset($this->mimetypes[$extension]) + ? $this->mimetypes[$extension] + : parent::getMimetypeFromExtension($extension); + } +} diff --git a/vendor/php-http/multipart-stream-builder/src/MimetypeHelper.php b/vendor/php-http/multipart-stream-builder/src/MimetypeHelper.php new file mode 100644 index 0000000000000000000000000000000000000000..fa7cf18003720731c5391e572537fb42795802e4 --- /dev/null +++ b/vendor/php-http/multipart-stream-builder/src/MimetypeHelper.php @@ -0,0 +1,27 @@ +<?php + +namespace Http\Message\MultipartStream; + +/** + * @author Tobias Nyholm <tobias.nyholm@gmail.com> + */ +interface MimetypeHelper +{ + /** + * Determines the mimetype of a file by looking at its extension. + * + * @param string $filename + * + * @return null|string + */ + public function getMimetypeFromFilename($filename); + + /** + * Maps a file extensions to a mimetype. + * + * @param string $extension The file extension + * + * @return string|null + */ + public function getMimetypeFromExtension($extension); +} diff --git a/vendor/php-http/multipart-stream-builder/src/MultipartStreamBuilder.php b/vendor/php-http/multipart-stream-builder/src/MultipartStreamBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..3421d73487438866f3d037abfd041244927f8b50 --- /dev/null +++ b/vendor/php-http/multipart-stream-builder/src/MultipartStreamBuilder.php @@ -0,0 +1,278 @@ +<?php + +namespace Http\Message\MultipartStream; + +use Http\Discovery\StreamFactoryDiscovery; +use Http\Message\StreamFactory; +use Psr\Http\Message\StreamInterface; + +/** + * Build your own Multipart stream. A Multipart stream is a collection of streams separated with a $bounary. This + * class helps you to create a Multipart stream with stream implementations from any PSR7 library. + * + * @author Michael Dowling and contributors to guzzlehttp/psr7 + * @author Tobias Nyholm <tobias.nyholm@gmail.com> + */ +class MultipartStreamBuilder +{ + /** + * @var StreamFactory + */ + private $streamFactory; + + /** + * @var MimetypeHelper + */ + private $mimetypeHelper; + + /** + * @var string + */ + private $boundary; + + /** + * @var array Element where each Element is an array with keys ['contents', 'headers', 'filename'] + */ + private $data = []; + + /** + * @param StreamFactory|null $streamFactory + */ + public function __construct(StreamFactory $streamFactory = null) + { + $this->streamFactory = $streamFactory ?: StreamFactoryDiscovery::find(); + } + + /** + * Add a resource to the Multipart Stream. + * + * @param string $name the formpost name + * @param string|resource|StreamInterface $resource + * @param array $options { + * + * @var array $headers additional headers ['header-name' => 'header-value'] + * @var string $filename + * } + * + * @return MultipartStreamBuilder + */ + public function addResource($name, $resource, array $options = []) + { + $stream = $this->streamFactory->createStream($resource); + + // validate options['headers'] exists + if (!isset($options['headers'])) { + $options['headers'] = []; + } + + // Try to add filename if it is missing + if (empty($options['filename'])) { + $options['filename'] = null; + $uri = $stream->getMetadata('uri'); + if (substr($uri, 0, 6) !== 'php://') { + $options['filename'] = $uri; + } + } + + $this->prepareHeaders($name, $stream, $options['filename'], $options['headers']); + $this->data[] = ['contents' => $stream, 'headers' => $options['headers'], 'filename' => $options['filename']]; + + return $this; + } + + /** + * Build the stream. + * + * @return StreamInterface + */ + public function build() + { + $streams = ''; + foreach ($this->data as $data) { + // Add start and headers + $streams .= "--{$this->getBoundary()}\r\n". + $this->getHeaders($data['headers'])."\r\n"; + + // Convert the stream to string + /* @var $contentStream StreamInterface */ + $contentStream = $data['contents']; + if ($contentStream->isSeekable()) { + $streams .= $contentStream->__toString(); + } else { + $streams .= $contentStream->getContents(); + } + + $streams .= "\r\n"; + } + + // Append end + $streams .= "--{$this->getBoundary()}--\r\n"; + + return $this->streamFactory->createStream($streams); + } + + /** + * Add extra headers if they are missing. + * + * @param string $name + * @param StreamInterface $stream + * @param string $filename + * @param array &$headers + */ + private function prepareHeaders($name, StreamInterface $stream, $filename, array &$headers) + { + $hasFilename = $filename === '0' || $filename; + + // Set a default content-disposition header if one was not provided + if (!$this->hasHeader($headers, 'content-disposition')) { + $headers['Content-Disposition'] = sprintf('form-data; name="%s"', $name); + if ($hasFilename) { + $headers['Content-Disposition'] .= sprintf('; filename="%s"', $this->basename($filename)); + } + } + + // Set a default content-length header if one was not provided + if (!$this->hasHeader($headers, 'content-length')) { + if ($length = $stream->getSize()) { + $headers['Content-Length'] = (string) $length; + } + } + + // Set a default Content-Type if one was not provided + if (!$this->hasHeader($headers, 'content-type') && $hasFilename) { + if ($type = $this->getMimetypeHelper()->getMimetypeFromFilename($filename)) { + $headers['Content-Type'] = $type; + } + } + } + + /** + * Get the headers formatted for the HTTP message. + * + * @param array $headers + * + * @return string + */ + private function getHeaders(array $headers) + { + $str = ''; + foreach ($headers as $key => $value) { + $str .= sprintf("%s: %s\r\n", $key, $value); + } + + return $str; + } + + /** + * Check if header exist. + * + * @param array $headers + * @param string $key case insensitive + * + * @return bool + */ + private function hasHeader(array $headers, $key) + { + $lowercaseHeader = strtolower($key); + foreach ($headers as $k => $v) { + if (strtolower($k) === $lowercaseHeader) { + return true; + } + } + + return false; + } + + /** + * Get the boundary that separates the streams. + * + * @return string + */ + public function getBoundary() + { + if ($this->boundary === null) { + $this->boundary = uniqid('', true); + } + + return $this->boundary; + } + + /** + * @param string $boundary + * + * @return MultipartStreamBuilder + */ + public function setBoundary($boundary) + { + $this->boundary = $boundary; + + return $this; + } + + /** + * @return MimetypeHelper + */ + private function getMimetypeHelper() + { + if ($this->mimetypeHelper === null) { + $this->mimetypeHelper = new ApacheMimetypeHelper(); + } + + return $this->mimetypeHelper; + } + + /** + * If you have custom file extension you may overwrite the default MimetypeHelper with your own. + * + * @param MimetypeHelper $mimetypeHelper + * + * @return MultipartStreamBuilder + */ + public function setMimetypeHelper(MimetypeHelper $mimetypeHelper) + { + $this->mimetypeHelper = $mimetypeHelper; + + return $this; + } + + /** + * Reset and clear all stored data. This allows you to use builder for a subsequent request. + * + * @return MultipartStreamBuilder + */ + public function reset() + { + $this->data = []; + $this->boundary = null; + + return $this; + } + + /** + * Gets the filename from a given path. + * + * PHP's basename() does not properly support streams or filenames beginning with a non-US-ASCII character. + * + * @author Drupal 8.2 + * + * @param string $path + * + * @return string + */ + private function basename($path) + { + $separators = '/'; + if (DIRECTORY_SEPARATOR != '/') { + // For Windows OS add special separator. + $separators .= DIRECTORY_SEPARATOR; + } + + // Remove right-most slashes when $path points to directory. + $path = rtrim($path, $separators); + + // Returns the trailing part of the $path starting after one of the directory separators. + $filename = preg_match('@[^'.preg_quote($separators, '@').']+$@', $path, $matches) ? $matches[0] : ''; + + return $filename; + } +} diff --git a/vendor/respect/validation/docs/Age.md b/vendor/respect/validation/docs/Age.md new file mode 100644 index 0000000000000000000000000000000000000000..740d7279b676e08c6062a1fdae87bc675fc6bbbc --- /dev/null +++ b/vendor/respect/validation/docs/Age.md @@ -0,0 +1,46 @@ +# Age + +- `v::age(int $minAge)` +- `v::age(int $minAge, int $maxAge)` +- `v::age(null, int $maxAge)` + +Validates ranges of years. + +The validated values can be any date value; internally they will be transformed +into [DateTime](http://php.net/manual/en/class.datetime.php) objects according +to the defined locale settings. + +The examples below validate if the given dates are lower or equal to 18 years ago: +```php +v::age(18)->validate('17 years ago'); // false +v::age(18)->validate('18 years ago'); // true +v::age(18)->validate('19 years ago'); // true +v::age(18)->validate('1970-01-01'); // true +v::age(18)->validate('today'); // false +``` + +The examples below validate if the given dates are between 10 and 50 years ago: +```php +v::age(10, 50)->validate('9 years ago'); // false +v::age(10, 50)->validate('10 years ago'); // true +v::age(10, 50)->validate('30 years ago'); // true +v::age(10, 50)->validate('50 years ago'); // true +v::age(10, 50)->validate('51 years ago'); // false +``` + +The examples below validate if the given dates are greater than or equal to 70 years ago: +```php +v::age(null, 70)->validate('today'); // true +v::age(null, 70)->validate('70 years ago'); // true +v::age(null, 70)->validate('71 years ago'); // false +``` + +Message template for this validator includes `{{minAge}}` and `{{maxAge}}`. + +*** +See also: + + * [Between](Between.md) + * [Date](Date.md) + * [Max](Max.md) + * [Min](Min.md) diff --git a/vendor/respect/validation/docs/AllOf.md b/vendor/respect/validation/docs/AllOf.md new file mode 100644 index 0000000000000000000000000000000000000000..7bd2ecf0203be63de28fd5a27c59f0eb7dbe8ddc --- /dev/null +++ b/vendor/respect/validation/docs/AllOf.md @@ -0,0 +1,30 @@ +# AllOf + +- `v::allOf(v $v1, v $v2, v $v3...)` + +Will validate if all inner validators validates. + +```php +v::allOf( + v::intVal(), + v::positive() +)->validate(15); // true +``` + +This is similar to the chain (which is an allOf already), but +its syntax allows you to set custom names for every node: + +```php +v::allOf( + v::intVal()->setName('Account Number'), + v::positive()->setName('Higher Than Zero') +)->setName('Positive integer') + ->validate(15); // true +``` + +*** +See also: + + * [OneOf](OneOf.md) + * [NoneOf](NoneOf.md) + * [When](When.md) diff --git a/vendor/respect/validation/docs/Alnum.md b/vendor/respect/validation/docs/Alnum.md new file mode 100644 index 0000000000000000000000000000000000000000..184c1e2cfb64c88fc4ee5340077c6a22e8a3710c --- /dev/null +++ b/vendor/respect/validation/docs/Alnum.md @@ -0,0 +1,44 @@ +# Alnum + +- `v::alnum()` +- `v::alnum(string $additionalChars)` + +Validates alphanumeric characters from a-Z and 0-9. + +```php +v::alnum()->validate('foo 123'); // true +v::alnum()->validate('number 100%'); // false +v::alnum('%')->validate('number 100%'); // true +``` + +Because this rule allows whitespaces by default, you can separate additional +characters with a whitespace: + +```php +v::alnum('- ! :')->validate('foo :- 123 !'); // true +``` + +This validator allows whitespace, if you want to +remove them add `->noWhitespace()` to the chain: + +```php +v::alnum()->noWhitespace()->validate('foo 123'); // false +``` + +You can restrict case using the `->lowercase()` and +`->uppercase()` validators: + +```php +v::alnum()->uppercase()->validate('aaa'); // false +``` + +Message template for this validator includes `{{additionalChars}}` as +the string of extra chars passed as the parameter. + +*** +See also: + + * [Alpha](Alpha.md) + * [Digit](Digit.md) + * [Consonant](Consonant.md) + * [Vowel](Vowel.md) diff --git a/vendor/respect/validation/docs/Alpha.md b/vendor/respect/validation/docs/Alpha.md new file mode 100644 index 0000000000000000000000000000000000000000..44f4dc3714c3ebfd64c46a9da17bfa8a91c091f4 --- /dev/null +++ b/vendor/respect/validation/docs/Alpha.md @@ -0,0 +1,14 @@ +# Alpha + +- `v::alpha()` +- `v::alpha(string $additionalChars)` + +This is similar to `v::alnum()`, but it doesn't allow numbers. + +*** +See also: + + * [Alnum](Alnum.md) + * [Digit](Digit.md) + * [Consonant](Consonant.md) + * [Vowel](Vowel.md) diff --git a/vendor/respect/validation/docs/AlwaysInvalid.md b/vendor/respect/validation/docs/AlwaysInvalid.md new file mode 100644 index 0000000000000000000000000000000000000000..34b364deb352ea110706b05ade042e04f0ee079f --- /dev/null +++ b/vendor/respect/validation/docs/AlwaysInvalid.md @@ -0,0 +1,14 @@ +# AlwaysInvalid + +- `v::alwaysInvalid()` + +Always return false. + +```php +v::alwaysInvalid()->validate($whatever); // false +``` + +*** +See also: + + * [AlwaysValid](AlwaysValid.md) diff --git a/vendor/respect/validation/docs/AlwaysValid.md b/vendor/respect/validation/docs/AlwaysValid.md new file mode 100644 index 0000000000000000000000000000000000000000..6a020bb420dfde6d6fe61722c7a15bbccd39a0bd --- /dev/null +++ b/vendor/respect/validation/docs/AlwaysValid.md @@ -0,0 +1,14 @@ +# AlwaysValid + +- `v::alwaysValid()` + +Always returns true. + +```php +v::alwaysValid()->validate($whatever); // true +``` + +*** +See also: + + * [AlwaysInvalid](AlwaysInvalid.md) diff --git a/vendor/respect/validation/docs/ArrayType.md b/vendor/respect/validation/docs/ArrayType.md new file mode 100644 index 0000000000000000000000000000000000000000..ed72eb393ccccd6ccfdb443b8c9c94891a5d7fa9 --- /dev/null +++ b/vendor/respect/validation/docs/ArrayType.md @@ -0,0 +1,27 @@ +# ArrayType + +- `v::arrayType()` + +Validates whether the type of an input is array. + +```php +v::arrayType()->validate([]); // true +v::arrayType()->validate([1, 2, 3]); // true +v::arrayType()->validate(new ArrayObject()); // false +``` + +*** +See also: + + * [ArrayVal](ArrayVal.md) + * [BoolType](BoolType.md) + * [CallableType](CallableType.md) + * [Countable](Countable.md) + * [FloatType](FloatType.md) + * [IntType](IntType.md) + * [IterableType](IterableType.md) + * [NullType](NullType.md) + * [ObjectType](ObjectType.md) + * [ResourceType](ResourceType.md) + * [StringType](StringType.md) + * [Type](Type.md) diff --git a/vendor/respect/validation/docs/ArrayVal.md b/vendor/respect/validation/docs/ArrayVal.md new file mode 100644 index 0000000000000000000000000000000000000000..ec9eaf066a3b42a0ea67dd7351b818bf828f0cd6 --- /dev/null +++ b/vendor/respect/validation/docs/ArrayVal.md @@ -0,0 +1,22 @@ +# ArrayVal + +- `v::arrayVal()` + +Validates if the input is an array or if the input can be used as an array +(instance of `ArrayAccess`). + +```php +v::arrayVal()->validate([]); // true +v::arrayVal()->validate(new ArrayObject); // true +``` + +*** +See also: + + * [ArrayType](ArrayType.md) + * [Countable](Countable.md) + * [Each](Each.md) + * [IterableType](IterableType.md) + * [Key](Key.md) + * [KeySet](KeySet.md) + * [KeyValue](KeyValue.md) diff --git a/vendor/respect/validation/docs/Attribute.md b/vendor/respect/validation/docs/Attribute.md new file mode 100644 index 0000000000000000000000000000000000000000..e48b6b664bb2c58027149a4870bacf6468659b4a --- /dev/null +++ b/vendor/respect/validation/docs/Attribute.md @@ -0,0 +1,33 @@ +# Attribute + +- `v::attribute(string $name)` +- `v::attribute(string $name, v $validator)` +- `v::attribute(string $name, v $validator, boolean $mandatory = true)` + +Validates an object attribute. + +```php +$obj = new stdClass; +$obj->foo = 'bar'; + +v::attribute('foo')->validate($obj); // true +``` + +You can also validate the attribute itself: + +```php +v::attribute('foo', v::equals('bar'))->validate($obj); // true +``` + +Third parameter makes the attribute presence optional: + +```php +v::attribute('lorem', v::stringType(), false)->validate($obj); // true +``` + +The name of this validator is automatically set to the attribute name. + +*** +See also: + + * [Key](Key.md) diff --git a/vendor/respect/validation/docs/Bank.md b/vendor/respect/validation/docs/Bank.md new file mode 100644 index 0000000000000000000000000000000000000000..028d71985d50b871bffeb9a9889c0cd8d81b27f2 --- /dev/null +++ b/vendor/respect/validation/docs/Bank.md @@ -0,0 +1,20 @@ +# Bank + +- `v::bank(string $countryCode)` + +Validates a bank. + +```php +v::bank("de")->validate("70169464"); // true +v::bank("de")->validate("12345"); // false +``` + +These country codes are supported: + + * "de" (Germany) - You must add `"malkusch/bav": "~1.0"` to your `require` property on composer.json file. + +*** +See also: + + * [BankAccount](BankAccount.md) + * [Bic](Bic.md) diff --git a/vendor/respect/validation/docs/BankAccount.md b/vendor/respect/validation/docs/BankAccount.md new file mode 100644 index 0000000000000000000000000000000000000000..f9d319d7f82c2ba7d6d681ab7f33ed43df3abfa4 --- /dev/null +++ b/vendor/respect/validation/docs/BankAccount.md @@ -0,0 +1,20 @@ +# BankAccount + +- `v::bankAccount(string $countryCode, string $bank)` + +Validates a bank account for a given bank. + +```php +v::bankAccount("de", "70169464")->validate("1112"); // true +v::bankAccount("de", "70169464")->validate("1234"); // false +``` + +These country codes are supported: + + * "de" (Germany) - You must add `"malkusch/bav": "~1.0"` to your `require` property on composer.json file. + +*** +See also: + + * [Bank](Bank.md) + * [Bic](Bic.md) diff --git a/vendor/respect/validation/docs/Between.md b/vendor/respect/validation/docs/Between.md new file mode 100644 index 0000000000000000000000000000000000000000..5c0204afc9aed1fb1834d82d0050cb274b060152 --- /dev/null +++ b/vendor/respect/validation/docs/Between.md @@ -0,0 +1,44 @@ +# Between + +- `v::between(mixed $start, mixed $end)` +- `v::between(mixed $start, mixed $end, boolean $inclusive = true)` + +Validates ranges. Most simple example: + +```php +v::intVal()->between(10, 20)->validate(15); // true +``` + +The type as the first validator in a chain is a good practice, +since between accepts many types: + +```php +v::stringType()->between('a', 'f')->validate('c'); // true +``` + +Also very powerful with dates: + +```php +v::date()->between('2009-01-01', '2013-01-01')->validate('2010-01-01'); // true +``` + +Date ranges accept strtotime values: + +```php +v::date()->between('yesterday', 'tomorrow')->validate('now'); // true +``` + +A third parameter may be passed to validate the passed values inclusive: + +```php +v::date()->between(10, 20, true)->validate(20); // true +``` + +Message template for this validator includes `{{minValue}}` and `{{maxValue}}`. + +*** +See also: + + * [Length](Length.md) + * [Min](Min.md) + * [Max](Max.md) diff --git a/vendor/respect/validation/docs/Bic.md b/vendor/respect/validation/docs/Bic.md new file mode 100644 index 0000000000000000000000000000000000000000..82c67e8810a5caaadcd36cf798b35969935b1567 --- /dev/null +++ b/vendor/respect/validation/docs/Bic.md @@ -0,0 +1,20 @@ +# Bic + +- `v::bic(string $countryCode)` + +Validates a BIC (Bank Identifier Code) for a given country. + +```php +v::bic("de")->validate("VZVDDED1XXX"); // true +v::bic("de")->validate("VZVDDED1"); // true +``` + +Theses country codes are supported: + + * "de" (Germany) - You must add `"malkusch/bav": "~1.0"` to your `require` property on composer.json file. + +*** +See also: + + * [Bank](Bank.md) + * [BankAccount](BankAccount.md) diff --git a/vendor/respect/validation/docs/BoolType.md b/vendor/respect/validation/docs/BoolType.md new file mode 100644 index 0000000000000000000000000000000000000000..979562189815b5d858b03e316120796971063de5 --- /dev/null +++ b/vendor/respect/validation/docs/BoolType.md @@ -0,0 +1,27 @@ +# BoolType + +- `v::boolType()` + +Validates if the input is a boolean value: + +```php +v::boolType()->validate(true); // true +v::boolType()->validate(false); // true +``` + +*** +See also: + + * [ArrayType](ArrayType.md) + * [CallableType](CallableType.md) + * [FloatType](FloatType.md) + * [FloatVal](FloatVal.md) + * [IntType](IntType.md) + * [No](No.md) + * [NullType](NullType.md) + * [ObjectType](ObjectType.md) + * [ResourceType](ResourceType.md) + * [StringType](StringType.md) + * [TrueVal](TrueVal.md) + * [Type](Type.md) + * [Yes](Yes.md) diff --git a/vendor/respect/validation/docs/BoolVal.md b/vendor/respect/validation/docs/BoolVal.md new file mode 100644 index 0000000000000000000000000000000000000000..26bf9a6d0d137efdb9707647190daf17041886ba --- /dev/null +++ b/vendor/respect/validation/docs/BoolVal.md @@ -0,0 +1,31 @@ +# BoolVal + +- `v::boolVal()` + +Validates if the input results in a boolean value: + +```php +v::boolVal()->validate('on'); // true +v::boolVal()->validate('off'); // true +v::boolVal()->validate('yes'); // true +v::boolVal()->validate('no'); // true +v::boolVal()->validate(1); // true +v::boolVal()->validate(0); // true +``` + +*** +See also: + + * [BoolType](BoolType.md) + * [CallableType](CallableType.md) + * [FloatType](FloatType.md) + * [FloatVal](FloatVal.md) + * [IntType](IntType.md) + * [No](No.md) + * [NullType](NullType.md) + * [ObjectType](ObjectType.md) + * [ResourceType](ResourceType.md) + * [StringType](StringType.md) + * [TrueVal](TrueVal.md) + * [Type](Type.md) + * [Yes](Yes.md) diff --git a/vendor/respect/validation/docs/Bsn.md b/vendor/respect/validation/docs/Bsn.md new file mode 100644 index 0000000000000000000000000000000000000000..e67f55e70d22aeddfe110578ff0cd57ff05fb2e3 --- /dev/null +++ b/vendor/respect/validation/docs/Bsn.md @@ -0,0 +1,16 @@ +# Bsn + +- `v::bsn()` + +Validates a Dutch citizen service number ([BSN](https://nl.wikipedia.org/wiki/Burgerservicenummer)). + +```php +v::bsn()->validate('612890053'); // true +``` + +*** +See also: + + * [Cnh](Cnh.md) + * [Cnpj](Cnpj.md) + * [Cpf](Cpf.md) diff --git a/vendor/respect/validation/docs/CONCRETE_API.md b/vendor/respect/validation/docs/CONCRETE_API.md new file mode 100644 index 0000000000000000000000000000000000000000..735b6283d558ed32516a61b8ef6e5c87a2ee75da --- /dev/null +++ b/vendor/respect/validation/docs/CONCRETE_API.md @@ -0,0 +1,77 @@ +# Concrete API + +There are many micro-frameworks that rely on magic methods. We don't. In this +document we're gonna explore the Respect\Validation API without fluent interfaces +or magic methods. We'll use a traditional dependency injection approach. + +```php +use Respect\Validation\Validator as v; + +$usernameValidator = v::alnum()->noWhitespace()->length(1,15); +$usernameValidator->validate('alganet'); // true +``` + +If you `var_dump($usernameValidator)`, you'll see a composite of objects with +`Respect\Validation\Rules\Alnum`, `Respect\Validation\Rules\NoWhitespace` and +`Respect\Validation\Rules\Length`. There is a specific object for each rule, and +the chain only builds the structure. You can build it by yourself: + +```php +use Respect\Validation\Rules; + +$usernameValidator = new Rules\AllOf( + new Rules\Alnum(), + new Rules\NoWhitespace(), + new Rules\Length(1, 15) +); +$usernameValidator->validate('alganet'); // true +``` + +This is still a very lean API. You can use it in any dependency injection +container or test it in the way you want. Nesting is still possible: + +```php +use Respect\Validation\Rules; + +$usernameValidator = new Rules\AllOf( + new Rules\Alnum(), + new Rules\NoWhitespace(), + new Rules\Length(1, 15) +); +$userValidator = new Rules\Key('name', $usernameValidator); +$userValidator->validate(['name' => 'alganet']); // true +``` + +## How It Works? + +The Respect\Validation chain is an +[internal DSL](http://martinfowler.com/bliki/InternalDslStyle.html). +It acts in the creational realm of objects (where Abstract Factories and Builders +live), and it's only job is to make rule construction terse and fluent. + +## FAQ + +> Is `v` in `v::something` a class name? + +No! The class is `Respect\Validation\Validator`, we suggest `v` as a very short alias. + +> Is `v::something()` a static call? + +Yes. Just like the default `DateTime::createFromFormat()` or +`Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration()`. It builds +something complex and returns for you. + +> I really don't like static calls, can I avoid it? + +Yes. Just use `$validator = new Validator();` each time you want a new validator, +and continue from there. + +> Do you have a static method for each rule? + +No. We use `__callStatic()`. + +> Magic methods are slow! Why do you use them? + +They're optional. If you use the `new` interface, they won't be called. + +(still, do some benchmarks, you'd be surprised with our implementation). diff --git a/vendor/respect/validation/docs/Call.md b/vendor/respect/validation/docs/Call.md new file mode 100644 index 0000000000000000000000000000000000000000..f56b0a8e5e73b80188026d98206c916ae0fe8969 --- /dev/null +++ b/vendor/respect/validation/docs/Call.md @@ -0,0 +1,51 @@ +# Call + +- `v::call(callable $callback)` + +This is a very low level validator. It calls a function, method or closure +for the input and then validates it. Consider the following variable: + +```php +$url = 'http://www.google.com/search?q=respect.github.com' +``` + +To validate every part of this URL we could use the native `parse_url` +function to break its parts: + +```php +$parts = parse_url($url); +``` + +This function returns an array containing `scheme`, `host`, `path` and `query`. +We can validate them this way: + +```php +v::arrayVal()->key('scheme', v::startsWith('http')) + ->key('host', v::domain()) + ->key('path', v::stringType()) + ->key('query', v::notEmpty()); +``` + +Using `v::call()` you can do this in a single chain: + +```php +v::call( + 'parse_url', + v::arrayVal()->key('scheme', v::startsWith('http')) + ->key('host', v::domain()) + ->key('path', v::stringType()) + ->key('query', v::notEmpty()) +)->validate($url); +``` + +It is possible to call methods and closures as the first parameter: + +```php +v::call([$myObj, 'methodName'], v::intVal())->validate($myInput); +v::call(function($input) {}, v::intVal())->validate($myInput); +``` + +*** +See also: + + * [Callback](Callback.md) diff --git a/vendor/respect/validation/docs/CallableType.md b/vendor/respect/validation/docs/CallableType.md new file mode 100644 index 0000000000000000000000000000000000000000..7f24dca7b0dfcbb4ae4591061d75f75793d35709 --- /dev/null +++ b/vendor/respect/validation/docs/CallableType.md @@ -0,0 +1,25 @@ +# CallableType + +- `v::callableType()` + +Validates if the input is a callable value. + +```php +v::callableType()->validate(function () {}); // true +v::callableType()->validate('trim'); // true +v::callableType()->validate([new ObjectType, 'methodName']); // true +``` + +*** +See also: + + * [ArrayType](ArrayType.md) + * [BoolType](BoolType.md) + * [Callback](Callback.md) + * [FloatType](FloatType.md) + * [IntType](IntType.md) + * [NullType](NullType.md) + * [ObjectType](ObjectType.md) + * [ResourceType](ResourceType.md) + * [StringType](StringType.md) + * [Type](Type.md) diff --git a/vendor/respect/validation/docs/Callback.md b/vendor/respect/validation/docs/Callback.md new file mode 100644 index 0000000000000000000000000000000000000000..d5ec6b86c62bea13d0b8b1e999129775b67e20e2 --- /dev/null +++ b/vendor/respect/validation/docs/Callback.md @@ -0,0 +1,21 @@ +# Callback + +- `v::callback(callable $callback)` + +This is a wildcard validator, it uses a function name, method or closure +to validate something: + +```php +v::callback('is_int')->validate(10); // true +``` + +(Please note that this is a sample, the `v::intVal()` validator is much better). + +As in `v::call()`, you can pass a method or closure to it. + +*** +See also: + + * [Call](Call.md) + * [CallableType](CallableType.md) + * [FilterVar](FilterVar.md) diff --git a/vendor/respect/validation/docs/Charset.md b/vendor/respect/validation/docs/Charset.md new file mode 100644 index 0000000000000000000000000000000000000000..43d889bdc687c4221eb82510f6fada2b39db8048 --- /dev/null +++ b/vendor/respect/validation/docs/Charset.md @@ -0,0 +1,19 @@ +# Charset + +- `v::charset(mixed $charset)` + +Validates if a string is in a specific charset. + +```php +v::charset('ASCII')->validate('açúcar'); // false +v::charset('ASCII')->validate('sugar'); //true +v::charset(['ISO-8859-1', 'EUC-JP'])->validate('日本国'); // true +``` + +The array format is a logic OR, not AND. + +*** +See also: + + * [Alnum](Alnum.md) + * [Alpha](Alpha.md) diff --git a/vendor/respect/validation/docs/Cnh.md b/vendor/respect/validation/docs/Cnh.md new file mode 100644 index 0000000000000000000000000000000000000000..6815929a3910d537c8e5131828dd68fd176d9d29 --- /dev/null +++ b/vendor/respect/validation/docs/Cnh.md @@ -0,0 +1,15 @@ +# Cnh + +- `v::cnh()` + +Validates a Brazillian driver's license. + +```php +v::cnh()->validate('02650306461'); // true +``` + +*** +See also: + + * [Cnpj](Cnpj.md) + * [Cpf](Cpf.md) diff --git a/vendor/respect/validation/docs/Cnpj.md b/vendor/respect/validation/docs/Cnpj.md new file mode 100644 index 0000000000000000000000000000000000000000..846d391762c2523cc527c61829c227ea3909f502 --- /dev/null +++ b/vendor/respect/validation/docs/Cnpj.md @@ -0,0 +1,12 @@ +# Cnpj + +- `v::cnpj()` + +Validates the Brazillian CNPJ number. Ignores non-digit chars, so +use `->digit()` if needed. + +*** +See also: + + * [Cpf](Cpf.md) + * [Cnh](Cnh.md) diff --git a/vendor/respect/validation/docs/Cntrl.md b/vendor/respect/validation/docs/Cntrl.md new file mode 100644 index 0000000000000000000000000000000000000000..7a6552aa8e0529dcbc08cd4017f9bd65434a1dc2 --- /dev/null +++ b/vendor/respect/validation/docs/Cntrl.md @@ -0,0 +1,17 @@ +# Cntrl + +- `v::cntrl()` +- `v::cntrl(string $additionalChars)` + +This is similar to `v::alnum()`, but only accepts control characters: + +```php +v::cntrl()->validate("\n\r\t"); // true +``` + +*** +See also: + + * [Alnum](Alnum.md) + * [Prnt](Prnt.md) + * [Space](Space.md) diff --git a/vendor/respect/validation/docs/Consonant.md b/vendor/respect/validation/docs/Consonant.md new file mode 100644 index 0000000000000000000000000000000000000000..fac1fe53319d7ba5afe0f39aef44f4116a1b6c71 --- /dev/null +++ b/vendor/respect/validation/docs/Consonant.md @@ -0,0 +1,18 @@ +# Consonant + +- `v::consonant()` +- `v::consonant(string $additionalChars)` + +Similar to `v::alnum()`. Validates strings that contain only consonants: + +```php +v::consonant()->validate('xkcd'); // true +``` + +*** +See also: + + * [Alnum](Alnum.md) + * [Digit](Digit.md) + * [Alpha](Alpha.md) + * [Vowel](Vowel.md) diff --git a/vendor/respect/validation/docs/Contains.md b/vendor/respect/validation/docs/Contains.md new file mode 100644 index 0000000000000000000000000000000000000000..6036494fe43cbbb06015a2e7edcc9fd4871d6d00 --- /dev/null +++ b/vendor/respect/validation/docs/Contains.md @@ -0,0 +1,28 @@ +# Contains + +- `v::contains(mixed $value)` +- `v::contains(mixed $value, boolean $identical = false)` + +For strings: + +```php +v::contains('ipsum')->validate('lorem ipsum'); // true +``` + +For arrays: + +```php +v::contains('ipsum')->validate(['ipsum', 'lorem']); // true +``` + +A second parameter may be passed for identical comparison instead +of equal comparison. + +Message template for this validator includes `{{containsValue}}`. + +*** +See also: + + * [StartsWith](StartsWith.md) + * [EndsWith](EndsWith.md) + * [In](In.md) diff --git a/vendor/respect/validation/docs/Countable.md b/vendor/respect/validation/docs/Countable.md new file mode 100644 index 0000000000000000000000000000000000000000..0353de4d7a748ed9f490149b8f07d1343f084036 --- /dev/null +++ b/vendor/respect/validation/docs/Countable.md @@ -0,0 +1,19 @@ +# Countable + +- `v::countable()` + +Validates if the input is countable, in other words, if you're allowed to use +[count()](http://php.net/count) function on it. + +```php +v::countable()->validate([]); // true +v::countable()->validate(new ArrayObject()); // true +v::countable()->validate('string'); // false +``` + +*** +See also: + + * [ArrayVal](ArrayVal.md) + * [Instance](Instance.md) + * [IterableType](IterableType.md) diff --git a/vendor/respect/validation/docs/CountryCode.md b/vendor/respect/validation/docs/CountryCode.md new file mode 100644 index 0000000000000000000000000000000000000000..469313db2dcb66a7306d53510b54c136afa758a8 --- /dev/null +++ b/vendor/respect/validation/docs/CountryCode.md @@ -0,0 +1,14 @@ +# CountryCode + +- `v::countryCode()` + +Validates an ISO country code like US or BR. + +```php +v::countryCode()->validate('BR'); // true +``` + +*** +See also: + + * [Tld](Tld.md) diff --git a/vendor/respect/validation/docs/Cpf.md b/vendor/respect/validation/docs/Cpf.md new file mode 100644 index 0000000000000000000000000000000000000000..0fc3a717af13febc2d111218e534d9f61271e037 --- /dev/null +++ b/vendor/respect/validation/docs/Cpf.md @@ -0,0 +1,28 @@ +# Cpf + +- `v::cpf()` + +Validates a Brazillian CPF number. + +```php +v::cpf()->validate('44455566820'); // true +``` + +It ignores any non-digit char: + +```php +v::cpf()->validate('444.555.668-20'); // true +``` + +If you need to validate digits only, add `->digit()` to +the chain: + +```php +v::digit()->cpf()->validate('44455566820'); // true +``` + +*** +See also: + + * [Cnpj](Cnpj.md) + * [Cnh](Cnh.md) diff --git a/vendor/respect/validation/docs/CreditCard.md b/vendor/respect/validation/docs/CreditCard.md new file mode 100644 index 0000000000000000000000000000000000000000..aa9783a23304444b5871f7965eec499ec9de7408 --- /dev/null +++ b/vendor/respect/validation/docs/CreditCard.md @@ -0,0 +1,39 @@ +# CreditCard + +- `v::creditCard()` +- `v::creditCard(string $brand)` + +Validates a credit card number. + +```php +v::creditCard()->validate('5376 7473 9720 8720'); // true + +v::creditCard('American Express')->validate('340316193809364'); // true +v::creditCard('Diners Club')->validate('30351042633884'); // true +v::creditCard('Discover')->validate('6011000990139424'); // true +v::creditCard('JCB')->validate('3566002020360505'); // true +v::creditCard('Master')->validate('5376747397208720'); // true +v::creditCard('Visa')->validate('4024007153361885'); // true +``` + +The current supported brands are: + +- American Express +- Diners Club +- Discover +- JCB +- MasterCard +- Visa + +It ignores any non-digit chars, so use `->digit()` when appropriate. + +```php +v::digit()->creditCard()->validate('5376747397208720'); // true +``` + +*** +See also: + + * [Bank](Bank.md) + * [BankAccount](BankAccount.md) + * [Bic](Bic.md) diff --git a/vendor/respect/validation/docs/CurrencyCode.md b/vendor/respect/validation/docs/CurrencyCode.md new file mode 100644 index 0000000000000000000000000000000000000000..95c13fae47325b977071590ec7304b7afdd5b3b6 --- /dev/null +++ b/vendor/respect/validation/docs/CurrencyCode.md @@ -0,0 +1,15 @@ +# CurrencyCode + +- `v::currencyCode()` + +Validates an [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) currency code like GBP or EUR. + +```php +v::currencyCode()->validate('GBP'); // true +``` + +*** +See also: + + * [CountryCode](CountryCode.md) + * [SubdivisionCode](SubdivisionCode.md) diff --git a/vendor/respect/validation/docs/Date.md b/vendor/respect/validation/docs/Date.md new file mode 100644 index 0000000000000000000000000000000000000000..4afb9ecbd56a4b49614375508f38bc18cb1b5170 --- /dev/null +++ b/vendor/respect/validation/docs/Date.md @@ -0,0 +1,40 @@ +# Date + +- `v::date()` +- `v::date(string $format)` + +Validates if input is a date: + +```php +v::date()->validate('2009-01-01'); // true +``` + +Also accepts strtotime values: + +```php +v::date()->validate('now'); // true +``` + +And DateTime instances: + +```php +v::date()->validate(new DateTime); // true +``` + +You can pass a format when validating strings: + +```php +v::date('Y-m-d')->validate('01-01-2009'); // false +``` + +Format has no effect when validating DateTime instances. + +Message template for this validator includes `{{format}}`. + +*** +See also: + + * [Between](Between.md) + * [MinimumAge](MinimumAge.md) + * [LeapDate](LeapDate.md) + * [LeapYear](LeapYear.md) diff --git a/vendor/respect/validation/docs/Digit.md b/vendor/respect/validation/docs/Digit.md new file mode 100644 index 0000000000000000000000000000000000000000..c4638483f4d6734817263c9891263a1ea2d41deb --- /dev/null +++ b/vendor/respect/validation/docs/Digit.md @@ -0,0 +1,13 @@ +# Digit + +- `v::digit()` + +This is similar to `v::alnum()`, but it doesn't allow a-Z. + +*** +See also: + + * [Alnum](Alnum.md) + * [Alpha](Alpha.md) + * [Vowel](Vowel.md) + * [Consonant](Consonant.md) diff --git a/vendor/respect/validation/docs/Directory.md b/vendor/respect/validation/docs/Directory.md new file mode 100644 index 0000000000000000000000000000000000000000..7d49c63b726e0bec8c8d615092d3ed7ce275755c --- /dev/null +++ b/vendor/respect/validation/docs/Directory.md @@ -0,0 +1,30 @@ +# Directory + +- `v::directory()` + +Validates directories. + +```php +v::directory()->validate(__DIR__); // true +v::directory()->validate(__FILE__); // false +``` + +This validator will consider SplFileInfo instances, so you can do something like: + +```php +v::directory()->validate(new \SplFileInfo($directory)); +``` + +*** +See also: + + * [Executable](Executable.md) + * [Exists](Exists.md) + * [Extension](Extension.md) + * [File](File.md) + * [Mimetype](Mimetype.md) + * [Readable](Readable.md) + * [Size](Size.md) + * [SymbolicLink](SymbolicLink.md) + * [Uploaded](Uploaded.md) + * [Writable](Writable.md) diff --git a/vendor/respect/validation/docs/Domain.md b/vendor/respect/validation/docs/Domain.md new file mode 100644 index 0000000000000000000000000000000000000000..ac5d76a7b77d89952de912a75c614fa3479f99aa --- /dev/null +++ b/vendor/respect/validation/docs/Domain.md @@ -0,0 +1,40 @@ +# Domain + +- `v::domain()` +- `v::domain(boolean $tldCheck = true)` + +Validates domain names. + +```php +v::domain()->validate('google.com'); +``` + +You can skip *top level domain* (TLD) checks to validate internal +domain names: + +```php +v::domain(false)->validate('dev.machine.local'); +``` + +This is a composite validator, it validates several rules +internally: + + * If input is an IP address, it fails. + * If input contains whitespace, it fails. + * If input does not contain any dots, it fails. + * If input has less than two parts, it fails. + * Input must end with a top-level-domain to pass (if not skipped). + * Each part must be alphanumeric and not start with an hyphen. + * [PunnyCode][] is accepted for [Internationalizing Domain Names in Applications][IDNA]. + +Messages for this validator will reflect rules above. + +*** +See also: + + * [Ip](Ip.md) + * [MacAddress](MacAddress.md) + * [Tld](Tld.md) + +[PunnyCode]: http://en.wikipedia.org/wiki/Punycode "Wikipedia: Punnycode" +[IDNA]: http://en.wikipedia.org/wiki/Internationalized_domain_name#Internationalizing_Domain_Names_in_Applications "Wikipedia: Internationalized domain name" diff --git a/vendor/respect/validation/docs/Each.md b/vendor/respect/validation/docs/Each.md new file mode 100644 index 0000000000000000000000000000000000000000..ecc1c666359e921a9a33cdebe1a2c3ee5a6c4a92 --- /dev/null +++ b/vendor/respect/validation/docs/Each.md @@ -0,0 +1,27 @@ +# Each + +- `v::each(v $validatorForValue)` +- `v::each(null, v $validatorForKey)` +- `v::each(v $validatorForValue, v $validatorForKey)` + +Iterates over an array or Iterator and validates the value or key +of each entry: + +```php +$releaseDates = [ + 'validation' => '2010-01-01', + 'template' => '2011-01-01', + 'relational' => '2011-02-05', +]; + +v::arrayVal()->each(v::date())->validate($releaseDates); // true +v::arrayVal()->each(v::date(), v::stringType()->lowercase())->validate($releaseDates); // true +``` + +Using `arrayVal()` before `each()` is a best practice. + +*** +See also: + + * [Key](Key.md) + * [ArrayVal](ArrayVal.md) diff --git a/vendor/respect/validation/docs/Email.md b/vendor/respect/validation/docs/Email.md new file mode 100644 index 0000000000000000000000000000000000000000..64a4d7cf3c4896dd1786e20c99b74bd89adbf184 --- /dev/null +++ b/vendor/respect/validation/docs/Email.md @@ -0,0 +1,16 @@ +# Email + +- `v::email()` + +Validates an email address. + +```php +v::email()->validate('alexandre@gaigalas.net'); // true +``` + +*** +See also: + + * [Phone](Phone.md) + * [Url](Url.md) + * [VideoUrl](VideoUrl.md) diff --git a/vendor/respect/validation/docs/EndsWith.md b/vendor/respect/validation/docs/EndsWith.md new file mode 100644 index 0000000000000000000000000000000000000000..99ec5b215a194760e80132ea1083bd791b903b0e --- /dev/null +++ b/vendor/respect/validation/docs/EndsWith.md @@ -0,0 +1,31 @@ +# EndsWith + +- `v::endsWith(mixed $value)` +- `v::endsWith(mixed $value, boolean $identical = false)` + +This validator is similar to `v::contains()`, but validates +only if the value is at the end of the input. + +For strings: + +```php +v::endsWith('ipsum')->validate('lorem ipsum'); // true +``` + +For arrays: + +```php +v::endsWith('ipsum')->validate(['lorem', 'ipsum']); // true +``` + +A second parameter may be passed for identical comparison instead +of equal comparison. + +Message template for this validator includes `{{endValue}}`. + +*** +See also: + + * [StartsWith](StartsWith.md) + * [Contains](Contains.md) + * [In](In.md) diff --git a/vendor/respect/validation/docs/Equals.md b/vendor/respect/validation/docs/Equals.md new file mode 100644 index 0000000000000000000000000000000000000000..e28f783dfcfd4128c7eecba94307e4ae53aeff1c --- /dev/null +++ b/vendor/respect/validation/docs/Equals.md @@ -0,0 +1,17 @@ +# Equals + +- `v::equals(mixed $value)` + +Validates if the input is equal to some value. + +```php +v::equals('alganet')->validate('alganet'); // true +``` + +Message template for this validator includes `{{compareTo}}`. + +*** +See also: + + * [Contains](Contains.md) + * [Identical](Identical.md) diff --git a/vendor/respect/validation/docs/Even.md b/vendor/respect/validation/docs/Even.md new file mode 100644 index 0000000000000000000000000000000000000000..da52597b85c0793e85862dd42611df0f4da6a7cd --- /dev/null +++ b/vendor/respect/validation/docs/Even.md @@ -0,0 +1,17 @@ +# Even + +- `v::even()` + +Validates an even number. + +```php +v::intVal()->even()->validate(2); // true +``` + +Using `int()` before `even()` is a best practice. + +*** +See also: + + * [Odd](Odd.md) + * [Multiple](Multiple.md) diff --git a/vendor/respect/validation/docs/Executable.md b/vendor/respect/validation/docs/Executable.md new file mode 100644 index 0000000000000000000000000000000000000000..7c1e1303dc350d4034dc1f8c6454e835943187e2 --- /dev/null +++ b/vendor/respect/validation/docs/Executable.md @@ -0,0 +1,23 @@ +# Executable + +- `v::executable()` + +Validates if a file is an executable. + +```php +v::email()->executable('script.sh'); // true +``` + +*** +See also: + + * [Directory](Directory.md) + * [Exists](Exists.md) + * [Extension](Extension.md) + * [File](File.md) + * [Mimetype](Mimetype.md) + * [Readable](Readable.md) + * [Size](Size.md) + * [SymbolicLink](SymbolicLink.md) + * [Uploaded](Uploaded.md) + * [Writable](Writable.md) diff --git a/vendor/respect/validation/docs/Exists.md b/vendor/respect/validation/docs/Exists.md new file mode 100644 index 0000000000000000000000000000000000000000..681c50743b70cd7b36548571ca47ae2d51cc4075 --- /dev/null +++ b/vendor/respect/validation/docs/Exists.md @@ -0,0 +1,30 @@ +# Exists + +- `v::exists()` + +Validates files or directories. + +```php +v::exists()->validate(__FILE__); // true +v::exists()->validate(__DIR__); // true +``` + +This validator will consider SplFileInfo instances, so you can do something like: + +```php +v::exists()->validate(new \SplFileInfo($file)); +``` + +*** +See also: + + * [Directory](Directory.md) + * [Executable](Executable.md) + * [Extension](Extension.md) + * [File](File.md) + * [Mimetype](Mimetype.md) + * [Readable](Readable.md) + * [Size](Size.md) + * [SymbolicLink](SymbolicLink.md) + * [Uploaded](Uploaded.md) + * [Writable](Writable.md) diff --git a/vendor/respect/validation/docs/Extension.md b/vendor/respect/validation/docs/Extension.md new file mode 100644 index 0000000000000000000000000000000000000000..4abc0d5ba51f701827dd166daac098ec79c65e3f --- /dev/null +++ b/vendor/respect/validation/docs/Extension.md @@ -0,0 +1,25 @@ +# Extension + +- `v::extension(string $extension)` + +Validates if the file extension matches the expected one: + +```php +v::extension('png')->validate('image.png'); // true +``` + +This rule is case-sensitive. + +*** +See also: + + * [Directory](Directory.md) + * [Executable](Executable.md) + * [Exists](Exists.md) + * [File](File.md) + * [Mimetype](Mimetype.md) + * [Readable](Readable.md) + * [Size](Size.md) + * [SymbolicLink](SymbolicLink.md) + * [Uploaded](Uploaded.md) + * [Writable](Writable.md) diff --git a/vendor/respect/validation/docs/Factor.md b/vendor/respect/validation/docs/Factor.md new file mode 100644 index 0000000000000000000000000000000000000000..1e04276432d1bc8583fa89da6c004d43abdb2568 --- /dev/null +++ b/vendor/respect/validation/docs/Factor.md @@ -0,0 +1,19 @@ +# Factor + +- `v::factor(int $dividend)` + +Validates if the input is a factor of the defined dividend. + +```php +v::factor(0)->validate(5); // true +v::factor(4)->validate(2); // true +v::factor(4)->validate(3); // false +``` + +*** +See also: + + * [Digit](Digit.md) + * [Finite](Finite.md) + * [Infinite](Infinite.md) + * [Numeric](Numeric.md) diff --git a/vendor/respect/validation/docs/FalseVal.md b/vendor/respect/validation/docs/FalseVal.md new file mode 100644 index 0000000000000000000000000000000000000000..6ca060d33ca40dd587efb0e4583b7606b1000f03 --- /dev/null +++ b/vendor/respect/validation/docs/FalseVal.md @@ -0,0 +1,21 @@ +# FalseVal + +- `v::falseVal()` + +Validates if a value is considered as `false`. + +```php +v::falseVal()->validate(false); // true +v::falseVal()->validate(0); // true +v::falseVal()->validate('0'); // true +v::falseVal()->validate('false'); // true +v::falseVal()->validate('off'); // true +v::falseVal()->validate('no'); // true +v::falseVal()->validate('0.5'); // false +v::falseVal()->validate('2'); // false +``` + +*** +See also: + + * [TrueVal](TrueVal.md) diff --git a/vendor/respect/validation/docs/Fibonacci.md b/vendor/respect/validation/docs/Fibonacci.md new file mode 100644 index 0000000000000000000000000000000000000000..fe8c5235b775e98fda3c81e43f1736e7e18dc30f --- /dev/null +++ b/vendor/respect/validation/docs/Fibonacci.md @@ -0,0 +1,17 @@ +# Fibonacci + + - `v::fibonacci()` + +Validates whether the input follows the Fibonacci integer sequence. + +```php +v::fibonacci()->validate(1); // true +v::fibonacci()->validate('34'); // true +v::fibonacci()->validate(6); // false +``` + +*** +See also: + + * [PrimeNumber](PrimeNumber.md) + * [PerfectSquare](PerfectSquare.md) \ No newline at end of file diff --git a/vendor/respect/validation/docs/File.md b/vendor/respect/validation/docs/File.md new file mode 100644 index 0000000000000000000000000000000000000000..8454d0258d2d1922fc5105c71f1e6ea3a3ab28fb --- /dev/null +++ b/vendor/respect/validation/docs/File.md @@ -0,0 +1,30 @@ +# File + +- `v::file()` + +Validates files. + +```php +v::file()->validate(__FILE__); // true +v::file()->validate(__DIR__); // false +``` + +This validator will consider SplFileInfo instances, so you can do something like: + +```php +v::file()->validate(new \SplFileInfo($file)); +``` + +*** +See also: + + * [Directory](Directory.md) + * [Executable](Executable.md) + * [Exists](Exists.md) + * [Extension](Extension.md) + * [Mimetype](Mimetype.md) + * [Readable](Readable.md) + * [Size](Size.md) + * [SymbolicLink](SymbolicLink.md) + * [Uploaded](Uploaded.md) + * [Writable](Writable.md) diff --git a/vendor/respect/validation/docs/FilterVar.md b/vendor/respect/validation/docs/FilterVar.md new file mode 100644 index 0000000000000000000000000000000000000000..a13d4fa091ffab6afb9a9df90b13d9adba374d64 --- /dev/null +++ b/vendor/respect/validation/docs/FilterVar.md @@ -0,0 +1,18 @@ +# FilterVar + +- `v::filterVar(int $filter)` +- `v::filterVar(int $filter, mixed $options)` + +A wrapper for PHP's [filter_var()](http://php.net/filter_var) function. + +```php +v::filterVar(FILTER_VALIDATE_EMAIL)->validate('bob@example.com'); // true +v::filterVar(FILTER_VALIDATE_URL)->validate('http://example.com'); // true +v::filterVar(FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED)->validate('http://example.com'); // false +v::filterVar(FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED)->validate('http://example.com/path'); // true +``` + +*** +See also: + + * [Callback](Callback.md) diff --git a/vendor/respect/validation/docs/Finite.md b/vendor/respect/validation/docs/Finite.md new file mode 100644 index 0000000000000000000000000000000000000000..42ef9f30d6d833305e0140c368d87694dd9b887c --- /dev/null +++ b/vendor/respect/validation/docs/Finite.md @@ -0,0 +1,18 @@ +# Finite + +- `v::finite()` + +Validates if the input is a finite number. + +```php +v::finite()->validate('10'); // true +v::finite()->validate(10); // true +``` + +*** +See also: + + * [Digit](Digit.md) + * [Infinite](Infinite.md) + * [IntVal](IntVal.md) + * [Numeric](Numeric.md) diff --git a/vendor/respect/validation/docs/FloatType.md b/vendor/respect/validation/docs/FloatType.md new file mode 100644 index 0000000000000000000000000000000000000000..87efee83511a971477a7ec4ca2f84fc4ab81dbcc --- /dev/null +++ b/vendor/respect/validation/docs/FloatType.md @@ -0,0 +1,25 @@ +# FloatType + +- `v::floatType()` + +Validates whether the type of a value is float. + +```php +v::floatType()->validate(1.5); // true +v::floatType()->validate('1.5'); // false +v::floatType()->validate(0e5); // true +``` + +*** +See also: + + * [BoolType](BoolType.md) + * [CallableType](CallableType.md) + * [FloatVal](FloatVal.md) + * [IntType](IntType.md) + * [IntVal](IntVal.md) + * [NullType](NullType.md) + * [ObjectType](ObjectType.md) + * [ResourceType](ResourceType.md) + * [StringType](StringType.md) + * [Type](Type.md) diff --git a/vendor/respect/validation/docs/FloatVal.md b/vendor/respect/validation/docs/FloatVal.md new file mode 100644 index 0000000000000000000000000000000000000000..f73c2fc073094600820a00cba34c34ec6c378bd3 --- /dev/null +++ b/vendor/respect/validation/docs/FloatVal.md @@ -0,0 +1,17 @@ +# FloatVal + +- `v::floatVal()` + +Validates a floating point number. + +```php +v::floatVal()->validate(1.5); // true +v::floatVal()->validate('1e5'); // true +``` + +*** +See also: + + * [FloatType](FloatType.md) + * [IntType](IntType.md) + * [IntVal](IntVal.md) diff --git a/vendor/respect/validation/docs/Graph.md b/vendor/respect/validation/docs/Graph.md new file mode 100644 index 0000000000000000000000000000000000000000..2c7503ad785414e4459968261f12b844a93db206 --- /dev/null +++ b/vendor/respect/validation/docs/Graph.md @@ -0,0 +1,15 @@ +# Graph + +- `v::graph()` +- `v::graph(string $additionalChars)` + +Validates all characters that are graphically represented. + +```php +v::graph()->validate('LKM@#$%4;'); // true +``` + +*** +See also: + + * [Prnt](Prnt.md) diff --git a/vendor/respect/validation/docs/HexRgbColor.md b/vendor/respect/validation/docs/HexRgbColor.md new file mode 100644 index 0000000000000000000000000000000000000000..3e4a1e98d9e538d3f90f4aa2f25ab88e85bfaf8e --- /dev/null +++ b/vendor/respect/validation/docs/HexRgbColor.md @@ -0,0 +1,16 @@ +# HexRgbColor + +- `v::hexRgbColor()` + +Validates a hex RGB color + +```php +v::hexRgbColor()->validate('#FFFAAA'); // true +v::hexRgbColor()->validate('123123'); // true +v::hexRgbColor()->validate('FCD'); // true +``` + +*** +See also: + + * [Vxdigit](Vxdigit.md) diff --git a/vendor/respect/validation/docs/INSTALL.md b/vendor/respect/validation/docs/INSTALL.md new file mode 100644 index 0000000000000000000000000000000000000000..9cf5efb04d0ebe5d4200890e6af78c7aa90f829d --- /dev/null +++ b/vendor/respect/validation/docs/INSTALL.md @@ -0,0 +1,18 @@ +# Installation + +Package is available on [Packagist](http://packagist.org/packages/respect/validation), +you can install it using [Composer](http://getcomposer.org). + +```shell +composer require respect/validation +``` + +[PHP](https://php.net) 5.4+ or [HHVM](http://hhvm.com) 3.3+ are required. + +*** +See also: + +- [Contributing](../CONTRIBUTING.md) +- [Feature Guide](README.md) +- [License](../LICENSE.md) +- [Validators](VALIDATORS.md) diff --git a/vendor/respect/validation/docs/Identical.md b/vendor/respect/validation/docs/Identical.md new file mode 100644 index 0000000000000000000000000000000000000000..0a280678abbaa25cb0749d159cf47b5b117d7793 --- /dev/null +++ b/vendor/respect/validation/docs/Identical.md @@ -0,0 +1,18 @@ +# Identical + +- `v::identical(mixed $value)` + +Validates if the input is identical to some value. + +```php +v::identical(42)->validate(42); // true +v::identical(42)->validate('42'); // false +``` + +Message template for this validator includes `{{compareTo}}`. + +*** +See also: + + * [Contains](Contains.md) + * [Equals](Equals.md) diff --git a/vendor/respect/validation/docs/IdentityCard.md b/vendor/respect/validation/docs/IdentityCard.md new file mode 100644 index 0000000000000000000000000000000000000000..052eca1a28fd616d8538eae8d56d50cc2042a729 --- /dev/null +++ b/vendor/respect/validation/docs/IdentityCard.md @@ -0,0 +1,21 @@ +# IdentityCard + +- `v::identityCard(string $countryCode)` + +Validates Identity Card numbers according to the defined country. + +```php +v::identityCard('PL')->validate('AYW036733'); // true +v::identityCard('PL')->validate('APH505567'); // true +v::identityCard('PL')->validate('APH 505567'); // false +v::identityCard('PL')->validate('AYW036731'); // false +``` + +For now this rule only accepts Polish Identity Card numbers (Dowód Osobisty). + +*** +See also: + + * [Bank](Bank.md) + * [Pesel](Pesel.md) + * [SubdivisionCode](SubdivisionCode.md) diff --git a/vendor/respect/validation/docs/Image.md b/vendor/respect/validation/docs/Image.md new file mode 100644 index 0000000000000000000000000000000000000000..5a84facf66d6e3f41314691b25d1fee0db21c383 --- /dev/null +++ b/vendor/respect/validation/docs/Image.md @@ -0,0 +1,32 @@ +# Image + +- `v::image()` +- `v::image(finfo $fileInfo)` + +Validates if the file is a valid image by checking its MIME type. + +```php +v::image()->validate('image.gif'); // true +v::image()->validate('image.jpg'); // true +v::image()->validate('image.png'); // true +``` + +All the validations above must return `false` if the input is not a valid file +or of the MIME doesn't match with the file extension. + +This rule relies on [fileinfo](http://php.net/fileinfo) PHP extension. + +*** +See also: + + * [Directory](Directory.md) + * [Executable](Executable.md) + * [Exists](Exists.md) + * [Extension](Extension.md) + * [File](File.md) + * [Mimetype](Mimetype.md) + * [Readable](Readable.md) + * [Size](Size.md) + * [SymbolicLink](SymbolicLink.md) + * [Uploaded](Uploaded.md) + * [Writable](Writable.md) diff --git a/vendor/respect/validation/docs/Imei.md b/vendor/respect/validation/docs/Imei.md new file mode 100644 index 0000000000000000000000000000000000000000..96ed8e0a2a9fd0175165d0c7dd96bdee6ae8d76b --- /dev/null +++ b/vendor/respect/validation/docs/Imei.md @@ -0,0 +1,20 @@ +# Imei + +- `v::imei()` + +Validates is the input is a valid [IMEI][]. + +```php +v::imei()->validate('35-209900-176148-1'); // true +v::imei()->validate('490154203237518'); // true +``` + +*** +See also: + + * [Bsn](Bsn.md) + * [Cnh](Cnh.md) + * [Cnpj](Cnpj.md) + * [Cpf](Cpf.md) + +[IMEI]: https://en.wikipedia.org/wiki/International_Mobile_Station_Equipment_Identity "International Mobile Station Equipment Identity" diff --git a/vendor/respect/validation/docs/In.md b/vendor/respect/validation/docs/In.md new file mode 100644 index 0000000000000000000000000000000000000000..a8aa698141b844e55c90845c8acdefca31f05ba1 --- /dev/null +++ b/vendor/respect/validation/docs/In.md @@ -0,0 +1,30 @@ +# In + +- `v::in(mixed $haystack)` +- `v::in(mixed $haystack, boolean $identical = false)` + +Validates if the input is contained in a specific haystack. + +For strings: + +```php +v::in('lorem ipsum')->validate('ipsum'); // true +``` + +For arrays: + +```php +v::in(['lorem', 'ipsum'])->validate('lorem'); // true +``` + +A second parameter may be passed for identical comparison instead +of equal comparison. + +Message template for this validator includes `{{haystack}}`. + +*** +See also: + + * [StartsWith](StartsWith.md) + * [EndsWith](EndsWith.md) + * [Contains](Contains.md) diff --git a/vendor/respect/validation/docs/Infinite.md b/vendor/respect/validation/docs/Infinite.md new file mode 100644 index 0000000000000000000000000000000000000000..d29c666a4f11afd0ae697fca58c4c837705a72b1 --- /dev/null +++ b/vendor/respect/validation/docs/Infinite.md @@ -0,0 +1,17 @@ +# Infinite + +- `v::infinite()` + +Validates if the input is an infinite number. + +```php +v::infinite()->validate(INF); // true +``` + +*** +See also: + + * [Digit](Digit.md) + * [Finite](Finite.md) + * [IntVal](IntVal.md) + * [Numeric](Numeric.md) diff --git a/vendor/respect/validation/docs/Instance.md b/vendor/respect/validation/docs/Instance.md new file mode 100644 index 0000000000000000000000000000000000000000..bbb45dd0c888a24183525f1d9e539c59bbd3c8cf --- /dev/null +++ b/vendor/respect/validation/docs/Instance.md @@ -0,0 +1,17 @@ +# Instance + +- `v::instance(string $instanceName)` + +Validates if the input is an instance of the given class or interface. + +```php +v::instance('DateTime')->validate(new DateTime); // true +v::instance('Traversable')->validate(new ArrayObject); // true +``` + +Message template for this validator includes `{{instanceName}}`. + +*** +See also: + + * [ObjectType](ObjectType.md) diff --git a/vendor/respect/validation/docs/IntType.md b/vendor/respect/validation/docs/IntType.md new file mode 100644 index 0000000000000000000000000000000000000000..d4313657fccba3df7b4c9c9a4fd95744a6d10950 --- /dev/null +++ b/vendor/respect/validation/docs/IntType.md @@ -0,0 +1,27 @@ +# IntType + +- `v::intType()` + +Validates whether the type of a value is integer. + +```php +v::intType()->validate(42); // true +v::intType()->validate('10'); // false +``` + +*** +See also: + + * [BoolType](BoolType.md) + * [CallableType](CallableType.md) + * [Digit](Digit.md) + * [Finite](Finite.md) + * [FloatType](FloatType.md) + * [Infinite](Infinite.md) + * [IntVal](IntVal.md) + * [NullType](NullType.md) + * [Numeric](Numeric.md) + * [ObjectType](ObjectType.md) + * [ResourceType](ResourceType.md) + * [StringType](StringType.md) + * [Type](Type.md) diff --git a/vendor/respect/validation/docs/IntVal.md b/vendor/respect/validation/docs/IntVal.md new file mode 100644 index 0000000000000000000000000000000000000000..18a04046192e8e3e6642d635d394946f16ec078f --- /dev/null +++ b/vendor/respect/validation/docs/IntVal.md @@ -0,0 +1,18 @@ +# IntVal + +- `v::intVal()` + +Validates if the input is an integer. + +```php +v::intVal()->validate('10'); // true +v::intVal()->validate(10); // true +``` + +*** +See also: + + * [Digit](Digit.md) + * [Finite](Finite.md) + * [Infinite](Infinite.md) + * [Numeric](Numeric.md) diff --git a/vendor/respect/validation/docs/Ip.md b/vendor/respect/validation/docs/Ip.md new file mode 100644 index 0000000000000000000000000000000000000000..927dbc7ef618932495bd9e39f38e735675d27d43 --- /dev/null +++ b/vendor/respect/validation/docs/Ip.md @@ -0,0 +1,24 @@ +# Ip + +- `v::ip()` +- `v::ip(mixed $options)` + +Validates IP Addresses. This validator uses the native filter_var() +PHP function. + +```php +v::ip()->validate('192.168.0.1'); +``` + +You can pass a parameter with filter_var flags for IP. + +```php +v::ip(FILTER_FLAG_NO_PRIV_RANGE)->validate('127.0.0.1'); // false +``` + +*** +See also: + + * [Domain](Domain.md) + * [MacAddress](MacAddress.md) + * [Tld](Tld.md) diff --git a/vendor/respect/validation/docs/Iterable.md b/vendor/respect/validation/docs/Iterable.md new file mode 100644 index 0000000000000000000000000000000000000000..b64abe28899857ddec73717780d5e5acc4a4560c --- /dev/null +++ b/vendor/respect/validation/docs/Iterable.md @@ -0,0 +1,5 @@ +# Iterable + +- `v::iterable()` + +**Deprecated**: Use [IterableType](IterableType.md) instead. diff --git a/vendor/respect/validation/docs/IterableType.md b/vendor/respect/validation/docs/IterableType.md new file mode 100644 index 0000000000000000000000000000000000000000..a246af271f9cba26a1b0dd538f1eb637e6056e14 --- /dev/null +++ b/vendor/respect/validation/docs/IterableType.md @@ -0,0 +1,20 @@ +# IterableType + +- `v::iterableType()` + +Validates if the input is iterable, in other words, if you're able to iterate +over it with [foreach](http://php.net/foreach) language construct. + +```php +v::iterableType()->validate([]); // true +v::iterableType()->validate(new ArrayObject()); // true +v::iterableType()->validate(new stdClass()); // true +v::iterableType()->validate('string'); // false +``` + +*** +See also: + + * [ArrayVal](ArrayVal.md) + * [Countable](Countable.md) + * [Instance](Instance.md) diff --git a/vendor/respect/validation/docs/Json.md b/vendor/respect/validation/docs/Json.md new file mode 100644 index 0000000000000000000000000000000000000000..eb41367ceaf4ffe1b8060977dada30cad6981013 --- /dev/null +++ b/vendor/respect/validation/docs/Json.md @@ -0,0 +1,18 @@ +# Json + +- `v::json()` + +Validates if the given input is a valid JSON. + +```php +v::json()->validate('{"foo":"bar"}'); // true +``` + +*** +See also: + + * [Domain](Domain.md) + * [Email](Email.md) + * [FilterVar](FilterVar.md) + * [Phone](Phone.md) + * [VideoUrl](VideoUrl.md) diff --git a/vendor/respect/validation/docs/Key.md b/vendor/respect/validation/docs/Key.md new file mode 100644 index 0000000000000000000000000000000000000000..70a74c07a5a2836c4879799cddfbae89d377a23a --- /dev/null +++ b/vendor/respect/validation/docs/Key.md @@ -0,0 +1,34 @@ +# Key + +- `v::key(string $name)` +- `v::key(string $name, v $validator)` +- `v::key(string $name, v $validator, boolean $mandatory = true)` + +Validates an array key. + +```php +$dict = [ + 'foo' => 'bar' +]; + +v::key('foo')->validate($dict); // true +``` + +You can also validate the key value itself: + +```php +v::key('foo', v::equals('bar'))->validate($dict); // true +``` + +Third parameter makes the key presence optional: + +```php +v::key('lorem', v::stringType(), false)->validate($dict); // true +``` + +The name of this validator is automatically set to the key name. + +*** +See also: + + * [Attribute](Attribute.md) diff --git a/vendor/respect/validation/docs/KeyNested.md b/vendor/respect/validation/docs/KeyNested.md new file mode 100644 index 0000000000000000000000000000000000000000..3129dde31c723082fab3332c9c0fa6a3ef81bd2e --- /dev/null +++ b/vendor/respect/validation/docs/KeyNested.md @@ -0,0 +1,40 @@ +# KeyNested + +- `v::keyNested(string $name)` +- `v::keyNested(string $name, v $validator)` +- `v::keyNested(string $name, v $validator, boolean $mandatory = true)` + +Validates an array key or an object property using `.` to represent nested data. + +Validating keys from arrays or `ArrayAccess` instances: + +```php +$array = [ + 'foo' => [ + 'bar' => 123, + ], +]; + +v::keyNested('foo.bar')->validate($array); // true +``` + +Validating object properties: + +```php +$object = new stdClass(); +$object->foo = new stdClass(); +$object->foo->bar = 42; + +v::keyNested('foo.bar')->validate($object); // true +``` + +This rule was inspired by [Yii2 ArrayHelper][]. + +*** +See also: + + * [Attribute](Attribute.md) + * [Key](Key.md) + + +[Yii2 ArrayHelper]: https://github.com/yiisoft/yii2/blob/68c30c1/framework/helpers/BaseArrayHelper.php "Yii2 ArrayHelper" diff --git a/vendor/respect/validation/docs/KeySet.md b/vendor/respect/validation/docs/KeySet.md new file mode 100644 index 0000000000000000000000000000000000000000..faf40818aafbd384335127681e039e5c744ce1dc --- /dev/null +++ b/vendor/respect/validation/docs/KeySet.md @@ -0,0 +1,51 @@ +# KeySet + +- `v::keySet(Key $rule...)` + +Validates a keys in a defined structure. + +```php +$dict = ['foo' => 42]; + +v::keySet( + v::key('foo', v::intVal()) +)->validate($dict); // true +``` + +Extra keys are not allowed: +```php +$dict = ['foo' => 42, 'bar' => 'String']; + +v::keySet( + v::key('foo', v::intVal()) +)->validate($dict); // false +``` + +Missing required keys are not allowed: +```php +$dict = ['foo' => 42, 'bar' => 'String']; + +v::keySet( + v::key('foo', v::intVal()), + v::key('bar', v::stringType()), + v::key('baz', v::boolType()) +)->validate($dict); // false +``` + +Missing non-required keys are allowed: +```php +$dict = ['foo' => 42, 'bar' => 'String']; + +v::keySet( + v::key('foo', v::intVal()), + v::key('bar', v::stringType()), + v::key('baz', v::boolType(), false) +)->validate($dict); // true +``` + +The keys' order is not considered in the validation. + +*** +See also: + + * [Key](Key.md) diff --git a/vendor/respect/validation/docs/KeyValue.md b/vendor/respect/validation/docs/KeyValue.md new file mode 100644 index 0000000000000000000000000000000000000000..98ee9db8731581b6fbda57e80f05742a5e4b4b0c --- /dev/null +++ b/vendor/respect/validation/docs/KeyValue.md @@ -0,0 +1,62 @@ +# KeyValue + +- `keyValue(string $comparedKey, string $ruleName, string $baseKey)` + +Performs validation of `$comparedKey` using the rule named on `$ruleName` with +`$baseKey` as base. + +Sometimes, when validating arrays, the validation of a key value depends on +another key value and that may cause some ugly code since you need the input +before the validation, making some checking manually: + +```php +v::key('password')->check($_POST); +v::key('password_confirmation', v::equals($_POST['password']))->check($_POST); +``` + +The problem with the above code is because you do not know if `password` is a +valid key, so you must check it manually before performing the validation on +`password_confirmation`. + +The `keyValue()` rule makes this job easier by creating a rule named on +`$ruleName` passing `$baseKey` as the first argument of this rule, see an example: + +```php +v::keyValue('password_confirmation', 'equals', 'password')->validate($_POST); +``` + +The above code will result on `true` if _`$_POST['password_confirmation']` is +[equals](Equals.md) to `$_POST['password']`_, it's the same of: + +See another example: + +```php +v::keyValue('state', 'subdivisionCode', 'country')->validate($_POST); +``` + +The above code will result on `true` if _`$_POST['state']` is a +[subdivision code](SubdivisionCode.md) of `$_POST['country']`_: + +This rule will invalidate the input if `$comparedKey` or `$baseKey` don't exist, +or if the rule named on `$ruleName` could not be created (or don't exist). + +When using `assert()` or `check()` methods and the rule do not pass, it overwrites +all values in the validation exceptions with `$baseKey` and `$comparedKey`. + +```php +v::keyValue('password_confirmation', 'equals', 'password')->check($input); +``` + +The above code may generate the message: + +``` +password_confirmation must be equals "password" +``` + +*** +See also: + + * [Key](Key.md) + * [KeyNested](KeyNested.md) + * [KeySet](KeySet.md) + diff --git a/vendor/respect/validation/docs/LanguageCode.md b/vendor/respect/validation/docs/LanguageCode.md new file mode 100644 index 0000000000000000000000000000000000000000..a990f315a9a6f8d8b5261bfeab954fa5890a1bed --- /dev/null +++ b/vendor/respect/validation/docs/LanguageCode.md @@ -0,0 +1,20 @@ +# LanguageCode + +- `v::languageCode()` + +Validates a language code based on ISO 639: + +```php +v::languageCode()->validate('pt'); // true +v::languageCode()->validate('en'); // true +v::languageCode()->validate('it'); // true +v::languageCode('alpha-3')->validate('ita'); // true +v::languageCode('alpha-3')->validate('eng'); // true +``` + +You can choose between alpha-2 and alpha-3, alpha-2 is set by default. + +*** +See also: + + * [CountryCode](CountryCode.md) \ No newline at end of file diff --git a/vendor/respect/validation/docs/LeapDate.md b/vendor/respect/validation/docs/LeapDate.md new file mode 100644 index 0000000000000000000000000000000000000000..aa0e7581f7ab4207e3f863dcd14a6c800cd5bd14 --- /dev/null +++ b/vendor/respect/validation/docs/LeapDate.md @@ -0,0 +1,18 @@ +# LeapDate + +- `v::leapDate(string $format)` + +Validates if a date is leap. + +```php +v::leapDate('Y-m-d')->validate('1988-02-29'); // true +``` + +This validator accepts DateTime instances as well. The $format +parameter is mandatory. + +*** +See also: + + * [Date](Date.md) + * [LeapYear](LeapYear.md) diff --git a/vendor/respect/validation/docs/LeapYear.md b/vendor/respect/validation/docs/LeapYear.md new file mode 100644 index 0000000000000000000000000000000000000000..db208993164f717ab648968850f78013a8794f74 --- /dev/null +++ b/vendor/respect/validation/docs/LeapYear.md @@ -0,0 +1,17 @@ +# LeapYear + +- `v::leapYear()` + +Validates if a year is leap. + +```php +v::leapYear()->validate('1988'); // true +``` + +This validator accepts DateTime instances as well. + +*** +See also: + + * [Date](Date.md) + * [LeapDate](LeapDate.md) diff --git a/vendor/respect/validation/docs/Length.md b/vendor/respect/validation/docs/Length.md new file mode 100644 index 0000000000000000000000000000000000000000..2fbf519536b85d41e705750ef6d05b57d0d59645 --- /dev/null +++ b/vendor/respect/validation/docs/Length.md @@ -0,0 +1,44 @@ +# Length + +- `v::length(int $min, int $max)` +- `v::length(int $min, null)` +- `v::length(null, int $max)` +- `v::length(int $min, int $max, boolean $inclusive = true)` + +Validates lengths. Most simple example: + +```php +v::stringType()->length(1, 5)->validate('abc'); // true +``` + +You can also validate only minimum length: + +```php +v::stringType()->length(5, null)->validate('abcdef'); // true +``` + +Only maximum length: + +```php +v::stringType()->length(null, 5)->validate('abc'); // true +``` + +The type as the first validator in a chain is a good practice, +since length accepts many types: + +```php +v::arrayVal()->length(1, 5)->validate(['foo', 'bar']); // true +``` + +A third parameter may be passed to validate the passed values inclusive: + +```php +v::stringType()->length(1, 5, true)->validate('a'); // true +``` + +Message template for this validator includes `{{minValue}}` and `{{maxValue}}`. + +*** +See also: + + * [Between](Between.md) diff --git a/vendor/respect/validation/docs/Lowercase.md b/vendor/respect/validation/docs/Lowercase.md new file mode 100644 index 0000000000000000000000000000000000000000..a79f82b76fdb91a36d71b1ceffa09daa00ea1b07 --- /dev/null +++ b/vendor/respect/validation/docs/Lowercase.md @@ -0,0 +1,14 @@ +# Lowercase + +- `v::lowercase()` + +Validates if string characters are lowercase in the input: + +```php +v::stringType()->lowercase()->validate('xkcd'); // true +``` + +*** +See also: + + * [Uppercase](Uppercase.md) diff --git a/vendor/respect/validation/docs/MacAddress.md b/vendor/respect/validation/docs/MacAddress.md new file mode 100644 index 0000000000000000000000000000000000000000..92f427af302b90114e4c6705be4687b1c87a3c29 --- /dev/null +++ b/vendor/respect/validation/docs/MacAddress.md @@ -0,0 +1,17 @@ +# MacAddress + +- `v::macAddress()` + +Validates a Mac Address. + +```php +v::macAddress()->validate('00:11:22:33:44:55'); // true +v::macAddress()->validate('af-AA-22-33-44-55'); // true +``` + +*** +See also: + + * [Domain](Domain.md) + * [Ip](Ip.md) + * [Tld](Tld.md) diff --git a/vendor/respect/validation/docs/Max.md b/vendor/respect/validation/docs/Max.md new file mode 100644 index 0000000000000000000000000000000000000000..1c199b9497ad9067e2241117fbc8893543443996 --- /dev/null +++ b/vendor/respect/validation/docs/Max.md @@ -0,0 +1,36 @@ +# Max + +- `v::max(mixed $maxValue)` +- `v::max(mixed $maxValue, boolean $inclusive = true)` + +Validates if the input doesn't exceed the maximum value. + +```php +v::intVal()->max(15)->validate(20); // false +v::intVal()->max(20)->validate(20); // false +v::intVal()->max(20, true)->validate(20); // true +``` + +Also accepts dates: + +```php +v::date()->max('2012-01-01')->validate('2010-01-01'); // true +``` + +Also date intervals: + +```php +// Same of minimum age validation +v::date()->max('-18 years')->validate('1988-09-09'); // true +``` + +`true` may be passed as a parameter to indicate that inclusive +values must be used. + +Message template for this validator includes `{{maxValue}}`. + +*** +See also: + + * [Min](Min.md) + * [Between](Between.md) diff --git a/vendor/respect/validation/docs/Mimetype.md b/vendor/respect/validation/docs/Mimetype.md new file mode 100644 index 0000000000000000000000000000000000000000..a2af05e8c74aec337944d3a1566a5a050ba822b4 --- /dev/null +++ b/vendor/respect/validation/docs/Mimetype.md @@ -0,0 +1,25 @@ +# Mimetype + +- `v::mimetype(string $mimetype)` + +Validates if the file mimetype matches the expected one: + +```php +v::mimetype('image/png')->validate('image.png'); // true +``` + +This rule is case-sensitive and requires [fileinfo](http://php.net/fileinfo) PHP extension. + +*** +See also: + + * [Directory](Directory.md) + * [Executable](Executable.md) + * [Exists](Exists.md) + * [Extension](Extension.md) + * [File](File.md) + * [Readable](Readable.md) + * [Size](Size.md) + * [SymbolicLink](SymbolicLink.md) + * [Uploaded](Uploaded.md) + * [Writable](Writable.md) diff --git a/vendor/respect/validation/docs/Min.md b/vendor/respect/validation/docs/Min.md new file mode 100644 index 0000000000000000000000000000000000000000..460154f25f8435fe489caff1681dd0c1ee49ce37 --- /dev/null +++ b/vendor/respect/validation/docs/Min.md @@ -0,0 +1,29 @@ +# Min + +- `v::min(mixed $minValue)` +- `v::min(mixed $minValue, boolean $inclusive = true)` + +Validates if the input is greater than the minimum value. + +```php +v::intVal()->min(15)->validate(5); // false +v::intVal()->min(5)->validate(5); // false +v::intVal()->min(5, true)->validate(5); // true +``` + +Also accepts dates: + +```php +v::date()->min('2012-01-01')->validate('2015-01-01'); // true +``` + +`true` may be passed as a parameter to indicate that inclusive +values must be used. + +Message template for this validator includes `{{minValue}}`. + +*** +See also: + + * [Max](Max.md) + * [Between](Between.md) diff --git a/vendor/respect/validation/docs/MinimumAge.md b/vendor/respect/validation/docs/MinimumAge.md new file mode 100644 index 0000000000000000000000000000000000000000..33b457ae0b0ad2d3b34288a56569dee05e6e6188 --- /dev/null +++ b/vendor/respect/validation/docs/MinimumAge.md @@ -0,0 +1,23 @@ +# MinimumAge + +This is going to be deprecated, please use [Age](Age.md) instead. + +- `v::minimumAge(int $age)` +- `v::minimumAge(int $age, string $format)` + +Validates a minimum age for a given date. + +```php +v::minimumAge(18)->validate('1987-01-01'); // true +v::minimumAge(18, 'd/m/Y')->validate('01/01/1987'); // true +``` + +Using `date()` before is a best-practice. + +Message template for this validator includes `{{age}}`. + +*** +See also: + + * [Age](Age.md) + * [Date](Date.md) diff --git a/vendor/respect/validation/docs/Multiple.md b/vendor/respect/validation/docs/Multiple.md new file mode 100644 index 0000000000000000000000000000000000000000..b6d8c7ff02ce91038d3b57c4abff84308cacc737 --- /dev/null +++ b/vendor/respect/validation/docs/Multiple.md @@ -0,0 +1,14 @@ +# Multiple + +- `v::multiple(int $multipleOf)` + +Validates if the input is a multiple of the given parameter + +```php +v::intVal()->multiple(3)->validate(9); // true +``` + +*** +See also: + + * [PrimeNumber](PrimeNumber.md) diff --git a/vendor/respect/validation/docs/Negative.md b/vendor/respect/validation/docs/Negative.md new file mode 100644 index 0000000000000000000000000000000000000000..efecb52018b0763c49d61deec12b3f45b1bbec7c --- /dev/null +++ b/vendor/respect/validation/docs/Negative.md @@ -0,0 +1,14 @@ +# Negative + +- `v::negative()` + +Validates if a number is lower than zero + +```php +v::numeric()->negative()->validate(-15); // true +``` + +*** +See also: + + * [Positive](Positive.md) diff --git a/vendor/respect/validation/docs/NfeAccessKey.md b/vendor/respect/validation/docs/NfeAccessKey.md new file mode 100644 index 0000000000000000000000000000000000000000..2f9188f1b0ce52d960b4ef30f58dd17b203c6d61 --- /dev/null +++ b/vendor/respect/validation/docs/NfeAccessKey.md @@ -0,0 +1,16 @@ +# NfeAccessKey + +- `v::nfeAccessKey(string $accessKey)` + +Validates the access key of the Brazilian electronic invoice (NFe). + +```php +v::nfeAccessKey()->validate('31841136830118868211870485416765268625116906'); // true +``` + +*** +See also: + + * [Cnh](Cnh.md) + * [Cnpj](Cnpj.md) + * [Cpf](Cpf.md) diff --git a/vendor/respect/validation/docs/No.md b/vendor/respect/validation/docs/No.md new file mode 100644 index 0000000000000000000000000000000000000000..e50b4c72becd343ad8682869488b9522d8fd456f --- /dev/null +++ b/vendor/respect/validation/docs/No.md @@ -0,0 +1,24 @@ +# No + +- `v::no()` +- `v::no(boolean $locale)` + +Validates if value is considered as "No". + +```php +v::no()->validate('N'); // true +v::no()->validate('Nay'); // true +v::no()->validate('Nix'); // true +v::no()->validate('No'); // true +v::no()->validate('Nope'); // true +v::no()->validate('Not'); // true +``` + +This rule is case insensitive. + +If `$locale` is TRUE, uses the value of [nl_langinfo()](http://php.net/nl_langinfo) with `NOEXPR` constant. + +*** +See also: + + * [Yes](Yes.md) diff --git a/vendor/respect/validation/docs/NoWhitespace.md b/vendor/respect/validation/docs/NoWhitespace.md new file mode 100644 index 0000000000000000000000000000000000000000..052cfcdee028d66c24fe55bb1b6bce6ee64e7a27 --- /dev/null +++ b/vendor/respect/validation/docs/NoWhitespace.md @@ -0,0 +1,21 @@ +# NoWhitespace + +- `v::noWhitespace()` + +Validates if a string contains no whitespace (spaces, tabs and line breaks); + +```php +v::noWhitespace()->validate('foo bar'); //false +v::noWhitespace()->validate("foo\nbar"); // false +``` + +This is most useful when chaining with other validators such as `v::alnum()` + +*** +See also: + + * [Alnum](Alnum.md) + * [Alpha](Alpha.md) + * [NotBlank](NotBlank.md) + * [NotEmpty](NotEmpty.md) + * [NotOptional](NotOptional.md) diff --git a/vendor/respect/validation/docs/NoneOf.md b/vendor/respect/validation/docs/NoneOf.md new file mode 100644 index 0000000000000000000000000000000000000000..44e91537e8754135bf7f3a0400e0d5259d036188 --- /dev/null +++ b/vendor/respect/validation/docs/NoneOf.md @@ -0,0 +1,21 @@ +# NoneOf + +- `v::noneOf(v $v1, v $v2, v $v3...)` + +Validates if NONE of the given validators validate: + +```php +v::noneOf( + v::intVal(), + v::floatVal() +)->validate('foo'); // true +``` + +In the sample above, 'foo' isn't a integer nor a float, so noneOf returns true. + +*** +See also: + + * [Not](Not.md) + * [AllOf](AllOf.md) + * [OneOf](OneOf.md) diff --git a/vendor/respect/validation/docs/Not.md b/vendor/respect/validation/docs/Not.md new file mode 100644 index 0000000000000000000000000000000000000000..31f575bca1748ce768a9dbc54e4b9ed4d7d7e4c3 --- /dev/null +++ b/vendor/respect/validation/docs/Not.md @@ -0,0 +1,24 @@ +# Not + +- `v::not(v $negatedValidator)` + +Negates any rule. + +```php +v::not(v::ip())->validate('foo'); // true +``` + +In the sample above, validator returns true because 'foo' isn't an IP Address. + +You can negate complex, grouped or chained validators as well: + +```php +v::not(v::intVal()->positive())->validate(-1.5); // true +``` + +Each other validation has custom messages for negated rules. + +*** +See also: + + * [NoneOf](NoneOf.md) diff --git a/vendor/respect/validation/docs/NotBlank.md b/vendor/respect/validation/docs/NotBlank.md new file mode 100644 index 0000000000000000000000000000000000000000..35a5ef2de273e29918c98c4a743603b026ffd3ca --- /dev/null +++ b/vendor/respect/validation/docs/NotBlank.md @@ -0,0 +1,34 @@ +# NotBlank + +- `v::notBlank()` + +Validates if the given input is not a blank value (`null`, zeros, empty strings +or empty arrays, recursively). + +```php +v::notBlank()->validate(null); // false +v::notBlank()->validate(''); // false +v::notBlank()->validate([]); // false +v::notBlank()->validate(' '); // false +v::notBlank()->validate(0); // false +v::notBlank()->validate('0'); // false +v::notBlank()->validate(0); // false +v::notBlank()->validate('0.0'); // false +v::notBlank()->validate(false); // false +v::notBlank()->validate(['']); // false +v::notBlank()->validate([' ']); // false +v::notBlank()->validate([0]); // false +v::notBlank()->validate(['0']); // false +v::notBlank()->validate([false]); // false +v::notBlank()->validate([[''], [0]]); // false +v::notBlank()->validate(new stdClass()); // false +``` + +It's similar to [NotEmpty](NotEmpty.md) but it's way more strict. + +*** +See also: + + * [NoWhitespace](NoWhitespace.md) + * [NotEmpty](NotEmpty.md) + * [NullType](NullType.md) diff --git a/vendor/respect/validation/docs/NotEmpty.md b/vendor/respect/validation/docs/NotEmpty.md new file mode 100644 index 0000000000000000000000000000000000000000..ab888f6a641664ad296b7de9cb616c4421500f08 --- /dev/null +++ b/vendor/respect/validation/docs/NotEmpty.md @@ -0,0 +1,42 @@ +# NotEmpty + +- `v::notEmpty()` + +Validates if the given input is not empty or in other words is input mandatory and +required. This function also takes whitespace into account, use `noWhitespace()` +if no spaces or linebreaks and other whitespace anywhere in the input is desired. + +```php +v::stringType()->notEmpty()->validate(''); // false +``` + +Null values are empty: + +```php +v::notEmpty()->validate(null); // false +``` + +Numbers: + +```php +v::intVal()->notEmpty()->validate(0); // false +``` + +Empty arrays: + +```php +v::arrayVal()->notEmpty()->validate([]); // false +``` + +Whitespace: + +```php +v::stringType()->notEmpty()->validate(' '); //false +v::stringType()->notEmpty()->validate("\t \n \r"); //false +``` + +*** +See also: + + * [NoWhitespace](NoWhitespace.md) + * [NullType](NullType.md) diff --git a/vendor/respect/validation/docs/NotOptional.md b/vendor/respect/validation/docs/NotOptional.md new file mode 100644 index 0000000000000000000000000000000000000000..487e7f1ef253ff82ead7b3f150f7c07a3163209b --- /dev/null +++ b/vendor/respect/validation/docs/NotOptional.md @@ -0,0 +1,39 @@ +# NotOptional + +- `v::notOptional()` + +Validates if the given input is not optional. By _optional_ we consider `null` +or an empty string (`''`). + +```php +v::notOptional()->validate(''); // false +v::notOptional()->validate(null); // false +``` + +Other values: + +```php +v::notOptional()->validate([]); // true +v::notOptional()->validate(' '); // true +v::notOptional()->validate(0); // true +v::notOptional()->validate('0'); // true +v::notOptional()->validate(0); // true +v::notOptional()->validate('0.0'); // true +v::notOptional()->validate(false); // true +v::notOptional()->validate(['']); // true +v::notOptional()->validate([' ']); // true +v::notOptional()->validate([0]); // true +v::notOptional()->validate(['0']); // true +v::notOptional()->validate([false]); // true +v::notOptional()->validate([[''), [0]]); // true +v::notOptional()->validate(new stdClass()); // true +``` + +*** +See also: + + * [NoWhitespace](NoWhitespace.md) + * [NotBlank](NotBlank.md) + * [NotEmpty](NotEmpty.md) + * [NullType](NullType.md) + * [Optional](Optional.md) diff --git a/vendor/respect/validation/docs/NullType.md b/vendor/respect/validation/docs/NullType.md new file mode 100644 index 0000000000000000000000000000000000000000..5b39feb6c2d0eb36a964fc982d2fcd58aa73cea8 --- /dev/null +++ b/vendor/respect/validation/docs/NullType.md @@ -0,0 +1,25 @@ +# NullType + +- `v::nullType()` + +Validates if the input is null. + +```php +v::nullType()->validate(null); // true +``` + +*** +See also: + + * [BoolType](BoolType.md) + * [CallableType](CallableType.md) + * [FloatType](FloatType.md) + * [IntType](IntType.md) + * [NotBlank](NotBlank.md) + * [NotEmpty](NotEmpty.md) + * [NotOptional](NotOptional.md) + * [NullType](NullType.md) + * [ObjectType](ObjectType.md) + * [ResourceType](ResourceType.md) + * [StringType](StringType.md) + * [Type](Type.md) diff --git a/vendor/respect/validation/docs/Numeric.md b/vendor/respect/validation/docs/Numeric.md new file mode 100644 index 0000000000000000000000000000000000000000..d8121fb61c9ae621e4ebe74b45b80853e5c95721 --- /dev/null +++ b/vendor/respect/validation/docs/Numeric.md @@ -0,0 +1,18 @@ +# Numeric + +- `v::numeric()` + +Validates on any numeric value. + +```php +v::numeric()->validate(-12); // true +v::numeric()->validate('135.0'); // true +``` + +*** +See also: + + * [Digit](Digit.md) + * [Finite](Finite.md) + * [Infinite](Infinite.md) + * [IntVal](IntVal.md) diff --git a/vendor/respect/validation/docs/ObjectType.md b/vendor/respect/validation/docs/ObjectType.md new file mode 100644 index 0000000000000000000000000000000000000000..39212603155048570ca891161b495f1f8f41792c --- /dev/null +++ b/vendor/respect/validation/docs/ObjectType.md @@ -0,0 +1,24 @@ +# ObjectType + +- `v::objectType()` + +Validates if the input is an object. + +```php +v::objectType()->validate(new stdClass); // true +``` + +*** +See also: + + * [Attribute](Attribute.md) + * [BoolType](BoolType.md) + * [CallableType](CallableType.md) + * [FloatType](FloatType.md) + * [Instance](Instance.md) + * [IntType](IntType.md) + * [NullType](NullType.md) + * [ObjectType](ObjectType.md) + * [ResourceType](ResourceType.md) + * [StringType](StringType.md) + * [Type](Type.md) diff --git a/vendor/respect/validation/docs/Odd.md b/vendor/respect/validation/docs/Odd.md new file mode 100644 index 0000000000000000000000000000000000000000..b1a8d05fc978f94cd5e074288b5988969c161868 --- /dev/null +++ b/vendor/respect/validation/docs/Odd.md @@ -0,0 +1,17 @@ +# Odd + +- `v::odd()` + +Validates an odd number. + +```php +v::intVal()->odd()->validate(3); // true +``` + +Using `int()` before `odd()` is a best practice. + +*** +See also: + + * [Even](Even.md) + * [Multiple](Multiple.md) diff --git a/vendor/respect/validation/docs/OneOf.md b/vendor/respect/validation/docs/OneOf.md new file mode 100644 index 0000000000000000000000000000000000000000..e16be50df043ad94aa622584da26a71746077ee0 --- /dev/null +++ b/vendor/respect/validation/docs/OneOf.md @@ -0,0 +1,25 @@ +# OneOf + +- `v::oneOf(v $v1, v $v2, v $v3...)` + +This is a group validator that acts as an OR operator. + +```php +v::oneOf( + v::intVal(), + v::floatVal() +)->validate(15.5); // true +``` + +In the sample above, `v::intVal()` doesn't validates, but +`v::floatVal()` validates, so oneOf returns true. + +`v::oneOf` returns true if at least one inner validator +passes. + +*** +See also: + + * [AllOf](AllOf.md) + * [NoneOf](NoneOf.md) + * [When](When.md) diff --git a/vendor/respect/validation/docs/Optional.md b/vendor/respect/validation/docs/Optional.md new file mode 100644 index 0000000000000000000000000000000000000000..1a4aa5ec091f9731c70ae017489abc01c6424de1 --- /dev/null +++ b/vendor/respect/validation/docs/Optional.md @@ -0,0 +1,21 @@ +# Optional + +- `v::optional(v $rule)` + +Validates if the given input is optional or not. By _optional_ we consider `null` +or an empty string (`''`). + +```php +v::optional(v::alpha())->validate(''); // true +v::optional(v::digit())->validate(null); // true +``` + + +*** +See also: + + * [NoWhitespace](NoWhitespace.md) + * [NotBlank](NotBlank.md) + * [NotEmpty](NotEmpty.md) + * [NotOptional](NotOptional.md) + * [NullType](NullType.md) diff --git a/vendor/respect/validation/docs/PerfectSquare.md b/vendor/respect/validation/docs/PerfectSquare.md new file mode 100644 index 0000000000000000000000000000000000000000..3a344b27c9125bd28f0ac6afc1fa8b3d485d372b --- /dev/null +++ b/vendor/respect/validation/docs/PerfectSquare.md @@ -0,0 +1,16 @@ +# PerfectSquare + +- `v::perfectSquare()` + +Validates a perfect square. + +```php +v::perfectSquare()->validate(25); // true (5*5) +v::perfectSquare()->validate(9); // true (3*3) +``` + +*** +See also: + + * [Factor](Factor.md) + * [PrimeNumber](PrimeNumber.md) diff --git a/vendor/respect/validation/docs/Pesel.md b/vendor/respect/validation/docs/Pesel.md new file mode 100644 index 0000000000000000000000000000000000000000..275ff7f8d3117304f091e08f9b3424aff30cbf65 --- /dev/null +++ b/vendor/respect/validation/docs/Pesel.md @@ -0,0 +1,12 @@ +# Pesel + +- `v::pesel()` + +Validates PESEL (Polish human identification number). + +```php +v::pesel()->validate('21120209256'); // true +v::pesel()->validate('97072704800'); // true +v::pesel()->validate('97072704801'); // false +v::pesel()->validate('PESEL123456'); // false +``` diff --git a/vendor/respect/validation/docs/Phone.md b/vendor/respect/validation/docs/Phone.md new file mode 100644 index 0000000000000000000000000000000000000000..ac3cba9b9582c7192467e65376d4c0e7dd8b0899 --- /dev/null +++ b/vendor/respect/validation/docs/Phone.md @@ -0,0 +1,22 @@ +# Phone + +- `v::phone()` + +Validates a valid 7, 10, 11 digit phone number (North America, Europe and most +Asian and Middle East countries), supporting country and area codes (in dot, +space or dashed notations) such as: + + (555)555-5555 + 555 555 5555 + +5(555)555.5555 + 33(1)22 22 22 22 + +33(1)22 22 22 22 + +33(020)7777 7777 + 03-6106666 + +*** +See also: + + * [Email](Email.md) + * [Url](Url.md) + * [VideoUrl](VideoUrl.md) diff --git a/vendor/respect/validation/docs/PhpLabel.md b/vendor/respect/validation/docs/PhpLabel.md new file mode 100644 index 0000000000000000000000000000000000000000..4295267d72fb63767b02985ce2fd2f4479226e43 --- /dev/null +++ b/vendor/respect/validation/docs/PhpLabel.md @@ -0,0 +1,24 @@ +# PhpLabel + +- `v::phpLabel()` + +Validates if a value is considered a valid PHP Label, +so that it can be used as a *variable*, *function* or *class* name, for example. + +Reference: +http://php.net/manual/en/language.variables.basics.php + +```php +v::phpLabel()->validate('person'); //true +v::phpLabel()->validate('foo'); //true +v::phpLabel()->validate('4ccess'); //false +``` + +*** +See also: + + * [Regex](Regex.md) + * [ResourceType](ResourceType.md) + * [Slug](Slug.md) + * [Charset](Charset.md) + \ No newline at end of file diff --git a/vendor/respect/validation/docs/Positive.md b/vendor/respect/validation/docs/Positive.md new file mode 100644 index 0000000000000000000000000000000000000000..ecf75d9f00fd536907b1e56462fda4f184920501 --- /dev/null +++ b/vendor/respect/validation/docs/Positive.md @@ -0,0 +1,14 @@ +# Positive + +- `v::positive()` + +Validates if a number is higher than zero + +```php +v::numeric()->positive()->validate(-15); // false +``` + +*** +See also: + + * [Negative](Negative.md) diff --git a/vendor/respect/validation/docs/PostalCode.md b/vendor/respect/validation/docs/PostalCode.md new file mode 100644 index 0000000000000000000000000000000000000000..c18ec96ede6a146bddb14f0c964cb95b278a4670 --- /dev/null +++ b/vendor/respect/validation/docs/PostalCode.md @@ -0,0 +1,22 @@ +# PostalCode + +- `v::postalCode(string $countryCode)` + +Validates a postal code according to the given country code. + +```php +v::postalCode('BR')->validate('02179000'); // true +v::postalCode('BR')->validate('02179-000'); // true +v::postalCode('US')->validate('02179-000'); // false +v::postalCode('US')->validate('55372'); // true +v::postalCode('PL')->validate('99-300'); // true +``` + +Message template for this validator includes `{{countryCode}}`. + +Extracted from [GeoNames](http://www.geonames.org/). + +*** +See also: + + * [CountryCode](CountryCode.md) diff --git a/vendor/respect/validation/docs/PrimeNumber.md b/vendor/respect/validation/docs/PrimeNumber.md new file mode 100644 index 0000000000000000000000000000000000000000..dee58eabd4c93b89b4e351fd856d9608beeddfa6 --- /dev/null +++ b/vendor/respect/validation/docs/PrimeNumber.md @@ -0,0 +1,16 @@ +# PrimeNumber + +- `v::primeNumber()` + +Validates a prime number + +```php +v::primeNumber()->validate(7); // true +``` + +*** +See also: + + * [Factor](Factor.md) + * [PerfectSquare](PerfectSquare.md) + * [PrimeNumber](PrimeNumber.md) diff --git a/vendor/respect/validation/docs/Prnt.md b/vendor/respect/validation/docs/Prnt.md new file mode 100644 index 0000000000000000000000000000000000000000..29dc6d76397b0d52e1cb0b8a269d4f4395952913 --- /dev/null +++ b/vendor/respect/validation/docs/Prnt.md @@ -0,0 +1,15 @@ +# Prnt + +- `v::prnt()` +- `v::prnt(string $additionalChars)` + +Similar to `v::graph` but accepts whitespace. + +```php +v::prnt()->validate('LMKA0$% _123'); // true +``` + +*** +See also: + + * [Graph](Graph.md) diff --git a/vendor/respect/validation/docs/Punct.md b/vendor/respect/validation/docs/Punct.md new file mode 100644 index 0000000000000000000000000000000000000000..d49411aa90978c85ffe136eb0afdf574dc985fd5 --- /dev/null +++ b/vendor/respect/validation/docs/Punct.md @@ -0,0 +1,17 @@ +# Punct + +- `v::punct()` +- `v::punct(string $additionalChars)` + +Accepts only punctuation characters: + +```php +v::punct()->validate('&,.;[]'); // true +``` + +*** +See also: + + * [Cntrl](Cntrl.md) + * [Graph](Graph.md) + * [Prnt](Prnt.md) diff --git a/vendor/respect/validation/docs/README.md b/vendor/respect/validation/docs/README.md new file mode 100644 index 0000000000000000000000000000000000000000..abd573aaff56a3aae4a2660f92ac9c3f62c8ac88 --- /dev/null +++ b/vendor/respect/validation/docs/README.md @@ -0,0 +1,310 @@ +# Feature Guide + +## Namespace import + +Respect\Validation is namespaced, but you can make your life easier by importing +a single class into your context: + +```php +use Respect\Validation\Validator as v; +``` + +## Simple validation + +The Hello World validator is something like this: + +```php +$number = 123; +v::numeric()->validate($number); // true +``` + +## Chained validation + +It is possible to use validators in a chain. Sample below validates a string +containing numbers and letters, no whitespace and length between 1 and 15. + +```php +$usernameValidator = v::alnum()->noWhitespace()->length(1, 15); +$usernameValidator->validate('alganet'); // true +``` + +## Validating object attributes + +Given this simple object: + +```php +$user = new stdClass; +$user->name = 'Alexandre'; +$user->birthdate = '1987-07-01'; +``` + +Is possible to validate its attributes in a single chain: + +```php +$userValidator = v::attribute('name', v::stringType()->length(1,32)) + ->attribute('birthdate', v::date()->age(18)); + +$userValidator->validate($user); // true +``` + +Validating array keys is also possible using `v::key()` + +Note that we used `v::stringType()` and `v::date()` in the beginning of the validator. +Although is not mandatory, it is a good practice to use the type of the +validated object as the first node in the chain. + +## Input optional + +On oldest versions of Respect\Validation all validators treat input as optional +and accept an empty string input as valid. Even though a useful feature that +caused a lot of troubles for our team and neither was an obvious behavior. Also +there was some people who likes to accept `null` as optional value, not only an +empty string. + +For that reason all rules are mandatory now but if you want to treat a value as +optional you can use `v::optional()` rule: + +```php +v::alpha()->validate(''); // false input required +v::alpha()->validate(null); // false input required + +v::optional(v::alpha())->validate(''); // true +v::optional(v::alpha())->validate(null); // true +``` + +By _optional_ we consider `null` or an empty string (`''`). + +See more on [Optional](Optional.md). + +## Negating rules + +You can use the `v::not()` to negate any rule: + +```php +v::not(v::intVal())->validate(10); // false, input must not be integer +``` + +## Validator reuse + +Once created, you can reuse your validator anywhere. Remember `$usernameValidator`? + +```php +$usernameValidator->validate('respect'); //true +$usernameValidator->validate('alexandre gaigalas'); // false +$usernameValidator->validate('#$%'); //false +``` + +## Exception types + +* `Respect\Validation\Exceptions\ExceptionInterface`: + * All exceptions implement this interface; +* `Respect\Validation\Exceptions\ValidationException`: + * Implements the `Respect\Validation\Exceptions\ExceptionInterface` interface + * Thrown when the `check()` fails + * All validation exceptions extend this class + * Available methods: + * `getMainMessage()`; + * `setMode($mode)`; + * `setName($name)`; + * `setParam($name, $value)`; + * `setTemplate($template)`; + * more... +* `Respect\Validation\Exceptions\NestedValidationException`: + * Extends the `Respect\Validation\Exceptions\ValidationException` class + * Usually thrown when the `assert()` fails + * Available methods: + * `findMessages()`; + * `getFullMessage()`; + * `getMessages()`; + * more... + +## Informative exceptions + +When something goes wrong, Validation can tell you exactly what's going on. For this, +we use the `assert()` method instead of `validate()`: + +```php +use Respect\Validation\Exceptions\NestedValidationException; + +try { + $usernameValidator->assert('really messed up screen#name'); +} catch(NestedValidationException $exception) { + echo $exception->getFullMessage(); +} +``` + +The printed message is exactly this, as a nested Markdown list: + +```no-highlight +- All of the required rules must pass for "really messed up screen#name" + - "really messed up screen#name" must contain only letters (a-z) and digits (0-9) + - "really messed up screen#name" must not contain whitespace + - "really messed up screen#name" must have a length between 1 and 15 +``` + +## Getting all messages as an array + +The Markdown list is fine, but unusable on a HTML form or something more custom. +For that you can use `getMessages()`. + +It will return all messages from the rules that did not pass the validation. + +```php +try { + $usernameValidator->assert('really messed up screen#name'); +} catch(NestedValidationException $exception) { + print_r($exception->getMessages()); +} +``` + +The code above may display something like: + +```no-highlight +Array +( + [0] => "really messed up screen#name" must contain only letters (a-z) and digits (0-9) + [1] => "really messed up screen#name" must not contain whitespace + [2] => "really messed up screen#name" must have a length between 1 and 15 +) +``` + +## Getting messages as an array by name + +If you want to get specific message by name you can use `findMessages()` passing +the names of the rules you want: + +```php +try { + $usernameValidator->assert('really messed up screen#name'); +} catch(NestedValidationException $exception) { + print_r($exception->findMessages(['alnum', 'noWhitespace'])); +} +``` + +The `findMessages()` returns an array with messages from the requested validators, +like this: + +```no-highlight +Array +( + [alnum] => "really messed up screen#name" must contain only letters (a-z) and digits (0-9) + [noWhitespace] => "really messed up screen#name" must not contain whitespace +) +``` + +## Custom messages + +Getting messages as an array is fine, but sometimes you need to customize them in order +to present them to the user. This is possible using the `findMessages()` method as well: + +```php +$errors = $exception->findMessages([ + 'alnum' => '{{name}} must contain only letters and digits', + 'length' => '{{name}} must not have more than 15 chars', + 'noWhitespace' => '{{name}} cannot contain spaces' +]); +``` + +For all messages, the `{{name}}` variable is available for templates. If you +do not define a name it uses the input to replace this placeholder. + +## Message localization + +You're also able to translate your message to another language with Validation. +The only thing one must do is to define the param `translator` as a callable that +will handle the translation: + +```php +$exception->setParam('translator', 'gettext'); +``` + +The example above uses `gettext()` but you can use any other callable value, like +`[$translator, 'trans']` or `you_custom_function()`. + +After that, if you call `getMainMessage()` or `getFullMessage()` (for nested), +the message will be translated. + +Note that `getMessage()` will keep the original message. + +## Custom rules + +You also can use your own rules: + +```php +namespace My\Validation\Rules; + +use Respect\Validation\Rules\AbstractRule; + +class MyRule extends AbstractRule +{ + public function validate($input) + { + // Do something here with the $input and return a boolean value + } +} +``` + +If you do want Validation to execute you rule (or rules) in the chain, you must +use `v::with()` passing your rule's namespace as an argument: + +```php +v::with('My\\Validation\\Rules\\'); +v::myRule(); // Try to load "My\Validation\Rules\MyRule" if any +``` + +By default `with()` appends the given prefix, but you can change this behavior +in order to overwrite default rules: + +```php +v::with('My\\Validation\\Rules', true); +v::alnum(); // Try to use "My\Validation\Rules\Alnum" if any +``` + +## Validator name + +On `v::attribute()` and `v::key()`, `{{name}}` is the attribute/key name. For others, +is the same as the input. You can customize a validator name using: + +```php +v::date('Y-m-d')->between('1980-02-02', 'now')->setName('Member Since'); +``` + +## Zend/Symfony validators + +It is also possible to reuse validators from other frameworks if they are installed: + +```php +$hostnameValidator = v::zend('Hostname')->assert('google.com'); +$timeValidator = v::sf('Time')->assert('22:00:01'); +``` + +## Validation methods + +We've seen `validate()` that returns true or false and `assert()` that throws a complete +validation report. There is also a `check()` method that returns an Exception +only with the first error found: + +```php +use Respect\Validation\Exceptions\ValidationException; + +try { + $usernameValidator->check('really messed up screen#name'); +} catch(ValidationException $exception) { + echo $exception->getMainMessage(); +} +``` + +Message: + +```no-highlight +"really messed up screen#name" must contain only letters (a-z) and digits (0-9) +``` + +*** +See also: + +- [Contributing](../CONTRIBUTING.md) +- [Installation](INSTALL.md) +- [License](../LICENSE.md) +- [Validators](VALIDATORS.md) +- [Changelog](../CHANGELOG.md) diff --git a/vendor/respect/validation/docs/Readable.md b/vendor/respect/validation/docs/Readable.md new file mode 100644 index 0000000000000000000000000000000000000000..00a074eb9142aa4700965e2bf593d6b3cbd67e3d --- /dev/null +++ b/vendor/respect/validation/docs/Readable.md @@ -0,0 +1,23 @@ +# Readable + +- `v::readable()` + +Validates if the given data is a file exists and is readable. + +```php +v::readable()->validate('/path/of/a/readable/file'); // true +``` + +*** +See also: + + * [Directory](Directory.md) + * [Executable](Executable.md) + * [Exists](Exists.md) + * [Extension](Extension.md) + * [File](File.md) + * [Mimetype](Mimetype.md) + * [Size](Size.md) + * [SymbolicLink](SymbolicLink.md) + * [Uploaded](Uploaded.md) + * [Writable](Writable.md) diff --git a/vendor/respect/validation/docs/Regex.md b/vendor/respect/validation/docs/Regex.md new file mode 100644 index 0000000000000000000000000000000000000000..ed0d2517345e6fcb37c9ad8e68a3d83d98b815ab --- /dev/null +++ b/vendor/respect/validation/docs/Regex.md @@ -0,0 +1,21 @@ +# Regex + +- `v::regex(string $regex)` + +Evaluates a regex on the input and validates if matches + +```php +v::regex('/[a-z]/')->validate('a'); // true +``` + +Message template for this validator includes `{{regex}}` + +*** +See also: + + * [Alnum](Alnum.md) + * [Alpha](Alpha.md) + * [Contains](Contains.md) + * [Digit](Digit.md) + * [EndsWith](EndsWith.md) + * [StartsWith](StartsWith.md) diff --git a/vendor/respect/validation/docs/ResourceType.md b/vendor/respect/validation/docs/ResourceType.md new file mode 100644 index 0000000000000000000000000000000000000000..c21a2f1d89b7a85c966d8eefdd07e3abe4d4e565 --- /dev/null +++ b/vendor/respect/validation/docs/ResourceType.md @@ -0,0 +1,21 @@ +# ResourceType + +- `v::resourceType()` + +Validates if the input is a resource. + +```php +v::resourceType()->validate(fopen('/path/to/file.txt', 'w')); // true +``` + +*** +See also: + + * [BoolType](BoolType.md) + * [CallableType](CallableType.md) + * [FloatType](FloatType.md) + * [IntType](IntType.md) + * [NullType](NullType.md) + * [ObjectType](ObjectType.md) + * [StringType](StringType.md) + * [Type](Type.md) diff --git a/vendor/respect/validation/docs/Roman.md b/vendor/respect/validation/docs/Roman.md new file mode 100644 index 0000000000000000000000000000000000000000..b619930e1bf61ec67b70c246aa1aaa23bbfafb00 --- /dev/null +++ b/vendor/respect/validation/docs/Roman.md @@ -0,0 +1,16 @@ +# Roman + +- `v::roman()` + +Validates roman numbers + +```php +v::roman()->validate('IV'); // true +``` + +*** +See also: + + * [In](In.md) + * [Regex](Regex.md) + * [Uppercase](Uppercase.md) diff --git a/vendor/respect/validation/docs/ScalarVal.md b/vendor/respect/validation/docs/ScalarVal.md new file mode 100644 index 0000000000000000000000000000000000000000..366657854d77bda4e2df7eac79e9787b4c392fc1 --- /dev/null +++ b/vendor/respect/validation/docs/ScalarVal.md @@ -0,0 +1,15 @@ +# ScalarVal + +- `v::scalarVal()` + +Validates if the input is a scalar value. + +```php +v::scalarVal()->validate([]); // false +v::scalarVal()->validate(135.0); // true +``` + +*** +See also: + + * [Type](Type.md) diff --git a/vendor/respect/validation/docs/Sf.md b/vendor/respect/validation/docs/Sf.md new file mode 100644 index 0000000000000000000000000000000000000000..a7988a8b98d4027c45045556046a7d7169bc4a0b --- /dev/null +++ b/vendor/respect/validation/docs/Sf.md @@ -0,0 +1,19 @@ +# Sf + +- `v::sf(string $validator)` + +Use Symfony2 validators inside Respect\Validation flow. Messages +are preserved. + +```php +v::sf('Time')->validate('15:00:00'); +``` + + +You must add `"symfony/validator": "~2.6"` to your `require` property on composer.json file. + + +*** +See also: + + * [Zend](Zend.md) diff --git a/vendor/respect/validation/docs/Size.md b/vendor/respect/validation/docs/Size.md new file mode 100644 index 0000000000000000000000000000000000000000..13f5aee4e96aec1c383ef7bed1c78a471aa33f6f --- /dev/null +++ b/vendor/respect/validation/docs/Size.md @@ -0,0 +1,48 @@ +# Size + +- `v::size(string $minSize)` +- `v::size(string $minSize, string $maxSize)` +- `v::size(null, string $maxSize)` + +Validates file sizes: + +```php +v::size('1KB')->validate($filename); // Must have at least 1KB size +v::size('1MB', '2MB')->validate($filename); // Must have the size between 1MB and 2MB +v::size(null, '1GB')->validate($filename); // Must not be greater than 1GB +``` + +Sizes are not case-sensitive and the accepted values are: + +- B +- KB +- MB +- GB +- TB +- PB +- EB +- ZB +- YB + +This validator will consider `SplFileInfo` instances, like: + +```php +$fileInfo = new SplFileInfo($filename); +v::size('1.5mb')->validate($fileInfo); // Will return true or false +``` + +Message template for this validator includes `{{minSize}}` and `{{maxSize}}`. + +*** +See also: + + * [Directory](Directory.md) + * [Executable](Executable.md) + * [Exists](Exists.md) + * [Extension](Extension.md) + * [File](File.md) + * [Mimetype](Mimetype.md) + * [Readable](Readable.md) + * [SymbolicLink](SymbolicLink.md) + * [Uploaded](Uploaded.md) + * [Writable](Writable.md) diff --git a/vendor/respect/validation/docs/Slug.md b/vendor/respect/validation/docs/Slug.md new file mode 100644 index 0000000000000000000000000000000000000000..599bbbaac904fdef72ddcf7fc753511aa67fc8a7 --- /dev/null +++ b/vendor/respect/validation/docs/Slug.md @@ -0,0 +1,17 @@ +# Slug + +- `v::slug()` + +Validates slug-like strings: + +```php +v::slug()->validate('my-wordpress-title'); // true +v::slug()->validate('my-wordpress--title'); // false +v::slug()->validate('my-wordpress-title-'); // false +``` + +*** +See also: + + * [Url](Url.md) + * [VideoUrl](VideoUrl.md) diff --git a/vendor/respect/validation/docs/Space.md b/vendor/respect/validation/docs/Space.md new file mode 100644 index 0000000000000000000000000000000000000000..a0faec57133569ef6457237c0eacd2f9e6782db0 --- /dev/null +++ b/vendor/respect/validation/docs/Space.md @@ -0,0 +1,15 @@ +# Space + +- `v::space()` +- `v::space(string $additionalChars)` + +Accepts only whitespace: + +```php +v::space()->validate(' '); // true +``` + +*** +See also: + + * [Cntrl](Cntrl.md) diff --git a/vendor/respect/validation/docs/StartsWith.md b/vendor/respect/validation/docs/StartsWith.md new file mode 100644 index 0000000000000000000000000000000000000000..842655d94b25b1460254e12d1d4618032cf77d5c --- /dev/null +++ b/vendor/respect/validation/docs/StartsWith.md @@ -0,0 +1,31 @@ +# StartsWith + +- `v::startsWith(mixed $value)` +- `v::startsWith(mixed $value, boolean $identical = false)` + +This validator is similar to `v::contains()`, but validates +only if the value is at the beginning of the input. + +For strings: + +```php +v::startsWith('lorem')->validate('lorem ipsum'); // true +``` + +For arrays: + +```php +v::startsWith('lorem')->validate(['lorem', 'ipsum']); // true +``` + +`true` may be passed as a parameter to indicate identical comparison +instead of equal. + +Message template for this validator includes `{{startValue}}`. + +*** +See also: + + * [EndsWith](EndsWith.md) + * [Contains](Contains.md) + * [In](In.md) diff --git a/vendor/respect/validation/docs/StringType.md b/vendor/respect/validation/docs/StringType.md new file mode 100644 index 0000000000000000000000000000000000000000..624c3df8cfbe16b0774d69203d9d5d32a5c12f03 --- /dev/null +++ b/vendor/respect/validation/docs/StringType.md @@ -0,0 +1,22 @@ +# StringType + +- `v::stringType()` + +Validates a string. + +```php +v::stringType()->validate('hi'); // true +``` + +*** +See also: + + * [Alnum](Alnum.md) + * [BoolType](BoolType.md) + * [CallableType](CallableType.md) + * [FloatType](FloatType.md) + * [IntType](IntType.md) + * [NullType](NullType.md) + * [ObjectType](ObjectType.md) + * [ResourceType](ResourceType.md) + * [Type](Type.md) diff --git a/vendor/respect/validation/docs/SubdivisionCode.md b/vendor/respect/validation/docs/SubdivisionCode.md new file mode 100644 index 0000000000000000000000000000000000000000..3cb031922eff171dcac07b05827f9420049fa83c --- /dev/null +++ b/vendor/respect/validation/docs/SubdivisionCode.md @@ -0,0 +1,284 @@ +# SubdivisionCode + +- `v::subdivisionCode(string $countryCode)` + +Validates subdivision country codes according to [ISO 3166-2][]. + +The `$countryCode` must be a country in [ISO 3166-1 alpha-2][] format. + +```php +v::subdivisionCode('BR')->validate('SP'); // true +v::subdivisionCode('US')->validate('CA'); // true +``` + +This rule is case sensitive. + +## Available country codes + +- `AD`: Andorra +- `AE`: United Arab Emirates +- `AF`: Afghanistan +- `AG`: Antigua and Barbuda +- `AI`: Anguilla +- `AL`: Albania +- `AM`: Armenia +- `AN`: AN.html +- `AO`: Angola +- `AQ`: Antarctica +- `AR`: Argentina +- `AS`: American Samoa +- `AT`: Austria +- `AU`: Australia +- `AW`: Aruba +- `AX`: Ã…land +- `AZ`: Azerbaijan +- `BA`: Bosnia and Herzegovina +- `BB`: Barbados +- `BD`: Bangladesh +- `BE`: Belgium +- `BF`: Burkina Faso +- `BG`: Bulgaria +- `BH`: Bahrain +- `BI`: Burundi +- `BJ`: Benin +- `BL`: Saint Barthélemy +- `BM`: Bermuda +- `BN`: Brunei +- `BO`: Bolivia +- `BQ`: Bonaire +- `BR`: Brazil +- `BS`: Bahamas +- `BT`: Bhutan +- `BV`: Bouvet Island +- `BW`: Botswana +- `BY`: Belarus +- `BZ`: Belize +- `CA`: Canada +- `CC`: Cocos [Keeling] Islands +- `CD`: Democratic Republic of the Congo +- `CF`: Central African Republic +- `CG`: Republic of the Congo +- `CH`: Switzerland +- `CI`: Ivory Coast +- `CK`: Cook Islands +- `CL`: Chile +- `CM`: Cameroon +- `CN`: China +- `CO`: Colombia +- `CR`: Costa Rica +- `CS`: CS.html +- `CU`: Cuba +- `CV`: Cape Verde +- `CW`: Curacao +- `CX`: Christmas Island +- `CY`: Cyprus +- `CZ`: Czech Republic +- `DE`: Germany +- `DJ`: Djibouti +- `DK`: Denmark +- `DM`: Dominica +- `DO`: Dominican Republic +- `DZ`: Algeria +- `EC`: Ecuador +- `EE`: Estonia +- `EG`: Egypt +- `EH`: Western Sahara +- `ER`: Eritrea +- `ES`: Spain +- `ET`: Ethiopia +- `FI`: Finland +- `FJ`: Fiji +- `FK`: Falkland Islands +- `FM`: Micronesia +- `FO`: Faroe Islands +- `FR`: France +- `GA`: Gabon +- `GB`: United Kingdom +- `GD`: Grenada +- `GE`: Georgia +- `GF`: French Guiana +- `GG`: Guernsey +- `GH`: Ghana +- `GI`: Gibraltar +- `GL`: Greenland +- `GM`: Gambia +- `GN`: Guinea +- `GP`: Guadeloupe +- `GQ`: Equatorial Guinea +- `GR`: Greece +- `GS`: South Georgia and the South Sandwich Islands +- `GT`: Guatemala +- `GU`: Guam +- `GW`: Guinea-Bissau +- `GY`: Guyana +- `HK`: Hong Kong +- `HM`: Heard Island and McDonald Islands +- `HN`: Honduras +- `HR`: Croatia +- `HT`: Haiti +- `HU`: Hungary +- `ID`: Indonesia +- `IE`: Ireland +- `IL`: Israel +- `IM`: Isle of Man +- `IN`: India +- `IO`: British Indian Ocean Territory +- `IQ`: Iraq +- `IR`: Iran +- `IS`: Iceland +- `IT`: Italy +- `JE`: Jersey +- `JM`: Jamaica +- `JO`: Jordan +- `JP`: Japan +- `KE`: Kenya +- `KG`: Kyrgyzstan +- `KH`: Cambodia +- `KI`: Kiribati +- `KM`: Comoros +- `KN`: Saint Kitts and Nevis +- `KP`: North Korea +- `KR`: South Korea +- `KW`: Kuwait +- `KY`: Cayman Islands +- `KZ`: Kazakhstan +- `LA`: Laos +- `LB`: Lebanon +- `LC`: Saint Lucia +- `LI`: Liechtenstein +- `LK`: Sri Lanka +- `LR`: Liberia +- `LS`: Lesotho +- `LT`: Lithuania +- `LU`: Luxembourg +- `LV`: Latvia +- `LY`: Libya +- `MA`: Morocco +- `MC`: Monaco +- `MD`: Moldova +- `ME`: Montenegro +- `MF`: Saint Martin +- `MG`: Madagascar +- `MH`: Marshall Islands +- `MK`: Macedonia +- `ML`: Mali +- `MM`: Myanmar [Burma] +- `MN`: Mongolia +- `MO`: Macao +- `MP`: Northern Mariana Islands +- `MQ`: Martinique +- `MR`: Mauritania +- `MS`: Montserrat +- `MT`: Malta +- `MU`: Mauritius +- `MV`: Maldives +- `MW`: Malawi +- `MX`: Mexico +- `MY`: Malaysia +- `MZ`: Mozambique +- `NA`: Namibia +- `NC`: New Caledonia +- `NE`: Niger +- `NF`: Norfolk Island +- `NG`: Nigeria +- `NI`: Nicaragua +- `NL`: Netherlands +- `NO`: Norway +- `NP`: Nepal +- `NR`: Nauru +- `NU`: Niue +- `NZ`: New Zealand +- `OM`: Oman +- `PA`: Panama +- `PE`: Peru +- `PF`: French Polynesia +- `PG`: Papua New Guinea +- `PH`: Philippines +- `PK`: Pakistan +- `PL`: Poland +- `PM`: Saint Pierre and Miquelon +- `PN`: Pitcairn Islands +- `PR`: Puerto Rico +- `PS`: Palestine +- `PT`: Portugal +- `PW`: Palau +- `PY`: Paraguay +- `QA`: Qatar +- `RE`: Réunion +- `RO`: Romania +- `RS`: Serbia +- `RU`: Russia +- `RW`: Rwanda +- `SA`: Saudi Arabia +- `SB`: Solomon Islands +- `SC`: Seychelles +- `SD`: Sudan +- `SE`: Sweden +- `SG`: Singapore +- `SH`: Saint Helena +- `SI`: Slovenia +- `SJ`: Svalbard and Jan Mayen +- `SK`: Slovakia +- `SL`: Sierra Leone +- `SM`: San Marino +- `SN`: Senegal +- `SO`: Somalia +- `SR`: Suriname +- `SS`: South Sudan +- `ST`: São Tomé and PrÃncipe +- `SV`: El Salvador +- `SX`: Sint Maarten +- `SY`: Syria +- `SZ`: Swaziland +- `TC`: Turks and Caicos Islands +- `TD`: Chad +- `TF`: French Southern Territories +- `TG`: Togo +- `TH`: Thailand +- `TJ`: Tajikistan +- `TK`: Tokelau +- `TL`: East Timor +- `TM`: Turkmenistan +- `TN`: Tunisia +- `TO`: Tonga +- `TR`: Turkey +- `TT`: Trinidad and Tobago +- `TV`: Tuvalu +- `TW`: Taiwan +- `TZ`: Tanzania +- `UA`: Ukraine +- `UG`: Uganda +- `UM`: U.S. Minor Outlying Islands +- `US`: United States +- `UY`: Uruguay +- `UZ`: Uzbekistan +- `VA`: Vatican City +- `VC`: Saint Vincent and the Grenadines +- `VE`: Venezuela +- `VG`: British Virgin Islands +- `VI`: U.S. Virgin Islands +- `VN`: Vietnam +- `VU`: Vanuatu +- `WF`: Wallis and Futuna +- `WS`: Samoa +- `XK`: Kosovo +- `YE`: Yemen +- `YT`: Mayotte +- `ZA`: South Africa +- `ZM`: Zambia +- `ZW`: Zimbabwe + +All data was extrated from [GeoNames][] which is licensed under a +[Creative Commons Attribution 3.0 License][]. + +*** +See also: + + * [CountryCode](CountryCode.md) + * [Tld](Tld.md) + + +[Creative Commons Attribution 3.0 License]: http://creativecommons.org/licenses/by/3.0 "Creative Commons Attribution 3.0 License" +[GeoNames]: http://www.geonames.org "GetNames" +[ISO 3166-1 alpha-2]: http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 "ISO 3166-1 alpha-2" +[ISO 3166-2]: http://en.wikipedia.org/wiki/ISO_3166-2 "ISO 3166-2" diff --git a/vendor/respect/validation/docs/SymbolicLink.md b/vendor/respect/validation/docs/SymbolicLink.md new file mode 100644 index 0000000000000000000000000000000000000000..bc9019657bc68072e439020da43c0169169eab43 --- /dev/null +++ b/vendor/respect/validation/docs/SymbolicLink.md @@ -0,0 +1,23 @@ +# SymbolicLink + +- `v::symbolicLink()` + +Validates if the given data is a path of a valid symbolic link. + +```php +v::symbolicLink()->validate('/path/of/valid/symbolic/link'); // true +``` + +*** +See also: + + * [Directory](Directory.md) + * [Executable](Executable.md) + * [Exists](Exists.md) + * [Extension](Extension.md) + * [File](File.md) + * [Mimetype](Mimetype.md) + * [Readable](Readable.md) + * [Size](Size.md) + * [Uploaded](Uploaded.md) + * [Writable](Writable.md) diff --git a/vendor/respect/validation/docs/Tld.md b/vendor/respect/validation/docs/Tld.md new file mode 100644 index 0000000000000000000000000000000000000000..db05452a196958e19b794707740c69487c99d5a2 --- /dev/null +++ b/vendor/respect/validation/docs/Tld.md @@ -0,0 +1,17 @@ +# Tld + +- `v::tld()` + +Validates a top-level domain + +```php +v::tld()->validate('com'); // true +v::tld()->validate('ly'); // true +v::tld()->validate('org'); // true +``` + +*** +See also: + + * [Domain](Domain.md) + * [CountryCode](CountryCode.md) diff --git a/vendor/respect/validation/docs/TrueVal.md b/vendor/respect/validation/docs/TrueVal.md new file mode 100644 index 0000000000000000000000000000000000000000..59869d200419e5db273de2f4fa7c6bb30847dbd7 --- /dev/null +++ b/vendor/respect/validation/docs/TrueVal.md @@ -0,0 +1,21 @@ +# TrueVal + +- `v::trueVal()` + +Validates if a value is considered as `true`. + +```php +v::trueVal()->validate(true); // true +v::trueVal()->validate(1); // true +v::trueVal()->validate('1'); // true +v::trueVal()->validate('true'); // true +v::trueVal()->validate('on'); // true +v::trueVal()->validate('yes'); // true +v::trueVal()->validate('0.5'); // false +v::trueVal()->validate('2'); // false +``` + +*** +See also: + + * [FalseVal](FalseVal.md) diff --git a/vendor/respect/validation/docs/Type.md b/vendor/respect/validation/docs/Type.md new file mode 100644 index 0000000000000000000000000000000000000000..50f2abb9f9a75a2e1fa087a69b38274ad45d8631 --- /dev/null +++ b/vendor/respect/validation/docs/Type.md @@ -0,0 +1,31 @@ +# Type + +- `v::type(string $type)` + +Validates the type of input. + +```php +v::type('bool')->validate(true); // true +v::type('callable')->validate(function (){}); // true +v::type('object')->validate(new stdClass()); // true +``` + +*** +See also: + + * [ArrayVal](ArrayVal.md) + * [BoolType](BoolType.md) + * [CallableType](CallableType.md) + * [Finite](Finite.md) + * [FloatType](FloatType.md) + * [FloatVal](FloatVal.md) + * [Infinite](Infinite.md) + * [Instance](Instance.md) + * [IntType](IntType.md) + * [IntVal](IntVal.md) + * [NullType](NullType.md) + * [ObjectType](ObjectType.md) + * [ResourceType](ResourceType.md) + * [ScalarVal](ScalarVal.md) + * [StringType](StringType.md) + * [Type](Type.md) diff --git a/vendor/respect/validation/docs/Uploaded.md b/vendor/respect/validation/docs/Uploaded.md new file mode 100644 index 0000000000000000000000000000000000000000..774f9bb8216835034c4fa9c02263dfe2c9f898f5 --- /dev/null +++ b/vendor/respect/validation/docs/Uploaded.md @@ -0,0 +1,23 @@ +# Uploaded + +- `v::uploaded()` + +Validates if the given data is a file that was uploaded via HTTP POST. + +```php +v::uploaded()->validate('/path/of/an/uploaded/file'); // true +``` + +*** +See also: + + * [Directory](Directory.md) + * [Executable](Executable.md) + * [Exists](Exists.md) + * [Extension](Extension.md) + * [File](File.md) + * [Mimetype](Mimetype.md) + * [Readable](Readable.md) + * [Size](Size.md) + * [SymbolicLink](SymbolicLink.md) + * [Writable](Writable.md) diff --git a/vendor/respect/validation/docs/Uppercase.md b/vendor/respect/validation/docs/Uppercase.md new file mode 100644 index 0000000000000000000000000000000000000000..1dff7acf584a5ee43724526f6ff729879521ef2e --- /dev/null +++ b/vendor/respect/validation/docs/Uppercase.md @@ -0,0 +1,14 @@ +# Uppercase + +- `v::uppercase()` + +Validates if string characters are uppercase in the input: + +```php +v::stringType()->uppercase()->validate('W3C'); // true +``` + +*** +See also: + + * [Lowercase](Lowercase.md) diff --git a/vendor/respect/validation/docs/Url.md b/vendor/respect/validation/docs/Url.md new file mode 100644 index 0000000000000000000000000000000000000000..5638cf55f4b364edceea324d80904c3f87ce3178 --- /dev/null +++ b/vendor/respect/validation/docs/Url.md @@ -0,0 +1,24 @@ +# Url + +- `v::url()` + +Validates if input is an URL: + +```php +v::url()->validate('http://example.com'); // true +v::url()->validate('https://www.youtube.com/watch?v=6FOUqQt3Kg0'); // true +v::url()->validate('ldap://[::1]'); // true +v::url()->validate('mailto:john.doe@example.com'); // true +v::url()->validate('news:new.example.com'); // true +``` + +This rule uses [FilterVar](FilterVar.md) + +*** +See also: + + * [Domain](Domain.md) + * [Email](Email.md) + * [FilterVar](FilterVar.md) + * [Phone](Phone.md) + * [VideoUrl](VideoUrl.md) diff --git a/vendor/respect/validation/docs/VALIDATORS.md b/vendor/respect/validation/docs/VALIDATORS.md new file mode 100644 index 0000000000000000000000000000000000000000..4804cbee39d14c11fbdd5325884fbd9399c06964 --- /dev/null +++ b/vendor/respect/validation/docs/VALIDATORS.md @@ -0,0 +1,338 @@ +# Validators + +## Types + + * [ArrayVal](ArrayVal.md) + * [ArrayType](ArrayType.md) + * [BoolVal](BoolVal.md) + * [BoolType](BoolType.md) + * [CallableType](CallableType.md) + * [Countable](Countable.md) + * [Date](Date.md) + * [FalseVal](FalseVal.md) + * [FloatVal](FloatVal.md) + * [FloatType](FloatType.md) + * [Instance](Instance.md) + * [IntVal](IntVal.md) + * [IntType](IntType.md) + * [IterableType](IterableType.md) + * [NullType](NullType.md) + * [Numeric](Numeric.md) + * [ObjectType](ObjectType.md) + * [ResourceType](ResourceType.md) + * [ScalarVal](ScalarVal.md) + * [StringType](StringType.md) + * [TrueVal](TrueVal.md) + * [Type](Type.md) + * [Xdigit](Xdigit.md) + +## Generics + + * [AlwaysInvalid](AlwaysInvalid.md) + * [AlwaysValid](AlwaysValid.md) + * [Call](Call.md) + * [Callback](Callback.md) + * [FilterVar](FilterVar.md) + * [Not](Not.md) + * [Optional](Optional.md) + * [Type](Type.md) + * [When](When.md) + +## Comparing Values + + * [Age](Age.md) + * [Between](Between.md) + * [Equals](Equals.md) + * [Identical](Identical.md) + * [Max](Max.md) + * [Min](Min.md) + +## Numeric + + * [Between](Between.md) + * [BoolType](BoolType.md) + * [Even](Even.md) + * [Factor](Factor.md) + * [Fibonacci](Fibonacci.md) + * [Finite](Finite.md) + * [FloatVal](FloatVal.md) + * [FloatType](FloatType.md) + * [Infinite](Infinite.md) + * [IntVal](IntVal.md) + * [IntType](IntType.md) + * [Multiple](Multiple.md) + * [Negative](Negative.md) + * [NotEmpty](NotEmpty.md) + * [Numeric](Numeric.md) + * [Odd](Odd.md) + * [PerfectSquare](PerfectSquare.md) + * [Positive](Positive.md) + * [PrimeNumber](PrimeNumber.md) + * [Roman](Roman.md) + * [Xdigit](Xdigit.md) + +## String + + * [Alnum](Alnum.md) + * [Alpha](Alpha.md) + * [Between](Between.md) + * [Charset](Charset.md) + * [Cntrl](Cntrl.md) + * [Consonant](Consonant.md) + * [Contains](Contains.md) + * [Digit](Digit.md) + * [EndsWith](EndsWith.md) + * [Graph](Graph.md) + * [In](In.md) + * [Length](Length.md) + * [Lowercase](Lowercase.md) + * [NotEmpty](NotEmpty.md) + * [NoWhitespace](NoWhitespace.md) + * [PhpLabel](PhpLabel.md) + * [Prnt](Prnt.md) + * [Punct](Punct.md) + * [Regex](Regex.md) + * [ResourceType](ResourceType.md) + * [Slug](Slug.md) + * [Space](Space.md) + * [StartsWith](StartsWith.md) + * [Uppercase](Uppercase.md) + * [Version](Version.md) + * [Vowel](Vowel.md) + * [Xdigit](Xdigit.md) + +## Arrays + + * [ArrayVal](ArrayVal.md) + * [ArrayType](ArrayType.md) + * [Contains](Contains.md) + * [Each](Each.md) + * [EndsWith](EndsWith.md) + * [In](In.md) + * [Key](Key.md) + * [KeyNested](KeyNested.md) + * [KeySet](KeySet.md) + * [KeyValue](KeyValue.md) + * [Length](Length.md) + * [NotEmpty](NotEmpty.md) + * [StartsWith](StartsWith.md) + +## Objects + + * [Attribute](Attribute.md) + * [Instance](Instance.md) + * [Length](Length.md) + +## Date and Time + + * [Age](Age.md) + * [Between](Between.md) + * [Date](Date.md) + * [LeapDate](LeapDate.md) + * [LeapYear](LeapYear.md) + * [MinimumAge](MinimumAge.md) + +## Group Validators + + * [AllOf](AllOf.md) + * [NoneOf](NoneOf.md) + * [OneOf](OneOf.md) + +## Regional + + * [CountryCode](CountryCode.md) + * [CurrencyCode](CurrencyCode.md) + * [IdentityCard](IdentityCard.md) + * [LanguageCode](LanguageCode.md) + * [PostalCode](PostalCode.md) + * [SubdivisionCode](SubdivisionCode.md) + * [Tld](Tld.md) + +## Files + + * [Directory](Directory.md) + * [Executable](Executable.md) + * [Exists](Exists.md) + * [Extension](Extension.md) + * [File](File.md) + * [Image](Image.md) + * [Mimetype](Mimetype.md) + * [Readable](Readable.md) + * [Size](Size.md) + * [SymbolicLink](SymbolicLink.md) + * [Uploaded](Uploaded.md) + * [Writable](Writable.md) + +## Banking + + * [Bank](Bank.md) + * [BankAccount](BankAccount.md) + * [Bic](Bic.md) + +## Other + + * [Bsn](Bsn.md) + * [Cnh](Cnh.md) + * [Cnpj](Cnpj.md) + * [Cpf](Cpf.md) + * [Domain](Domain.md) + * [Email](Email.md) + * [HexRgbColor](HexRgbColor.md) + * [Imei](Imei.md) + * [Ip](Ip.md) + * [Json](Json.md) + * [MacAddress](MacAddress.md) + * [NfeAccessKey](NfeAccessKey.md) + * [NotBlank](NotBlank.md) + * [NotOptional](NotOptional.md) + * [Pesel](Pesel.md) + * [Phone](Phone.md) + * [Sf](Sf.md) + * [Url](Url.md) + * [VideoUrl](VideoUrl.md) + * [Zend](Zend.md) + +## Yes/No + + * [No](No.md) + * [Yes](Yes.md) + +## Alphabetically + + * [Age](Age.md) + * [AllOf](AllOf.md) + * [Alnum](Alnum.md) + * [Alpha](Alpha.md) + * [AlwaysInvalid](AlwaysInvalid.md) + * [AlwaysValid](AlwaysValid.md) + * [ArrayVal](ArrayVal.md) + * [ArrayType](ArrayType.md) + * [Attribute](Attribute.md) + * [Bank](Bank.md) + * [BankAccount](BankAccount.md) + * [Between](Between.md) + * [Bic](Bic.md) + * [BoolType](BoolType.md) + * [Bsn](Bsn.md) + * [Call](Call.md) + * [CallableType](CallableType.md) + * [Callback](Callback.md) + * [Charset](Charset.md) + * [Cnh](Cnh.md) + * [Cnpj](Cnpj.md) + * [Cntrl](Cntrl.md) + * [Consonant](Consonant.md) + * [Contains](Contains.md) + * [Countable](Countable.md) + * [CountryCode](CountryCode.md) + * [Cpf](Cpf.md) + * [CreditCard](CreditCard.md) + * [Date](Date.md) + * [Digit](Digit.md) + * [Directory](Directory.md) + * [Domain](Domain.md) + * [Each](Each.md) + * [Email](Email.md) + * [EndsWith](EndsWith.md) + * [Equals](Equals.md) + * [Even](Even.md) + * [Executable](Executable.md) + * [Exists](Exists.md) + * [Extension](Extension.md) + * [Factor](Factor.md) + * [FalseVal](FalseVal.md) + * [Fibonacci](Fibonacci.md) + * [File](File.md) + * [FilterVar](FilterVar.md) + * [Finite](Finite.md) + * [FloatVal](FloatVal.md) + * [FloatType](FloatType.md) + * [Graph](Graph.md) + * [HexRgbColor](HexRgbColor.md) + * [Identical](Identical.md) + * [IdentityCard](IdentityCard.md) + * [Image](Image.md) + * [Imei](Imei.md) + * [In](In.md) + * [Infinite](Infinite.md) + * [Instance](Instance.md) + * [IntVal](IntVal.md) + * [IntType](IntType.md) + * [Ip](Ip.md) + * [IterableType](IterableType.md) + * [Json](Json.md) + * [Key](Key.md) + * [KeyNested](KeyNested.md) + * [KeySet](KeySet.md) + * [KeyValue](KeyValue.md) + * [LanguageCode](LanguageCode.md) + * [LeapDate](LeapDate.md) + * [LeapYear](LeapYear.md) + * [Length](Length.md) + * [Lowercase](Lowercase.md) + * [MacAddress](MacAddress.md) + * [Max](Max.md) + * [Mimetype](Mimetype.md) + * [Min](Min.md) + * [MinimumAge](MinimumAge.md) + * [Multiple](Multiple.md) + * [Negative](Negative.md) + * [NfeAccessKey](NfeAccessKey.md) + * [No](No.md) + * [NoWhitespace](NoWhitespace.md) + * [NoneOf](NoneOf.md) + * [Not](Not.md) + * [NotBlank](NotBlank.md) + * [NotEmpty](NotEmpty.md) + * [NotOptional](NotOptional.md) + * [NullType](NullType.md) + * [Numeric](Numeric.md) + * [ObjectType](ObjectType.md) + * [Odd](Odd.md) + * [OneOf](OneOf.md) + * [Optional](Optional.md) + * [PerfectSquare](PerfectSquare.md) + * [Pesel](Pesel.md) + * [Phone](Phone.md) + * [PhpLabel](PhpLabel.md) + * [Positive](Positive.md) + * [PostalCode](PostalCode.md) + * [PrimeNumber](PrimeNumber.md) + * [Prnt](Prnt.md) + * [Punct](Punct.md) + * [Readable](Readable.md) + * [Regex](Regex.md) + * [ResourceType](ResourceType.md) + * [Roman](Roman.md) + * [ScalarVal](ScalarVal.md) + * [Sf](Sf.md) + * [Size](Size.md) + * [Slug](Slug.md) + * [Space](Space.md) + * [StartsWith](StartsWith.md) + * [StringType](StringType.md) + * [SubdivisionCode](SubdivisionCode.md) + * [SymbolicLink](SymbolicLink.md) + * [Tld](Tld.md) + * [TrueVal](TrueVal.md) + * [Type](Type.md) + * [Uploaded](Uploaded.md) + * [Uppercase](Uppercase.md) + * [Url](Url.md) + * [Version](Version.md) + * [VideoUrl](VideoUrl.md) + * [Vowel](Vowel.md) + * [When](When.md) + * [Writable](Writable.md) + * [Xdigit](Xdigit.md) + * [Yes](Yes.md) + * [Zend](Zend.md) + +*** +See also: + +- [Contributing](../CONTRIBUTING.md) +- [Feature Guide](README.md) +- [Installation](INSTALL.md) +- [License](../LICENSE.md) +- [Changelog](../CHANGELOG.md) diff --git a/vendor/respect/validation/docs/Version.md b/vendor/respect/validation/docs/Version.md new file mode 100644 index 0000000000000000000000000000000000000000..aad3ce8a3d02bc333d3bff0c11a9b359a67c66c7 --- /dev/null +++ b/vendor/respect/validation/docs/Version.md @@ -0,0 +1,16 @@ +# Version + +- `v::version()` + +Validates version numbers using Semantic Versioning. + +```php +v::version()->validate('1.0.0'); +``` + +*** +See also: + + * [Equals](Equals.md) + * [Regex](Regex.md) + * [Roman](Roman.md) diff --git a/vendor/respect/validation/docs/VideoUrl.md b/vendor/respect/validation/docs/VideoUrl.md new file mode 100644 index 0000000000000000000000000000000000000000..1ef962793bdc6082f57ad70d42f059a06095ca5a --- /dev/null +++ b/vendor/respect/validation/docs/VideoUrl.md @@ -0,0 +1,35 @@ +# VideoUrl + +- `v::videoUrl()` +- `v::videoUrl(string $service)` + +Validates if the input is a video URL value: + +```php +v::videoUrl()->validate('https://player.vimeo.com/video/71787467'); // true +v::videoUrl()->validate('https://vimeo.com/71787467'); // true +v::videoUrl()->validate('https://www.youtube.com/embed/netHLn9TScY'); // true +v::videoUrl()->validate('https://www.youtube.com/watch?v=netHLn9TScY'); // true +v::videoUrl()->validate('https://youtu.be/netHLn9TScY'); // true + +v::videoUrl('youtube')->validate('https://www.youtube.com/watch?v=netHLn9TScY'); // true +v::videoUrl('vimeo')->validate('https://vimeo.com/71787467'); // true + +v::videoUrl()->validate('https://youtube.com'); // false +v::videoUrl('youtube')->validate('https://vimeo.com/71787467'); // false +``` + +The services accepted are: + +- YouTube +- Vimeo + +The `$service` value is not case-sensitive. + +Message template for this validator includes `{{service}}`. + + +*** +See also: + + * [Url](Url.md) diff --git a/vendor/respect/validation/docs/Vowel.md b/vendor/respect/validation/docs/Vowel.md new file mode 100644 index 0000000000000000000000000000000000000000..98d806f5d90b39658d61d9e69dec3d86b5330e2f --- /dev/null +++ b/vendor/respect/validation/docs/Vowel.md @@ -0,0 +1,17 @@ +# Vowel + +- `v::vowel()` + +Similar to `v::alnum()`. Validates strings that contains only vowels: + +```php +v::vowel()->validate('aei'); // true +``` + +*** +See also: + + * [Alnum](Alnum.md) + * [Digit](Digit.md) + * [Alpha](Alpha.md) + * [Consonant](Consonant.md) diff --git a/vendor/respect/validation/docs/When.md b/vendor/respect/validation/docs/When.md new file mode 100644 index 0000000000000000000000000000000000000000..6254cb34d991733bd29c9b2281bad838f362a24e --- /dev/null +++ b/vendor/respect/validation/docs/When.md @@ -0,0 +1,24 @@ +# When + +- `v::when(v $if, v $then, v $else)` +- `v::when(v $if, v $then)` + +A ternary validator that accepts three parameters. + +When the `$if` validates, returns validation for `$then`. +When the `$if` doesn't validate, returns validation for `$else`, if defined. + +```php +v::when(v::intVal(), v::positive(), v::notEmpty())->validate($input); +``` + +In the sample above, if `$input` is an integer, then it must be positive. +If `$input` is not an integer, then it must not me empty. +When `$else` is not defined use [AlwaysInvalid](AlwaysInvalid.md) + +*** +See also: + + * [AllOf](AllOf.md) + * [OneOf](OneOf.md) + * [NoneOf](NoneOf.md) diff --git a/vendor/respect/validation/docs/Writable.md b/vendor/respect/validation/docs/Writable.md new file mode 100644 index 0000000000000000000000000000000000000000..b7aa5e436534c6fee4bdf42b5fdafefc7494b08f --- /dev/null +++ b/vendor/respect/validation/docs/Writable.md @@ -0,0 +1,23 @@ +# Writable + +- `v::writable()` + +Validates if the given input is writable file. + +```php +v::writable()->validate('/path/of/a/writable/file'); // true +``` + +*** +See also: + + * [Directory](Directory.md) + * [Executable](Executable.md) + * [Exists](Exists.md) + * [Extension](Extension.md) + * [File](File.md) + * [Mimetype](Mimetype.md) + * [Readable](Readable.md) + * [Size](Size.md) + * [SymbolicLink](SymbolicLink.md) + * [Uploaded](Uploaded.md) diff --git a/vendor/respect/validation/docs/Xdigit.md b/vendor/respect/validation/docs/Xdigit.md new file mode 100644 index 0000000000000000000000000000000000000000..9e79d0fdfc6b52ac263f8748ce5dc03c778c9c81 --- /dev/null +++ b/vendor/respect/validation/docs/Xdigit.md @@ -0,0 +1,22 @@ +# Xdigit + +- `v::xdigit()` + +Accepts an hexadecimal number: + +```php +v::xdigit()->validate('abc123'); // true +``` + +Notice, however, that it doesn't accept strings starting with 0x: + +```php +v::xdigit()->validate('0x1f'); // false +``` + +*** +See also: + + * [Digit](Digit.md) + * [Alnum](Alnum.md) + * [HexRgbColor](HexRgbColor.md) diff --git a/vendor/respect/validation/docs/Yes.md b/vendor/respect/validation/docs/Yes.md new file mode 100644 index 0000000000000000000000000000000000000000..9fef6d8f4d6b0e02e6b9dab619c39451b9f83db6 --- /dev/null +++ b/vendor/respect/validation/docs/Yes.md @@ -0,0 +1,23 @@ +# Yes + +- `v::yes()` +- `v::yes(boolean $locale)` + +Validates if value is considered as "Yes". + +```php +v::yes()->validate('Y'); // true +v::yes()->validate('Yea'); // true +v::yes()->validate('Yeah'); // true +v::yes()->validate('Yep'); // true +v::yes()->validate('Yes'); // true +``` + +This rule is case insensitive. + +If `$locale` is TRUE, uses the value of [nl_langinfo()](http://php.net/nl_langinfo) with `YESEXPR` constant. + +*** +See also: + + * [No](No.md) diff --git a/vendor/respect/validation/docs/Zend.md b/vendor/respect/validation/docs/Zend.md new file mode 100644 index 0000000000000000000000000000000000000000..8ec0ae8ed7ff8daf197e3ef1b5e42ed594ca2b94 --- /dev/null +++ b/vendor/respect/validation/docs/Zend.md @@ -0,0 +1,17 @@ +# Zend + +- `v::zend(mixed $validator)` + +Use Zend validators inside Respect\Validation flow. Messages +are preserved. + +```php +v::zend('Hostname')->validate('google.com'); +``` + +You must add `"zendframework/zend-validator": "~2.3"` to your `require` property on composer.json file. + +*** +See also: + + * [Sf](Sf.md)