/** * {@inheritdoc} */ public function prepare(CommandInterface $command) { $request = $this->createRequest($command); // Keep an array of visitors found in the operation $foundVisitors = array(); // Add arguments to the request using the location attribute foreach ($command->getOperation()->getParams() as $name => $arg) { /** @var $arg \Guzzle\Service\Description\Parameter */ if ($location = $arg->getLocation()) { // Skip 'uri' locations because they've already been processed if ($location == 'uri') { continue; } // 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->get($name); if ($value !== null) { // Apply the parameter value with the location visitor $foundVisitors[$location]->visit($command, $request, $arg, $value); } } } // Call the after method on each visitor found in the operation foreach ($foundVisitors as $visitor) { $visitor->after($command, $request); } return $request; }
/** * {@inheritdoc} */ protected function init() { if (!isset($this['event_id'])) { /** * Support the old namespace */ if (class_exists('Rhumsaa\\Uuid\\Uuid')) { $uuid = \Rhumsaa\Uuid\Uuid::uuid4(); } else { $uuid = Uuid::uuid4(); } $this['event_id'] = str_replace('-', '', $uuid->toString()); } if (!isset($this['timestamp'])) { $this['timestamp'] = new \DateTime(); } if ($this['timestamp'] instanceof \DateTime) { $this['timestamp'] = clone $this['timestamp']; $this['timestamp']->setTimezone(new \DateTimeZone('UTC')); $this['timestamp'] = $this['timestamp']->format('Y-m-d\\TH:i:s'); } $factory = new VisitorFlyweight(); $factory->addRequestVisitor('json', new JsonVisitor()); $this->setRequestSerializer(new DefaultRequestSerializer($factory)); }
public function testAllowsAddingVisitors() { $f = new VisitorFlyweight(); $j1 = new JsonRequestVisitor(); $j2 = new JsonResponseVisitor(); $f->addRequestVisitor('json', $j1); $f->addResponseVisitor('json', $j2); $this->assertSame($j1, $f->getRequestVisitor('json')); $this->assertSame($j2, $f->getResponseVisitor('json')); }
/** * Ensures that the visitor for a given location is added to the array * * This will create the visitor if it's not already in $visitors, and then * run its "before()" method, before adding it as $visitors[$location]. */ private function addVisitor(array &$visitors, $location, EmbeddedCommand $command, array &$result) { if ($location && !isset($visitors[$location])) { $visitors[$location] = $this->visitors->getResponseVisitor($location); $visitors[$location]->before($command, $result); } }
public static function getInstance() { if (!static::$instance) { static::$instance = new static(VisitorFlyweight::getInstance()); } return static::$instance; }
/** * Get singleton * @return StrictResponseParser */ public static function getInstance() { if (!static::$instance) { static::$instance = new StrictResponseParser(VisitorFlyweight::getInstance(), true); } return static::$instance; }
public function testHasRequestSerializer() { $operation = new OperationCommand(); $a = $operation->getRequestSerializer(); $b = new DefaultRequestSerializer(VisitorFlyweight::getInstance()); $operation->setRequestSerializer($b); $this->assertNotSame($a, $operation->getRequestSerializer()); }
/** * {@inheritdoc} */ protected function init() { if (!isset($this['event_id'])) { $this['event_id'] = Uuid::uuid4()->toString(); } if (!isset($this['timestamp'])) { $this['timestamp'] = new \DateTime(); } if ($this['timestamp'] instanceof \DateTime) { $this['timestamp'] = clone $this['timestamp']; $this['timestamp']->setTimezone(new \DateTimeZone('UTC')); $this['timestamp'] = $this['timestamp']->format(\DateTime::ISO8601); } $factory = new VisitorFlyweight(); $factory->addRequestVisitor('json', new JsonVisitor()); $this->setRequestSerializer(new DefaultRequestSerializer($factory)); }
/** * {@inheritdoc} * * Overridden to store this class separately to the parent class, * because otherwise an instance of this child class will be * retrieved by a call to the parent method (which is undesirable). * * @return Desk\Relationship\ResponseParser */ public static function getInstance() { if (!self::$relationshipInstance) { $instance = new self(VisitorFlyweight::getInstance()); self::$relationshipInstance = $instance; } return self::$relationshipInstance; }
public function testCanInjectModelSchemaIntoModels() { $parser = new OperationResponseParser(VisitorFlyweight::getInstance(), true); $desc = $this->getDescription(); $operation = $desc->getOperation('test'); $op = new OperationCommand(array(), $operation); $op->setResponseParser($parser)->setClient(new Client()); $op->prepare()->setResponse(new Response(200, array('Content-Type' => 'application/json'), '{"baz":"bar","enigma":"123"}'), true); $result = $op->execute(); $this->assertSame($result->getStructure(), $desc->getModel('Foo')); }
/** * Processes model data according to a parameter schema * * @param Desk\Relationship\Resource\EmbeddedCommand $command * @param Guzzle\Service\Description\Parameter $schema * @param array $data * * @return array */ public function process(EmbeddedCommand $command, Parameter $schema, array $data) { $result = array(); $visitors = array(); $properties = $schema->getProperties(); foreach ($properties as $property) { $location = $property->getLocation(); if ($location && !isset($visitors[$location])) { // add visitor for this location and trigger before() $visitor = $this->visitors->getResponseVisitor($location); $visitor->before($command, $result); $visitors[$location] = $visitor; } } $response = $command->getResponse(); // Visit additional properties when it is an actual schema $additional = $schema->getAdditionalProperties(); if ($additional instanceof Parameter) { // Only visit when a location is specified $location = $additional->getLocation(); if ($location) { if (!isset($visitors[$location])) { $visitors[$location] = $this->visitors->getResponseVisitor($location); $visitors[$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 (!$schema->getProperty($key)) { // Set the name to the key so that we can parse it with each visitor $additional->setName($key); $visitors[$location]->visit($command, $response, $additional, $result); } } // Reset the additionalProperties name to null $additional->setName(null); } } } // Apply the parameter value with the location visitor foreach ($properties as $property) { $location = $property->getLocation(); if ($location) { $visitors[$location]->visit($command, $response, $property, $result); } } // Call the after() method of each found visitor foreach ($visitors as $visitor) { $visitor->after($command); } return $result; }
/** * 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 = 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()) { if ($additional instanceof Parameter) { // 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); } } } } // Apply the parameter value with the location visitor foreach ($props as $schema) { if ($location = $schema->getLocation()) { $foundVisitors[$location]->visit($command, $response, $schema, $result); } } // Call the after() method of each found visitor foreach ($foundVisitors as $visitor) { $visitor->after($command); } return $result; }
/** * 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); foreach ($command->getAll() as $key => $value) { // Ignore values that are null or built-in command options if ($value !== null && $key != 'command.headers' && $key != 'command.response_processing' && !$operation->hasParam($key)) { $additional->setName($key); $visitor->visit($command, $request, $additional, $value); } } return $visitor; }
/** * 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; }
/** * 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) { // Determine what visitors are associated with the model $foundVisitors = $result = array(); foreach ($model->getProperties() as $schema) { if ($location = $schema->getLocation()) { $foundVisitors[$location] = $this->factory->getResponseVisitor($location); $foundVisitors[$location]->before($command, $result); } } foreach ($model->getProperties() as $schema) { /** @var $arg Parameter */ if ($location = $schema->getLocation()) { // Apply the parameter value with the location visitor $foundVisitors[$location]->visit($command, $response, $schema, $result); } } 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); } } }
/** * Accepts a VisitorFlyweight for LocationVisitors * * @param Desk\Relationship\Resource\EmbeddedCommandFactoryInterface $factory * @param Guzzle\Service\Command\LocationVisitor\VisitorFlyweight $visitors */ public function __construct(EmbeddedCommandFactoryInterface $factory = null, VisitorFlyweight $visitors = null) { $this->factory = $factory ?: new EmbeddedCommandFactory(); $this->visitors = $visitors ?: VisitorFlyweight::getInstance(); }