Вход Регистрация
Файл: monst/Xsolla/Guzzle/Service/Client.php
Строк: 405
<?php

namespace GuzzleService;

use 
GuzzleCommonCollection;
use 
GuzzleCommonExceptionInvalidArgumentException;
use 
GuzzleCommonExceptionBadMethodCallException;
use 
GuzzleCommonVersion;
use 
GuzzleInflectionInflectorInterface;
use 
GuzzleInflectionInflector;
use 
GuzzleHttpClient as HttpClient;
use 
GuzzleHttpExceptionMultiTransferException;
use 
GuzzleServiceExceptionCommandTransferException;
use 
GuzzleHttpMessageRequestInterface;
use 
GuzzleServiceCommandCommandInterface;
use 
GuzzleServiceCommandFactoryCompositeFactory;
use 
GuzzleServiceCommandFactoryFactoryInterface as CommandFactoryInterface;
use 
GuzzleServiceResourceResourceIteratorClassFactory;
use 
GuzzleServiceResourceResourceIteratorFactoryInterface;
use 
GuzzleServiceDescriptionServiceDescriptionInterface;

/**
 * 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 CommandFactoryServiceDescriptionFactory($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 ExceptionCommandTransferException
     */
    
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');
    }
}
Онлайн: 1
Реклама