Ampache PHP Cross Reference Groupware Applications

Source: /modules/Guzzle/Plugin/Mock/MockPlugin.php - 242 lines - 6891 bytes - Summary - Text - Print

   1  <?php
   2  
   3  namespace Guzzle\Plugin\Mock;
   4  
   5  use Guzzle\Common\Event;
   6  use Guzzle\Common\Exception\InvalidArgumentException;
   7  use Guzzle\Common\AbstractHasDispatcher;
   8  use Guzzle\Http\Exception\CurlException;
   9  use Guzzle\Http\Message\RequestInterface;
  10  use Guzzle\Http\Message\EntityEnclosingRequestInterface;
  11  use Guzzle\Http\Message\Response;
  12  use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  13  
  14  /**
  15   * Queues mock responses or exceptions and delivers mock responses or exceptions in a fifo order.
  16   */
  17  class MockPlugin extends AbstractHasDispatcher implements EventSubscriberInterface, \Countable
  18  {
  19      /** @var array Array of mock responses / exceptions */
  20      protected $queue = array();
  21  
  22      /** @var bool Whether or not to remove the plugin when the queue is empty */
  23      protected $temporary = false;
  24  
  25      /** @var array Array of requests that were mocked */
  26      protected $received = array();
  27  
  28      /** @var bool Whether or not to consume an entity body when a mock response is served */
  29      protected $readBodies;
  30  
  31      /**
  32       * @param array $items      Array of responses or exceptions to queue
  33       * @param bool  $temporary  Set to TRUE to remove the plugin when the queue is empty
  34       * @param bool  $readBodies Set to TRUE to consume the entity body when a mock is served
  35       */
  36      public function __construct(array $items = null, $temporary = false, $readBodies = false)
  37      {
  38          $this->readBodies = $readBodies;
  39          $this->temporary = $temporary;
  40          if ($items) {
  41              foreach ($items as $item) {
  42                  if ($item instanceof \Exception) {
  43                      $this->addException($item);
  44                  } else {
  45                      $this->addResponse($item);
  46                  }
  47              }
  48          }
  49      }
  50  
  51      public static function getSubscribedEvents()
  52      {
  53          // Use a number lower than the CachePlugin
  54          return array('request.before_send' => array('onRequestBeforeSend', -999));
  55      }
  56  
  57      public static function getAllEvents()
  58      {
  59          return array('mock.request');
  60      }
  61  
  62      /**
  63       * Get a mock response from a file
  64       *
  65       * @param string $path File to retrieve a mock response from
  66       *
  67       * @return Response
  68       * @throws InvalidArgumentException if the file is not found
  69       */
  70      public static function getMockFile($path)
  71      {
  72          if (!file_exists($path)) {
  73              throw new InvalidArgumentException('Unable to open mock file: ' . $path);
  74          }
  75  
  76          return Response::fromMessage(file_get_contents($path));
  77      }
  78  
  79      /**
  80       * Set whether or not to consume the entity body of a request when a mock
  81       * response is used
  82       *
  83       * @param bool $readBodies Set to true to read and consume entity bodies
  84       *
  85       * @return self
  86       */
  87      public function readBodies($readBodies)
  88      {
  89          $this->readBodies = $readBodies;
  90  
  91          return $this;
  92      }
  93  
  94      /**
  95       * Returns the number of remaining mock responses
  96       *
  97       * @return int
  98       */
  99      public function count()
 100      {
 101          return count($this->queue);
 102      }
 103  
 104      /**
 105       * Add a response to the end of the queue
 106       *
 107       * @param string|Response $response Response object or path to response file
 108       *
 109       * @return MockPlugin
 110       * @throws InvalidArgumentException if a string or Response is not passed
 111       */
 112      public function addResponse($response)
 113      {
 114          if (!($response instanceof Response)) {
 115              if (!is_string($response)) {
 116                  throw new InvalidArgumentException('Invalid response');
 117              }
 118              $response = self::getMockFile($response);
 119          }
 120  
 121          $this->queue[] = $response;
 122  
 123          return $this;
 124      }
 125  
 126      /**
 127       * Add an exception to the end of the queue
 128       *
 129       * @param CurlException $e Exception to throw when the request is executed
 130       *
 131       * @return MockPlugin
 132       */
 133      public function addException(CurlException $e)
 134      {
 135          $this->queue[] = $e;
 136  
 137          return $this;
 138      }
 139  
 140      /**
 141       * Clear the queue
 142       *
 143       * @return MockPlugin
 144       */
 145      public function clearQueue()
 146      {
 147          $this->queue = array();
 148  
 149          return $this;
 150      }
 151  
 152      /**
 153       * Returns an array of mock responses remaining in the queue
 154       *
 155       * @return array
 156       */
 157      public function getQueue()
 158      {
 159          return $this->queue;
 160      }
 161  
 162      /**
 163       * Check if this is a temporary plugin
 164       *
 165       * @return bool
 166       */
 167      public function isTemporary()
 168      {
 169          return $this->temporary;
 170      }
 171  
 172      /**
 173       * Get a response from the front of the list and add it to a request
 174       *
 175       * @param RequestInterface $request Request to mock
 176       *
 177       * @return self
 178       * @throws CurlException When request.send is called and an exception is queued
 179       */
 180      public function dequeue(RequestInterface $request)
 181      {
 182          $this->dispatch('mock.request', array('plugin' => $this, 'request' => $request));
 183  
 184          $item = array_shift($this->queue);
 185          if ($item instanceof Response) {
 186              if ($this->readBodies && $request instanceof EntityEnclosingRequestInterface) {
 187                  $request->getEventDispatcher()->addListener('request.sent', $f = function (Event $event) use (&$f) {
 188                      while ($data = $event['request']->getBody()->read(8096));
 189                      // Remove the listener after one-time use
 190                      $event['request']->getEventDispatcher()->removeListener('request.sent', $f);
 191                  });
 192              }
 193              $request->setResponse($item);
 194          } elseif ($item instanceof CurlException) {
 195              // Emulates exceptions encountered while transferring requests
 196              $item->setRequest($request);
 197              $state = $request->setState(RequestInterface::STATE_ERROR, array('exception' => $item));
 198              // Only throw if the exception wasn't handled
 199              if ($state == RequestInterface::STATE_ERROR) {
 200                  throw $item;
 201              }
 202          }
 203  
 204          return $this;
 205      }
 206  
 207      /**
 208       * Clear the array of received requests
 209       */
 210      public function flush()
 211      {
 212          $this->received = array();
 213      }
 214  
 215      /**
 216       * Get an array of requests that were mocked by this plugin
 217       *
 218       * @return array
 219       */
 220      public function getReceivedRequests()
 221      {
 222          return $this->received;
 223      }
 224  
 225      /**
 226       * Called when a request is about to be sent
 227       *
 228       * @param Event $event
 229       */
 230      public function onRequestBeforeSend(Event $event)
 231      {
 232          if ($this->queue) {
 233              $request = $event['request'];
 234              $this->received[] = $request;
 235              // Detach the filter from the client so it's a one-time use
 236              if ($this->temporary && count($this->queue) == 1 && $request->getClient()) {
 237                  $request->getClient()->getEventDispatcher()->removeSubscriber($this);
 238              }
 239              $this->dequeue($request);
 240          }
 241      }
 242  }

title

Description

title

Description

title

Description

title

title

Body