summaryrefslogtreecommitdiff
path: root/vendor/guzzle/guzzle/src/Guzzle/Service
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/guzzle/guzzle/src/Guzzle/Service')
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/AbstractConfigLoader.php177
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilder.php189
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilderInterface.php40
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilderLoader.php89
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/CachingConfigLoader.php46
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Client.php297
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/ClientInterface.php68
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/AbstractCommand.php390
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/ClosureCommand.php41
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/CommandInterface.php128
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/CreateResponseClassEvent.php32
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/DefaultRequestSerializer.php169
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/DefaultResponseParser.php55
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/AliasFactory.php39
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/CompositeFactory.php154
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/ConcreteClassFactory.php47
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/FactoryInterface.php21
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/MapFactory.php27
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/ServiceDescriptionFactory.php71
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/AbstractRequestVisitor.php69
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/BodyVisitor.php58
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/HeaderVisitor.php44
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/JsonVisitor.php63
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/PostFieldVisitor.php18
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/PostFileVisitor.php24
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/QueryVisitor.php18
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/RequestVisitorInterface.php31
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/ResponseBodyVisitor.php18
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/XmlVisitor.php252
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/AbstractResponseVisitor.php26
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/BodyVisitor.php23
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/HeaderVisitor.php50
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/JsonVisitor.php93
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/ReasonPhraseVisitor.php23
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/ResponseVisitorInterface.php46
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/StatusCodeVisitor.php23
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/XmlVisitor.php151
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/VisitorFlyweight.php138
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/OperationCommand.php89
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/OperationResponseParser.php195
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/RequestSerializerInterface.php21
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/ResponseClassInterface.php18
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Command/ResponseParserInterface.php18
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/ConfigLoaderInterface.php22
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Description/Operation.php547
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Description/OperationInterface.php159
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Description/Parameter.php925
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Description/SchemaFormatter.php156
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Description/SchemaValidator.php291
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescription.php271
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescriptionInterface.php106
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescriptionLoader.php64
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Description/ValidatorInterface.php28
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Exception/CommandException.php7
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Exception/CommandTransferException.php119
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Exception/DescriptionBuilderException.php7
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Exception/InconsistentClientTransferException.php38
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ResponseClassException.php9
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ServiceBuilderException.php7
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ServiceNotFoundException.php5
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ValidationException.php30
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Resource/AbstractResourceIteratorFactory.php37
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Resource/CompositeResourceIteratorFactory.php67
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Resource/MapResourceIteratorFactory.php34
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Resource/Model.php64
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIterator.php254
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorApplyBatched.php111
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorClassFactory.php60
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorFactoryInterface.php30
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorInterface.php61
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Service/composer.json29
71 files changed, 7127 insertions, 0 deletions
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/AbstractConfigLoader.php b/vendor/guzzle/guzzle/src/Guzzle/Service/AbstractConfigLoader.php
new file mode 100644
index 0000000..cd06f57
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/AbstractConfigLoader.php
@@ -0,0 +1,177 @@
+<?php
+
+namespace Guzzle\Service;
+
+use Guzzle\Common\Exception\InvalidArgumentException;
+use Guzzle\Common\Exception\RuntimeException;
+
+/**
+ * Abstract config loader
+ */
+abstract class AbstractConfigLoader implements ConfigLoaderInterface
+{
+ /** @var array Array of aliases for actual filenames */
+ protected $aliases = array();
+
+ /** @var array Hash of previously loaded filenames */
+ protected $loadedFiles = array();
+
+ /** @var array JSON error code mappings */
+ protected static $jsonErrors = array(
+ JSON_ERROR_NONE => 'JSON_ERROR_NONE - No errors',
+ JSON_ERROR_DEPTH => 'JSON_ERROR_DEPTH - Maximum stack depth exceeded',
+ JSON_ERROR_STATE_MISMATCH => 'JSON_ERROR_STATE_MISMATCH - Underflow or the modes mismatch',
+ JSON_ERROR_CTRL_CHAR => 'JSON_ERROR_CTRL_CHAR - Unexpected control character found',
+ JSON_ERROR_SYNTAX => 'JSON_ERROR_SYNTAX - Syntax error, malformed JSON',
+ JSON_ERROR_UTF8 => 'JSON_ERROR_UTF8 - Malformed UTF-8 characters, possibly incorrectly encoded'
+ );
+
+ public function load($config, array $options = array())
+ {
+ // Reset the array of loaded files because this is a new config
+ $this->loadedFiles = array();
+
+ if (is_string($config)) {
+ $config = $this->loadFile($config);
+ } elseif (!is_array($config)) {
+ throw new InvalidArgumentException('Unknown type passed to configuration loader: ' . gettype($config));
+ } else {
+ $this->mergeIncludes($config);
+ }
+
+ return $this->build($config, $options);
+ }
+
+ /**
+ * Add an include alias to the loader
+ *
+ * @param string $filename Filename to alias (e.g. _foo)
+ * @param string $alias Actual file to use (e.g. /path/to/foo.json)
+ *
+ * @return self
+ */
+ public function addAlias($filename, $alias)
+ {
+ $this->aliases[$filename] = $alias;
+
+ return $this;
+ }
+
+ /**
+ * Remove an alias from the loader
+ *
+ * @param string $alias Alias to remove
+ *
+ * @return self
+ */
+ public function removeAlias($alias)
+ {
+ unset($this->aliases[$alias]);
+
+ return $this;
+ }
+
+ /**
+ * Perform the parsing of a config file and create the end result
+ *
+ * @param array $config Configuration data
+ * @param array $options Options to use when building
+ *
+ * @return mixed
+ */
+ protected abstract function build($config, array $options);
+
+ /**
+ * Load a configuration file (can load JSON or PHP files that return an array when included)
+ *
+ * @param string $filename File to load
+ *
+ * @return array
+ * @throws InvalidArgumentException
+ * @throws RuntimeException when the JSON cannot be parsed
+ */
+ protected function loadFile($filename)
+ {
+ if (isset($this->aliases[$filename])) {
+ $filename = $this->aliases[$filename];
+ }
+
+ switch (pathinfo($filename, PATHINFO_EXTENSION)) {
+ case 'js':
+ case 'json':
+ $level = error_reporting(0);
+ $json = file_get_contents($filename);
+ error_reporting($level);
+
+ if ($json === false) {
+ $err = error_get_last();
+ throw new InvalidArgumentException("Unable to open {$filename}: " . $err['message']);
+ }
+
+ $config = json_decode($json, true);
+ // Throw an exception if there was an error loading the file
+ if ($error = json_last_error()) {
+ $message = isset(self::$jsonErrors[$error]) ? self::$jsonErrors[$error] : 'Unknown error';
+ throw new RuntimeException("Error loading JSON data from {$filename}: ({$error}) - {$message}");
+ }
+ break;
+ case 'php':
+ if (!is_readable($filename)) {
+ throw new InvalidArgumentException("Unable to open {$filename} for reading");
+ }
+ $config = require $filename;
+ if (!is_array($config)) {
+ throw new InvalidArgumentException('PHP files must return an array of configuration data');
+ }
+ break;
+ default:
+ throw new InvalidArgumentException('Unknown file extension: ' . $filename);
+ }
+
+ // Keep track of this file being loaded to prevent infinite recursion
+ $this->loadedFiles[$filename] = true;
+
+ // Merge include files into the configuration array
+ $this->mergeIncludes($config, dirname($filename));
+
+ return $config;
+ }
+
+ /**
+ * Merges in all include files
+ *
+ * @param array $config Config data that contains includes
+ * @param string $basePath Base path to use when a relative path is encountered
+ *
+ * @return array Returns the merged and included data
+ */
+ protected function mergeIncludes(&$config, $basePath = null)
+ {
+ if (!empty($config['includes'])) {
+ foreach ($config['includes'] as &$path) {
+ // Account for relative paths
+ if ($path[0] != DIRECTORY_SEPARATOR && !isset($this->aliases[$path]) && $basePath) {
+ $path = "{$basePath}/{$path}";
+ }
+ // Don't load the same files more than once
+ if (!isset($this->loadedFiles[$path])) {
+ $this->loadedFiles[$path] = true;
+ $config = $this->mergeData($this->loadFile($path), $config);
+ }
+ }
+ }
+ }
+
+ /**
+ * Default implementation for merging two arrays of data (uses array_merge_recursive)
+ *
+ * @param array $a Original data
+ * @param array $b Data to merge into the original and overwrite existing values
+ *
+ * @return array
+ */
+ protected function mergeData(array $a, array $b)
+ {
+ return array_merge_recursive($a, $b);
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilder.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilder.php
new file mode 100644
index 0000000..38150db
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilder.php
@@ -0,0 +1,189 @@
+<?php
+
+namespace Guzzle\Service\Builder;
+
+use Guzzle\Common\AbstractHasDispatcher;
+use Guzzle\Service\ClientInterface;
+use Guzzle\Service\Exception\ServiceBuilderException;
+use Guzzle\Service\Exception\ServiceNotFoundException;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * {@inheritdoc}
+ *
+ * Clients and data can be set, retrieved, and removed by accessing the service builder like an associative array.
+ */
+class ServiceBuilder extends AbstractHasDispatcher implements ServiceBuilderInterface, \ArrayAccess, \Serializable
+{
+ /** @var array Service builder configuration data */
+ protected $builderConfig = array();
+
+ /** @var array Instantiated client objects */
+ protected $clients = array();
+
+ /** @var ServiceBuilderLoader Cached instance of the service builder loader */
+ protected static $cachedFactory;
+
+ /** @var array Plugins to attach to each client created by the service builder */
+ protected $plugins = array();
+
+ /**
+ * Create a new ServiceBuilder using configuration data sourced from an
+ * array, .js|.json or .php file.
+ *
+ * @param array|string $config The full path to an .json|.js or .php file, or an associative array
+ * @param array $globalParameters Array of global parameters to pass to every service as it is instantiated.
+ *
+ * @return ServiceBuilderInterface
+ * @throws ServiceBuilderException if a file cannot be opened
+ * @throws ServiceNotFoundException when trying to extend a missing client
+ */
+ public static function factory($config = null, array $globalParameters = array())
+ {
+ // @codeCoverageIgnoreStart
+ if (!static::$cachedFactory) {
+ static::$cachedFactory = new ServiceBuilderLoader();
+ }
+ // @codeCoverageIgnoreEnd
+
+ return self::$cachedFactory->load($config, $globalParameters);
+ }
+
+ /**
+ * @param array $serviceBuilderConfig Service configuration settings:
+ * - name: Name of the service
+ * - class: Client class to instantiate using a factory method
+ * - params: array of key value pair configuration settings for the builder
+ */
+ public function __construct(array $serviceBuilderConfig = array())
+ {
+ $this->builderConfig = $serviceBuilderConfig;
+ }
+
+ public static function getAllEvents()
+ {
+ return array('service_builder.create_client');
+ }
+
+ public function unserialize($serialized)
+ {
+ $this->builderConfig = json_decode($serialized, true);
+ }
+
+ public function serialize()
+ {
+ return json_encode($this->builderConfig);
+ }
+
+ /**
+ * Attach a plugin to every client created by the builder
+ *
+ * @param EventSubscriberInterface $plugin Plugin to attach to each client
+ *
+ * @return self
+ */
+ public function addGlobalPlugin(EventSubscriberInterface $plugin)
+ {
+ $this->plugins[] = $plugin;
+
+ return $this;
+ }
+
+ /**
+ * Get data from the service builder without triggering the building of a service
+ *
+ * @param string $name Name of the service to retrieve
+ *
+ * @return array|null
+ */
+ public function getData($name)
+ {
+ return isset($this->builderConfig[$name]) ? $this->builderConfig[$name] : null;
+ }
+
+ public function get($name, $throwAway = false)
+ {
+ if (!isset($this->builderConfig[$name])) {
+
+ // Check to see if arbitrary data is being referenced
+ if (isset($this->clients[$name])) {
+ return $this->clients[$name];
+ }
+
+ // Check aliases and return a match if found
+ foreach ($this->builderConfig as $actualName => $config) {
+ if (isset($config['alias']) && $config['alias'] == $name) {
+ return $this->get($actualName, $throwAway);
+ }
+ }
+ throw new ServiceNotFoundException('No service is registered as ' . $name);
+ }
+
+ if (!$throwAway && isset($this->clients[$name])) {
+ return $this->clients[$name];
+ }
+
+ $builder =& $this->builderConfig[$name];
+
+ // Convert references to the actual client
+ foreach ($builder['params'] as &$v) {
+ if (is_string($v) && substr($v, 0, 1) == '{' && substr($v, -1) == '}') {
+ $v = $this->get(trim($v, '{} '));
+ }
+ }
+
+ // Get the configured parameters and merge in any parameters provided for throw-away clients
+ $config = $builder['params'];
+ if (is_array($throwAway)) {
+ $config = $throwAway + $config;
+ }
+
+ $client = $builder['class']::factory($config);
+
+ if (!$throwAway) {
+ $this->clients[$name] = $client;
+ }
+
+ if ($client instanceof ClientInterface) {
+ foreach ($this->plugins as $plugin) {
+ $client->addSubscriber($plugin);
+ }
+ // Dispatch an event letting listeners know a client was created
+ $this->dispatch('service_builder.create_client', array('client' => $client));
+ }
+
+ return $client;
+ }
+
+ public function set($key, $service)
+ {
+ if (is_array($service) && isset($service['class']) && isset($service['params'])) {
+ $this->builderConfig[$key] = $service;
+ } else {
+ $this->clients[$key] = $service;
+ }
+
+ return $this;
+ }
+
+ public function offsetSet($offset, $value)
+ {
+ $this->set($offset, $value);
+ }
+
+ public function offsetUnset($offset)
+ {
+ unset($this->builderConfig[$offset]);
+ unset($this->clients[$offset]);
+ }
+
+ public function offsetExists($offset)
+ {
+ return isset($this->builderConfig[$offset]) || isset($this->clients[$offset]);
+ }
+
+ public function offsetGet($offset)
+ {
+ return $this->get($offset);
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilderInterface.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilderInterface.php
new file mode 100644
index 0000000..4fc310a
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilderInterface.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Guzzle\Service\Builder;
+
+use Guzzle\Service\Exception\ServiceNotFoundException;
+
+/**
+ * Service builder used to store and build clients or arbitrary data. Client configuration data can be supplied to tell
+ * the service builder how to create and cache {@see \Guzzle\Service\ClientInterface} objects. Arbitrary data can be
+ * supplied and accessed from a service builder. Arbitrary data and other clients can be referenced by name in client
+ * configuration arrays to make them input for building other clients (e.g. "{key}").
+ */
+interface ServiceBuilderInterface
+{
+ /**
+ * Get a ClientInterface object or arbitrary data from the service builder
+ *
+ * @param string $name Name of the registered service or data to retrieve
+ * @param bool|array $throwAway Only pertains to retrieving client objects built using a configuration array.
+ * Set to TRUE to not store the client for later retrieval from the ServiceBuilder.
+ * If an array is specified, that data will overwrite the configured params of the
+ * client if the client implements {@see \Guzzle\Common\FromConfigInterface} and will
+ * not store the client for later retrieval.
+ *
+ * @return \Guzzle\Service\ClientInterface|mixed
+ * @throws ServiceNotFoundException when a client or data cannot be found by the given name
+ */
+ public function get($name, $throwAway = false);
+
+ /**
+ * Register a service or arbitrary data by name with the service builder
+ *
+ * @param string $key Name of the client or data to register
+ * @param mixed $service Client configuration array or arbitrary data to register. The client configuration array
+ * must include a 'class' (string) and 'params' (array) key.
+ *
+ * @return ServiceBuilderInterface
+ */
+ public function set($key, $service);
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilderLoader.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilderLoader.php
new file mode 100644
index 0000000..c561a3d
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Builder/ServiceBuilderLoader.php
@@ -0,0 +1,89 @@
+<?php
+
+namespace Guzzle\Service\Builder;
+
+use Guzzle\Service\AbstractConfigLoader;
+use Guzzle\Service\Exception\ServiceNotFoundException;
+
+/**
+ * Service builder config loader
+ */
+class ServiceBuilderLoader extends AbstractConfigLoader
+{
+ protected function build($config, array $options)
+ {
+ // A service builder class can be specified in the class field
+ $class = !empty($config['class']) ? $config['class'] : __NAMESPACE__ . '\\ServiceBuilder';
+
+ // Account for old style configs that do not have a services array
+ $services = isset($config['services']) ? $config['services'] : $config;
+
+ // Validate the configuration and handle extensions
+ foreach ($services as $name => &$service) {
+
+ $service['params'] = isset($service['params']) ? $service['params'] : array();
+
+ // Check if this client builder extends another client
+ if (!empty($service['extends'])) {
+
+ // Make sure that the service it's extending has been defined
+ if (!isset($services[$service['extends']])) {
+ throw new ServiceNotFoundException(
+ "{$name} is trying to extend a non-existent service: {$service['extends']}"
+ );
+ }
+
+ $extended = &$services[$service['extends']];
+
+ // Use the correct class attribute
+ if (empty($service['class'])) {
+ $service['class'] = isset($extended['class']) ? $extended['class'] : '';
+ }
+ if ($extendsParams = isset($extended['params']) ? $extended['params'] : false) {
+ $service['params'] = $service['params'] + $extendsParams;
+ }
+ }
+
+ // Overwrite default values with global parameter values
+ if (!empty($options)) {
+ $service['params'] = $options + $service['params'];
+ }
+
+ $service['class'] = isset($service['class']) ? $service['class'] : '';
+ }
+
+ return new $class($services);
+ }
+
+ protected function mergeData(array $a, array $b)
+ {
+ $result = $b + $a;
+
+ // Merge services using a recursive union of arrays
+ if (isset($a['services']) && $b['services']) {
+
+ // Get a union of the services of the two arrays
+ $result['services'] = $b['services'] + $a['services'];
+
+ // Merge each service in using a union of the two arrays
+ foreach ($result['services'] as $name => &$service) {
+
+ // By default, services completely override a previously defined service unless it extends itself
+ if (isset($a['services'][$name]['extends'])
+ && isset($b['services'][$name]['extends'])
+ && $b['services'][$name]['extends'] == $name
+ ) {
+ $service += $a['services'][$name];
+ // Use the `extends` attribute of the parent
+ $service['extends'] = $a['services'][$name]['extends'];
+ // Merge parameters using a union if both have parameters
+ if (isset($a['services'][$name]['params'])) {
+ $service['params'] += $a['services'][$name]['params'];
+ }
+ }
+ }
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/CachingConfigLoader.php b/vendor/guzzle/guzzle/src/Guzzle/Service/CachingConfigLoader.php
new file mode 100644
index 0000000..26f8360
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/CachingConfigLoader.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Guzzle\Service;
+
+use Guzzle\Cache\CacheAdapterInterface;
+
+/**
+ * Decorator that adds caching to a service description loader
+ */
+class CachingConfigLoader implements ConfigLoaderInterface
+{
+ /** @var ConfigLoaderInterface */
+ protected $loader;
+
+ /** @var CacheAdapterInterface */
+ protected $cache;
+
+ /**
+ * @param ConfigLoaderInterface $loader Loader used to load the config when there is a cache miss
+ * @param CacheAdapterInterface $cache Object used to cache the loaded result
+ */
+ public function __construct(ConfigLoaderInterface $loader, CacheAdapterInterface $cache)
+ {
+ $this->loader = $loader;
+ $this->cache = $cache;
+ }
+
+ public function load($config, array $options = array())
+ {
+ if (!is_string($config)) {
+ $key = false;
+ } else {
+ $key = 'loader_' . crc32($config);
+ if ($result = $this->cache->fetch($key)) {
+ return $result;
+ }
+ }
+
+ $result = $this->loader->load($config, $options);
+ if ($key) {
+ $this->cache->save($key, $result);
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Client.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Client.php
new file mode 100644
index 0000000..3e5f8e5
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Client.php
@@ -0,0 +1,297 @@
+<?php
+
+namespace Guzzle\Service;
+
+use Guzzle\Common\Collection;
+use Guzzle\Common\Exception\InvalidArgumentException;
+use Guzzle\Common\Exception\BadMethodCallException;
+use Guzzle\Common\Version;
+use Guzzle\Inflection\InflectorInterface;
+use Guzzle\Inflection\Inflector;
+use Guzzle\Http\Client as HttpClient;
+use Guzzle\Http\Exception\MultiTransferException;
+use Guzzle\Service\Exception\CommandTransferException;
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Service\Command\CommandInterface;
+use Guzzle\Service\Command\Factory\CompositeFactory;
+use Guzzle\Service\Command\Factory\FactoryInterface as CommandFactoryInterface;
+use Guzzle\Service\Resource\ResourceIteratorClassFactory;
+use Guzzle\Service\Resource\ResourceIteratorFactoryInterface;
+use Guzzle\Service\Description\ServiceDescriptionInterface;
+
+/**
+ * Client object for executing commands on a web service.
+ */
+class Client extends HttpClient implements ClientInterface
+{
+ const COMMAND_PARAMS = 'command.params';
+
+ /** @var ServiceDescriptionInterface Description of the service and possible commands */
+ protected $serviceDescription;
+
+ /** @var CommandFactoryInterface */
+ protected $commandFactory;
+
+ /** @var ResourceIteratorFactoryInterface */
+ protected $resourceIteratorFactory;
+
+ /** @var InflectorInterface Inflector associated with the service/client */
+ protected $inflector;
+
+ /**
+ * Basic factory method to create a new client. Extend this method in subclasses to build more complex clients.
+ *
+ * @param array|Collection $config Configuration data
+ *
+ * @return Client
+ */
+ public static function factory($config = array())
+ {
+ return new static(isset($config['base_url']) ? $config['base_url'] : null, $config);
+ }
+
+ public static function getAllEvents()
+ {
+ return array_merge(HttpClient::getAllEvents(), array(
+ 'client.command.create',
+ 'command.before_prepare',
+ 'command.after_prepare',
+ 'command.before_send',
+ 'command.after_send',
+ 'command.parse_response'
+ ));
+ }
+
+ /**
+ * Magic method used to retrieve a command
+ *
+ * @param string $method Name of the command object to instantiate
+ * @param array $args Arguments to pass to the command
+ *
+ * @return mixed Returns the result of the command
+ * @throws BadMethodCallException when a command is not found
+ */
+ public function __call($method, $args)
+ {
+ return $this->getCommand($method, isset($args[0]) ? $args[0] : array())->getResult();
+ }
+
+ public function getCommand($name, array $args = array())
+ {
+ // Add global client options to the command
+ if ($options = $this->getConfig(self::COMMAND_PARAMS)) {
+ $args += $options;
+ }
+
+ if (!($command = $this->getCommandFactory()->factory($name, $args))) {
+ throw new InvalidArgumentException("Command was not found matching {$name}");
+ }
+
+ $command->setClient($this);
+ $this->dispatch('client.command.create', array('client' => $this, 'command' => $command));
+
+ return $command;
+ }
+
+ /**
+ * Set the command factory used to create commands by name
+ *
+ * @param CommandFactoryInterface $factory Command factory
+ *
+ * @return self
+ */
+ public function setCommandFactory(CommandFactoryInterface $factory)
+ {
+ $this->commandFactory = $factory;
+
+ return $this;
+ }
+
+ /**
+ * Set the resource iterator factory associated with the client
+ *
+ * @param ResourceIteratorFactoryInterface $factory Resource iterator factory
+ *
+ * @return self
+ */
+ public function setResourceIteratorFactory(ResourceIteratorFactoryInterface $factory)
+ {
+ $this->resourceIteratorFactory = $factory;
+
+ return $this;
+ }
+
+ public function getIterator($command, array $commandOptions = null, array $iteratorOptions = array())
+ {
+ if (!($command instanceof CommandInterface)) {
+ $command = $this->getCommand($command, $commandOptions ?: array());
+ }
+
+ return $this->getResourceIteratorFactory()->build($command, $iteratorOptions);
+ }
+
+ public function execute($command)
+ {
+ if ($command instanceof CommandInterface) {
+ $this->send($this->prepareCommand($command));
+ $this->dispatch('command.after_send', array('command' => $command));
+ return $command->getResult();
+ } elseif (is_array($command) || $command instanceof \Traversable) {
+ return $this->executeMultiple($command);
+ } else {
+ throw new InvalidArgumentException('Command must be a command or array of commands');
+ }
+ }
+
+ public function setDescription(ServiceDescriptionInterface $service)
+ {
+ $this->serviceDescription = $service;
+
+ if ($this->getCommandFactory() && $this->getCommandFactory() instanceof CompositeFactory) {
+ $this->commandFactory->add(new Command\Factory\ServiceDescriptionFactory($service));
+ }
+
+ // If a baseUrl was set on the description, then update the client
+ if ($baseUrl = $service->getBaseUrl()) {
+ $this->setBaseUrl($baseUrl);
+ }
+
+ return $this;
+ }
+
+ public function getDescription()
+ {
+ return $this->serviceDescription;
+ }
+
+ /**
+ * Set the inflector used with the client
+ *
+ * @param InflectorInterface $inflector Inflection object
+ *
+ * @return self
+ */
+ public function setInflector(InflectorInterface $inflector)
+ {
+ $this->inflector = $inflector;
+
+ return $this;
+ }
+
+ /**
+ * Get the inflector used with the client
+ *
+ * @return self
+ */
+ public function getInflector()
+ {
+ if (!$this->inflector) {
+ $this->inflector = Inflector::getDefault();
+ }
+
+ return $this->inflector;
+ }
+
+ /**
+ * Prepare a command for sending and get the RequestInterface object created by the command
+ *
+ * @param CommandInterface $command Command to prepare
+ *
+ * @return RequestInterface
+ */
+ protected function prepareCommand(CommandInterface $command)
+ {
+ // Set the client and prepare the command
+ $request = $command->setClient($this)->prepare();
+ // Set the state to new if the command was previously executed
+ $request->setState(RequestInterface::STATE_NEW);
+ $this->dispatch('command.before_send', array('command' => $command));
+
+ return $request;
+ }
+
+ /**
+ * Execute multiple commands in parallel
+ *
+ * @param array|Traversable $commands Array of CommandInterface objects to execute
+ *
+ * @return array Returns an array of the executed commands
+ * @throws Exception\CommandTransferException
+ */
+ protected function executeMultiple($commands)
+ {
+ $requests = array();
+ $commandRequests = new \SplObjectStorage();
+
+ foreach ($commands as $command) {
+ $request = $this->prepareCommand($command);
+ $commandRequests[$request] = $command;
+ $requests[] = $request;
+ }
+
+ try {
+ $this->send($requests);
+ foreach ($commands as $command) {
+ $this->dispatch('command.after_send', array('command' => $command));
+ }
+ return $commands;
+ } catch (MultiTransferException $failureException) {
+ // Throw a CommandTransferException using the successful and failed commands
+ $e = CommandTransferException::fromMultiTransferException($failureException);
+
+ // Remove failed requests from the successful requests array and add to the failures array
+ foreach ($failureException->getFailedRequests() as $request) {
+ if (isset($commandRequests[$request])) {
+ $e->addFailedCommand($commandRequests[$request]);
+ unset($commandRequests[$request]);
+ }
+ }
+
+ // Always emit the command after_send events for successful commands
+ foreach ($commandRequests as $success) {
+ $e->addSuccessfulCommand($commandRequests[$success]);
+ $this->dispatch('command.after_send', array('command' => $commandRequests[$success]));
+ }
+
+ throw $e;
+ }
+ }
+
+ protected function getResourceIteratorFactory()
+ {
+ if (!$this->resourceIteratorFactory) {
+ // Build the default resource iterator factory if one is not set
+ $clientClass = get_class($this);
+ $prefix = substr($clientClass, 0, strrpos($clientClass, '\\'));
+ $this->resourceIteratorFactory = new ResourceIteratorClassFactory(array(
+ "{$prefix}\\Iterator",
+ "{$prefix}\\Model"
+ ));
+ }
+
+ return $this->resourceIteratorFactory;
+ }
+
+ /**
+ * Get the command factory associated with the client
+ *
+ * @return CommandFactoryInterface
+ */
+ protected function getCommandFactory()
+ {
+ if (!$this->commandFactory) {
+ $this->commandFactory = CompositeFactory::getDefaultChain($this);
+ }
+
+ return $this->commandFactory;
+ }
+
+ /**
+ * @deprecated
+ * @codeCoverageIgnore
+ */
+ public function enableMagicMethods($isEnabled)
+ {
+ Version::warn(__METHOD__ . ' is deprecated');
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/ClientInterface.php b/vendor/guzzle/guzzle/src/Guzzle/Service/ClientInterface.php
new file mode 100644
index 0000000..814154f
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/ClientInterface.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Guzzle\Service;
+
+use Guzzle\Common\FromConfigInterface;
+use Guzzle\Common\Exception\InvalidArgumentException;
+use Guzzle\Http\ClientInterface as HttpClientInterface;
+use Guzzle\Service\Exception\CommandTransferException;
+use Guzzle\Service\Command\CommandInterface;
+use Guzzle\Service\Description\ServiceDescriptionInterface;
+use Guzzle\Service\Resource\ResourceIteratorInterface;
+
+/**
+ * Client interface for executing commands on a web service.
+ */
+interface ClientInterface extends HttpClientInterface, FromConfigInterface
+{
+ /**
+ * Get a command by name. First, the client will see if it has a service description and if the service description
+ * defines a command by the supplied name. If no dynamic command is found, the client will look for a concrete
+ * command class exists matching the name supplied. If neither are found, an InvalidArgumentException is thrown.
+ *
+ * @param string $name Name of the command to retrieve
+ * @param array $args Arguments to pass to the command
+ *
+ * @return CommandInterface
+ * @throws InvalidArgumentException if no command can be found by name
+ */
+ public function getCommand($name, array $args = array());
+
+ /**
+ * Execute one or more commands
+ *
+ * @param CommandInterface|array|Traversable $command Command, array of commands or Traversable object containing commands to execute
+ *
+ * @return mixed Returns the result of the executed command or an array of commands if executing multiple commands
+ * @throws InvalidArgumentException if an invalid command is passed
+ * @throws CommandTransferException if an exception is encountered when transferring multiple commands
+ */
+ public function execute($command);
+
+ /**
+ * Set the service description of the client
+ *
+ * @param ServiceDescriptionInterface $service Service description
+ *
+ * @return ClientInterface
+ */
+ public function setDescription(ServiceDescriptionInterface $service);
+
+ /**
+ * Get the service description of the client
+ *
+ * @return ServiceDescriptionInterface|null
+ */
+ public function getDescription();
+
+ /**
+ * Get a resource iterator from the client.
+ *
+ * @param string|CommandInterface $command Command class or command name.
+ * @param array $commandOptions Command options used when creating commands.
+ * @param array $iteratorOptions Iterator options passed to the iterator when it is instantiated.
+ *
+ * @return ResourceIteratorInterface
+ */
+ public function getIterator($command, array $commandOptions = null, array $iteratorOptions = array());
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/AbstractCommand.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/AbstractCommand.php
new file mode 100644
index 0000000..e42ff90
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/AbstractCommand.php
@@ -0,0 +1,390 @@
+<?php
+
+namespace Guzzle\Service\Command;
+
+use Guzzle\Common\Collection;
+use Guzzle\Common\Exception\InvalidArgumentException;
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Http\Curl\CurlHandle;
+use Guzzle\Service\Client;
+use Guzzle\Service\ClientInterface;
+use Guzzle\Service\Description\Operation;
+use Guzzle\Service\Description\OperationInterface;
+use Guzzle\Service\Description\ValidatorInterface;
+use Guzzle\Service\Description\SchemaValidator;
+use Guzzle\Service\Exception\CommandException;
+use Guzzle\Service\Exception\ValidationException;
+
+/**
+ * Command object to handle preparing and processing client requests and responses of the requests
+ */
+abstract class AbstractCommand extends Collection implements CommandInterface
+{
+ // @deprecated: Option used to specify custom headers to add to the generated request
+ const HEADERS_OPTION = 'command.headers';
+ // @deprecated: Option used to add an onComplete method to a command
+ const ON_COMPLETE = 'command.on_complete';
+ // @deprecated: Option used to change the entity body used to store a response
+ const RESPONSE_BODY = 'command.response_body';
+
+ // Option used to add request options to the request created by a command
+ const REQUEST_OPTIONS = 'command.request_options';
+ // command values to not count as additionalParameters
+ const HIDDEN_PARAMS = 'command.hidden_params';
+ // Option used to disable any pre-sending command validation
+ const DISABLE_VALIDATION = 'command.disable_validation';
+ // Option used to override how a command result will be formatted
+ const RESPONSE_PROCESSING = 'command.response_processing';
+ // Different response types that commands can use
+ const TYPE_RAW = 'raw';
+ const TYPE_MODEL = 'model';
+ const TYPE_NO_TRANSLATION = 'no_translation';
+
+ /** @var ClientInterface Client object used to execute the command */
+ protected $client;
+
+ /** @var RequestInterface The request object associated with the command */
+ protected $request;
+
+ /** @var mixed The result of the command */
+ protected $result;
+
+ /** @var OperationInterface API information about the command */
+ protected $operation;
+
+ /** @var mixed callable */
+ protected $onComplete;
+
+ /** @var ValidatorInterface Validator used to prepare and validate properties against a JSON schema */
+ protected $validator;
+
+ /**
+ * @param array|Collection $parameters Collection of parameters to set on the command
+ * @param OperationInterface $operation Command definition from description
+ */
+ public function __construct($parameters = array(), OperationInterface $operation = null)
+ {
+ parent::__construct($parameters);
+ $this->operation = $operation ?: $this->createOperation();
+ foreach ($this->operation->getParams() as $name => $arg) {
+ $currentValue = $this[$name];
+ $configValue = $arg->getValue($currentValue);
+ // If default or static values are set, then this should always be updated on the config object
+ if ($currentValue !== $configValue) {
+ $this[$name] = $configValue;
+ }
+ }
+
+ $headers = $this[self::HEADERS_OPTION];
+ if (!$headers instanceof Collection) {
+ $this[self::HEADERS_OPTION] = new Collection((array) $headers);
+ }
+
+ // You can set a command.on_complete option in your parameters to set an onComplete callback
+ if ($onComplete = $this['command.on_complete']) {
+ unset($this['command.on_complete']);
+ $this->setOnComplete($onComplete);
+ }
+
+ // Set the hidden additional parameters
+ if (!$this[self::HIDDEN_PARAMS]) {
+ $this[self::HIDDEN_PARAMS] = array(
+ self::HEADERS_OPTION,
+ self::RESPONSE_PROCESSING,
+ self::HIDDEN_PARAMS,
+ self::REQUEST_OPTIONS
+ );
+ }
+
+ $this->init();
+ }
+
+ /**
+ * Custom clone behavior
+ */
+ public function __clone()
+ {
+ $this->request = null;
+ $this->result = null;
+ }
+
+ /**
+ * Execute the command in the same manner as calling a function
+ *
+ * @return mixed Returns the result of {@see AbstractCommand::execute}
+ */
+ public function __invoke()
+ {
+ return $this->execute();
+ }
+
+ public function getName()
+ {
+ return $this->operation->getName();
+ }
+
+ /**
+ * Get the API command information about the command
+ *
+ * @return OperationInterface
+ */
+ public function getOperation()
+ {
+ return $this->operation;
+ }
+
+ public function setOnComplete($callable)
+ {
+ if (!is_callable($callable)) {
+ throw new InvalidArgumentException('The onComplete function must be callable');
+ }
+
+ $this->onComplete = $callable;
+
+ return $this;
+ }
+
+ public function execute()
+ {
+ if (!$this->client) {
+ throw new CommandException('A client must be associated with the command before it can be executed.');
+ }
+
+ return $this->client->execute($this);
+ }
+
+ public function getClient()
+ {
+ return $this->client;
+ }
+
+ public function setClient(ClientInterface $client)
+ {
+ $this->client = $client;
+
+ return $this;
+ }
+
+ public function getRequest()
+ {
+ if (!$this->request) {
+ throw new CommandException('The command must be prepared before retrieving the request');
+ }
+
+ return $this->request;
+ }
+
+ public function getResponse()
+ {
+ if (!$this->isExecuted()) {
+ $this->execute();
+ }
+
+ return $this->request->getResponse();
+ }
+
+ public function getResult()
+ {
+ if (!$this->isExecuted()) {
+ $this->execute();
+ }
+
+ if (null === $this->result) {
+ $this->process();
+ // Call the onComplete method if one is set
+ if ($this->onComplete) {
+ call_user_func($this->onComplete, $this);
+ }
+ }
+
+ return $this->result;
+ }
+
+ public function setResult($result)
+ {
+ $this->result = $result;
+
+ return $this;
+ }
+
+ public function isPrepared()
+ {
+ return $this->request !== null;
+ }
+
+ public function isExecuted()
+ {
+ return $this->request !== null && $this->request->getState() == 'complete';
+ }
+
+ public function prepare()
+ {
+ if (!$this->isPrepared()) {
+ if (!$this->client) {
+ throw new CommandException('A client must be associated with the command before it can be prepared.');
+ }
+
+ // If no response processing value was specified, then attempt to use the highest level of processing
+ if (!isset($this[self::RESPONSE_PROCESSING])) {
+ $this[self::RESPONSE_PROCESSING] = self::TYPE_MODEL;
+ }
+
+ // Notify subscribers of the client that the command is being prepared
+ $this->client->dispatch('command.before_prepare', array('command' => $this));
+
+ // Fail on missing required arguments, and change parameters via filters
+ $this->validate();
+ // Delegate to the subclass that implements the build method
+ $this->build();
+
+ // Add custom request headers set on the command
+ if ($headers = $this[self::HEADERS_OPTION]) {
+ foreach ($headers as $key => $value) {
+ $this->request->setHeader($key, $value);
+ }
+ }
+
+ // Add any curl options to the request
+ if ($options = $this[Client::CURL_OPTIONS]) {
+ $this->request->getCurlOptions()->overwriteWith(CurlHandle::parseCurlConfig($options));
+ }
+
+ // Set a custom response body
+ if ($responseBody = $this[self::RESPONSE_BODY]) {
+ $this->request->setResponseBody($responseBody);
+ }
+
+ $this->client->dispatch('command.after_prepare', array('command' => $this));
+ }
+
+ return $this->request;
+ }
+
+ /**
+ * Set the validator used to validate and prepare command parameters and nested JSON schemas. If no validator is
+ * set, then the command will validate using the default {@see SchemaValidator}.
+ *
+ * @param ValidatorInterface $validator Validator used to prepare and validate properties against a JSON schema
+ *
+ * @return self
+ */
+ public function setValidator(ValidatorInterface $validator)
+ {
+ $this->validator = $validator;
+
+ return $this;
+ }
+
+ public function getRequestHeaders()
+ {
+ return $this[self::HEADERS_OPTION];
+ }
+
+ /**
+ * Initialize the command (hook that can be implemented in subclasses)
+ */
+ protected function init() {}
+
+ /**
+ * Create the request object that will carry out the command
+ */
+ abstract protected function build();
+
+ /**
+ * Hook used to create an operation for concrete commands that are not associated with a service description
+ *
+ * @return OperationInterface
+ */
+ protected function createOperation()
+ {
+ return new Operation(array('name' => get_class($this)));
+ }
+
+ /**
+ * Create the result of the command after the request has been completed.
+ * Override this method in subclasses to customize this behavior
+ */
+ protected function process()
+ {
+ $this->result = $this[self::RESPONSE_PROCESSING] != self::TYPE_RAW
+ ? DefaultResponseParser::getInstance()->parse($this)
+ : $this->request->getResponse();
+ }
+
+ /**
+ * Validate and prepare the command based on the schema and rules defined by the command's Operation object
+ *
+ * @throws ValidationException when validation errors occur
+ */
+ protected function validate()
+ {
+ // Do not perform request validation/transformation if it is disable
+ if ($this[self::DISABLE_VALIDATION]) {
+ return;
+ }
+
+ $errors = array();
+ $validator = $this->getValidator();
+ foreach ($this->operation->getParams() as $name => $schema) {
+ $value = $this[$name];
+ if (!$validator->validate($schema, $value)) {
+ $errors = array_merge($errors, $validator->getErrors());
+ } elseif ($value !== $this[$name]) {
+ // Update the config value if it changed and no validation errors were encountered
+ $this->data[$name] = $value;
+ }
+ }
+
+ // Validate additional parameters
+ $hidden = $this[self::HIDDEN_PARAMS];
+
+ if ($properties = $this->operation->getAdditionalParameters()) {
+ foreach ($this->toArray() as $name => $value) {
+ // It's only additional if it isn't defined in the schema
+ if (!$this->operation->hasParam($name) && !in_array($name, $hidden)) {
+ // Always set the name so that error messages are useful
+ $properties->setName($name);
+ if (!$validator->validate($properties, $value)) {
+ $errors = array_merge($errors, $validator->getErrors());
+ } elseif ($value !== $this[$name]) {
+ $this->data[$name] = $value;
+ }
+ }
+ }
+ }
+
+ if (!empty($errors)) {
+ $e = new ValidationException('Validation errors: ' . implode("\n", $errors));
+ $e->setErrors($errors);
+ throw $e;
+ }
+ }
+
+ /**
+ * Get the validator used to prepare and validate properties. If no validator has been set on the command, then
+ * the default {@see SchemaValidator} will be used.
+ *
+ * @return ValidatorInterface
+ */
+ protected function getValidator()
+ {
+ if (!$this->validator) {
+ $this->validator = SchemaValidator::getInstance();
+ }
+
+ return $this->validator;
+ }
+
+ /**
+ * Get array of any validation errors
+ * If no validator has been set then return false
+ */
+ public function getValidationErrors()
+ {
+ if (!$this->validator) {
+ return false;
+ }
+
+ return $this->validator->getErrors();
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/ClosureCommand.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/ClosureCommand.php
new file mode 100644
index 0000000..cb6ac40
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/ClosureCommand.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Guzzle\Service\Command;
+
+use Guzzle\Common\Exception\InvalidArgumentException;
+use Guzzle\Common\Exception\UnexpectedValueException;
+use Guzzle\Http\Message\RequestInterface;
+
+/**
+ * A ClosureCommand is a command that allows dynamic commands to be created at runtime using a closure to prepare the
+ * request. A closure key and \Closure value must be passed to the command in the constructor. The closure must
+ * accept the command object as an argument.
+ */
+class ClosureCommand extends AbstractCommand
+{
+ /**
+ * {@inheritdoc}
+ * @throws InvalidArgumentException if a closure was not passed
+ */
+ protected function init()
+ {
+ if (!$this['closure']) {
+ throw new InvalidArgumentException('A closure must be passed in the parameters array');
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ * @throws UnexpectedValueException If the closure does not return a request
+ */
+ protected function build()
+ {
+ $closure = $this['closure'];
+ /** @var $closure \Closure */
+ $this->request = $closure($this, $this->operation);
+
+ if (!$this->request || !$this->request instanceof RequestInterface) {
+ throw new UnexpectedValueException('Closure command did not return a RequestInterface object');
+ }
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/CommandInterface.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/CommandInterface.php
new file mode 100644
index 0000000..fbb61d2
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/CommandInterface.php
@@ -0,0 +1,128 @@
+<?php
+
+namespace Guzzle\Service\Command;
+
+use Guzzle\Common\Collection;
+use Guzzle\Common\Exception\InvalidArgumentException;
+use Guzzle\Http\Message\Response;
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Service\Exception\CommandException;
+use Guzzle\Service\Description\OperationInterface;
+use Guzzle\Service\ClientInterface;
+use Guzzle\Common\ToArrayInterface;
+
+/**
+ * A command object that contains parameters that can be modified and accessed like an array and turned into an array
+ */
+interface CommandInterface extends \ArrayAccess, ToArrayInterface
+{
+ /**
+ * Get the short form name of the command
+ *
+ * @return string
+ */
+ public function getName();
+
+ /**
+ * Get the API operation information about the command
+ *
+ * @return OperationInterface
+ */
+ public function getOperation();
+
+ /**
+ * Execute the command and return the result
+ *
+ * @return mixed Returns the result of {@see CommandInterface::execute}
+ * @throws CommandException if a client has not been associated with the command
+ */
+ public function execute();
+
+ /**
+ * Get the client object that will execute the command
+ *
+ * @return ClientInterface|null
+ */
+ public function getClient();
+
+ /**
+ * Set the client object that will execute the command
+ *
+ * @param ClientInterface $client The client object that will execute the command
+ *
+ * @return self
+ */
+ public function setClient(ClientInterface $client);
+
+ /**
+ * Get the request object associated with the command
+ *
+ * @return RequestInterface
+ * @throws CommandException if the command has not been executed
+ */
+ public function getRequest();
+
+ /**
+ * Get the response object associated with the command
+ *
+ * @return Response
+ * @throws CommandException if the command has not been executed
+ */
+ public function getResponse();
+
+ /**
+ * Get the result of the command
+ *
+ * @return Response By default, commands return a Response object unless overridden in a subclass
+ * @throws CommandException if the command has not been executed
+ */
+ public function getResult();
+
+ /**
+ * Set the result of the command
+ *
+ * @param mixed $result Result to set
+ *
+ * @return self
+ */
+ public function setResult($result);
+
+ /**
+ * Returns TRUE if the command has been prepared for executing
+ *
+ * @return bool
+ */
+ public function isPrepared();
+
+ /**
+ * Returns TRUE if the command has been executed
+ *
+ * @return bool
+ */
+ public function isExecuted();
+
+ /**
+ * Prepare the command for executing and create a request object.
+ *
+ * @return RequestInterface Returns the generated request
+ * @throws CommandException if a client object has not been set previously or in the prepare()
+ */
+ public function prepare();
+
+ /**
+ * Get the object that manages the request headers that will be set on any outbound requests from the command
+ *
+ * @return Collection
+ */
+ public function getRequestHeaders();
+
+ /**
+ * Specify a callable to execute when the command completes
+ *
+ * @param mixed $callable Callable to execute when the command completes. The callable must accept a
+ * {@see CommandInterface} object as the only argument.
+ * @return self
+ * @throws InvalidArgumentException
+ */
+ public function setOnComplete($callable);
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/CreateResponseClassEvent.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/CreateResponseClassEvent.php
new file mode 100644
index 0000000..e050678
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/CreateResponseClassEvent.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Guzzle\Service\Command;
+
+use Guzzle\Common\Event;
+
+/**
+ * Event class emitted with the operation.parse_class event
+ */
+class CreateResponseClassEvent extends Event
+{
+ /**
+ * Set the result of the object creation
+ *
+ * @param mixed $result Result value to set
+ */
+ public function setResult($result)
+ {
+ $this['result'] = $result;
+ $this->stopPropagation();
+ }
+
+ /**
+ * Get the created object
+ *
+ * @return mixed
+ */
+ public function getResult()
+ {
+ return $this['result'];
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/DefaultRequestSerializer.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/DefaultRequestSerializer.php
new file mode 100644
index 0000000..2dc4acd
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/DefaultRequestSerializer.php
@@ -0,0 +1,169 @@
+<?php
+
+namespace Guzzle\Service\Command;
+
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Service\Command\LocationVisitor\Request\RequestVisitorInterface;
+use Guzzle\Service\Command\LocationVisitor\VisitorFlyweight;
+use Guzzle\Service\Description\OperationInterface;
+use Guzzle\Service\Description\Parameter;
+
+/**
+ * Default request serializer that transforms command options and operation parameters into a request
+ */
+class DefaultRequestSerializer implements RequestSerializerInterface
+{
+ /** @var VisitorFlyweight $factory Visitor factory */
+ protected $factory;
+
+ /** @var self */
+ protected static $instance;
+
+ /**
+ * @return self
+ * @codeCoverageIgnore
+ */
+ public static function getInstance()
+ {
+ if (!self::$instance) {
+ self::$instance = new self(VisitorFlyweight::getInstance());
+ }
+
+ return self::$instance;
+ }
+
+ /**
+ * @param VisitorFlyweight $factory Factory to use when creating visitors
+ */
+ public function __construct(VisitorFlyweight $factory)
+ {
+ $this->factory = $factory;
+ }
+
+ /**
+ * Add a location visitor to the serializer
+ *
+ * @param string $location Location to associate with the visitor
+ * @param RequestVisitorInterface $visitor Visitor to attach
+ *
+ * @return self
+ */
+ public function addVisitor($location, RequestVisitorInterface $visitor)
+ {
+ $this->factory->addRequestVisitor($location, $visitor);
+
+ return $this;
+ }
+
+ public function prepare(CommandInterface $command)
+ {
+ $request = $this->createRequest($command);
+ // Keep an array of visitors found in the operation
+ $foundVisitors = array();
+ $operation = $command->getOperation();
+
+ // Add arguments to the request using the location attribute
+ foreach ($operation->getParams() as $name => $arg) {
+ /** @var $arg \Guzzle\Service\Description\Parameter */
+ $location = $arg->getLocation();
+ // Skip 'uri' locations because they've already been processed
+ if ($location && $location != 'uri') {
+ // Instantiate visitors as they are detected in the properties
+ if (!isset($foundVisitors[$location])) {
+ $foundVisitors[$location] = $this->factory->getRequestVisitor($location);
+ }
+ // Ensure that a value has been set for this parameter
+ $value = $command[$name];
+ if ($value !== null) {
+ // Apply the parameter value with the location visitor
+ $foundVisitors[$location]->visit($command, $request, $arg, $value);
+ }
+ }
+ }
+
+ // Serialize additional parameters
+ if ($additional = $operation->getAdditionalParameters()) {
+ if ($visitor = $this->prepareAdditionalParameters($operation, $command, $request, $additional)) {
+ $foundVisitors[$additional->getLocation()] = $visitor;
+ }
+ }
+
+ // Call the after method on each visitor found in the operation
+ foreach ($foundVisitors as $visitor) {
+ $visitor->after($command, $request);
+ }
+
+ return $request;
+ }
+
+ /**
+ * Serialize additional parameters
+ *
+ * @param OperationInterface $operation Operation that owns the command
+ * @param CommandInterface $command Command to prepare
+ * @param RequestInterface $request Request to serialize
+ * @param Parameter $additional Additional parameters
+ *
+ * @return null|RequestVisitorInterface
+ */
+ protected function prepareAdditionalParameters(
+ OperationInterface $operation,
+ CommandInterface $command,
+ RequestInterface $request,
+ Parameter $additional
+ ) {
+ if (!($location = $additional->getLocation())) {
+ return;
+ }
+
+ $visitor = $this->factory->getRequestVisitor($location);
+ $hidden = $command[$command::HIDDEN_PARAMS];
+
+ foreach ($command->toArray() as $key => $value) {
+ // Ignore values that are null or built-in command options
+ if ($value !== null
+ && !in_array($key, $hidden)
+ && !$operation->hasParam($key)
+ ) {
+ $additional->setName($key);
+ $visitor->visit($command, $request, $additional, $value);
+ }
+ }
+
+ return $visitor;
+ }
+
+ /**
+ * Create a request for the command and operation
+ *
+ * @param CommandInterface $command Command to create a request for
+ *
+ * @return RequestInterface
+ */
+ protected function createRequest(CommandInterface $command)
+ {
+ $operation = $command->getOperation();
+ $client = $command->getClient();
+ $options = $command[AbstractCommand::REQUEST_OPTIONS] ?: array();
+
+ // If the command does not specify a template, then assume the base URL of the client
+ if (!($uri = $operation->getUri())) {
+ return $client->createRequest($operation->getHttpMethod(), $client->getBaseUrl(), null, null, $options);
+ }
+
+ // Get the path values and use the client config settings
+ $variables = array();
+ foreach ($operation->getParams() as $name => $arg) {
+ if ($arg->getLocation() == 'uri') {
+ if (isset($command[$name])) {
+ $variables[$name] = $arg->filter($command[$name]);
+ if (!is_array($variables[$name])) {
+ $variables[$name] = (string) $variables[$name];
+ }
+ }
+ }
+ }
+
+ return $client->createRequest($operation->getHttpMethod(), array($uri, $variables), null, null, $options);
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/DefaultResponseParser.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/DefaultResponseParser.php
new file mode 100644
index 0000000..4fe3803
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/DefaultResponseParser.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Guzzle\Service\Command;
+
+use Guzzle\Http\Message\Response;
+
+/**
+ * Default HTTP response parser used to marshal JSON responses into arrays and XML responses into SimpleXMLElement
+ */
+class DefaultResponseParser implements ResponseParserInterface
+{
+ /** @var self */
+ protected static $instance;
+
+ /**
+ * @return self
+ * @codeCoverageIgnore
+ */
+ public static function getInstance()
+ {
+ if (!self::$instance) {
+ self::$instance = new self;
+ }
+
+ return self::$instance;
+ }
+
+ public function parse(CommandInterface $command)
+ {
+ $response = $command->getRequest()->getResponse();
+
+ // Account for hard coded content-type values specified in service descriptions
+ if ($contentType = $command['command.expects']) {
+ $response->setHeader('Content-Type', $contentType);
+ } else {
+ $contentType = (string) $response->getHeader('Content-Type');
+ }
+
+ return $this->handleParsing($command, $response, $contentType);
+ }
+
+ protected function handleParsing(CommandInterface $command, Response $response, $contentType)
+ {
+ $result = $response;
+ if ($result->getBody()) {
+ if (stripos($contentType, 'json') !== false) {
+ $result = $result->json();
+ } elseif (stripos($contentType, 'xml') !== false) {
+ $result = $result->xml();
+ }
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/AliasFactory.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/AliasFactory.php
new file mode 100644
index 0000000..1c5ce07
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/AliasFactory.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Guzzle\Service\Command\Factory;
+
+use Guzzle\Common\Exception\InvalidArgumentException;
+use Guzzle\Service\ClientInterface;
+
+/**
+ * Command factory used when you need to provide aliases to commands
+ */
+class AliasFactory implements FactoryInterface
+{
+ /** @var array Associative array mapping command aliases to the aliased command */
+ protected $aliases;
+
+ /** @var ClientInterface Client used to retry using aliases */
+ protected $client;
+
+ /**
+ * @param ClientInterface $client Client used to retry with the alias
+ * @param array $aliases Associative array mapping aliases to the alias
+ */
+ public function __construct(ClientInterface $client, array $aliases)
+ {
+ $this->client = $client;
+ $this->aliases = $aliases;
+ }
+
+ public function factory($name, array $args = array())
+ {
+ if (isset($this->aliases[$name])) {
+ try {
+ return $this->client->getCommand($this->aliases[$name], $args);
+ } catch (InvalidArgumentException $e) {
+ return null;
+ }
+ }
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/CompositeFactory.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/CompositeFactory.php
new file mode 100644
index 0000000..8c46983
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/CompositeFactory.php
@@ -0,0 +1,154 @@
+<?php
+
+namespace Guzzle\Service\Command\Factory;
+
+use Guzzle\Service\Command\CommandInterface;
+use Guzzle\Service\ClientInterface;
+
+/**
+ * Composite factory used by a client object to create command objects utilizing multiple factories
+ */
+class CompositeFactory implements \IteratorAggregate, \Countable, FactoryInterface
+{
+ /** @var array Array of command factories */
+ protected $factories;
+
+ /**
+ * Get the default chain to use with clients
+ *
+ * @param ClientInterface $client Client to base the chain on
+ *
+ * @return self
+ */
+ public static function getDefaultChain(ClientInterface $client)
+ {
+ $factories = array();
+ if ($description = $client->getDescription()) {
+ $factories[] = new ServiceDescriptionFactory($description);
+ }
+ $factories[] = new ConcreteClassFactory($client);
+
+ return new self($factories);
+ }
+
+ /**
+ * @param array $factories Array of command factories
+ */
+ public function __construct(array $factories = array())
+ {
+ $this->factories = $factories;
+ }
+
+ /**
+ * Add a command factory to the chain
+ *
+ * @param FactoryInterface $factory Factory to add
+ * @param string|FactoryInterface $before Insert the new command factory before a command factory class or object
+ * matching a class name.
+ * @return CompositeFactory
+ */
+ public function add(FactoryInterface $factory, $before = null)
+ {
+ $pos = null;
+
+ if ($before) {
+ foreach ($this->factories as $i => $f) {
+ if ($before instanceof FactoryInterface) {
+ if ($f === $before) {
+ $pos = $i;
+ break;
+ }
+ } elseif (is_string($before)) {
+ if ($f instanceof $before) {
+ $pos = $i;
+ break;
+ }
+ }
+ }
+ }
+
+ if ($pos === null) {
+ $this->factories[] = $factory;
+ } else {
+ array_splice($this->factories, $i, 0, array($factory));
+ }
+
+ return $this;
+ }
+
+ /**
+ * Check if the chain contains a specific command factory
+ *
+ * @param FactoryInterface|string $factory Factory to check
+ *
+ * @return bool
+ */
+ public function has($factory)
+ {
+ return (bool) $this->find($factory);
+ }
+
+ /**
+ * Remove a specific command factory from the chain
+ *
+ * @param string|FactoryInterface $factory Factory to remove by name or instance
+ *
+ * @return CompositeFactory
+ */
+ public function remove($factory = null)
+ {
+ if (!($factory instanceof FactoryInterface)) {
+ $factory = $this->find($factory);
+ }
+
+ $this->factories = array_values(array_filter($this->factories, function($f) use ($factory) {
+ return $f !== $factory;
+ }));
+
+ return $this;
+ }
+
+ /**
+ * Get a command factory by class name
+ *
+ * @param string|FactoryInterface $factory Command factory class or instance
+ *
+ * @return null|FactoryInterface
+ */
+ public function find($factory)
+ {
+ foreach ($this->factories as $f) {
+ if ($factory === $f || (is_string($factory) && $f instanceof $factory)) {
+ return $f;
+ }
+ }
+ }
+
+ /**
+ * Create a command using the associated command factories
+ *
+ * @param string $name Name of the command
+ * @param array $args Command arguments
+ *
+ * @return CommandInterface
+ */
+ public function factory($name, array $args = array())
+ {
+ foreach ($this->factories as $factory) {
+ $command = $factory->factory($name, $args);
+ if ($command) {
+ return $command;
+ }
+ }
+ }
+
+ public function count()
+ {
+ return count($this->factories);
+ }
+
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->factories);
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/ConcreteClassFactory.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/ConcreteClassFactory.php
new file mode 100644
index 0000000..0e93dea
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/ConcreteClassFactory.php
@@ -0,0 +1,47 @@
+<?php
+
+namespace Guzzle\Service\Command\Factory;
+
+use Guzzle\Inflection\InflectorInterface;
+use Guzzle\Inflection\Inflector;
+use Guzzle\Service\ClientInterface;
+
+/**
+ * Command factory used to create commands referencing concrete command classes
+ */
+class ConcreteClassFactory implements FactoryInterface
+{
+ /** @var ClientInterface */
+ protected $client;
+
+ /** @var InflectorInterface */
+ protected $inflector;
+
+ /**
+ * @param ClientInterface $client Client that owns the commands
+ * @param InflectorInterface $inflector Inflector used to resolve class names
+ */
+ public function __construct(ClientInterface $client, InflectorInterface $inflector = null)
+ {
+ $this->client = $client;
+ $this->inflector = $inflector ?: Inflector::getDefault();
+ }
+
+ public function factory($name, array $args = array())
+ {
+ // Determine the class to instantiate based on the namespace of the current client and the default directory
+ $prefix = $this->client->getConfig('command.prefix');
+ if (!$prefix) {
+ // The prefix can be specified in a factory method and is cached
+ $prefix = implode('\\', array_slice(explode('\\', get_class($this->client)), 0, -1)) . '\\Command\\';
+ $this->client->getConfig()->set('command.prefix', $prefix);
+ }
+
+ $class = $prefix . str_replace(' ', '\\', ucwords(str_replace('.', ' ', $this->inflector->camel($name))));
+
+ // Create the concrete command if it exists
+ if (class_exists($class)) {
+ return new $class($args);
+ }
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/FactoryInterface.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/FactoryInterface.php
new file mode 100644
index 0000000..35c299d
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/FactoryInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Guzzle\Service\Command\Factory;
+
+use Guzzle\Service\Command\CommandInterface;
+
+/**
+ * Interface for creating commands by name
+ */
+interface FactoryInterface
+{
+ /**
+ * Create a command by name
+ *
+ * @param string $name Command to create
+ * @param array $args Command arguments
+ *
+ * @return CommandInterface|null
+ */
+ public function factory($name, array $args = array());
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/MapFactory.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/MapFactory.php
new file mode 100644
index 0000000..0ad80bc
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/MapFactory.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Guzzle\Service\Command\Factory;
+
+/**
+ * Command factory used when explicitly mapping strings to command classes
+ */
+class MapFactory implements FactoryInterface
+{
+ /** @var array Associative array mapping command names to classes */
+ protected $map;
+
+ /** @param array $map Associative array mapping command names to classes */
+ public function __construct(array $map)
+ {
+ $this->map = $map;
+ }
+
+ public function factory($name, array $args = array())
+ {
+ if (isset($this->map[$name])) {
+ $class = $this->map[$name];
+
+ return new $class($args);
+ }
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/ServiceDescriptionFactory.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/ServiceDescriptionFactory.php
new file mode 100644
index 0000000..b943a5b
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/ServiceDescriptionFactory.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace Guzzle\Service\Command\Factory;
+
+use Guzzle\Service\Description\ServiceDescriptionInterface;
+use Guzzle\Inflection\InflectorInterface;
+
+/**
+ * Command factory used to create commands based on service descriptions
+ */
+class ServiceDescriptionFactory implements FactoryInterface
+{
+ /** @var ServiceDescriptionInterface */
+ protected $description;
+
+ /** @var InflectorInterface */
+ protected $inflector;
+
+ /**
+ * @param ServiceDescriptionInterface $description Service description
+ * @param InflectorInterface $inflector Optional inflector to use if the command is not at first found
+ */
+ public function __construct(ServiceDescriptionInterface $description, InflectorInterface $inflector = null)
+ {
+ $this->setServiceDescription($description);
+ $this->inflector = $inflector;
+ }
+
+ /**
+ * Change the service description used with the factory
+ *
+ * @param ServiceDescriptionInterface $description Service description to use
+ *
+ * @return FactoryInterface
+ */
+ public function setServiceDescription(ServiceDescriptionInterface $description)
+ {
+ $this->description = $description;
+
+ return $this;
+ }
+
+ /**
+ * Returns the service description
+ *
+ * @return ServiceDescriptionInterface
+ */
+ public function getServiceDescription()
+ {
+ return $this->description;
+ }
+
+ public function factory($name, array $args = array())
+ {
+ $command = $this->description->getOperation($name);
+
+ // If a command wasn't found, then try to uppercase the first letter and try again
+ if (!$command) {
+ $command = $this->description->getOperation(ucfirst($name));
+ // If an inflector was passed, then attempt to get the command using snake_case inflection
+ if (!$command && $this->inflector) {
+ $command = $this->description->getOperation($this->inflector->snake($name));
+ }
+ }
+
+ if ($command) {
+ $class = $command->getClass();
+ return new $class($args, $command, $this->description);
+ }
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/AbstractRequestVisitor.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/AbstractRequestVisitor.php
new file mode 100644
index 0000000..adcfca1
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/AbstractRequestVisitor.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Request;
+
+use Guzzle\Service\Command\CommandInterface;
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Service\Description\Parameter;
+
+abstract class AbstractRequestVisitor implements RequestVisitorInterface
+{
+ /**
+ * @codeCoverageIgnore
+ */
+ public function after(CommandInterface $command, RequestInterface $request) {}
+
+ /**
+ * @codeCoverageIgnore
+ */
+ public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value) {}
+
+ /**
+ * Prepare (filter and set desired name for request item) the value for request.
+ *
+ * @param mixed $value
+ * @param \Guzzle\Service\Description\Parameter $param
+ *
+ * @return array|mixed
+ */
+ protected function prepareValue($value, Parameter $param)
+ {
+ return is_array($value)
+ ? $this->resolveRecursively($value, $param)
+ : $param->filter($value);
+ }
+
+ /**
+ * Map nested parameters into the location_key based parameters
+ *
+ * @param array $value Value to map
+ * @param Parameter $param Parameter that holds information about the current key
+ *
+ * @return array Returns the mapped array
+ */
+ protected function resolveRecursively(array $value, Parameter $param)
+ {
+ foreach ($value as $name => &$v) {
+ switch ($param->getType()) {
+ case 'object':
+ if ($subParam = $param->getProperty($name)) {
+ $key = $subParam->getWireName();
+ $value[$key] = $this->prepareValue($v, $subParam);
+ if ($name != $key) {
+ unset($value[$name]);
+ }
+ } elseif ($param->getAdditionalProperties() instanceof Parameter) {
+ $v = $this->prepareValue($v, $param->getAdditionalProperties());
+ }
+ break;
+ case 'array':
+ if ($items = $param->getItems()) {
+ $v = $this->prepareValue($v, $items);
+ }
+ break;
+ }
+ }
+
+ return $param->filter($value);
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/BodyVisitor.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/BodyVisitor.php
new file mode 100644
index 0000000..168d780
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/BodyVisitor.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Request;
+
+use Guzzle\Http\EntityBody;
+use Guzzle\Http\Message\EntityEnclosingRequestInterface;
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Http\EntityBodyInterface;
+use Guzzle\Service\Command\CommandInterface;
+use Guzzle\Service\Description\Parameter;
+
+/**
+ * Visitor used to apply a body to a request
+ *
+ * This visitor can use a data parameter of 'expect' to control the Expect header. Set the expect data parameter to
+ * false to disable the expect header, or set the value to an integer so that the expect 100-continue header is only
+ * added if the Content-Length of the entity body is greater than the value.
+ */
+class BodyVisitor extends AbstractRequestVisitor
+{
+ public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value)
+ {
+ $value = $param->filter($value);
+ $entityBody = EntityBody::factory($value);
+ $request->setBody($entityBody);
+ $this->addExpectHeader($request, $entityBody, $param->getData('expect_header'));
+ // Add the Content-Encoding header if one is set on the EntityBody
+ if ($encoding = $entityBody->getContentEncoding()) {
+ $request->setHeader('Content-Encoding', $encoding);
+ }
+ }
+
+ /**
+ * Add the appropriate expect header to a request
+ *
+ * @param EntityEnclosingRequestInterface $request Request to update
+ * @param EntityBodyInterface $body Entity body of the request
+ * @param string|int $expect Expect header setting
+ */
+ protected function addExpectHeader(EntityEnclosingRequestInterface $request, EntityBodyInterface $body, $expect)
+ {
+ // Allow the `expect` data parameter to be set to remove the Expect header from the request
+ if ($expect === false) {
+ $request->removeHeader('Expect');
+ } elseif ($expect !== true) {
+ // Default to using a MB as the point in which to start using the expect header
+ $expect = $expect ?: 1048576;
+ // If the expect_header value is numeric then only add if the size is greater than the cutoff
+ if (is_numeric($expect) && $body->getSize()) {
+ if ($body->getSize() < $expect) {
+ $request->removeHeader('Expect');
+ } else {
+ $request->setHeader('Expect', '100-Continue');
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/HeaderVisitor.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/HeaderVisitor.php
new file mode 100644
index 0000000..2a53754
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/HeaderVisitor.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Request;
+
+use Guzzle\Common\Exception\InvalidArgumentException;
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Service\Command\CommandInterface;
+use Guzzle\Service\Description\Parameter;
+
+/**
+ * Visitor used to apply a parameter to a header value
+ */
+class HeaderVisitor extends AbstractRequestVisitor
+{
+ public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value)
+ {
+ $value = $param->filter($value);
+ if ($param->getType() == 'object' && $param->getAdditionalProperties() instanceof Parameter) {
+ $this->addPrefixedHeaders($request, $param, $value);
+ } else {
+ $request->setHeader($param->getWireName(), $value);
+ }
+ }
+
+ /**
+ * Add a prefixed array of headers to the request
+ *
+ * @param RequestInterface $request Request to update
+ * @param Parameter $param Parameter object
+ * @param array $value Header array to add
+ *
+ * @throws InvalidArgumentException
+ */
+ protected function addPrefixedHeaders(RequestInterface $request, Parameter $param, $value)
+ {
+ if (!is_array($value)) {
+ throw new InvalidArgumentException('An array of mapped headers expected, but received a single value');
+ }
+ $prefix = $param->getSentAs();
+ foreach ($value as $headerName => $headerValue) {
+ $request->setHeader($prefix . $headerName, $headerValue);
+ }
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/JsonVisitor.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/JsonVisitor.php
new file mode 100644
index 0000000..757e1c5
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/JsonVisitor.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Request;
+
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Service\Command\CommandInterface;
+use Guzzle\Service\Description\Parameter;
+
+/**
+ * Visitor used to apply a parameter to an array that will be serialized as a top level key-value pair in a JSON body
+ */
+class JsonVisitor extends AbstractRequestVisitor
+{
+ /** @var bool Whether or not to add a Content-Type header when JSON is found */
+ protected $jsonContentType = 'application/json';
+
+ /** @var \SplObjectStorage Data object for persisting JSON data */
+ protected $data;
+
+ public function __construct()
+ {
+ $this->data = new \SplObjectStorage();
+ }
+
+ /**
+ * Set the Content-Type header to add to the request if JSON is added to the body. This visitor does not add a
+ * Content-Type header unless you specify one here.
+ *
+ * @param string $header Header to set when JSON is added (e.g. application/json)
+ *
+ * @return self
+ */
+ public function setContentTypeHeader($header = 'application/json')
+ {
+ $this->jsonContentType = $header;
+
+ return $this;
+ }
+
+ public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value)
+ {
+ if (isset($this->data[$command])) {
+ $json = $this->data[$command];
+ } else {
+ $json = array();
+ }
+ $json[$param->getWireName()] = $this->prepareValue($value, $param);
+ $this->data[$command] = $json;
+ }
+
+ public function after(CommandInterface $command, RequestInterface $request)
+ {
+ if (isset($this->data[$command])) {
+ // Don't overwrite the Content-Type if one is set
+ if ($this->jsonContentType && !$request->hasHeader('Content-Type')) {
+ $request->setHeader('Content-Type', $this->jsonContentType);
+ }
+
+ $request->setBody(json_encode($this->data[$command]));
+ unset($this->data[$command]);
+ }
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/PostFieldVisitor.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/PostFieldVisitor.php
new file mode 100644
index 0000000..975850b
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/PostFieldVisitor.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Request;
+
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Service\Command\CommandInterface;
+use Guzzle\Service\Description\Parameter;
+
+/**
+ * Visitor used to apply a parameter to a POST field
+ */
+class PostFieldVisitor extends AbstractRequestVisitor
+{
+ public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value)
+ {
+ $request->setPostField($param->getWireName(), $this->prepareValue($value, $param));
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/PostFileVisitor.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/PostFileVisitor.php
new file mode 100644
index 0000000..0853ebe
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/PostFileVisitor.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Request;
+
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Http\Message\PostFileInterface;
+use Guzzle\Service\Command\CommandInterface;
+use Guzzle\Service\Description\Parameter;
+
+/**
+ * Visitor used to apply a parameter to a POST file
+ */
+class PostFileVisitor extends AbstractRequestVisitor
+{
+ public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value)
+ {
+ $value = $param->filter($value);
+ if ($value instanceof PostFileInterface) {
+ $request->addPostFile($value);
+ } else {
+ $request->addPostFile($param->getWireName(), $value);
+ }
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/QueryVisitor.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/QueryVisitor.php
new file mode 100644
index 0000000..315877a
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/QueryVisitor.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Request;
+
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Service\Command\CommandInterface;
+use Guzzle\Service\Description\Parameter;
+
+/**
+ * Visitor used to apply a parameter to a request's query string
+ */
+class QueryVisitor extends AbstractRequestVisitor
+{
+ public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value)
+ {
+ $request->getQuery()->set($param->getWireName(), $this->prepareValue($value, $param));
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/RequestVisitorInterface.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/RequestVisitorInterface.php
new file mode 100644
index 0000000..14e0b2d
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/RequestVisitorInterface.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Request;
+
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Service\Description\Parameter;
+use Guzzle\Service\Command\CommandInterface;
+
+/**
+ * Location visitor used to add values to different locations in a request with different behaviors as needed
+ */
+interface RequestVisitorInterface
+{
+ /**
+ * Called after visiting all parameters
+ *
+ * @param CommandInterface $command Command being visited
+ * @param RequestInterface $request Request being visited
+ */
+ public function after(CommandInterface $command, RequestInterface $request);
+
+ /**
+ * Called once for each parameter being visited that matches the location type
+ *
+ * @param CommandInterface $command Command being visited
+ * @param RequestInterface $request Request being visited
+ * @param Parameter $param Parameter being visited
+ * @param mixed $value Value to set
+ */
+ public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value);
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/ResponseBodyVisitor.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/ResponseBodyVisitor.php
new file mode 100644
index 0000000..09f35f8
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/ResponseBodyVisitor.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Request;
+
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Service\Command\CommandInterface;
+use Guzzle\Service\Description\Parameter;
+
+/**
+ * Visitor used to change the location in which a response body is saved
+ */
+class ResponseBodyVisitor extends AbstractRequestVisitor
+{
+ public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value)
+ {
+ $request->setResponseBody($value);
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/XmlVisitor.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/XmlVisitor.php
new file mode 100644
index 0000000..5b71487
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/XmlVisitor.php
@@ -0,0 +1,252 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Request;
+
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Service\Command\CommandInterface;
+use Guzzle\Service\Description\Operation;
+use Guzzle\Service\Description\Parameter;
+
+/**
+ * Location visitor used to serialize XML bodies
+ */
+class XmlVisitor extends AbstractRequestVisitor
+{
+ /** @var \SplObjectStorage Data object for persisting XML data */
+ protected $data;
+
+ /** @var bool Content-Type header added when XML is found */
+ protected $contentType = 'application/xml';
+
+ public function __construct()
+ {
+ $this->data = new \SplObjectStorage();
+ }
+
+ /**
+ * Change the content-type header that is added when XML is found
+ *
+ * @param string $header Header to set when XML is found
+ *
+ * @return self
+ */
+ public function setContentTypeHeader($header)
+ {
+ $this->contentType = $header;
+
+ return $this;
+ }
+
+ public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value)
+ {
+ $xml = isset($this->data[$command])
+ ? $this->data[$command]
+ : $this->createRootElement($param->getParent());
+ $this->addXml($xml, $param, $value);
+
+ $this->data[$command] = $xml;
+ }
+
+ public function after(CommandInterface $command, RequestInterface $request)
+ {
+ $xml = null;
+
+ // If data was found that needs to be serialized, then do so
+ if (isset($this->data[$command])) {
+ $xml = $this->finishDocument($this->data[$command]);
+ unset($this->data[$command]);
+ } else {
+ // Check if XML should always be sent for the command
+ $operation = $command->getOperation();
+ if ($operation->getData('xmlAllowEmpty')) {
+ $xmlWriter = $this->createRootElement($operation);
+ $xml = $this->finishDocument($xmlWriter);
+ }
+ }
+
+ if ($xml) {
+ // Don't overwrite the Content-Type if one is set
+ if ($this->contentType && !$request->hasHeader('Content-Type')) {
+ $request->setHeader('Content-Type', $this->contentType);
+ }
+ $request->setBody($xml);
+ }
+ }
+
+ /**
+ * Create the root XML element to use with a request
+ *
+ * @param Operation $operation Operation object
+ *
+ * @return \XMLWriter
+ */
+ protected function createRootElement(Operation $operation)
+ {
+ static $defaultRoot = array('name' => 'Request');
+ // If no root element was specified, then just wrap the XML in 'Request'
+ $root = $operation->getData('xmlRoot') ?: $defaultRoot;
+ // Allow the XML declaration to be customized with xmlEncoding
+ $encoding = $operation->getData('xmlEncoding');
+
+ $xmlWriter = $this->startDocument($encoding);
+
+ $xmlWriter->startElement($root['name']);
+ // Create the wrapping element with no namespaces if no namespaces were present
+ if (!empty($root['namespaces'])) {
+ // Create the wrapping element with an array of one or more namespaces
+ foreach ((array) $root['namespaces'] as $prefix => $uri) {
+ $nsLabel = 'xmlns';
+ if (!is_numeric($prefix)) {
+ $nsLabel .= ':'.$prefix;
+ }
+ $xmlWriter->writeAttribute($nsLabel, $uri);
+ }
+ }
+ return $xmlWriter;
+ }
+
+ /**
+ * Recursively build the XML body
+ *
+ * @param \XMLWriter $xmlWriter XML to modify
+ * @param Parameter $param API Parameter
+ * @param mixed $value Value to add
+ */
+ protected function addXml(\XMLWriter $xmlWriter, Parameter $param, $value)
+ {
+ if ($value === null) {
+ return;
+ }
+
+ $value = $param->filter($value);
+ $type = $param->getType();
+ $name = $param->getWireName();
+ $prefix = null;
+ $namespace = $param->getData('xmlNamespace');
+ if (false !== strpos($name, ':')) {
+ list($prefix, $name) = explode(':', $name, 2);
+ }
+
+ if ($type == 'object' || $type == 'array') {
+ if (!$param->getData('xmlFlattened')) {
+ $xmlWriter->startElementNS(null, $name, $namespace);
+ }
+ if ($param->getType() == 'array') {
+ $this->addXmlArray($xmlWriter, $param, $value);
+ } elseif ($param->getType() == 'object') {
+ $this->addXmlObject($xmlWriter, $param, $value);
+ }
+ if (!$param->getData('xmlFlattened')) {
+ $xmlWriter->endElement();
+ }
+ return;
+ }
+ if ($param->getData('xmlAttribute')) {
+ $this->writeAttribute($xmlWriter, $prefix, $name, $namespace, $value);
+ } else {
+ $this->writeElement($xmlWriter, $prefix, $name, $namespace, $value);
+ }
+ }
+
+ /**
+ * Write an attribute with namespace if used
+ *
+ * @param \XMLWriter $xmlWriter XMLWriter instance
+ * @param string $prefix Namespace prefix if any
+ * @param string $name Attribute name
+ * @param string $namespace The uri of the namespace
+ * @param string $value The attribute content
+ */
+ protected function writeAttribute($xmlWriter, $prefix, $name, $namespace, $value)
+ {
+ if (empty($namespace)) {
+ $xmlWriter->writeAttribute($name, $value);
+ } else {
+ $xmlWriter->writeAttributeNS($prefix, $name, $namespace, $value);
+ }
+ }
+
+ /**
+ * Write an element with namespace if used
+ *
+ * @param \XMLWriter $xmlWriter XML writer resource
+ * @param string $prefix Namespace prefix if any
+ * @param string $name Element name
+ * @param string $namespace The uri of the namespace
+ * @param string $value The element content
+ */
+ protected function writeElement(\XMLWriter $xmlWriter, $prefix, $name, $namespace, $value)
+ {
+ $xmlWriter->startElementNS($prefix, $name, $namespace);
+ if (strpbrk($value, '<>&')) {
+ $xmlWriter->writeCData($value);
+ } else {
+ $xmlWriter->writeRaw($value);
+ }
+ $xmlWriter->endElement();
+ }
+
+ /**
+ * Create a new xml writer and start a document
+ *
+ * @param string $encoding document encoding
+ *
+ * @return \XMLWriter the writer resource
+ */
+ protected function startDocument($encoding)
+ {
+ $xmlWriter = new \XMLWriter();
+ $xmlWriter->openMemory();
+ $xmlWriter->startDocument('1.0', $encoding);
+
+ return $xmlWriter;
+ }
+
+ /**
+ * End the document and return the output
+ *
+ * @param \XMLWriter $xmlWriter
+ *
+ * @return \string the writer resource
+ */
+ protected function finishDocument($xmlWriter)
+ {
+ $xmlWriter->endDocument();
+
+ return $xmlWriter->outputMemory();
+ }
+
+ /**
+ * Add an array to the XML
+ */
+ protected function addXmlArray(\XMLWriter $xmlWriter, Parameter $param, &$value)
+ {
+ if ($items = $param->getItems()) {
+ foreach ($value as $v) {
+ $this->addXml($xmlWriter, $items, $v);
+ }
+ }
+ }
+
+ /**
+ * Add an object to the XML
+ */
+ protected function addXmlObject(\XMLWriter $xmlWriter, Parameter $param, &$value)
+ {
+ $noAttributes = array();
+ // add values which have attributes
+ foreach ($value as $name => $v) {
+ if ($property = $param->getProperty($name)) {
+ if ($property->getData('xmlAttribute')) {
+ $this->addXml($xmlWriter, $property, $v);
+ } else {
+ $noAttributes[] = array('value' => $v, 'property' => $property);
+ }
+ }
+ }
+ // now add values with no attributes
+ foreach ($noAttributes as $element) {
+ $this->addXml($xmlWriter, $element['property'], $element['value']);
+ }
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/AbstractResponseVisitor.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/AbstractResponseVisitor.php
new file mode 100644
index 0000000..d87eeb9
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/AbstractResponseVisitor.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Response;
+
+use Guzzle\Service\Command\CommandInterface;
+use Guzzle\Http\Message\Response;
+use Guzzle\Service\Description\Parameter;
+
+/**
+ * {@inheritdoc}
+ * @codeCoverageIgnore
+ */
+abstract class AbstractResponseVisitor implements ResponseVisitorInterface
+{
+ public function before(CommandInterface $command, array &$result) {}
+
+ public function after(CommandInterface $command) {}
+
+ public function visit(
+ CommandInterface $command,
+ Response $response,
+ Parameter $param,
+ &$value,
+ $context = null
+ ) {}
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/BodyVisitor.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/BodyVisitor.php
new file mode 100644
index 0000000..f70b727
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/BodyVisitor.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Response;
+
+use Guzzle\Service\Command\CommandInterface;
+use Guzzle\Http\Message\Response;
+use Guzzle\Service\Description\Parameter;
+
+/**
+ * Visitor used to add the body of a response to a particular key
+ */
+class BodyVisitor extends AbstractResponseVisitor
+{
+ public function visit(
+ CommandInterface $command,
+ Response $response,
+ Parameter $param,
+ &$value,
+ $context = null
+ ) {
+ $value[$param->getName()] = $param->filter($response->getBody());
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/HeaderVisitor.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/HeaderVisitor.php
new file mode 100644
index 0000000..0f8737c
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/HeaderVisitor.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Response;
+
+use Guzzle\Http\Message\Response;
+use Guzzle\Service\Description\Parameter;
+use Guzzle\Service\Command\CommandInterface;
+
+/**
+ * Location visitor used to add a particular header of a response to a key in the result
+ */
+class HeaderVisitor extends AbstractResponseVisitor
+{
+ public function visit(
+ CommandInterface $command,
+ Response $response,
+ Parameter $param,
+ &$value,
+ $context = null
+ ) {
+ if ($param->getType() == 'object' && $param->getAdditionalProperties() instanceof Parameter) {
+ $this->processPrefixedHeaders($response, $param, $value);
+ } else {
+ $value[$param->getName()] = $param->filter((string) $response->getHeader($param->getWireName()));
+ }
+ }
+
+ /**
+ * Process a prefixed header array
+ *
+ * @param Response $response Response that contains the headers
+ * @param Parameter $param Parameter object
+ * @param array $value Value response array to modify
+ */
+ protected function processPrefixedHeaders(Response $response, Parameter $param, &$value)
+ {
+ // Grab prefixed headers that should be placed into an array with the prefix stripped
+ if ($prefix = $param->getSentAs()) {
+ $container = $param->getName();
+ $len = strlen($prefix);
+ // Find all matching headers and place them into the containing element
+ foreach ($response->getHeaders()->toArray() as $key => $header) {
+ if (stripos($key, $prefix) === 0) {
+ // Account for multi-value headers
+ $value[$container][substr($key, $len)] = count($header) == 1 ? end($header) : $header;
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/JsonVisitor.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/JsonVisitor.php
new file mode 100644
index 0000000..a609ebd
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/JsonVisitor.php
@@ -0,0 +1,93 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Response;
+
+use Guzzle\Http\Message\Response;
+use Guzzle\Service\Description\Parameter;
+use Guzzle\Service\Command\CommandInterface;
+
+/**
+ * Location visitor used to marshal JSON response data into a formatted array.
+ *
+ * Allows top level JSON parameters to be inserted into the result of a command. The top level attributes are grabbed
+ * from the response's JSON data using the name value by default. Filters can be applied to parameters as they are
+ * traversed. This allows data to be normalized before returning it to users (for example converting timestamps to
+ * DateTime objects).
+ */
+class JsonVisitor extends AbstractResponseVisitor
+{
+ public function before(CommandInterface $command, array &$result)
+ {
+ // Ensure that the result of the command is always rooted with the parsed JSON data
+ $result = $command->getResponse()->json();
+ }
+
+ public function visit(
+ CommandInterface $command,
+ Response $response,
+ Parameter $param,
+ &$value,
+ $context = null
+ ) {
+ $name = $param->getName();
+ $key = $param->getWireName();
+ if (isset($value[$key])) {
+ $this->recursiveProcess($param, $value[$key]);
+ if ($key != $name) {
+ $value[$name] = $value[$key];
+ unset($value[$key]);
+ }
+ }
+ }
+
+ /**
+ * Recursively process a parameter while applying filters
+ *
+ * @param Parameter $param API parameter being validated
+ * @param mixed $value Value to validate and process. The value may change during this process.
+ */
+ protected function recursiveProcess(Parameter $param, &$value)
+ {
+ if ($value === null) {
+ return;
+ }
+
+ if (is_array($value)) {
+ $type = $param->getType();
+ if ($type == 'array') {
+ foreach ($value as &$item) {
+ $this->recursiveProcess($param->getItems(), $item);
+ }
+ } elseif ($type == 'object' && !isset($value[0])) {
+ // On the above line, we ensure that the array is associative and not numerically indexed
+ $knownProperties = array();
+ if ($properties = $param->getProperties()) {
+ foreach ($properties as $property) {
+ $name = $property->getName();
+ $key = $property->getWireName();
+ $knownProperties[$name] = 1;
+ if (isset($value[$key])) {
+ $this->recursiveProcess($property, $value[$key]);
+ if ($key != $name) {
+ $value[$name] = $value[$key];
+ unset($value[$key]);
+ }
+ }
+ }
+ }
+
+ // Remove any unknown and potentially unsafe properties
+ if ($param->getAdditionalProperties() === false) {
+ $value = array_intersect_key($value, $knownProperties);
+ } elseif (($additional = $param->getAdditionalProperties()) !== true) {
+ // Validate and filter additional properties
+ foreach ($value as &$v) {
+ $this->recursiveProcess($additional, $v);
+ }
+ }
+ }
+ }
+
+ $value = $param->filter($value);
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/ReasonPhraseVisitor.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/ReasonPhraseVisitor.php
new file mode 100644
index 0000000..1b10ebc
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/ReasonPhraseVisitor.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Response;
+
+use Guzzle\Http\Message\Response;
+use Guzzle\Service\Description\Parameter;
+use Guzzle\Service\Command\CommandInterface;
+
+/**
+ * Location visitor used to add the reason phrase of a response to a key in the result
+ */
+class ReasonPhraseVisitor extends AbstractResponseVisitor
+{
+ public function visit(
+ CommandInterface $command,
+ Response $response,
+ Parameter $param,
+ &$value,
+ $context = null
+ ) {
+ $value[$param->getName()] = $response->getReasonPhrase();
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/ResponseVisitorInterface.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/ResponseVisitorInterface.php
new file mode 100644
index 0000000..033f40c
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/ResponseVisitorInterface.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Response;
+
+use Guzzle\Http\Message\Response;
+use Guzzle\Service\Description\Parameter;
+use Guzzle\Service\Command\CommandInterface;
+
+/**
+ * Location visitor used to parse values out of a response into an associative array
+ */
+interface ResponseVisitorInterface
+{
+ /**
+ * Called before visiting all parameters. This can be used for seeding the result of a command with default
+ * data (e.g. populating with JSON data in the response then adding to the parsed data).
+ *
+ * @param CommandInterface $command Command being visited
+ * @param array $result Result value to update if needed (e.g. parsing XML or JSON)
+ */
+ public function before(CommandInterface $command, array &$result);
+
+ /**
+ * Called after visiting all parameters
+ *
+ * @param CommandInterface $command Command being visited
+ */
+ public function after(CommandInterface $command);
+
+ /**
+ * Called once for each parameter being visited that matches the location type
+ *
+ * @param CommandInterface $command Command being visited
+ * @param Response $response Response being visited
+ * @param Parameter $param Parameter being visited
+ * @param mixed $value Result associative array value being updated by reference
+ * @param mixed $context Parsing context
+ */
+ public function visit(
+ CommandInterface $command,
+ Response $response,
+ Parameter $param,
+ &$value,
+ $context = null
+ );
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/StatusCodeVisitor.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/StatusCodeVisitor.php
new file mode 100644
index 0000000..00c5ce0
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/StatusCodeVisitor.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Response;
+
+use Guzzle\Http\Message\Response;
+use Guzzle\Service\Description\Parameter;
+use Guzzle\Service\Command\CommandInterface;
+
+/**
+ * Location visitor used to add the status code of a response to a key in the result
+ */
+class StatusCodeVisitor extends AbstractResponseVisitor
+{
+ public function visit(
+ CommandInterface $command,
+ Response $response,
+ Parameter $param,
+ &$value,
+ $context = null
+ ) {
+ $value[$param->getName()] = $response->getStatusCode();
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/XmlVisitor.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/XmlVisitor.php
new file mode 100644
index 0000000..bb7124b
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Response/XmlVisitor.php
@@ -0,0 +1,151 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor\Response;
+
+use Guzzle\Http\Message\Response;
+use Guzzle\Service\Description\Parameter;
+use Guzzle\Service\Command\CommandInterface;
+
+/**
+ * Location visitor used to marshal XML response data into a formatted array
+ */
+class XmlVisitor extends AbstractResponseVisitor
+{
+ public function before(CommandInterface $command, array &$result)
+ {
+ // Set the result of the command to the array conversion of the XML body
+ $result = json_decode(json_encode($command->getResponse()->xml()), true);
+ }
+
+ public function visit(
+ CommandInterface $command,
+ Response $response,
+ Parameter $param,
+ &$value,
+ $context = null
+ ) {
+ $sentAs = $param->getWireName();
+ $name = $param->getName();
+ if (isset($value[$sentAs])) {
+ $this->recursiveProcess($param, $value[$sentAs]);
+ if ($name != $sentAs) {
+ $value[$name] = $value[$sentAs];
+ unset($value[$sentAs]);
+ }
+ }
+ }
+
+ /**
+ * Recursively process a parameter while applying filters
+ *
+ * @param Parameter $param API parameter being processed
+ * @param mixed $value Value to validate and process. The value may change during this process.
+ */
+ protected function recursiveProcess(Parameter $param, &$value)
+ {
+ $type = $param->getType();
+
+ if (!is_array($value)) {
+ if ($type == 'array') {
+ // Cast to an array if the value was a string, but should be an array
+ $this->recursiveProcess($param->getItems(), $value);
+ $value = array($value);
+ }
+ } elseif ($type == 'object') {
+ $this->processObject($param, $value);
+ } elseif ($type == 'array') {
+ $this->processArray($param, $value);
+ } elseif ($type == 'string' && gettype($value) == 'array') {
+ $value = '';
+ }
+
+ if ($value !== null) {
+ $value = $param->filter($value);
+ }
+ }
+
+ /**
+ * Process an array
+ *
+ * @param Parameter $param API parameter being parsed
+ * @param mixed $value Value to process
+ */
+ protected function processArray(Parameter $param, &$value)
+ {
+ // Convert the node if it was meant to be an array
+ if (!isset($value[0])) {
+ // Collections fo nodes are sometimes wrapped in an additional array. For example:
+ // <Items><Item><a>1</a></Item><Item><a>2</a></Item></Items> should become:
+ // array('Items' => array(array('a' => 1), array('a' => 2))
+ // Some nodes are not wrapped. For example: <Foo><a>1</a></Foo><Foo><a>2</a></Foo>
+ // should become array('Foo' => array(array('a' => 1), array('a' => 2))
+ if ($param->getItems() && isset($value[$param->getItems()->getWireName()])) {
+ // Account for the case of a collection wrapping wrapped nodes: Items => Item[]
+ $value = $value[$param->getItems()->getWireName()];
+ // If the wrapped node only had one value, then make it an array of nodes
+ if (!isset($value[0]) || !is_array($value)) {
+ $value = array($value);
+ }
+ } elseif (!empty($value)) {
+ // Account for repeated nodes that must be an array: Foo => Baz, Foo => Baz, but only if the
+ // value is set and not empty
+ $value = array($value);
+ }
+ }
+
+ foreach ($value as &$item) {
+ $this->recursiveProcess($param->getItems(), $item);
+ }
+ }
+
+ /**
+ * Process an object
+ *
+ * @param Parameter $param API parameter being parsed
+ * @param mixed $value Value to process
+ */
+ protected function processObject(Parameter $param, &$value)
+ {
+ // Ensure that the array is associative and not numerically indexed
+ if (!isset($value[0]) && ($properties = $param->getProperties())) {
+ $knownProperties = array();
+ foreach ($properties as $property) {
+ $name = $property->getName();
+ $sentAs = $property->getWireName();
+ $knownProperties[$name] = 1;
+ if ($property->getData('xmlAttribute')) {
+ $this->processXmlAttribute($property, $value);
+ } elseif (isset($value[$sentAs])) {
+ $this->recursiveProcess($property, $value[$sentAs]);
+ if ($name != $sentAs) {
+ $value[$name] = $value[$sentAs];
+ unset($value[$sentAs]);
+ }
+ }
+ }
+
+ // Remove any unknown and potentially unsafe properties
+ if ($param->getAdditionalProperties() === false) {
+ $value = array_intersect_key($value, $knownProperties);
+ }
+ }
+ }
+
+ /**
+ * Process an XML attribute property
+ *
+ * @param Parameter $property Property to process
+ * @param array $value Value to process and update
+ */
+ protected function processXmlAttribute(Parameter $property, array &$value)
+ {
+ $sentAs = $property->getWireName();
+ if (isset($value['@attributes'][$sentAs])) {
+ $value[$property->getName()] = $value['@attributes'][$sentAs];
+ unset($value['@attributes'][$sentAs]);
+ if (empty($value['@attributes'])) {
+ unset($value['@attributes']);
+ }
+ }
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/VisitorFlyweight.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/VisitorFlyweight.php
new file mode 100644
index 0000000..74cb628
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/VisitorFlyweight.php
@@ -0,0 +1,138 @@
+<?php
+
+namespace Guzzle\Service\Command\LocationVisitor;
+
+use Guzzle\Common\Exception\InvalidArgumentException;
+use Guzzle\Service\Command\LocationVisitor\Request\RequestVisitorInterface;
+use Guzzle\Service\Command\LocationVisitor\Response\ResponseVisitorInterface;
+
+/**
+ * Flyweight factory used to instantiate request and response visitors
+ */
+class VisitorFlyweight
+{
+ /** @var self Singleton instance of self */
+ protected static $instance;
+
+ /** @var array Default array of mappings of location names to classes */
+ protected static $defaultMappings = array(
+ 'request.body' => 'Guzzle\Service\Command\LocationVisitor\Request\BodyVisitor',
+ 'request.header' => 'Guzzle\Service\Command\LocationVisitor\Request\HeaderVisitor',
+ 'request.json' => 'Guzzle\Service\Command\LocationVisitor\Request\JsonVisitor',
+ 'request.postField' => 'Guzzle\Service\Command\LocationVisitor\Request\PostFieldVisitor',
+ 'request.postFile' => 'Guzzle\Service\Command\LocationVisitor\Request\PostFileVisitor',
+ 'request.query' => 'Guzzle\Service\Command\LocationVisitor\Request\QueryVisitor',
+ 'request.response_body' => 'Guzzle\Service\Command\LocationVisitor\Request\ResponseBodyVisitor',
+ 'request.responseBody' => 'Guzzle\Service\Command\LocationVisitor\Request\ResponseBodyVisitor',
+ 'request.xml' => 'Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor',
+ 'response.body' => 'Guzzle\Service\Command\LocationVisitor\Response\BodyVisitor',
+ 'response.header' => 'Guzzle\Service\Command\LocationVisitor\Response\HeaderVisitor',
+ 'response.json' => 'Guzzle\Service\Command\LocationVisitor\Response\JsonVisitor',
+ 'response.reasonPhrase' => 'Guzzle\Service\Command\LocationVisitor\Response\ReasonPhraseVisitor',
+ 'response.statusCode' => 'Guzzle\Service\Command\LocationVisitor\Response\StatusCodeVisitor',
+ 'response.xml' => 'Guzzle\Service\Command\LocationVisitor\Response\XmlVisitor'
+ );
+
+ /** @var array Array of mappings of location names to classes */
+ protected $mappings;
+
+ /** @var array Cache of instantiated visitors */
+ protected $cache = array();
+
+ /**
+ * @return self
+ * @codeCoverageIgnore
+ */
+ public static function getInstance()
+ {
+ if (!self::$instance) {
+ self::$instance = new self();
+ }
+
+ return self::$instance;
+ }
+
+ /**
+ * @param array $mappings Array mapping request.name and response.name to location visitor classes. Leave null to
+ * use the default values.
+ */
+ public function __construct(array $mappings = null)
+ {
+ $this->mappings = $mappings === null ? self::$defaultMappings : $mappings;
+ }
+
+ /**
+ * Get an instance of a request visitor by location name
+ *
+ * @param string $visitor Visitor name
+ *
+ * @return RequestVisitorInterface
+ */
+ public function getRequestVisitor($visitor)
+ {
+ return $this->getKey('request.' . $visitor);
+ }
+
+ /**
+ * Get an instance of a response visitor by location name
+ *
+ * @param string $visitor Visitor name
+ *
+ * @return ResponseVisitorInterface
+ */
+ public function getResponseVisitor($visitor)
+ {
+ return $this->getKey('response.' . $visitor);
+ }
+
+ /**
+ * Add a response visitor to the factory by name
+ *
+ * @param string $name Name of the visitor
+ * @param RequestVisitorInterface $visitor Visitor to add
+ *
+ * @return self
+ */
+ public function addRequestVisitor($name, RequestVisitorInterface $visitor)
+ {
+ $this->cache['request.' . $name] = $visitor;
+
+ return $this;
+ }
+
+ /**
+ * Add a response visitor to the factory by name
+ *
+ * @param string $name Name of the visitor
+ * @param ResponseVisitorInterface $visitor Visitor to add
+ *
+ * @return self
+ */
+ public function addResponseVisitor($name, ResponseVisitorInterface $visitor)
+ {
+ $this->cache['response.' . $name] = $visitor;
+
+ return $this;
+ }
+
+ /**
+ * Get a visitor by key value name
+ *
+ * @param string $key Key name to retrieve
+ *
+ * @return mixed
+ * @throws InvalidArgumentException
+ */
+ private function getKey($key)
+ {
+ if (!isset($this->cache[$key])) {
+ if (!isset($this->mappings[$key])) {
+ list($type, $name) = explode('.', $key);
+ throw new InvalidArgumentException("No {$type} visitor has been mapped for {$name}");
+ }
+ $this->cache[$key] = new $this->mappings[$key];
+ }
+
+ return $this->cache[$key];
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/OperationCommand.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/OperationCommand.php
new file mode 100644
index 0000000..0748b5a
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/OperationCommand.php
@@ -0,0 +1,89 @@
+<?php
+
+namespace Guzzle\Service\Command;
+
+/**
+ * A command that creates requests based on {@see Guzzle\Service\Description\OperationInterface} objects, and if the
+ * matching operation uses a service description model in the responseClass attribute, then this command will marshal
+ * the response into an associative array based on the JSON schema of the model.
+ */
+class OperationCommand extends AbstractCommand
+{
+ /** @var RequestSerializerInterface */
+ protected $requestSerializer;
+
+ /** @var ResponseParserInterface Response parser */
+ protected $responseParser;
+
+ /**
+ * Set the response parser used with the command
+ *
+ * @param ResponseParserInterface $parser Response parser
+ *
+ * @return self
+ */
+ public function setResponseParser(ResponseParserInterface $parser)
+ {
+ $this->responseParser = $parser;
+
+ return $this;
+ }
+
+ /**
+ * Set the request serializer used with the command
+ *
+ * @param RequestSerializerInterface $serializer Request serializer
+ *
+ * @return self
+ */
+ public function setRequestSerializer(RequestSerializerInterface $serializer)
+ {
+ $this->requestSerializer = $serializer;
+
+ return $this;
+ }
+
+ /**
+ * Get the request serializer used with the command
+ *
+ * @return RequestSerializerInterface
+ */
+ public function getRequestSerializer()
+ {
+ if (!$this->requestSerializer) {
+ // Use the default request serializer if none was found
+ $this->requestSerializer = DefaultRequestSerializer::getInstance();
+ }
+
+ return $this->requestSerializer;
+ }
+
+ /**
+ * Get the response parser used for the operation
+ *
+ * @return ResponseParserInterface
+ */
+ public function getResponseParser()
+ {
+ if (!$this->responseParser) {
+ // Use the default response parser if none was found
+ $this->responseParser = OperationResponseParser::getInstance();
+ }
+
+ return $this->responseParser;
+ }
+
+ protected function build()
+ {
+ // Prepare and serialize the request
+ $this->request = $this->getRequestSerializer()->prepare($this);
+ }
+
+ protected function process()
+ {
+ // Do not process the response if 'command.response_processing' is set to 'raw'
+ $this->result = $this[self::RESPONSE_PROCESSING] == self::TYPE_RAW
+ ? $this->request->getResponse()
+ : $this->getResponseParser()->parse($this);
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/OperationResponseParser.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/OperationResponseParser.php
new file mode 100644
index 0000000..ca00bc0
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/OperationResponseParser.php
@@ -0,0 +1,195 @@
+<?php
+
+namespace Guzzle\Service\Command;
+
+use Guzzle\Http\Message\Response;
+use Guzzle\Service\Command\LocationVisitor\VisitorFlyweight;
+use Guzzle\Service\Command\LocationVisitor\Response\ResponseVisitorInterface;
+use Guzzle\Service\Description\Parameter;
+use Guzzle\Service\Description\OperationInterface;
+use Guzzle\Service\Description\Operation;
+use Guzzle\Service\Exception\ResponseClassException;
+use Guzzle\Service\Resource\Model;
+
+/**
+ * Response parser that attempts to marshal responses into an associative array based on models in a service description
+ */
+class OperationResponseParser extends DefaultResponseParser
+{
+ /** @var VisitorFlyweight $factory Visitor factory */
+ protected $factory;
+
+ /** @var self */
+ protected static $instance;
+
+ /** @var bool */
+ private $schemaInModels;
+
+ /**
+ * @return self
+ * @codeCoverageIgnore
+ */
+ public static function getInstance()
+ {
+ if (!static::$instance) {
+ static::$instance = new static(VisitorFlyweight::getInstance());
+ }
+
+ return static::$instance;
+ }
+
+ /**
+ * @param VisitorFlyweight $factory Factory to use when creating visitors
+ * @param bool $schemaInModels Set to true to inject schemas into models
+ */
+ public function __construct(VisitorFlyweight $factory, $schemaInModels = false)
+ {
+ $this->factory = $factory;
+ $this->schemaInModels = $schemaInModels;
+ }
+
+ /**
+ * Add a location visitor to the command
+ *
+ * @param string $location Location to associate with the visitor
+ * @param ResponseVisitorInterface $visitor Visitor to attach
+ *
+ * @return self
+ */
+ public function addVisitor($location, ResponseVisitorInterface $visitor)
+ {
+ $this->factory->addResponseVisitor($location, $visitor);
+
+ return $this;
+ }
+
+ protected function handleParsing(CommandInterface $command, Response $response, $contentType)
+ {
+ $operation = $command->getOperation();
+ $type = $operation->getResponseType();
+ $model = null;
+
+ if ($type == OperationInterface::TYPE_MODEL) {
+ $model = $operation->getServiceDescription()->getModel($operation->getResponseClass());
+ } elseif ($type == OperationInterface::TYPE_CLASS) {
+ return $this->parseClass($command);
+ }
+
+ if (!$model) {
+ // Return basic processing if the responseType is not model or the model cannot be found
+ return parent::handleParsing($command, $response, $contentType);
+ } elseif ($command[AbstractCommand::RESPONSE_PROCESSING] != AbstractCommand::TYPE_MODEL) {
+ // Returns a model with no visiting if the command response processing is not model
+ return new Model(parent::handleParsing($command, $response, $contentType));
+ } else {
+ // Only inject the schema into the model if "schemaInModel" is true
+ return new Model($this->visitResult($model, $command, $response), $this->schemaInModels ? $model : null);
+ }
+ }
+
+ /**
+ * Parse a class object
+ *
+ * @param CommandInterface $command Command to parse into an object
+ *
+ * @return mixed
+ * @throws ResponseClassException
+ */
+ protected function parseClass(CommandInterface $command)
+ {
+ // Emit the operation.parse_class event. If a listener injects a 'result' property, then that will be the result
+ $event = new CreateResponseClassEvent(array('command' => $command));
+ $command->getClient()->getEventDispatcher()->dispatch('command.parse_response', $event);
+ if ($result = $event->getResult()) {
+ return $result;
+ }
+
+ $className = $command->getOperation()->getResponseClass();
+ if (!method_exists($className, 'fromCommand')) {
+ throw new ResponseClassException("{$className} must exist and implement a static fromCommand() method");
+ }
+
+ return $className::fromCommand($command);
+ }
+
+ /**
+ * Perform transformations on the result array
+ *
+ * @param Parameter $model Model that defines the structure
+ * @param CommandInterface $command Command that performed the operation
+ * @param Response $response Response received
+ *
+ * @return array Returns the array of result data
+ */
+ protected function visitResult(Parameter $model, CommandInterface $command, Response $response)
+ {
+ $foundVisitors = $result = $knownProps = array();
+ $props = $model->getProperties();
+
+ foreach ($props as $schema) {
+ if ($location = $schema->getLocation()) {
+ // Trigger the before method on the first found visitor of this type
+ if (!isset($foundVisitors[$location])) {
+ $foundVisitors[$location] = $this->factory->getResponseVisitor($location);
+ $foundVisitors[$location]->before($command, $result);
+ }
+ }
+ }
+
+ // Visit additional properties when it is an actual schema
+ if (($additional = $model->getAdditionalProperties()) instanceof Parameter) {
+ $this->visitAdditionalProperties($model, $command, $response, $additional, $result, $foundVisitors);
+ }
+
+ // Apply the parameter value with the location visitor
+ foreach ($props as $schema) {
+ $knownProps[$schema->getName()] = 1;
+ if ($location = $schema->getLocation()) {
+ $foundVisitors[$location]->visit($command, $response, $schema, $result);
+ }
+ }
+
+ // Remove any unknown and potentially unsafe top-level properties
+ if ($additional === false) {
+ $result = array_intersect_key($result, $knownProps);
+ }
+
+ // Call the after() method of each found visitor
+ foreach ($foundVisitors as $visitor) {
+ $visitor->after($command);
+ }
+
+ return $result;
+ }
+
+ protected function visitAdditionalProperties(
+ Parameter $model,
+ CommandInterface $command,
+ Response $response,
+ Parameter $additional,
+ &$result,
+ array &$foundVisitors
+ ) {
+ // Only visit when a location is specified
+ if ($location = $additional->getLocation()) {
+ if (!isset($foundVisitors[$location])) {
+ $foundVisitors[$location] = $this->factory->getResponseVisitor($location);
+ $foundVisitors[$location]->before($command, $result);
+ }
+ // Only traverse if an array was parsed from the before() visitors
+ if (is_array($result)) {
+ // Find each additional property
+ foreach (array_keys($result) as $key) {
+ // Check if the model actually knows this property. If so, then it is not additional
+ if (!$model->getProperty($key)) {
+ // Set the name to the key so that we can parse it with each visitor
+ $additional->setName($key);
+ $foundVisitors[$location]->visit($command, $response, $additional, $result);
+ }
+ }
+ // Reset the additionalProperties name to null
+ $additional->setName(null);
+ }
+ }
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/RequestSerializerInterface.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/RequestSerializerInterface.php
new file mode 100644
index 0000000..60b9334
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/RequestSerializerInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Guzzle\Service\Command;
+
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Service\Command\CommandInterface;
+
+/**
+ * Translates command options and operation parameters into a request object
+ */
+interface RequestSerializerInterface
+{
+ /**
+ * Create a request for a command
+ *
+ * @param CommandInterface $command Command that will own the request
+ *
+ * @return RequestInterface
+ */
+ public function prepare(CommandInterface $command);
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/ResponseClassInterface.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/ResponseClassInterface.php
new file mode 100644
index 0000000..325dd08
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/ResponseClassInterface.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Guzzle\Service\Command;
+
+/**
+ * Interface used to accept a completed OperationCommand and parse the result into a specific response type
+ */
+interface ResponseClassInterface
+{
+ /**
+ * Create a response model object from a completed command
+ *
+ * @param OperationCommand $command That serialized the request
+ *
+ * @return self
+ */
+ public static function fromCommand(OperationCommand $command);
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Command/ResponseParserInterface.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/ResponseParserInterface.php
new file mode 100644
index 0000000..015f0bb
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Command/ResponseParserInterface.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Guzzle\Service\Command;
+
+/**
+ * Parses the HTTP response of a command and sets the appropriate result on a command object
+ */
+interface ResponseParserInterface
+{
+ /**
+ * Parse the HTTP response received by the command and update the command's result contents
+ *
+ * @param CommandInterface $command Command to parse and update
+ *
+ * @return mixed Returns the result to set on the command
+ */
+ public function parse(CommandInterface $command);
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/ConfigLoaderInterface.php b/vendor/guzzle/guzzle/src/Guzzle/Service/ConfigLoaderInterface.php
new file mode 100644
index 0000000..304100d
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/ConfigLoaderInterface.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Guzzle\Service;
+
+/**
+ * Interface used for loading configuration data (service descriptions, service builder configs, etc)
+ *
+ * If a loaded configuration data sets includes a top level key containing an 'includes' section, then the data in the
+ * file will extend the merged result of all of the included config files.
+ */
+interface ConfigLoaderInterface
+{
+ /**
+ * Loads configuration data and returns an array of the loaded result
+ *
+ * @param mixed $config Data to load (filename or array of data)
+ * @param array $options Array of options to use when loading
+ *
+ * @return mixed
+ */
+ public function load($config, array $options = array());
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Description/Operation.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/Operation.php
new file mode 100644
index 0000000..81a1134
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/Operation.php
@@ -0,0 +1,547 @@
+<?php
+
+namespace Guzzle\Service\Description;
+
+use Guzzle\Common\Exception\InvalidArgumentException;
+
+/**
+ * Data object holding the information of an API command
+ */
+class Operation implements OperationInterface
+{
+ /** @var string Default command class to use when none is specified */
+ const DEFAULT_COMMAND_CLASS = 'Guzzle\\Service\\Command\\OperationCommand';
+
+ /** @var array Hashmap of properties that can be specified. Represented as a hash to speed up constructor. */
+ protected static $properties = array(
+ 'name' => true, 'httpMethod' => true, 'uri' => true, 'class' => true, 'responseClass' => true,
+ 'responseType' => true, 'responseNotes' => true, 'notes' => true, 'summary' => true, 'documentationUrl' => true,
+ 'deprecated' => true, 'data' => true, 'parameters' => true, 'additionalParameters' => true,
+ 'errorResponses' => true
+ );
+
+ /** @var array Parameters */
+ protected $parameters = array();
+
+ /** @var Parameter Additional parameters schema */
+ protected $additionalParameters;
+
+ /** @var string Name of the command */
+ protected $name;
+
+ /** @var string HTTP method */
+ protected $httpMethod;
+
+ /** @var string This is a short summary of what the operation does */
+ protected $summary;
+
+ /** @var string A longer text field to explain the behavior of the operation. */
+ protected $notes;
+
+ /** @var string Reference URL providing more information about the operation */
+ protected $documentationUrl;
+
+ /** @var string HTTP URI of the command */
+ protected $uri;
+
+ /** @var string Class of the command object */
+ protected $class;
+
+ /** @var string This is what is returned from the method */
+ protected $responseClass;
+
+ /** @var string Type information about the response */
+ protected $responseType;
+
+ /** @var string Information about the response returned by the operation */
+ protected $responseNotes;
+
+ /** @var bool Whether or not the command is deprecated */
+ protected $deprecated;
+
+ /** @var array Array of errors that could occur when running the command */
+ protected $errorResponses;
+
+ /** @var ServiceDescriptionInterface */
+ protected $description;
+
+ /** @var array Extra operation information */
+ protected $data;
+
+ /**
+ * Builds an Operation object using an array of configuration data:
+ * - name: (string) Name of the command
+ * - httpMethod: (string) HTTP method of the operation
+ * - uri: (string) URI template that can create a relative or absolute URL
+ * - class: (string) Concrete class that implements this command
+ * - parameters: (array) Associative array of parameters for the command. {@see Parameter} for information.
+ * - summary: (string) This is a short summary of what the operation does
+ * - notes: (string) A longer text field to explain the behavior of the operation.
+ * - documentationUrl: (string) Reference URL providing more information about the operation
+ * - responseClass: (string) This is what is returned from the method. Can be a primitive, PSR-0 compliant
+ * class name, or model.
+ * - responseNotes: (string) Information about the response returned by the operation
+ * - responseType: (string) One of 'primitive', 'class', 'model', or 'documentation'. If not specified, this
+ * value will be automatically inferred based on whether or not there is a model matching the
+ * name, if a matching PSR-0 compliant class name is found, or set to 'primitive' by default.
+ * - deprecated: (bool) Set to true if this is a deprecated command
+ * - errorResponses: (array) Errors that could occur when executing the command. Array of hashes, each with a
+ * 'code' (the HTTP response code), 'reason' (response reason phrase or description of the
+ * error), and 'class' (a custom exception class that would be thrown if the error is
+ * encountered).
+ * - data: (array) Any extra data that might be used to help build or serialize the operation
+ * - additionalParameters: (null|array) Parameter schema to use when an option is passed to the operation that is
+ * not in the schema
+ *
+ * @param array $config Array of configuration data
+ * @param ServiceDescriptionInterface $description Service description used to resolve models if $ref tags are found
+ */
+ public function __construct(array $config = array(), ServiceDescriptionInterface $description = null)
+ {
+ $this->description = $description;
+
+ // Get the intersection of the available properties and properties set on the operation
+ foreach (array_intersect_key($config, self::$properties) as $key => $value) {
+ $this->{$key} = $value;
+ }
+
+ $this->class = $this->class ?: self::DEFAULT_COMMAND_CLASS;
+ $this->deprecated = (bool) $this->deprecated;
+ $this->errorResponses = $this->errorResponses ?: array();
+ $this->data = $this->data ?: array();
+
+ if (!$this->responseClass) {
+ $this->responseClass = 'array';
+ $this->responseType = 'primitive';
+ } elseif ($this->responseType) {
+ // Set the response type to perform validation
+ $this->setResponseType($this->responseType);
+ } else {
+ // A response class was set and no response type was set, so guess what the type is
+ $this->inferResponseType();
+ }
+
+ // Parameters need special handling when adding
+ if ($this->parameters) {
+ foreach ($this->parameters as $name => $param) {
+ if ($param instanceof Parameter) {
+ $param->setName($name)->setParent($this);
+ } elseif (is_array($param)) {
+ $param['name'] = $name;
+ $this->addParam(new Parameter($param, $this->description));
+ }
+ }
+ }
+
+ if ($this->additionalParameters) {
+ if ($this->additionalParameters instanceof Parameter) {
+ $this->additionalParameters->setParent($this);
+ } elseif (is_array($this->additionalParameters)) {
+ $this->setadditionalParameters(new Parameter($this->additionalParameters, $this->description));
+ }
+ }
+ }
+
+ public function toArray()
+ {
+ $result = array();
+ // Grab valid properties and filter out values that weren't set
+ foreach (array_keys(self::$properties) as $check) {
+ if ($value = $this->{$check}) {
+ $result[$check] = $value;
+ }
+ }
+ // Remove the name property
+ unset($result['name']);
+ // Parameters need to be converted to arrays
+ $result['parameters'] = array();
+ foreach ($this->parameters as $key => $param) {
+ $result['parameters'][$key] = $param->toArray();
+ }
+ // Additional parameters need to be cast to an array
+ if ($this->additionalParameters instanceof Parameter) {
+ $result['additionalParameters'] = $this->additionalParameters->toArray();
+ }
+
+ return $result;
+ }
+
+ public function getServiceDescription()
+ {
+ return $this->description;
+ }
+
+ public function setServiceDescription(ServiceDescriptionInterface $description)
+ {
+ $this->description = $description;
+
+ return $this;
+ }
+
+ public function getParams()
+ {
+ return $this->parameters;
+ }
+
+ public function getParamNames()
+ {
+ return array_keys($this->parameters);
+ }
+
+ public function hasParam($name)
+ {
+ return isset($this->parameters[$name]);
+ }
+
+ public function getParam($param)
+ {
+ return isset($this->parameters[$param]) ? $this->parameters[$param] : null;
+ }
+
+ /**
+ * Add a parameter to the command
+ *
+ * @param Parameter $param Parameter to add
+ *
+ * @return self
+ */
+ public function addParam(Parameter $param)
+ {
+ $this->parameters[$param->getName()] = $param;
+ $param->setParent($this);
+
+ return $this;
+ }
+
+ /**
+ * Remove a parameter from the command
+ *
+ * @param string $name Name of the parameter to remove
+ *
+ * @return self
+ */
+ public function removeParam($name)
+ {
+ unset($this->parameters[$name]);
+
+ return $this;
+ }
+
+ public function getHttpMethod()
+ {
+ return $this->httpMethod;
+ }
+
+ /**
+ * Set the HTTP method of the command
+ *
+ * @param string $httpMethod Method to set
+ *
+ * @return self
+ */
+ public function setHttpMethod($httpMethod)
+ {
+ $this->httpMethod = $httpMethod;
+
+ return $this;
+ }
+
+ public function getClass()
+ {
+ return $this->class;
+ }
+
+ /**
+ * Set the concrete class of the command
+ *
+ * @param string $className Concrete class name
+ *
+ * @return self
+ */
+ public function setClass($className)
+ {
+ $this->class = $className;
+
+ return $this;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Set the name of the command
+ *
+ * @param string $name Name of the command
+ *
+ * @return self
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+
+ return $this;
+ }
+
+ public function getSummary()
+ {
+ return $this->summary;
+ }
+
+ /**
+ * Set a short summary of what the operation does
+ *
+ * @param string $summary Short summary of the operation
+ *
+ * @return self
+ */
+ public function setSummary($summary)
+ {
+ $this->summary = $summary;
+
+ return $this;
+ }
+
+ public function getNotes()
+ {
+ return $this->notes;
+ }
+
+ /**
+ * Set a longer text field to explain the behavior of the operation.
+ *
+ * @param string $notes Notes on the operation
+ *
+ * @return self
+ */
+ public function setNotes($notes)
+ {
+ $this->notes = $notes;
+
+ return $this;
+ }
+
+ public function getDocumentationUrl()
+ {
+ return $this->documentationUrl;
+ }
+
+ /**
+ * Set the URL pointing to additional documentation on the command
+ *
+ * @param string $docUrl Documentation URL
+ *
+ * @return self
+ */
+ public function setDocumentationUrl($docUrl)
+ {
+ $this->documentationUrl = $docUrl;
+
+ return $this;
+ }
+
+ public function getResponseClass()
+ {
+ return $this->responseClass;
+ }
+
+ /**
+ * Set what is returned from the method. Can be a primitive, class name, or model. For example: 'array',
+ * 'Guzzle\\Foo\\Baz', or 'MyModelName' (to reference a model by ID).
+ *
+ * @param string $responseClass Type of response
+ *
+ * @return self
+ */
+ public function setResponseClass($responseClass)
+ {
+ $this->responseClass = $responseClass;
+ $this->inferResponseType();
+
+ return $this;
+ }
+
+ public function getResponseType()
+ {
+ return $this->responseType;
+ }
+
+ /**
+ * Set qualifying information about the responseClass. One of 'primitive', 'class', 'model', or 'documentation'
+ *
+ * @param string $responseType Response type information
+ *
+ * @return self
+ * @throws InvalidArgumentException
+ */
+ public function setResponseType($responseType)
+ {
+ static $types = array(
+ self::TYPE_PRIMITIVE => true,
+ self::TYPE_CLASS => true,
+ self::TYPE_MODEL => true,
+ self::TYPE_DOCUMENTATION => true
+ );
+ if (!isset($types[$responseType])) {
+ throw new InvalidArgumentException('responseType must be one of ' . implode(', ', array_keys($types)));
+ }
+
+ $this->responseType = $responseType;
+
+ return $this;
+ }
+
+ public function getResponseNotes()
+ {
+ return $this->responseNotes;
+ }
+
+ /**
+ * Set notes about the response of the operation
+ *
+ * @param string $notes Response notes
+ *
+ * @return self
+ */
+ public function setResponseNotes($notes)
+ {
+ $this->responseNotes = $notes;
+
+ return $this;
+ }
+
+ public function getDeprecated()
+ {
+ return $this->deprecated;
+ }
+
+ /**
+ * Set whether or not the command is deprecated
+ *
+ * @param bool $isDeprecated Set to true to mark as deprecated
+ *
+ * @return self
+ */
+ public function setDeprecated($isDeprecated)
+ {
+ $this->deprecated = $isDeprecated;
+
+ return $this;
+ }
+
+ public function getUri()
+ {
+ return $this->uri;
+ }
+
+ /**
+ * Set the URI template of the command
+ *
+ * @param string $uri URI template to set
+ *
+ * @return self
+ */
+ public function setUri($uri)
+ {
+ $this->uri = $uri;
+
+ return $this;
+ }
+
+ public function getErrorResponses()
+ {
+ return $this->errorResponses;
+ }
+
+ /**
+ * Add an error to the command
+ *
+ * @param string $code HTTP response code
+ * @param string $reason HTTP response reason phrase or information about the error
+ * @param string $class Exception class associated with the error
+ *
+ * @return self
+ */
+ public function addErrorResponse($code, $reason, $class)
+ {
+ $this->errorResponses[] = array('code' => $code, 'reason' => $reason, 'class' => $class);
+
+ return $this;
+ }
+
+ /**
+ * Set all of the error responses of the operation
+ *
+ * @param array $errorResponses Hash of error name to a hash containing a code, reason, class
+ *
+ * @return self
+ */
+ public function setErrorResponses(array $errorResponses)
+ {
+ $this->errorResponses = $errorResponses;
+
+ return $this;
+ }
+
+ public function getData($name)
+ {
+ return isset($this->data[$name]) ? $this->data[$name] : null;
+ }
+
+ /**
+ * Set a particular data point on the operation
+ *
+ * @param string $name Name of the data value
+ * @param mixed $value Value to set
+ *
+ * @return self
+ */
+ public function setData($name, $value)
+ {
+ $this->data[$name] = $value;
+
+ return $this;
+ }
+
+ /**
+ * Get the additionalParameters of the operation
+ *
+ * @return Parameter|null
+ */
+ public function getAdditionalParameters()
+ {
+ return $this->additionalParameters;
+ }
+
+ /**
+ * Set the additionalParameters of the operation
+ *
+ * @param Parameter|null $parameter Parameter to set
+ *
+ * @return self
+ */
+ public function setAdditionalParameters($parameter)
+ {
+ if ($this->additionalParameters = $parameter) {
+ $this->additionalParameters->setParent($this);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Infer the response type from the responseClass value
+ */
+ protected function inferResponseType()
+ {
+ static $primitives = array('array' => 1, 'boolean' => 1, 'string' => 1, 'integer' => 1, '' => 1);
+ if (isset($primitives[$this->responseClass])) {
+ $this->responseType = self::TYPE_PRIMITIVE;
+ } elseif ($this->description && $this->description->hasModel($this->responseClass)) {
+ $this->responseType = self::TYPE_MODEL;
+ } else {
+ $this->responseType = self::TYPE_CLASS;
+ }
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Description/OperationInterface.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/OperationInterface.php
new file mode 100644
index 0000000..4de41bd
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/OperationInterface.php
@@ -0,0 +1,159 @@
+<?php
+
+namespace Guzzle\Service\Description;
+
+use Guzzle\Common\ToArrayInterface;
+
+/**
+ * Interface defining data objects that hold the information of an API operation
+ */
+interface OperationInterface extends ToArrayInterface
+{
+ const TYPE_PRIMITIVE = 'primitive';
+ const TYPE_CLASS = 'class';
+ const TYPE_DOCUMENTATION = 'documentation';
+ const TYPE_MODEL = 'model';
+
+ /**
+ * Get the service description that the operation belongs to
+ *
+ * @return ServiceDescriptionInterface|null
+ */
+ public function getServiceDescription();
+
+ /**
+ * Set the service description that the operation belongs to
+ *
+ * @param ServiceDescriptionInterface $description Service description
+ *
+ * @return self
+ */
+ public function setServiceDescription(ServiceDescriptionInterface $description);
+
+ /**
+ * Get the params of the operation
+ *
+ * @return array
+ */
+ public function getParams();
+
+ /**
+ * Returns an array of parameter names
+ *
+ * @return array
+ */
+ public function getParamNames();
+
+ /**
+ * Check if the operation has a specific parameter by name
+ *
+ * @param string $name Name of the param
+ *
+ * @return bool
+ */
+ public function hasParam($name);
+
+ /**
+ * Get a single parameter of the operation
+ *
+ * @param string $param Parameter to retrieve by name
+ *
+ * @return Parameter|null
+ */
+ public function getParam($param);
+
+ /**
+ * Get the HTTP method of the operation
+ *
+ * @return string|null
+ */
+ public function getHttpMethod();
+
+ /**
+ * Get the concrete operation class that implements this operation
+ *
+ * @return string
+ */
+ public function getClass();
+
+ /**
+ * Get the name of the operation
+ *
+ * @return string|null
+ */
+ public function getName();
+
+ /**
+ * Get a short summary of what the operation does
+ *
+ * @return string|null
+ */
+ public function getSummary();
+
+ /**
+ * Get a longer text field to explain the behavior of the operation
+ *
+ * @return string|null
+ */
+ public function getNotes();
+
+ /**
+ * Get the documentation URL of the operation
+ *
+ * @return string|null
+ */
+ public function getDocumentationUrl();
+
+ /**
+ * Get what is returned from the method. Can be a primitive, class name, or model. For example, the responseClass
+ * could be 'array', which would inherently use a responseType of 'primitive'. Using a class name would set a
+ * responseType of 'class'. Specifying a model by ID will use a responseType of 'model'.
+ *
+ * @return string|null
+ */
+ public function getResponseClass();
+
+ /**
+ * Get information about how the response is unmarshalled: One of 'primitive', 'class', 'model', or 'documentation'
+ *
+ * @return string
+ */
+ public function getResponseType();
+
+ /**
+ * Get notes about the response of the operation
+ *
+ * @return string|null
+ */
+ public function getResponseNotes();
+
+ /**
+ * Get whether or not the operation is deprecated
+ *
+ * @return bool
+ */
+ public function getDeprecated();
+
+ /**
+ * Get the URI that will be merged into the generated request
+ *
+ * @return string
+ */
+ public function getUri();
+
+ /**
+ * Get the errors that could be encountered when executing the operation
+ *
+ * @return array
+ */
+ public function getErrorResponses();
+
+ /**
+ * Get extra data from the operation
+ *
+ * @param string $name Name of the data point to retrieve
+ *
+ * @return mixed|null
+ */
+ public function getData($name);
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Description/Parameter.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/Parameter.php
new file mode 100644
index 0000000..9ed3c30
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/Parameter.php
@@ -0,0 +1,925 @@
+<?php
+
+namespace Guzzle\Service\Description;
+
+use Guzzle\Common\Exception\InvalidArgumentException;
+
+/**
+ * API parameter object used with service descriptions
+ */
+class Parameter
+{
+ protected $name;
+ protected $description;
+ protected $serviceDescription;
+ protected $type;
+ protected $required;
+ protected $enum;
+ protected $pattern;
+ protected $minimum;
+ protected $maximum;
+ protected $minLength;
+ protected $maxLength;
+ protected $minItems;
+ protected $maxItems;
+ protected $default;
+ protected $static;
+ protected $instanceOf;
+ protected $filters;
+ protected $location;
+ protected $sentAs;
+ protected $data;
+ protected $properties = array();
+ protected $additionalProperties;
+ protected $items;
+ protected $parent;
+ protected $ref;
+ protected $format;
+ protected $propertiesCache = null;
+
+ /**
+ * Create a new Parameter using an associative array of data. The array can contain the following information:
+ * - name: (string) Unique name of the parameter
+ * - type: (string|array) Type of variable (string, number, integer, boolean, object, array, numeric,
+ * null, any). Types are using for validation and determining the structure of a parameter. You
+ * can use a union type by providing an array of simple types. If one of the union types matches
+ * the provided value, then the value is valid.
+ * - instanceOf: (string) When the type is an object, you can specify the class that the object must implement
+ * - required: (bool) Whether or not the parameter is required
+ * - default: (mixed) Default value to use if no value is supplied
+ * - static: (bool) Set to true to specify that the parameter value cannot be changed from the default
+ * - description: (string) Documentation of the parameter
+ * - location: (string) The location of a request used to apply a parameter. Custom locations can be registered
+ * with a command, but the defaults are uri, query, header, body, json, xml, postField, postFile.
+ * - sentAs: (string) Specifies how the data being modeled is sent over the wire. For example, you may wish
+ * to include certain headers in a response model that have a normalized casing of FooBar, but the
+ * actual header is x-foo-bar. In this case, sentAs would be set to x-foo-bar.
+ * - filters: (array) Array of static method names to to run a parameter value through. Each value in the
+ * array must be a string containing the full class path to a static method or an array of complex
+ * filter information. You can specify static methods of classes using the full namespace class
+ * name followed by '::' (e.g. Foo\Bar::baz()). Some filters require arguments in order to properly
+ * filter a value. For complex filters, use a hash containing a 'method' key pointing to a static
+ * method, and an 'args' key containing an array of positional arguments to pass to the method.
+ * Arguments can contain keywords that are replaced when filtering a value: '@value' is replaced
+ * with the value being validated, '@api' is replaced with the Parameter object.
+ * - properties: When the type is an object, you can specify nested parameters
+ * - additionalProperties: (array) This attribute defines a schema for all properties that are not explicitly
+ * defined in an object type definition. If specified, the value MUST be a schema or a boolean. If
+ * false is provided, no additional properties are allowed beyond the properties defined in the
+ * schema. The default value is an empty schema which allows any value for additional properties.
+ * - items: This attribute defines the allowed items in an instance array, and MUST be a schema or an array
+ * of schemas. The default value is an empty schema which allows any value for items in the
+ * instance array.
+ * When this attribute value is a schema and the instance value is an array, then all the items
+ * in the array MUST be valid according to the schema.
+ * - pattern: When the type is a string, you can specify the regex pattern that a value must match
+ * - enum: When the type is a string, you can specify a list of acceptable values
+ * - minItems: (int) Minimum number of items allowed in an array
+ * - maxItems: (int) Maximum number of items allowed in an array
+ * - minLength: (int) Minimum length of a string
+ * - maxLength: (int) Maximum length of a string
+ * - minimum: (int) Minimum value of an integer
+ * - maximum: (int) Maximum value of an integer
+ * - data: (array) Any additional custom data to use when serializing, validating, etc
+ * - format: (string) Format used to coax a value into the correct format when serializing or unserializing.
+ * You may specify either an array of filters OR a format, but not both.
+ * Supported values: date-time, date, time, timestamp, date-time-http
+ * - $ref: (string) String referencing a service description model. The parameter is replaced by the
+ * schema contained in the model.
+ *
+ * @param array $data Array of data as seen in service descriptions
+ * @param ServiceDescriptionInterface $description Service description used to resolve models if $ref tags are found
+ *
+ * @throws InvalidArgumentException
+ */
+ public function __construct(array $data = array(), ServiceDescriptionInterface $description = null)
+ {
+ if ($description) {
+ if (isset($data['$ref'])) {
+ if ($model = $description->getModel($data['$ref'])) {
+ $data = $model->toArray() + $data;
+ }
+ } elseif (isset($data['extends'])) {
+ // If this parameter extends from another parameter then start with the actual data
+ // union in the parent's data (e.g. actual supersedes parent)
+ if ($extends = $description->getModel($data['extends'])) {
+ $data += $extends->toArray();
+ }
+ }
+ }
+
+ // Pull configuration data into the parameter
+ foreach ($data as $key => $value) {
+ $this->{$key} = $value;
+ }
+
+ $this->serviceDescription = $description;
+ $this->required = (bool) $this->required;
+ $this->data = (array) $this->data;
+
+ if ($this->filters) {
+ $this->setFilters((array) $this->filters);
+ }
+
+ if ($this->type == 'object' && $this->additionalProperties === null) {
+ $this->additionalProperties = true;
+ }
+ }
+
+ /**
+ * Convert the object to an array
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ static $checks = array('required', 'description', 'static', 'type', 'format', 'instanceOf', 'location', 'sentAs',
+ 'pattern', 'minimum', 'maximum', 'minItems', 'maxItems', 'minLength', 'maxLength', 'data', 'enum',
+ 'filters');
+
+ $result = array();
+
+ // Anything that is in the `Items` attribute of an array *must* include it's name if available
+ if ($this->parent instanceof self && $this->parent->getType() == 'array' && isset($this->name)) {
+ $result['name'] = $this->name;
+ }
+
+ foreach ($checks as $c) {
+ if ($value = $this->{$c}) {
+ $result[$c] = $value;
+ }
+ }
+
+ if ($this->default !== null) {
+ $result['default'] = $this->default;
+ }
+
+ if ($this->items !== null) {
+ $result['items'] = $this->getItems()->toArray();
+ }
+
+ if ($this->additionalProperties !== null) {
+ $result['additionalProperties'] = $this->getAdditionalProperties();
+ if ($result['additionalProperties'] instanceof self) {
+ $result['additionalProperties'] = $result['additionalProperties']->toArray();
+ }
+ }
+
+ if ($this->type == 'object' && $this->properties) {
+ $result['properties'] = array();
+ foreach ($this->getProperties() as $name => $property) {
+ $result['properties'][$name] = $property->toArray();
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Get the default or static value of the command based on a value
+ *
+ * @param string $value Value that is currently set
+ *
+ * @return mixed Returns the value, a static value if one is present, or a default value
+ */
+ public function getValue($value)
+ {
+ if ($this->static || ($this->default !== null && $value === null)) {
+ return $this->default;
+ }
+
+ return $value;
+ }
+
+ /**
+ * Run a value through the filters OR format attribute associated with the parameter
+ *
+ * @param mixed $value Value to filter
+ *
+ * @return mixed Returns the filtered value
+ */
+ public function filter($value)
+ {
+ // Formats are applied exclusively and supersed filters
+ if ($this->format) {
+ return SchemaFormatter::format($this->format, $value);
+ }
+
+ // Convert Boolean values
+ if ($this->type == 'boolean' && !is_bool($value)) {
+ $value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
+ }
+
+ // Apply filters to the value
+ if ($this->filters) {
+ foreach ($this->filters as $filter) {
+ if (is_array($filter)) {
+ // Convert complex filters that hold value place holders
+ foreach ($filter['args'] as &$data) {
+ if ($data == '@value') {
+ $data = $value;
+ } elseif ($data == '@api') {
+ $data = $this;
+ }
+ }
+ $value = call_user_func_array($filter['method'], $filter['args']);
+ } else {
+ $value = call_user_func($filter, $value);
+ }
+ }
+ }
+
+ return $value;
+ }
+
+ /**
+ * Get the name of the parameter
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Get the key of the parameter, where sentAs will supersede name if it is set
+ *
+ * @return string
+ */
+ public function getWireName()
+ {
+ return $this->sentAs ?: $this->name;
+ }
+
+ /**
+ * Set the name of the parameter
+ *
+ * @param string $name Name to set
+ *
+ * @return self
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+
+ return $this;
+ }
+
+ /**
+ * Get the type(s) of the parameter
+ *
+ * @return string|array
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * Set the type(s) of the parameter
+ *
+ * @param string|array $type Type of parameter or array of simple types used in a union
+ *
+ * @return self
+ */
+ public function setType($type)
+ {
+ $this->type = $type;
+
+ return $this;
+ }
+
+ /**
+ * Get if the parameter is required
+ *
+ * @return bool
+ */
+ public function getRequired()
+ {
+ return $this->required;
+ }
+
+ /**
+ * Set if the parameter is required
+ *
+ * @param bool $isRequired Whether or not the parameter is required
+ *
+ * @return self
+ */
+ public function setRequired($isRequired)
+ {
+ $this->required = (bool) $isRequired;
+
+ return $this;
+ }
+
+ /**
+ * Get the default value of the parameter
+ *
+ * @return string|null
+ */
+ public function getDefault()
+ {
+ return $this->default;
+ }
+
+ /**
+ * Set the default value of the parameter
+ *
+ * @param string|null $default Default value to set
+ *
+ * @return self
+ */
+ public function setDefault($default)
+ {
+ $this->default = $default;
+
+ return $this;
+ }
+
+ /**
+ * Get the description of the parameter
+ *
+ * @return string|null
+ */
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ /**
+ * Set the description of the parameter
+ *
+ * @param string $description Description
+ *
+ * @return self
+ */
+ public function setDescription($description)
+ {
+ $this->description = $description;
+
+ return $this;
+ }
+
+ /**
+ * Get the minimum acceptable value for an integer
+ *
+ * @return int|null
+ */
+ public function getMinimum()
+ {
+ return $this->minimum;
+ }
+
+ /**
+ * Set the minimum acceptable value for an integer
+ *
+ * @param int|null $min Minimum
+ *
+ * @return self
+ */
+ public function setMinimum($min)
+ {
+ $this->minimum = $min;
+
+ return $this;
+ }
+
+ /**
+ * Get the maximum acceptable value for an integer
+ *
+ * @return int|null
+ */
+ public function getMaximum()
+ {
+ return $this->maximum;
+ }
+
+ /**
+ * Set the maximum acceptable value for an integer
+ *
+ * @param int $max Maximum
+ *
+ * @return self
+ */
+ public function setMaximum($max)
+ {
+ $this->maximum = $max;
+
+ return $this;
+ }
+
+ /**
+ * Get the minimum allowed length of a string value
+ *
+ * @return int
+ */
+ public function getMinLength()
+ {
+ return $this->minLength;
+ }
+
+ /**
+ * Set the minimum allowed length of a string value
+ *
+ * @param int|null $min Minimum
+ *
+ * @return self
+ */
+ public function setMinLength($min)
+ {
+ $this->minLength = $min;
+
+ return $this;
+ }
+
+ /**
+ * Get the maximum allowed length of a string value
+ *
+ * @return int|null
+ */
+ public function getMaxLength()
+ {
+ return $this->maxLength;
+ }
+
+ /**
+ * Set the maximum allowed length of a string value
+ *
+ * @param int $max Maximum length
+ *
+ * @return self
+ */
+ public function setMaxLength($max)
+ {
+ $this->maxLength = $max;
+
+ return $this;
+ }
+
+ /**
+ * Get the maximum allowed number of items in an array value
+ *
+ * @return int|null
+ */
+ public function getMaxItems()
+ {
+ return $this->maxItems;
+ }
+
+ /**
+ * Set the maximum allowed number of items in an array value
+ *
+ * @param int $max Maximum
+ *
+ * @return self
+ */
+ public function setMaxItems($max)
+ {
+ $this->maxItems = $max;
+
+ return $this;
+ }
+
+ /**
+ * Get the minimum allowed number of items in an array value
+ *
+ * @return int
+ */
+ public function getMinItems()
+ {
+ return $this->minItems;
+ }
+
+ /**
+ * Set the minimum allowed number of items in an array value
+ *
+ * @param int|null $min Minimum
+ *
+ * @return self
+ */
+ public function setMinItems($min)
+ {
+ $this->minItems = $min;
+
+ return $this;
+ }
+
+ /**
+ * Get the location of the parameter
+ *
+ * @return string|null
+ */
+ public function getLocation()
+ {
+ return $this->location;
+ }
+
+ /**
+ * Set the location of the parameter
+ *
+ * @param string|null $location Location of the parameter
+ *
+ * @return self
+ */
+ public function setLocation($location)
+ {
+ $this->location = $location;
+
+ return $this;
+ }
+
+ /**
+ * Get the sentAs attribute of the parameter that used with locations to sentAs an attribute when it is being
+ * applied to a location.
+ *
+ * @return string|null
+ */
+ public function getSentAs()
+ {
+ return $this->sentAs;
+ }
+
+ /**
+ * Set the sentAs attribute
+ *
+ * @param string|null $name Name of the value as it is sent over the wire
+ *
+ * @return self
+ */
+ public function setSentAs($name)
+ {
+ $this->sentAs = $name;
+
+ return $this;
+ }
+
+ /**
+ * Retrieve a known property from the parameter by name or a data property by name. When not specific name value
+ * is specified, all data properties will be returned.
+ *
+ * @param string|null $name Specify a particular property name to retrieve
+ *
+ * @return array|mixed|null
+ */
+ public function getData($name = null)
+ {
+ if (!$name) {
+ return $this->data;
+ }
+
+ if (isset($this->data[$name])) {
+ return $this->data[$name];
+ } elseif (isset($this->{$name})) {
+ return $this->{$name};
+ }
+
+ return null;
+ }
+
+ /**
+ * Set the extra data properties of the parameter or set a specific extra property
+ *
+ * @param string|array|null $nameOrData The name of a specific extra to set or an array of extras to set
+ * @param mixed|null $data When setting a specific extra property, specify the data to set for it
+ *
+ * @return self
+ */
+ public function setData($nameOrData, $data = null)
+ {
+ if (is_array($nameOrData)) {
+ $this->data = $nameOrData;
+ } else {
+ $this->data[$nameOrData] = $data;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get whether or not the default value can be changed
+ *
+ * @return mixed|null
+ */
+ public function getStatic()
+ {
+ return $this->static;
+ }
+
+ /**
+ * Set to true if the default value cannot be changed
+ *
+ * @param bool $static True or false
+ *
+ * @return self
+ */
+ public function setStatic($static)
+ {
+ $this->static = (bool) $static;
+
+ return $this;
+ }
+
+ /**
+ * Get an array of filters used by the parameter
+ *
+ * @return array
+ */
+ public function getFilters()
+ {
+ return $this->filters ?: array();
+ }
+
+ /**
+ * Set the array of filters used by the parameter
+ *
+ * @param array $filters Array of functions to use as filters
+ *
+ * @return self
+ */
+ public function setFilters(array $filters)
+ {
+ $this->filters = array();
+ foreach ($filters as $filter) {
+ $this->addFilter($filter);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add a filter to the parameter
+ *
+ * @param string|array $filter Method to filter the value through
+ *
+ * @return self
+ * @throws InvalidArgumentException
+ */
+ public function addFilter($filter)
+ {
+ if (is_array($filter)) {
+ if (!isset($filter['method'])) {
+ throw new InvalidArgumentException('A [method] value must be specified for each complex filter');
+ }
+ }
+
+ if (!$this->filters) {
+ $this->filters = array($filter);
+ } else {
+ $this->filters[] = $filter;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get the parent object (an {@see OperationInterface} or {@see Parameter}
+ *
+ * @return OperationInterface|Parameter|null
+ */
+ public function getParent()
+ {
+ return $this->parent;
+ }
+
+ /**
+ * Set the parent object of the parameter
+ *
+ * @param OperationInterface|Parameter|null $parent Parent container of the parameter
+ *
+ * @return self
+ */
+ public function setParent($parent)
+ {
+ $this->parent = $parent;
+
+ return $this;
+ }
+
+ /**
+ * Get the properties of the parameter
+ *
+ * @return array
+ */
+ public function getProperties()
+ {
+ if (!$this->propertiesCache) {
+ $this->propertiesCache = array();
+ foreach (array_keys($this->properties) as $name) {
+ $this->propertiesCache[$name] = $this->getProperty($name);
+ }
+ }
+
+ return $this->propertiesCache;
+ }
+
+ /**
+ * Get a specific property from the parameter
+ *
+ * @param string $name Name of the property to retrieve
+ *
+ * @return null|Parameter
+ */
+ public function getProperty($name)
+ {
+ if (!isset($this->properties[$name])) {
+ return null;
+ }
+
+ if (!($this->properties[$name] instanceof self)) {
+ $this->properties[$name]['name'] = $name;
+ $this->properties[$name] = new static($this->properties[$name], $this->serviceDescription);
+ $this->properties[$name]->setParent($this);
+ }
+
+ return $this->properties[$name];
+ }
+
+ /**
+ * Remove a property from the parameter
+ *
+ * @param string $name Name of the property to remove
+ *
+ * @return self
+ */
+ public function removeProperty($name)
+ {
+ unset($this->properties[$name]);
+ $this->propertiesCache = null;
+
+ return $this;
+ }
+
+ /**
+ * Add a property to the parameter
+ *
+ * @param Parameter $property Properties to set
+ *
+ * @return self
+ */
+ public function addProperty(Parameter $property)
+ {
+ $this->properties[$property->getName()] = $property;
+ $property->setParent($this);
+ $this->propertiesCache = null;
+
+ return $this;
+ }
+
+ /**
+ * Get the additionalProperties value of the parameter
+ *
+ * @return bool|Parameter|null
+ */
+ public function getAdditionalProperties()
+ {
+ if (is_array($this->additionalProperties)) {
+ $this->additionalProperties = new static($this->additionalProperties, $this->serviceDescription);
+ $this->additionalProperties->setParent($this);
+ }
+
+ return $this->additionalProperties;
+ }
+
+ /**
+ * Set the additionalProperties value of the parameter
+ *
+ * @param bool|Parameter|null $additional Boolean to allow any, an Parameter to specify a schema, or false to disallow
+ *
+ * @return self
+ */
+ public function setAdditionalProperties($additional)
+ {
+ $this->additionalProperties = $additional;
+
+ return $this;
+ }
+
+ /**
+ * Set the items data of the parameter
+ *
+ * @param Parameter|null $items Items to set
+ *
+ * @return self
+ */
+ public function setItems(Parameter $items = null)
+ {
+ if ($this->items = $items) {
+ $this->items->setParent($this);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get the item data of the parameter
+ *
+ * @return Parameter|null
+ */
+ public function getItems()
+ {
+ if (is_array($this->items)) {
+ $this->items = new static($this->items, $this->serviceDescription);
+ $this->items->setParent($this);
+ }
+
+ return $this->items;
+ }
+
+ /**
+ * Get the class that the parameter must implement
+ *
+ * @return null|string
+ */
+ public function getInstanceOf()
+ {
+ return $this->instanceOf;
+ }
+
+ /**
+ * Set the class that the parameter must be an instance of
+ *
+ * @param string|null $instanceOf Class or interface name
+ *
+ * @return self
+ */
+ public function setInstanceOf($instanceOf)
+ {
+ $this->instanceOf = $instanceOf;
+
+ return $this;
+ }
+
+ /**
+ * Get the enum of strings that are valid for the parameter
+ *
+ * @return array|null
+ */
+ public function getEnum()
+ {
+ return $this->enum;
+ }
+
+ /**
+ * Set the enum of strings that are valid for the parameter
+ *
+ * @param array|null $enum Array of strings or null
+ *
+ * @return self
+ */
+ public function setEnum(array $enum = null)
+ {
+ $this->enum = $enum;
+
+ return $this;
+ }
+
+ /**
+ * Get the regex pattern that must match a value when the value is a string
+ *
+ * @return string
+ */
+ public function getPattern()
+ {
+ return $this->pattern;
+ }
+
+ /**
+ * Set the regex pattern that must match a value when the value is a string
+ *
+ * @param string $pattern Regex pattern
+ *
+ * @return self
+ */
+ public function setPattern($pattern)
+ {
+ $this->pattern = $pattern;
+
+ return $this;
+ }
+
+ /**
+ * Get the format attribute of the schema
+ *
+ * @return string
+ */
+ public function getFormat()
+ {
+ return $this->format;
+ }
+
+ /**
+ * Set the format attribute of the schema
+ *
+ * @param string $format Format to set (e.g. date, date-time, timestamp, time, date-time-http)
+ *
+ * @return self
+ */
+ public function setFormat($format)
+ {
+ $this->format = $format;
+
+ return $this;
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Description/SchemaFormatter.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/SchemaFormatter.php
new file mode 100644
index 0000000..7f47fc9
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/SchemaFormatter.php
@@ -0,0 +1,156 @@
+<?php
+
+namespace Guzzle\Service\Description;
+
+use Guzzle\Common\Exception\InvalidArgumentException;
+
+/**
+ * JSON Schema formatter class
+ */
+class SchemaFormatter
+{
+ /** @var \DateTimeZone */
+ protected static $utcTimeZone;
+
+ /**
+ * Format a value by a registered format name
+ *
+ * @param string $format Registered format used to format the value
+ * @param mixed $value Value being formatted
+ *
+ * @return mixed
+ */
+ public static function format($format, $value)
+ {
+ switch ($format) {
+ case 'date-time':
+ return self::formatDateTime($value);
+ case 'date-time-http':
+ return self::formatDateTimeHttp($value);
+ case 'date':
+ return self::formatDate($value);
+ case 'time':
+ return self::formatTime($value);
+ case 'timestamp':
+ return self::formatTimestamp($value);
+ case 'boolean-string':
+ return self::formatBooleanAsString($value);
+ default:
+ return $value;
+ }
+ }
+
+ /**
+ * Create a ISO 8601 (YYYY-MM-DDThh:mm:ssZ) formatted date time value in UTC time
+ *
+ * @param string|integer|\DateTime $value Date time value
+ *
+ * @return string
+ */
+ public static function formatDateTime($value)
+ {
+ return self::dateFormatter($value, 'Y-m-d\TH:i:s\Z');
+ }
+
+ /**
+ * Create an HTTP date (RFC 1123 / RFC 822) formatted UTC date-time string
+ *
+ * @param string|integer|\DateTime $value Date time value
+ *
+ * @return string
+ */
+ public static function formatDateTimeHttp($value)
+ {
+ return self::dateFormatter($value, 'D, d M Y H:i:s \G\M\T');
+ }
+
+ /**
+ * Create a YYYY-MM-DD formatted string
+ *
+ * @param string|integer|\DateTime $value Date time value
+ *
+ * @return string
+ */
+ public static function formatDate($value)
+ {
+ return self::dateFormatter($value, 'Y-m-d');
+ }
+
+ /**
+ * Create a hh:mm:ss formatted string
+ *
+ * @param string|integer|\DateTime $value Date time value
+ *
+ * @return string
+ */
+ public static function formatTime($value)
+ {
+ return self::dateFormatter($value, 'H:i:s');
+ }
+
+ /**
+ * Formats a boolean value as a string
+ *
+ * @param string|integer|bool $value Value to convert to a boolean 'true' / 'false' value
+ *
+ * @return string
+ */
+ public static function formatBooleanAsString($value)
+ {
+ return filter_var($value, FILTER_VALIDATE_BOOLEAN) ? 'true' : 'false';
+ }
+
+ /**
+ * Return a UNIX timestamp in the UTC timezone
+ *
+ * @param string|integer|\DateTime $value Time value
+ *
+ * @return int
+ */
+ public static function formatTimestamp($value)
+ {
+ return (int) self::dateFormatter($value, 'U');
+ }
+
+ /**
+ * Get a UTC DateTimeZone object
+ *
+ * @return \DateTimeZone
+ */
+ protected static function getUtcTimeZone()
+ {
+ // @codeCoverageIgnoreStart
+ if (!self::$utcTimeZone) {
+ self::$utcTimeZone = new \DateTimeZone('UTC');
+ }
+ // @codeCoverageIgnoreEnd
+
+ return self::$utcTimeZone;
+ }
+
+ /**
+ * Perform the actual DateTime formatting
+ *
+ * @param int|string|\DateTime $dateTime Date time value
+ * @param string $format Format of the result
+ *
+ * @return string
+ * @throws InvalidArgumentException
+ */
+ protected static function dateFormatter($dateTime, $format)
+ {
+ if (is_numeric($dateTime)) {
+ return gmdate($format, (int) $dateTime);
+ }
+
+ if (is_string($dateTime)) {
+ $dateTime = new \DateTime($dateTime);
+ }
+
+ if ($dateTime instanceof \DateTime) {
+ return $dateTime->setTimezone(self::getUtcTimeZone())->format($format);
+ }
+
+ throw new InvalidArgumentException('Date/Time values must be either a string, integer, or DateTime object');
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Description/SchemaValidator.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/SchemaValidator.php
new file mode 100644
index 0000000..b045422
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/SchemaValidator.php
@@ -0,0 +1,291 @@
+<?php
+
+namespace Guzzle\Service\Description;
+
+use Guzzle\Common\ToArrayInterface;
+
+/**
+ * Default parameter validator
+ */
+class SchemaValidator implements ValidatorInterface
+{
+ /** @var self Cache instance of the object */
+ protected static $instance;
+
+ /** @var bool Whether or not integers are converted to strings when an integer is received for a string input */
+ protected $castIntegerToStringType;
+
+ /** @var array Errors encountered while validating */
+ protected $errors;
+
+ /**
+ * @return self
+ * @codeCoverageIgnore
+ */
+ public static function getInstance()
+ {
+ if (!self::$instance) {
+ self::$instance = new self();
+ }
+
+ return self::$instance;
+ }
+
+ /**
+ * @param bool $castIntegerToStringType Set to true to convert integers into strings when a required type is a
+ * string and the input value is an integer. Defaults to true.
+ */
+ public function __construct($castIntegerToStringType = true)
+ {
+ $this->castIntegerToStringType = $castIntegerToStringType;
+ }
+
+ public function validate(Parameter $param, &$value)
+ {
+ $this->errors = array();
+ $this->recursiveProcess($param, $value);
+
+ if (empty($this->errors)) {
+ return true;
+ } else {
+ sort($this->errors);
+ return false;
+ }
+ }
+
+ /**
+ * Get the errors encountered while validating
+ *
+ * @return array
+ */
+ public function getErrors()
+ {
+ return $this->errors ?: array();
+ }
+
+ /**
+ * Recursively validate a parameter
+ *
+ * @param Parameter $param API parameter being validated
+ * @param mixed $value Value to validate and validate. The value may change during this validate.
+ * @param string $path Current validation path (used for error reporting)
+ * @param int $depth Current depth in the validation validate
+ *
+ * @return bool Returns true if valid, or false if invalid
+ */
+ protected function recursiveProcess(Parameter $param, &$value, $path = '', $depth = 0)
+ {
+ // Update the value by adding default or static values
+ $value = $param->getValue($value);
+
+ $required = $param->getRequired();
+ // if the value is null and the parameter is not required or is static, then skip any further recursion
+ if ((null === $value && !$required) || $param->getStatic()) {
+ return true;
+ }
+
+ $type = $param->getType();
+ // Attempt to limit the number of times is_array is called by tracking if the value is an array
+ $valueIsArray = is_array($value);
+ // If a name is set then update the path so that validation messages are more helpful
+ if ($name = $param->getName()) {
+ $path .= "[{$name}]";
+ }
+
+ if ($type == 'object') {
+
+ // Objects are either associative arrays, ToArrayInterface, or some other object
+ if ($param->getInstanceOf()) {
+ $instance = $param->getInstanceOf();
+ if (!($value instanceof $instance)) {
+ $this->errors[] = "{$path} must be an instance of {$instance}";
+ return false;
+ }
+ }
+
+ // Determine whether or not this "value" has properties and should be traversed
+ $traverse = $temporaryValue = false;
+
+ // Convert the value to an array
+ if (!$valueIsArray && $value instanceof ToArrayInterface) {
+ $value = $value->toArray();
+ }
+
+ if ($valueIsArray) {
+ // Ensure that the array is associative and not numerically indexed
+ if (isset($value[0])) {
+ $this->errors[] = "{$path} must be an array of properties. Got a numerically indexed array.";
+ return false;
+ }
+ $traverse = true;
+ } elseif ($value === null) {
+ // Attempt to let the contents be built up by default values if possible
+ $value = array();
+ $temporaryValue = $valueIsArray = $traverse = true;
+ }
+
+ if ($traverse) {
+
+ if ($properties = $param->getProperties()) {
+ // if properties were found, the validate each property of the value
+ foreach ($properties as $property) {
+ $name = $property->getName();
+ if (isset($value[$name])) {
+ $this->recursiveProcess($property, $value[$name], $path, $depth + 1);
+ } else {
+ $current = null;
+ $this->recursiveProcess($property, $current, $path, $depth + 1);
+ // Only set the value if it was populated with something
+ if (null !== $current) {
+ $value[$name] = $current;
+ }
+ }
+ }
+ }
+
+ $additional = $param->getAdditionalProperties();
+ if ($additional !== true) {
+ // If additional properties were found, then validate each against the additionalProperties attr.
+ $keys = array_keys($value);
+ // Determine the keys that were specified that were not listed in the properties of the schema
+ $diff = array_diff($keys, array_keys($properties));
+ if (!empty($diff)) {
+ // Determine which keys are not in the properties
+ if ($additional instanceOf Parameter) {
+ foreach ($diff as $key) {
+ $this->recursiveProcess($additional, $value[$key], "{$path}[{$key}]", $depth);
+ }
+ } else {
+ // if additionalProperties is set to false and there are additionalProperties in the values, then fail
+ foreach ($diff as $prop) {
+ $this->errors[] = sprintf('%s[%s] is not an allowed property', $path, $prop);
+ }
+ }
+ }
+ }
+
+ // A temporary value will be used to traverse elements that have no corresponding input value.
+ // This allows nested required parameters with default values to bubble up into the input.
+ // Here we check if we used a temp value and nothing bubbled up, then we need to remote the value.
+ if ($temporaryValue && empty($value)) {
+ $value = null;
+ $valueIsArray = false;
+ }
+ }
+
+ } elseif ($type == 'array' && $valueIsArray && $param->getItems()) {
+ foreach ($value as $i => &$item) {
+ // Validate each item in an array against the items attribute of the schema
+ $this->recursiveProcess($param->getItems(), $item, $path . "[{$i}]", $depth + 1);
+ }
+ }
+
+ // If the value is required and the type is not null, then there is an error if the value is not set
+ if ($required && $value === null && $type != 'null') {
+ $message = "{$path} is " . ($param->getType() ? ('a required ' . implode(' or ', (array) $param->getType())) : 'required');
+ if ($param->getDescription()) {
+ $message .= ': ' . $param->getDescription();
+ }
+ $this->errors[] = $message;
+ return false;
+ }
+
+ // Validate that the type is correct. If the type is string but an integer was passed, the class can be
+ // instructed to cast the integer to a string to pass validation. This is the default behavior.
+ if ($type && (!$type = $this->determineType($type, $value))) {
+ if ($this->castIntegerToStringType && $param->getType() == 'string' && is_integer($value)) {
+ $value = (string) $value;
+ } else {
+ $this->errors[] = "{$path} must be of type " . implode(' or ', (array) $param->getType());
+ }
+ }
+
+ // Perform type specific validation for strings, arrays, and integers
+ if ($type == 'string') {
+
+ // Strings can have enums which are a list of predefined values
+ if (($enum = $param->getEnum()) && !in_array($value, $enum)) {
+ $this->errors[] = "{$path} must be one of " . implode(' or ', array_map(function ($s) {
+ return '"' . addslashes($s) . '"';
+ }, $enum));
+ }
+ // Strings can have a regex pattern that the value must match
+ if (($pattern = $param->getPattern()) && !preg_match($pattern, $value)) {
+ $this->errors[] = "{$path} must match the following regular expression: {$pattern}";
+ }
+
+ $strLen = null;
+ if ($min = $param->getMinLength()) {
+ $strLen = strlen($value);
+ if ($strLen < $min) {
+ $this->errors[] = "{$path} length must be greater than or equal to {$min}";
+ }
+ }
+ if ($max = $param->getMaxLength()) {
+ if (($strLen ?: strlen($value)) > $max) {
+ $this->errors[] = "{$path} length must be less than or equal to {$max}";
+ }
+ }
+
+ } elseif ($type == 'array') {
+
+ $size = null;
+ if ($min = $param->getMinItems()) {
+ $size = count($value);
+ if ($size < $min) {
+ $this->errors[] = "{$path} must contain {$min} or more elements";
+ }
+ }
+ if ($max = $param->getMaxItems()) {
+ if (($size ?: count($value)) > $max) {
+ $this->errors[] = "{$path} must contain {$max} or fewer elements";
+ }
+ }
+
+ } elseif ($type == 'integer' || $type == 'number' || $type == 'numeric') {
+ if (($min = $param->getMinimum()) && $value < $min) {
+ $this->errors[] = "{$path} must be greater than or equal to {$min}";
+ }
+ if (($max = $param->getMaximum()) && $value > $max) {
+ $this->errors[] = "{$path} must be less than or equal to {$max}";
+ }
+ }
+
+ return empty($this->errors);
+ }
+
+ /**
+ * From the allowable types, determine the type that the variable matches
+ *
+ * @param string $type Parameter type
+ * @param mixed $value Value to determine the type
+ *
+ * @return string|bool Returns the matching type on
+ */
+ protected function determineType($type, $value)
+ {
+ foreach ((array) $type as $t) {
+ if ($t == 'string' && (is_string($value) || (is_object($value) && method_exists($value, '__toString')))) {
+ return 'string';
+ } elseif ($t == 'object' && (is_array($value) || is_object($value))) {
+ return 'object';
+ } elseif ($t == 'array' && is_array($value)) {
+ return 'array';
+ } elseif ($t == 'integer' && is_integer($value)) {
+ return 'integer';
+ } elseif ($t == 'boolean' && is_bool($value)) {
+ return 'boolean';
+ } elseif ($t == 'number' && is_numeric($value)) {
+ return 'number';
+ } elseif ($t == 'numeric' && is_numeric($value)) {
+ return 'numeric';
+ } elseif ($t == 'null' && !$value) {
+ return 'null';
+ } elseif ($t == 'any') {
+ return 'any';
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescription.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescription.php
new file mode 100644
index 0000000..286e65e
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescription.php
@@ -0,0 +1,271 @@
+<?php
+
+namespace Guzzle\Service\Description;
+
+use Guzzle\Common\Exception\InvalidArgumentException;
+use Guzzle\Common\ToArrayInterface;
+
+/**
+ * A ServiceDescription stores service information based on a service document
+ */
+class ServiceDescription implements ServiceDescriptionInterface, ToArrayInterface
+{
+ /** @var array Array of {@see OperationInterface} objects */
+ protected $operations = array();
+
+ /** @var array Array of API models */
+ protected $models = array();
+
+ /** @var string Name of the API */
+ protected $name;
+
+ /** @var string API version */
+ protected $apiVersion;
+
+ /** @var string Summary of the API */
+ protected $description;
+
+ /** @var array Any extra API data */
+ protected $extraData = array();
+
+ /** @var ServiceDescriptionLoader Factory used in factory method */
+ protected static $descriptionLoader;
+
+ /** @var string baseUrl/basePath */
+ protected $baseUrl;
+
+ /**
+ * {@inheritdoc}
+ * @param string|array $config File to build or array of operation information
+ * @param array $options Service description factory options
+ *
+ * @return self
+ */
+ public static function factory($config, array $options = array())
+ {
+ // @codeCoverageIgnoreStart
+ if (!self::$descriptionLoader) {
+ self::$descriptionLoader = new ServiceDescriptionLoader();
+ }
+ // @codeCoverageIgnoreEnd
+
+ return self::$descriptionLoader->load($config, $options);
+ }
+
+ /**
+ * @param array $config Array of configuration data
+ */
+ public function __construct(array $config = array())
+ {
+ $this->fromArray($config);
+ }
+
+ public function serialize()
+ {
+ return json_encode($this->toArray());
+ }
+
+ public function unserialize($json)
+ {
+ $this->operations = array();
+ $this->fromArray(json_decode($json, true));
+ }
+
+ public function toArray()
+ {
+ $result = array(
+ 'name' => $this->name,
+ 'apiVersion' => $this->apiVersion,
+ 'baseUrl' => $this->baseUrl,
+ 'description' => $this->description
+ ) + $this->extraData;
+ $result['operations'] = array();
+ foreach ($this->getOperations() as $name => $operation) {
+ $result['operations'][$operation->getName() ?: $name] = $operation->toArray();
+ }
+ if (!empty($this->models)) {
+ $result['models'] = array();
+ foreach ($this->models as $id => $model) {
+ $result['models'][$id] = $model instanceof Parameter ? $model->toArray(): $model;
+ }
+ }
+
+ return array_filter($result);
+ }
+
+ public function getBaseUrl()
+ {
+ return $this->baseUrl;
+ }
+
+ /**
+ * Set the baseUrl of the description
+ *
+ * @param string $baseUrl Base URL of each operation
+ *
+ * @return self
+ */
+ public function setBaseUrl($baseUrl)
+ {
+ $this->baseUrl = $baseUrl;
+
+ return $this;
+ }
+
+ public function getOperations()
+ {
+ foreach (array_keys($this->operations) as $name) {
+ $this->getOperation($name);
+ }
+
+ return $this->operations;
+ }
+
+ public function hasOperation($name)
+ {
+ return isset($this->operations[$name]);
+ }
+
+ public function getOperation($name)
+ {
+ // Lazily retrieve and build operations
+ if (!isset($this->operations[$name])) {
+ return null;
+ }
+
+ if (!($this->operations[$name] instanceof Operation)) {
+ $this->operations[$name] = new Operation($this->operations[$name], $this);
+ }
+
+ return $this->operations[$name];
+ }
+
+ /**
+ * Add a operation to the service description
+ *
+ * @param OperationInterface $operation Operation to add
+ *
+ * @return self
+ */
+ public function addOperation(OperationInterface $operation)
+ {
+ $this->operations[$operation->getName()] = $operation->setServiceDescription($this);
+
+ return $this;
+ }
+
+ public function getModel($id)
+ {
+ if (!isset($this->models[$id])) {
+ return null;
+ }
+
+ if (!($this->models[$id] instanceof Parameter)) {
+ $this->models[$id] = new Parameter($this->models[$id] + array('name' => $id), $this);
+ }
+
+ return $this->models[$id];
+ }
+
+ public function getModels()
+ {
+ // Ensure all models are converted into parameter objects
+ foreach (array_keys($this->models) as $id) {
+ $this->getModel($id);
+ }
+
+ return $this->models;
+ }
+
+ public function hasModel($id)
+ {
+ return isset($this->models[$id]);
+ }
+
+ /**
+ * Add a model to the service description
+ *
+ * @param Parameter $model Model to add
+ *
+ * @return self
+ */
+ public function addModel(Parameter $model)
+ {
+ $this->models[$model->getName()] = $model;
+
+ return $this;
+ }
+
+ public function getApiVersion()
+ {
+ return $this->apiVersion;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ public function getData($key)
+ {
+ return isset($this->extraData[$key]) ? $this->extraData[$key] : null;
+ }
+
+ public function setData($key, $value)
+ {
+ $this->extraData[$key] = $value;
+
+ return $this;
+ }
+
+ /**
+ * Initialize the state from an array
+ *
+ * @param array $config Configuration data
+ * @throws InvalidArgumentException
+ */
+ protected function fromArray(array $config)
+ {
+ // Keep a list of default keys used in service descriptions that is later used to determine extra data keys
+ static $defaultKeys = array('name', 'models', 'apiVersion', 'baseUrl', 'description');
+ // Pull in the default configuration values
+ foreach ($defaultKeys as $key) {
+ if (isset($config[$key])) {
+ $this->{$key} = $config[$key];
+ }
+ }
+
+ // Account for the Swagger name for Guzzle's baseUrl
+ if (isset($config['basePath'])) {
+ $this->baseUrl = $config['basePath'];
+ }
+
+ // Ensure that the models and operations properties are always arrays
+ $this->models = (array) $this->models;
+ $this->operations = (array) $this->operations;
+
+ // We want to add operations differently than adding the other properties
+ $defaultKeys[] = 'operations';
+
+ // Create operations for each operation
+ if (isset($config['operations'])) {
+ foreach ($config['operations'] as $name => $operation) {
+ if (!($operation instanceof Operation) && !is_array($operation)) {
+ throw new InvalidArgumentException('Invalid operation in service description: '
+ . gettype($operation));
+ }
+ $this->operations[$name] = $operation;
+ }
+ }
+
+ // Get all of the additional properties of the service description and store them in a data array
+ foreach (array_diff(array_keys($config), $defaultKeys) as $key) {
+ $this->extraData[$key] = $config[$key];
+ }
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescriptionInterface.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescriptionInterface.php
new file mode 100644
index 0000000..5983e58
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescriptionInterface.php
@@ -0,0 +1,106 @@
+<?php
+
+namespace Guzzle\Service\Description;
+
+/**
+ * A ServiceDescription stores service information based on a service document
+ */
+interface ServiceDescriptionInterface extends \Serializable
+{
+ /**
+ * Get the basePath/baseUrl of the description
+ *
+ * @return string
+ */
+ public function getBaseUrl();
+
+ /**
+ * Get the API operations of the service
+ *
+ * @return array Returns an array of {@see OperationInterface} objects
+ */
+ public function getOperations();
+
+ /**
+ * Check if the service has an operation by name
+ *
+ * @param string $name Name of the operation to check
+ *
+ * @return bool
+ */
+ public function hasOperation($name);
+
+ /**
+ * Get an API operation by name
+ *
+ * @param string $name Name of the command
+ *
+ * @return OperationInterface|null
+ */
+ public function getOperation($name);
+
+ /**
+ * Get a specific model from the description
+ *
+ * @param string $id ID of the model
+ *
+ * @return Parameter|null
+ */
+ public function getModel($id);
+
+ /**
+ * Get all service description models
+ *
+ * @return array
+ */
+ public function getModels();
+
+ /**
+ * Check if the description has a specific model by name
+ *
+ * @param string $id ID of the model
+ *
+ * @return bool
+ */
+ public function hasModel($id);
+
+ /**
+ * Get the API version of the service
+ *
+ * @return string
+ */
+ public function getApiVersion();
+
+ /**
+ * Get the name of the API
+ *
+ * @return string
+ */
+ public function getName();
+
+ /**
+ * Get a summary of the purpose of the API
+ *
+ * @return string
+ */
+ public function getDescription();
+
+ /**
+ * Get arbitrary data from the service description that is not part of the Guzzle spec
+ *
+ * @param string $key Data key to retrieve
+ *
+ * @return null|mixed
+ */
+ public function getData($key);
+
+ /**
+ * Set arbitrary data on the service description
+ *
+ * @param string $key Data key to set
+ * @param mixed $value Value to set
+ *
+ * @return self
+ */
+ public function setData($key, $value);
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescriptionLoader.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescriptionLoader.php
new file mode 100644
index 0000000..90fe7f4
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ServiceDescriptionLoader.php
@@ -0,0 +1,64 @@
+<?php
+
+namespace Guzzle\Service\Description;
+
+use Guzzle\Service\AbstractConfigLoader;
+use Guzzle\Service\Exception\DescriptionBuilderException;
+
+/**
+ * Loader for service descriptions
+ */
+class ServiceDescriptionLoader extends AbstractConfigLoader
+{
+ protected function build($config, array $options)
+ {
+ $operations = array();
+ if (!empty($config['operations'])) {
+ foreach ($config['operations'] as $name => $op) {
+ $name = $op['name'] = isset($op['name']) ? $op['name'] : $name;
+ // Extend other operations
+ if (!empty($op['extends'])) {
+ $this->resolveExtension($name, $op, $operations);
+ }
+ $op['parameters'] = isset($op['parameters']) ? $op['parameters'] : array();
+ $operations[$name] = $op;
+ }
+ }
+
+ return new ServiceDescription(array(
+ 'apiVersion' => isset($config['apiVersion']) ? $config['apiVersion'] : null,
+ 'baseUrl' => isset($config['baseUrl']) ? $config['baseUrl'] : null,
+ 'description' => isset($config['description']) ? $config['description'] : null,
+ 'operations' => $operations,
+ 'models' => isset($config['models']) ? $config['models'] : null
+ ) + $config);
+ }
+
+ /**
+ * @param string $name Name of the operation
+ * @param array $op Operation value array
+ * @param array $operations Currently loaded operations
+ * @throws DescriptionBuilderException when extending a non-existent operation
+ */
+ protected function resolveExtension($name, array &$op, array &$operations)
+ {
+ $resolved = array();
+ $original = empty($op['parameters']) ? false: $op['parameters'];
+ $hasClass = !empty($op['class']);
+ foreach ((array) $op['extends'] as $extendedCommand) {
+ if (empty($operations[$extendedCommand])) {
+ throw new DescriptionBuilderException("{$name} extends missing operation {$extendedCommand}");
+ }
+ $toArray = $operations[$extendedCommand];
+ $resolved = empty($resolved)
+ ? $toArray['parameters']
+ : array_merge($resolved, $toArray['parameters']);
+
+ $op = $op + $toArray;
+ if (!$hasClass && isset($toArray['class'])) {
+ $op['class'] = $toArray['class'];
+ }
+ }
+ $op['parameters'] = $original ? array_merge($resolved, $original) : $resolved;
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ValidatorInterface.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ValidatorInterface.php
new file mode 100644
index 0000000..94ca77d
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Description/ValidatorInterface.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace Guzzle\Service\Description;
+
+/**
+ * Validator responsible for preparing and validating parameters against the parameter's schema
+ */
+interface ValidatorInterface
+{
+ /**
+ * Validate a value against the acceptable types, regular expressions, minimum, maximums, instanceOf, enums, etc
+ * Add default and static values to the passed in variable. If the validation completes successfully, the input
+ * must be run correctly through the matching schema's filters attribute.
+ *
+ * @param Parameter $param Schema that is being validated against the value
+ * @param mixed $value Value to validate and process. The value may change during this process.
+ *
+ * @return bool Returns true if the input data is valid for the schema
+ */
+ public function validate(Parameter $param, &$value);
+
+ /**
+ * Get validation errors encountered while validating
+ *
+ * @return array
+ */
+ public function getErrors();
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/CommandException.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/CommandException.php
new file mode 100644
index 0000000..0f016fb
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/CommandException.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace Guzzle\Service\Exception;
+
+use Guzzle\Common\Exception\RuntimeException;
+
+class CommandException extends RuntimeException {}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/CommandTransferException.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/CommandTransferException.php
new file mode 100644
index 0000000..eabe93d
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/CommandTransferException.php
@@ -0,0 +1,119 @@
+<?php
+
+namespace Guzzle\Service\Exception;
+
+use Guzzle\Http\Exception\MultiTransferException;
+use Guzzle\Service\Command\CommandInterface;
+
+/**
+ * Exception thrown when transferring commands in parallel
+ */
+class CommandTransferException extends MultiTransferException
+{
+ protected $successfulCommands = array();
+ protected $failedCommands = array();
+
+ /**
+ * Creates a new CommandTransferException from a MultiTransferException
+ *
+ * @param MultiTransferException $e Exception to base a new exception on
+ *
+ * @return self
+ */
+ public static function fromMultiTransferException(MultiTransferException $e)
+ {
+ $ce = new self($e->getMessage(), $e->getCode(), $e->getPrevious());
+ $ce->setSuccessfulRequests($e->getSuccessfulRequests());
+
+ $alreadyAddedExceptions = array();
+ foreach ($e->getFailedRequests() as $request) {
+ if ($re = $e->getExceptionForFailedRequest($request)) {
+ $alreadyAddedExceptions[] = $re;
+ $ce->addFailedRequestWithException($request, $re);
+ } else {
+ $ce->addFailedRequest($request);
+ }
+ }
+
+ // Add any exceptions that did not map to a request
+ if (count($alreadyAddedExceptions) < count($e)) {
+ foreach ($e as $ex) {
+ if (!in_array($ex, $alreadyAddedExceptions)) {
+ $ce->add($ex);
+ }
+ }
+ }
+
+ return $ce;
+ }
+
+ /**
+ * Get all of the commands in the transfer
+ *
+ * @return array
+ */
+ public function getAllCommands()
+ {
+ return array_merge($this->successfulCommands, $this->failedCommands);
+ }
+
+ /**
+ * Add to the array of successful commands
+ *
+ * @param CommandInterface $command Successful command
+ *
+ * @return self
+ */
+ public function addSuccessfulCommand(CommandInterface $command)
+ {
+ $this->successfulCommands[] = $command;
+
+ return $this;
+ }
+
+ /**
+ * Add to the array of failed commands
+ *
+ * @param CommandInterface $command Failed command
+ *
+ * @return self
+ */
+ public function addFailedCommand(CommandInterface $command)
+ {
+ $this->failedCommands[] = $command;
+
+ return $this;
+ }
+
+ /**
+ * Get an array of successful commands
+ *
+ * @return array
+ */
+ public function getSuccessfulCommands()
+ {
+ return $this->successfulCommands;
+ }
+
+ /**
+ * Get an array of failed commands
+ *
+ * @return array
+ */
+ public function getFailedCommands()
+ {
+ return $this->failedCommands;
+ }
+
+ /**
+ * Get the Exception that caused the given $command to fail
+ *
+ * @param CommandInterface $command Failed command
+ *
+ * @return \Exception|null
+ */
+ public function getExceptionForFailedCommand(CommandInterface $command)
+ {
+ return $this->getExceptionForFailedRequest($command->getRequest());
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/DescriptionBuilderException.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/DescriptionBuilderException.php
new file mode 100644
index 0000000..1407e56
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/DescriptionBuilderException.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace Guzzle\Service\Exception;
+
+use Guzzle\Common\Exception\RuntimeException;
+
+class DescriptionBuilderException extends RuntimeException {}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/InconsistentClientTransferException.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/InconsistentClientTransferException.php
new file mode 100644
index 0000000..71cbc01
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/InconsistentClientTransferException.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Guzzle\Service\Exception;
+
+use Guzzle\Common\Exception\RuntimeException;
+
+/**
+ * Command transfer exception when commands do not all use the same client
+ */
+class InconsistentClientTransferException extends RuntimeException
+{
+ /**
+ * @var array Commands with an invalid client
+ */
+ private $invalidCommands = array();
+
+ /**
+ * @param array $commands Invalid commands
+ */
+ public function __construct(array $commands)
+ {
+ $this->invalidCommands = $commands;
+ parent::__construct(
+ 'Encountered commands in a batch transfer that use inconsistent clients. The batching ' .
+ 'strategy you use with a command transfer must divide command batches by client.'
+ );
+ }
+
+ /**
+ * Get the invalid commands
+ *
+ * @return array
+ */
+ public function getCommands()
+ {
+ return $this->invalidCommands;
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ResponseClassException.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ResponseClassException.php
new file mode 100644
index 0000000..d59ff21
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ResponseClassException.php
@@ -0,0 +1,9 @@
+<?php
+
+namespace Guzzle\Service\Exception;
+
+use Guzzle\Common\Exception\RuntimeException;
+
+class ResponseClassException extends RuntimeException
+{
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ServiceBuilderException.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ServiceBuilderException.php
new file mode 100644
index 0000000..e857e5f
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ServiceBuilderException.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace Guzzle\Service\Exception;
+
+use Guzzle\Common\Exception\RuntimeException;
+
+class ServiceBuilderException extends RuntimeException {}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ServiceNotFoundException.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ServiceNotFoundException.php
new file mode 100644
index 0000000..59a0d55
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ServiceNotFoundException.php
@@ -0,0 +1,5 @@
+<?php
+
+namespace Guzzle\Service\Exception;
+
+class ServiceNotFoundException extends ServiceBuilderException {}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ValidationException.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ValidationException.php
new file mode 100644
index 0000000..9033bce
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Exception/ValidationException.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Guzzle\Service\Exception;
+
+use Guzzle\Common\Exception\RuntimeException;
+
+class ValidationException extends RuntimeException
+{
+ protected $errors = array();
+
+ /**
+ * Set the validation error messages
+ *
+ * @param array $errors Array of validation errors
+ */
+ public function setErrors(array $errors)
+ {
+ $this->errors = $errors;
+ }
+
+ /**
+ * Get any validation errors
+ *
+ * @return array
+ */
+ public function getErrors()
+ {
+ return $this->errors;
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/AbstractResourceIteratorFactory.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/AbstractResourceIteratorFactory.php
new file mode 100644
index 0000000..21140e7
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/AbstractResourceIteratorFactory.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Guzzle\Service\Resource;
+
+use Guzzle\Common\Exception\InvalidArgumentException;
+use Guzzle\Service\Command\CommandInterface;
+
+/**
+ * Abstract resource iterator factory implementation
+ */
+abstract class AbstractResourceIteratorFactory implements ResourceIteratorFactoryInterface
+{
+ public function build(CommandInterface $command, array $options = array())
+ {
+ if (!$this->canBuild($command)) {
+ throw new InvalidArgumentException('Iterator was not found for ' . $command->getName());
+ }
+
+ $className = $this->getClassName($command);
+
+ return new $className($command, $options);
+ }
+
+ public function canBuild(CommandInterface $command)
+ {
+ return (bool) $this->getClassName($command);
+ }
+
+ /**
+ * Get the name of the class to instantiate for the command
+ *
+ * @param CommandInterface $command Command that is associated with the iterator
+ *
+ * @return string
+ */
+ abstract protected function getClassName(CommandInterface $command);
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/CompositeResourceIteratorFactory.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/CompositeResourceIteratorFactory.php
new file mode 100644
index 0000000..2efc133
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/CompositeResourceIteratorFactory.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace Guzzle\Service\Resource;
+
+use Guzzle\Common\Exception\InvalidArgumentException;
+use Guzzle\Service\Command\CommandInterface;
+
+/**
+ * Factory that utilizes multiple factories for creating iterators
+ */
+class CompositeResourceIteratorFactory implements ResourceIteratorFactoryInterface
+{
+ /** @var array Array of factories */
+ protected $factories;
+
+ /** @param array $factories Array of factories used to instantiate iterators */
+ public function __construct(array $factories)
+ {
+ $this->factories = $factories;
+ }
+
+ public function build(CommandInterface $command, array $options = array())
+ {
+ if (!($factory = $this->getFactory($command))) {
+ throw new InvalidArgumentException('Iterator was not found for ' . $command->getName());
+ }
+
+ return $factory->build($command, $options);
+ }
+
+ public function canBuild(CommandInterface $command)
+ {
+ return $this->getFactory($command) !== false;
+ }
+
+ /**
+ * Add a factory to the composite factory
+ *
+ * @param ResourceIteratorFactoryInterface $factory Factory to add
+ *
+ * @return self
+ */
+ public function addFactory(ResourceIteratorFactoryInterface $factory)
+ {
+ $this->factories[] = $factory;
+
+ return $this;
+ }
+
+ /**
+ * Get the factory that matches the command object
+ *
+ * @param CommandInterface $command Command retrieving the iterator for
+ *
+ * @return ResourceIteratorFactoryInterface|bool
+ */
+ protected function getFactory(CommandInterface $command)
+ {
+ foreach ($this->factories as $factory) {
+ if ($factory->canBuild($command)) {
+ return $factory;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/MapResourceIteratorFactory.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/MapResourceIteratorFactory.php
new file mode 100644
index 0000000..c71ca9d
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/MapResourceIteratorFactory.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Guzzle\Service\Resource;
+
+use Guzzle\Service\Command\CommandInterface;
+
+/**
+ * Resource iterator factory used when explicitly mapping strings to iterator classes
+ */
+class MapResourceIteratorFactory extends AbstractResourceIteratorFactory
+{
+ /** @var array Associative array mapping iterator names to class names */
+ protected $map;
+
+ /** @param array $map Associative array mapping iterator names to class names */
+ public function __construct(array $map)
+ {
+ $this->map = $map;
+ }
+
+ public function getClassName(CommandInterface $command)
+ {
+ $className = $command->getName();
+
+ if (isset($this->map[$className])) {
+ return $this->map[$className];
+ } elseif (isset($this->map['*'])) {
+ // If a wildcard was added, then always use that
+ return $this->map['*'];
+ }
+
+ return null;
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/Model.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/Model.php
new file mode 100644
index 0000000..2322434
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/Model.php
@@ -0,0 +1,64 @@
+<?php
+
+namespace Guzzle\Service\Resource;
+
+use Guzzle\Common\Collection;
+use Guzzle\Service\Description\Parameter;
+
+/**
+ * Default model created when commands create service description model responses
+ */
+class Model extends Collection
+{
+ /** @var Parameter Structure of the model */
+ protected $structure;
+
+ /**
+ * @param array $data Data contained by the model
+ * @param Parameter $structure The structure of the model
+ */
+ public function __construct(array $data = array(), Parameter $structure = null)
+ {
+ $this->data = $data;
+ $this->structure = $structure;
+ }
+
+ /**
+ * Get the structure of the model
+ *
+ * @return Parameter
+ */
+ public function getStructure()
+ {
+ return $this->structure ?: new Parameter();
+ }
+
+ /**
+ * Provides debug information about the model object
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ $output = 'Debug output of ';
+ if ($this->structure) {
+ $output .= $this->structure->getName() . ' ';
+ }
+ $output .= 'model';
+ $output = str_repeat('=', strlen($output)) . "\n" . $output . "\n" . str_repeat('=', strlen($output)) . "\n\n";
+ $output .= "Model data\n-----------\n\n";
+ $output .= "This data can be retrieved from the model object using the get() method of the model "
+ . "(e.g. \$model->get(\$key)) or accessing the model like an associative array (e.g. \$model['key']).\n\n";
+ $lines = array_slice(explode("\n", trim(print_r($this->toArray(), true))), 2, -1);
+ $output .= implode("\n", $lines);
+
+ if ($this->structure) {
+ $output .= "\n\nModel structure\n---------------\n\n";
+ $output .= "The following JSON document defines how the model was parsed from an HTTP response into the "
+ . "associative array structure you see above.\n\n";
+ $output .= ' ' . json_encode($this->structure->toArray()) . "\n\n";
+ }
+
+ return $output . "\n";
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIterator.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIterator.php
new file mode 100644
index 0000000..e141524
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIterator.php
@@ -0,0 +1,254 @@
+<?php
+
+namespace Guzzle\Service\Resource;
+
+use Guzzle\Common\AbstractHasDispatcher;
+use Guzzle\Service\Command\CommandInterface;
+
+abstract class ResourceIterator extends AbstractHasDispatcher implements ResourceIteratorInterface
+{
+ /** @var CommandInterface Command used to send requests */
+ protected $command;
+
+ /** @var CommandInterface First sent command */
+ protected $originalCommand;
+
+ /** @var array Currently loaded resources */
+ protected $resources;
+
+ /** @var int Total number of resources that have been retrieved */
+ protected $retrievedCount = 0;
+
+ /** @var int Total number of resources that have been iterated */
+ protected $iteratedCount = 0;
+
+ /** @var string NextToken/Marker for a subsequent request */
+ protected $nextToken = false;
+
+ /** @var int Maximum number of resources to fetch per request */
+ protected $pageSize;
+
+ /** @var int Maximum number of resources to retrieve in total */
+ protected $limit;
+
+ /** @var int Number of requests sent */
+ protected $requestCount = 0;
+
+ /** @var array Initial data passed to the constructor */
+ protected $data = array();
+
+ /** @var bool Whether or not the current value is known to be invalid */
+ protected $invalid;
+
+ public static function getAllEvents()
+ {
+ return array(
+ // About to issue another command to get more results
+ 'resource_iterator.before_send',
+ // Issued another command to get more results
+ 'resource_iterator.after_send'
+ );
+ }
+
+ /**
+ * @param CommandInterface $command Initial command used for iteration
+ * @param array $data Associative array of additional parameters. You may specify any number of custom
+ * options for an iterator. Among these options, you may also specify the following values:
+ * - limit: Attempt to limit the maximum number of resources to this amount
+ * - page_size: Attempt to retrieve this number of resources per request
+ */
+ public function __construct(CommandInterface $command, array $data = array())
+ {
+ // Clone the command to keep track of the originating command for rewind
+ $this->originalCommand = $command;
+
+ // Parse options from the array of options
+ $this->data = $data;
+ $this->limit = array_key_exists('limit', $data) ? $data['limit'] : 0;
+ $this->pageSize = array_key_exists('page_size', $data) ? $data['page_size'] : false;
+ }
+
+ /**
+ * Get all of the resources as an array (Warning: this could issue a large number of requests)
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ return iterator_to_array($this, false);
+ }
+
+ public function setLimit($limit)
+ {
+ $this->limit = $limit;
+ $this->resetState();
+
+ return $this;
+ }
+
+ public function setPageSize($pageSize)
+ {
+ $this->pageSize = $pageSize;
+ $this->resetState();
+
+ return $this;
+ }
+
+ /**
+ * Get an option from the iterator
+ *
+ * @param string $key Key of the option to retrieve
+ *
+ * @return mixed|null Returns NULL if not set or the value if set
+ */
+ public function get($key)
+ {
+ return array_key_exists($key, $this->data) ? $this->data[$key] : null;
+ }
+
+ /**
+ * Set an option on the iterator
+ *
+ * @param string $key Key of the option to set
+ * @param mixed $value Value to set for the option
+ *
+ * @return ResourceIterator
+ */
+ public function set($key, $value)
+ {
+ $this->data[$key] = $value;
+
+ return $this;
+ }
+
+ public function current()
+ {
+ return $this->resources ? current($this->resources) : false;
+ }
+
+ public function key()
+ {
+ return max(0, $this->iteratedCount - 1);
+ }
+
+ public function count()
+ {
+ return $this->retrievedCount;
+ }
+
+ /**
+ * Get the total number of requests sent
+ *
+ * @return int
+ */
+ public function getRequestCount()
+ {
+ return $this->requestCount;
+ }
+
+ /**
+ * Rewind the Iterator to the first element and send the original command
+ */
+ public function rewind()
+ {
+ // Use the original command
+ $this->command = clone $this->originalCommand;
+ $this->resetState();
+ $this->next();
+ }
+
+ public function valid()
+ {
+ return !$this->invalid && (!$this->resources || $this->current() || $this->nextToken)
+ && (!$this->limit || $this->iteratedCount < $this->limit + 1);
+ }
+
+ public function next()
+ {
+ $this->iteratedCount++;
+
+ // Check if a new set of resources needs to be retrieved
+ $sendRequest = false;
+ if (!$this->resources) {
+ $sendRequest = true;
+ } else {
+ // iterate over the internal array
+ $current = next($this->resources);
+ $sendRequest = $current === false && $this->nextToken && (!$this->limit || $this->iteratedCount < $this->limit + 1);
+ }
+
+ if ($sendRequest) {
+
+ $this->dispatch('resource_iterator.before_send', array(
+ 'iterator' => $this,
+ 'resources' => $this->resources
+ ));
+
+ // Get a new command object from the original command
+ $this->command = clone $this->originalCommand;
+ // Send a request and retrieve the newly loaded resources
+ $this->resources = $this->sendRequest();
+ $this->requestCount++;
+
+ // If no resources were found, then the last request was not needed
+ // and iteration must stop
+ if (empty($this->resources)) {
+ $this->invalid = true;
+ } else {
+ // Add to the number of retrieved resources
+ $this->retrievedCount += count($this->resources);
+ // Ensure that we rewind to the beginning of the array
+ reset($this->resources);
+ }
+
+ $this->dispatch('resource_iterator.after_send', array(
+ 'iterator' => $this,
+ 'resources' => $this->resources
+ ));
+ }
+ }
+
+ /**
+ * Retrieve the NextToken that can be used in other iterators.
+ *
+ * @return string Returns a NextToken
+ */
+ public function getNextToken()
+ {
+ return $this->nextToken;
+ }
+
+ /**
+ * Returns the value that should be specified for the page size for a request that will maintain any hard limits,
+ * but still honor the specified pageSize if the number of items retrieved + pageSize < hard limit
+ *
+ * @return int Returns the page size of the next request.
+ */
+ protected function calculatePageSize()
+ {
+ if ($this->limit && $this->iteratedCount + $this->pageSize > $this->limit) {
+ return 1 + ($this->limit - $this->iteratedCount);
+ }
+
+ return (int) $this->pageSize;
+ }
+
+ /**
+ * Reset the internal state of the iterator without triggering a rewind()
+ */
+ protected function resetState()
+ {
+ $this->iteratedCount = 0;
+ $this->retrievedCount = 0;
+ $this->nextToken = false;
+ $this->resources = null;
+ $this->invalid = false;
+ }
+
+ /**
+ * Send a request to retrieve the next page of results. Hook for subclasses to implement.
+ *
+ * @return array Returns the newly loaded resources
+ */
+ abstract protected function sendRequest();
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorApplyBatched.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorApplyBatched.php
new file mode 100644
index 0000000..6aa3615
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorApplyBatched.php
@@ -0,0 +1,111 @@
+<?php
+
+namespace Guzzle\Service\Resource;
+
+use Guzzle\Common\AbstractHasDispatcher;
+use Guzzle\Batch\BatchBuilder;
+use Guzzle\Batch\BatchSizeDivisor;
+use Guzzle\Batch\BatchClosureTransfer;
+use Guzzle\Common\Version;
+
+/**
+ * Apply a callback to the contents of a {@see ResourceIteratorInterface}
+ * @deprecated Will be removed in a future version and is no longer maintained. Use the Batch\ abstractions instead.
+ * @codeCoverageIgnore
+ */
+class ResourceIteratorApplyBatched extends AbstractHasDispatcher
+{
+ /** @var callable|array */
+ protected $callback;
+
+ /** @var ResourceIteratorInterface */
+ protected $iterator;
+
+ /** @var integer Total number of sent batches */
+ protected $batches = 0;
+
+ /** @var int Total number of iterated resources */
+ protected $iterated = 0;
+
+ public static function getAllEvents()
+ {
+ return array(
+ // About to send a batch of requests to the callback
+ 'iterator_batch.before_batch',
+ // Finished sending a batch of requests to the callback
+ 'iterator_batch.after_batch',
+ // Created the batch object
+ 'iterator_batch.created_batch'
+ );
+ }
+
+ /**
+ * @param ResourceIteratorInterface $iterator Resource iterator to apply a callback to
+ * @param array|callable $callback Callback method accepting the resource iterator
+ * and an array of the iterator's current resources
+ */
+ public function __construct(ResourceIteratorInterface $iterator, $callback)
+ {
+ $this->iterator = $iterator;
+ $this->callback = $callback;
+ Version::warn(__CLASS__ . ' is deprecated');
+ }
+
+ /**
+ * Apply the callback to the contents of the resource iterator
+ *
+ * @param int $perBatch The number of records to group per batch transfer
+ *
+ * @return int Returns the number of iterated resources
+ */
+ public function apply($perBatch = 50)
+ {
+ $this->iterated = $this->batches = $batches = 0;
+ $that = $this;
+ $it = $this->iterator;
+ $callback = $this->callback;
+
+ $batch = BatchBuilder::factory()
+ ->createBatchesWith(new BatchSizeDivisor($perBatch))
+ ->transferWith(new BatchClosureTransfer(function (array $batch) use ($that, $callback, &$batches, $it) {
+ $batches++;
+ $that->dispatch('iterator_batch.before_batch', array('iterator' => $it, 'batch' => $batch));
+ call_user_func_array($callback, array($it, $batch));
+ $that->dispatch('iterator_batch.after_batch', array('iterator' => $it, 'batch' => $batch));
+ }))
+ ->autoFlushAt($perBatch)
+ ->build();
+
+ $this->dispatch('iterator_batch.created_batch', array('batch' => $batch));
+
+ foreach ($this->iterator as $resource) {
+ $this->iterated++;
+ $batch->add($resource);
+ }
+
+ $batch->flush();
+ $this->batches = $batches;
+
+ return $this->iterated;
+ }
+
+ /**
+ * Get the total number of batches sent
+ *
+ * @return int
+ */
+ public function getBatchCount()
+ {
+ return $this->batches;
+ }
+
+ /**
+ * Get the total number of iterated resources
+ *
+ * @return int
+ */
+ public function getIteratedCount()
+ {
+ return $this->iterated;
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorClassFactory.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorClassFactory.php
new file mode 100644
index 0000000..2fd9980
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorClassFactory.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace Guzzle\Service\Resource;
+
+use Guzzle\Inflection\InflectorInterface;
+use Guzzle\Inflection\Inflector;
+use Guzzle\Service\Command\CommandInterface;
+
+/**
+ * Factory for creating {@see ResourceIteratorInterface} objects using a convention of storing iterator classes under a
+ * root namespace using the name of a {@see CommandInterface} object as a convention for determining the name of an
+ * iterator class. The command name is converted to CamelCase and Iterator is appended (e.g. abc_foo => AbcFoo).
+ */
+class ResourceIteratorClassFactory extends AbstractResourceIteratorFactory
+{
+ /** @var array List of namespaces used to look for classes */
+ protected $namespaces;
+
+ /** @var InflectorInterface Inflector used to determine class names */
+ protected $inflector;
+
+ /**
+ * @param string|array $namespaces List of namespaces for iterator objects
+ * @param InflectorInterface $inflector Inflector used to resolve class names
+ */
+ public function __construct($namespaces = array(), InflectorInterface $inflector = null)
+ {
+ $this->namespaces = (array) $namespaces;
+ $this->inflector = $inflector ?: Inflector::getDefault();
+ }
+
+ /**
+ * Registers a namespace to check for Iterators
+ *
+ * @param string $namespace Namespace which contains Iterator classes
+ *
+ * @return self
+ */
+ public function registerNamespace($namespace)
+ {
+ array_unshift($this->namespaces, $namespace);
+
+ return $this;
+ }
+
+ protected function getClassName(CommandInterface $command)
+ {
+ $iteratorName = $this->inflector->camel($command->getName()) . 'Iterator';
+
+ // Determine the name of the class to load
+ foreach ($this->namespaces as $namespace) {
+ $potentialClassName = $namespace . '\\' . $iteratorName;
+ if (class_exists($potentialClassName)) {
+ return $potentialClassName;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorFactoryInterface.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorFactoryInterface.php
new file mode 100644
index 0000000..8b4e8db
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorFactoryInterface.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Guzzle\Service\Resource;
+
+use Guzzle\Service\Command\CommandInterface;
+
+/**
+ * Factory for creating {@see ResourceIteratorInterface} objects
+ */
+interface ResourceIteratorFactoryInterface
+{
+ /**
+ * Create a resource iterator
+ *
+ * @param CommandInterface $command Command to create an iterator for
+ * @param array $options Iterator options that are exposed as data.
+ *
+ * @return ResourceIteratorInterface
+ */
+ public function build(CommandInterface $command, array $options = array());
+
+ /**
+ * Check if the factory can create an iterator
+ *
+ * @param CommandInterface $command Command to create an iterator for
+ *
+ * @return bool
+ */
+ public function canBuild(CommandInterface $command);
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorInterface.php b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorInterface.php
new file mode 100644
index 0000000..dbaafde
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/Resource/ResourceIteratorInterface.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace Guzzle\Service\Resource;
+
+use Guzzle\Common\HasDispatcherInterface;
+use Guzzle\Common\ToArrayInterface;
+
+/**
+ * Iterates over a paginated resource using subsequent requests in order to retrieve the entire matching result set
+ */
+interface ResourceIteratorInterface extends ToArrayInterface, HasDispatcherInterface, \Iterator, \Countable
+{
+ /**
+ * Retrieve the NextToken that can be used in other iterators.
+ *
+ * @return string Returns a NextToken
+ */
+ public function getNextToken();
+
+ /**
+ * Attempt to limit the total number of resources returned by the iterator.
+ *
+ * You may still receive more items than you specify. Set to 0 to specify no limit.
+ *
+ * @param int $limit Limit amount
+ *
+ * @return ResourceIteratorInterface
+ */
+ public function setLimit($limit);
+
+ /**
+ * Attempt to limit the total number of resources retrieved per request by the iterator.
+ *
+ * The iterator may return more than you specify in the page size argument depending on the service and underlying
+ * command implementation. Set to 0 to specify no page size limitation.
+ *
+ * @param int $pageSize Limit amount
+ *
+ * @return ResourceIteratorInterface
+ */
+ public function setPageSize($pageSize);
+
+ /**
+ * Get a data option from the iterator
+ *
+ * @param string $key Key of the option to retrieve
+ *
+ * @return mixed|null Returns NULL if not set or the value if set
+ */
+ public function get($key);
+
+ /**
+ * Set a data option on the iterator
+ *
+ * @param string $key Key of the option to set
+ * @param mixed $value Value to set for the option
+ *
+ * @return ResourceIteratorInterface
+ */
+ public function set($key, $value);
+}
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Service/composer.json b/vendor/guzzle/guzzle/src/Guzzle/Service/composer.json
new file mode 100644
index 0000000..cb7ace6
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Service/composer.json
@@ -0,0 +1,29 @@
+{
+ "name": "guzzle/service",
+ "description": "Guzzle service component for abstracting RESTful web services",
+ "homepage": "http://guzzlephp.org/",
+ "keywords": ["web service", "webservice", "REST", "guzzle"],
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.2",
+ "guzzle/cache": "self.version",
+ "guzzle/http": "self.version",
+ "guzzle/inflection": "self.version"
+ },
+ "autoload": {
+ "psr-0": { "Guzzle\\Service": "" }
+ },
+ "target-dir": "Guzzle/Service",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.7-dev"
+ }
+ }
+}