Open Journal Systems  3.3.0
AbstractCommand.php
1 <?php
2 
4 
17 
21 abstract class AbstractCommand extends Collection implements CommandInterface
22 {
23  // @deprecated: Option used to specify custom headers to add to the generated request
24  const HEADERS_OPTION = 'command.headers';
25  // @deprecated: Option used to add an onComplete method to a command
26  const ON_COMPLETE = 'command.on_complete';
27  // @deprecated: Option used to change the entity body used to store a response
28  const RESPONSE_BODY = 'command.response_body';
29 
30  // Option used to add request options to the request created by a command
31  const REQUEST_OPTIONS = 'command.request_options';
32  // command values to not count as additionalParameters
33  const HIDDEN_PARAMS = 'command.hidden_params';
34  // Option used to disable any pre-sending command validation
35  const DISABLE_VALIDATION = 'command.disable_validation';
36  // Option used to override how a command result will be formatted
37  const RESPONSE_PROCESSING = 'command.response_processing';
38  // Different response types that commands can use
39  const TYPE_RAW = 'raw';
40  const TYPE_MODEL = 'model';
41  const TYPE_NO_TRANSLATION = 'no_translation';
42 
44  protected $client;
45 
47  protected $request;
48 
50  protected $result;
51 
53  protected $operation;
54 
56  protected $onComplete;
57 
59  protected $validator;
60 
65  public function __construct($parameters = array(), OperationInterface $operation = null)
66  {
67  parent::__construct($parameters);
68  $this->operation = $operation ?: $this->createOperation();
69  foreach ($this->operation->getParams() as $name => $arg) {
70  $currentValue = $this[$name];
71  $configValue = $arg->getValue($currentValue);
72  // If default or static values are set, then this should always be updated on the config object
73  if ($currentValue !== $configValue) {
74  $this[$name] = $configValue;
75  }
76  }
77 
78  $headers = $this[self::HEADERS_OPTION];
79  if (!$headers instanceof Collection) {
80  $this[self::HEADERS_OPTION] = new Collection((array) $headers);
81  }
82 
83  // You can set a command.on_complete option in your parameters to set an onComplete callback
84  if ($onComplete = $this['command.on_complete']) {
85  unset($this['command.on_complete']);
86  $this->setOnComplete($onComplete);
87  }
88 
89  // Set the hidden additional parameters
90  if (!$this[self::HIDDEN_PARAMS]) {
91  $this[self::HIDDEN_PARAMS] = array(
92  self::HEADERS_OPTION,
93  self::RESPONSE_PROCESSING,
94  self::HIDDEN_PARAMS,
95  self::REQUEST_OPTIONS
96  );
97  }
98 
99  $this->init();
100  }
101 
105  public function __clone()
106  {
107  $this->request = null;
108  $this->result = null;
109  }
110 
116  public function __invoke()
117  {
118  return $this->execute();
119  }
120 
121  public function getName()
122  {
123  return $this->operation->getName();
124  }
125 
131  public function getOperation()
132  {
133  return $this->operation;
134  }
135 
136  public function setOnComplete($callable)
137  {
138  if (!is_callable($callable)) {
139  throw new InvalidArgumentException('The onComplete function must be callable');
140  }
141 
142  $this->onComplete = $callable;
143 
144  return $this;
145  }
146 
147  public function execute()
148  {
149  if (!$this->client) {
150  throw new CommandException('A client must be associated with the command before it can be executed.');
151  }
152 
153  return $this->client->execute($this);
154  }
155 
156  public function getClient()
157  {
158  return $this->client;
159  }
160 
161  public function setClient(ClientInterface $client)
162  {
163  $this->client = $client;
164 
165  return $this;
166  }
167 
168  public function getRequest()
169  {
170  if (!$this->request) {
171  throw new CommandException('The command must be prepared before retrieving the request');
172  }
173 
175  }
176 
177  public function getResponse()
178  {
179  if (!$this->isExecuted()) {
180  $this->execute();
181  }
182 
183  return $this->request->getResponse();
184  }
185 
186  public function getResult()
187  {
188  if (!$this->isExecuted()) {
189  $this->execute();
190  }
191 
192  if (null === $this->result) {
193  $this->process();
194  // Call the onComplete method if one is set
195  if ($this->onComplete) {
196  call_user_func($this->onComplete, $this);
197  }
198  }
199 
200  return $this->result;
201  }
202 
203  public function setResult($result)
204  {
205  $this->result = $result;
206 
207  return $this;
208  }
209 
210  public function isPrepared()
211  {
212  return $this->request !== null;
213  }
214 
215  public function isExecuted()
216  {
217  return $this->request !== null && $this->request->getState() == 'complete';
218  }
219 
220  public function prepare()
221  {
222  if (!$this->isPrepared()) {
223  if (!$this->client) {
224  throw new CommandException('A client must be associated with the command before it can be prepared.');
225  }
226 
227  // If no response processing value was specified, then attempt to use the highest level of processing
228  if (!isset($this[self::RESPONSE_PROCESSING])) {
230  }
231 
232  // Notify subscribers of the client that the command is being prepared
233  $this->client->dispatch('command.before_prepare', array('command' => $this));
234 
235  // Fail on missing required arguments, and change parameters via filters
236  $this->validate();
237  // Delegate to the subclass that implements the build method
238  $this->build();
239 
240  // Add custom request headers set on the command
241  if ($headers = $this[self::HEADERS_OPTION]) {
242  foreach ($headers as $key => $value) {
243  $this->request->setHeader($key, $value);
244  }
245  }
246 
247  // Add any curl options to the request
248  if ($options = $this[Client::CURL_OPTIONS]) {
249  $this->request->getCurlOptions()->overwriteWith(CurlHandle::parseCurlConfig($options));
250  }
251 
252  // Set a custom response body
253  if ($responseBody = $this[self::RESPONSE_BODY]) {
254  $this->request->setResponseBody($responseBody);
255  }
256 
257  $this->client->dispatch('command.after_prepare', array('command' => $this));
258  }
259 
260  return $this->request;
261  }
262 
271  public function setValidator(ValidatorInterface $validator)
272  {
273  $this->validator = $validator;
274 
275  return $this;
276  }
277 
278  public function getRequestHeaders()
279  {
280  return $this[self::HEADERS_OPTION];
281  }
282 
286  protected function init() {}
287 
291  abstract protected function build();
292 
298  protected function createOperation()
299  {
300  return new Operation(array('name' => get_class($this)));
301  }
302 
307  protected function process()
308  {
309  $this->result = $this[self::RESPONSE_PROCESSING] != self::TYPE_RAW
310  ? DefaultResponseParser::getInstance()->parse($this)
311  : $this->request->getResponse();
312  }
313 
319  protected function validate()
320  {
321  // Do not perform request validation/transformation if it is disable
322  if ($this[self::DISABLE_VALIDATION]) {
323  return;
324  }
325 
326  $errors = array();
327  $validator = $this->getValidator();
328  foreach ($this->operation->getParams() as $name => $schema) {
329  $value = $this[$name];
330  if (!$validator->validate($schema, $value)) {
331  $errors = array_merge($errors, $validator->getErrors());
332  } elseif ($value !== $this[$name]) {
333  // Update the config value if it changed and no validation errors were encountered
334  $this->data[$name] = $value;
335  }
336  }
337 
338  // Validate additional parameters
339  $hidden = $this[self::HIDDEN_PARAMS];
340 
341  if ($properties = $this->operation->getAdditionalParameters()) {
342  foreach ($this->toArray() as $name => $value) {
343  // It's only additional if it isn't defined in the schema
344  if (!$this->operation->hasParam($name) && !in_array($name, $hidden)) {
345  // Always set the name so that error messages are useful
346  $properties->setName($name);
347  if (!$validator->validate($properties, $value)) {
348  $errors = array_merge($errors, $validator->getErrors());
349  } elseif ($value !== $this[$name]) {
350  $this->data[$name] = $value;
351  }
352  }
353  }
354  }
355 
356  if (!empty($errors)) {
357  $e = new ValidationException('Validation errors: ' . implode("\n", $errors));
358  $e->setErrors($errors);
359  throw $e;
360  }
361  }
362 
369  protected function getValidator()
370  {
371  if (!$this->validator) {
372  $this->validator = SchemaValidator::getInstance();
373  }
374 
375  return $this->validator;
376  }
377 
382  public function getValidationErrors()
383  {
384  if (!$this->validator) {
385  return false;
386  }
387 
388  return $this->validator->getErrors();
389  }
390 }
Guzzle\Service\Command\AbstractCommand\build
build()
Guzzle\Service\Command\AbstractCommand\$result
$result
Definition: AbstractCommand.php:59
Guzzle\Service\Command\AbstractCommand\isExecuted
isExecuted()
Definition: AbstractCommand.php:233
Guzzle\Service\Command\AbstractCommand\execute
execute()
Definition: AbstractCommand.php:165
Guzzle\Http\Client\CURL_OPTIONS
const CURL_OPTIONS
Definition: lib/vendor/guzzle/guzzle/src/Guzzle/Http/Client.php:30
Guzzle\Service\Command\AbstractCommand\TYPE_NO_TRANSLATION
const TYPE_NO_TRANSLATION
Definition: AbstractCommand.php:41
Guzzle\Service\Command\AbstractCommand\getValidationErrors
getValidationErrors()
Definition: AbstractCommand.php:400
Guzzle\Service\Command\AbstractCommand\setOnComplete
setOnComplete($callable)
Definition: AbstractCommand.php:154
Guzzle\Http\Message\RequestInterface
Definition: lib/vendor/guzzle/guzzle/src/Guzzle/Http/Message/RequestInterface.php:16
Guzzle\Service\Command\AbstractCommand\getClient
getClient()
Definition: AbstractCommand.php:174
Guzzle\Service\Command
Definition: AbstractCommand.php:3
Guzzle\Service\Command\AbstractCommand\getName
getName()
Definition: AbstractCommand.php:139
Guzzle\Service\Description\Operation
Definition: Operation.php:10
Guzzle\Service\Command\AbstractCommand\$operation
$operation
Definition: AbstractCommand.php:65
Guzzle\Service\Command\AbstractCommand\getOperation
getOperation()
Definition: AbstractCommand.php:149
Guzzle\Service\Client
Definition: lib/vendor/guzzle/guzzle/src/Guzzle/Service/Client.php:25
Guzzle\Http\Curl\CurlHandle\parseCurlConfig
static parseCurlConfig($config)
Definition: CurlHandle.php:457
Guzzle\Service\Command\AbstractCommand\ON_COMPLETE
const ON_COMPLETE
Definition: AbstractCommand.php:26
Guzzle\Service\Command\AbstractCommand\createOperation
createOperation()
Definition: AbstractCommand.php:316
Guzzle\Service\Command\AbstractCommand\$request
$request
Definition: AbstractCommand.php:53
Guzzle\Service\Command\AbstractCommand\setClient
setClient(ClientInterface $client)
Definition: AbstractCommand.php:179
Guzzle\Service\Command\AbstractCommand\isPrepared
isPrepared()
Definition: AbstractCommand.php:228
Guzzle\Service\Command\AbstractCommand\getResult
getResult()
Definition: AbstractCommand.php:204
Guzzle\Service\Command\AbstractCommand\getRequest
getRequest()
Definition: AbstractCommand.php:186
Guzzle\Service\Description\OperationInterface
Definition: OperationInterface.php:10
Guzzle\Service\Command\AbstractCommand\__clone
__clone()
Definition: AbstractCommand.php:123
Guzzle\Service\Description\SchemaValidator\getInstance
static getInstance()
Definition: SchemaValidator.php:31
Guzzle\Service\Command\AbstractCommand\$validator
$validator
Definition: AbstractCommand.php:77
Guzzle\Service\Command\AbstractCommand\getRequestHeaders
getRequestHeaders()
Definition: AbstractCommand.php:296
Guzzle\Service\Command\AbstractCommand\TYPE_RAW
const TYPE_RAW
Definition: AbstractCommand.php:39
Guzzle\Service\Command\AbstractCommand\init
init()
Definition: AbstractCommand.php:304
Guzzle\Service\Command\CommandInterface
Definition: CommandInterface.php:17
Guzzle\Service\Exception\CommandException
Definition: CommandException.php:7
Guzzle\Service\ClientInterface
Definition: lib/vendor/guzzle/guzzle/src/Guzzle/Service/ClientInterface.php:16
Guzzle\Common\Exception\InvalidArgumentException
Definition: lib/vendor/guzzle/guzzle/src/Guzzle/Common/Exception/InvalidArgumentException.php:5
Guzzle\Service\Command\AbstractCommand\setValidator
setValidator(ValidatorInterface $validator)
Definition: AbstractCommand.php:289
Guzzle\Service\Command\AbstractCommand\RESPONSE_PROCESSING
const RESPONSE_PROCESSING
Definition: AbstractCommand.php:37
Guzzle\Service\Command\AbstractCommand\__construct
__construct($parameters=array(), OperationInterface $operation=null)
Definition: AbstractCommand.php:83
Guzzle\Service\Command\AbstractCommand\setResult
setResult($result)
Definition: AbstractCommand.php:221
Guzzle\Service\Command\AbstractCommand\getResponse
getResponse()
Definition: AbstractCommand.php:195
Guzzle\Service\Command\AbstractCommand\HEADERS_OPTION
const HEADERS_OPTION
Definition: AbstractCommand.php:24
Guzzle\Service\Command\AbstractCommand\$onComplete
$onComplete
Definition: AbstractCommand.php:71
Guzzle\Service\Command\AbstractCommand\getValidator
getValidator()
Definition: AbstractCommand.php:387
Guzzle\Service\Command\AbstractCommand
Definition: AbstractCommand.php:21
Guzzle\Service\Exception\ValidationException
Definition: ValidationException.php:7
Guzzle\Service\Command\AbstractCommand\TYPE_MODEL
const TYPE_MODEL
Definition: AbstractCommand.php:40
Guzzle\Service\Command\AbstractCommand\validate
validate()
Definition: AbstractCommand.php:337
Guzzle\Service\Description\ValidatorInterface
Definition: ValidatorInterface.php:8
Guzzle\Service\Command\AbstractCommand\REQUEST_OPTIONS
const REQUEST_OPTIONS
Definition: AbstractCommand.php:31
Guzzle\Service\Command\AbstractCommand\process
process()
Definition: AbstractCommand.php:325
Guzzle\Service\Command\AbstractCommand\RESPONSE_BODY
const RESPONSE_BODY
Definition: AbstractCommand.php:28
Guzzle\Service\Description\SchemaValidator
Definition: SchemaValidator.php:10
Guzzle\Http\Curl\CurlHandle
Definition: CurlHandle.php:16
Guzzle\Service\Command\AbstractCommand\__invoke
__invoke()
Definition: AbstractCommand.php:134
Guzzle\Service\Command\AbstractCommand\$client
$client
Definition: AbstractCommand.php:47
Guzzle\Common\Collection\toArray
toArray()
Definition: paymethod/paypal/lib/vendor/guzzle/guzzle/src/Guzzle/Common/Collection.php:58
Guzzle\Service\Command\DefaultResponseParser\getInstance
static getInstance()
Definition: DefaultResponseParser.php:19
Guzzle\Service\Command\AbstractCommand\DISABLE_VALIDATION
const DISABLE_VALIDATION
Definition: AbstractCommand.php:35
Guzzle\Service\Command\AbstractCommand\prepare
prepare()
Definition: AbstractCommand.php:238
Guzzle\Common\Collection
Definition: paymethod/paypal/lib/vendor/guzzle/guzzle/src/Guzzle/Common/Collection.php:11
Guzzle\Service\Command\AbstractCommand\HIDDEN_PARAMS
const HIDDEN_PARAMS
Definition: AbstractCommand.php:33