1<?php 2namespace Aws; 3 4use Psr\Http\Message\RequestInterface; 5use Aws\Exception\AwsException; 6 7/** 8 * Represents a history container that is required when using the history 9 * middleware. 10 */ 11class History implements \Countable, \IteratorAggregate 12{ 13 private $maxEntries; 14 private $entries = array(); 15 16 /** 17 * @param int $maxEntries Maximum number of entries to store. 18 */ 19 public function __construct($maxEntries = 10) 20 { 21 $this->maxEntries = $maxEntries; 22 } 23 24 public function count() 25 { 26 return count($this->entries); 27 } 28 29 public function getIterator() 30 { 31 return new \ArrayIterator(array_values($this->entries)); 32 } 33 34 /** 35 * Get the last finished command seen by the history container. 36 * 37 * @return CommandInterface 38 * @throws \LogicException if no commands have been seen. 39 */ 40 public function getLastCommand() 41 { 42 if (!$this->entries) { 43 throw new \LogicException('No commands received'); 44 } 45 46 return end($this->entries)['command']; 47 } 48 49 /** 50 * Get the last finished request seen by the history container. 51 * 52 * @return RequestInterface 53 * @throws \LogicException if no requests have been seen. 54 */ 55 public function getLastRequest() 56 { 57 if (!$this->entries) { 58 throw new \LogicException('No requests received'); 59 } 60 61 return end($this->entries)['request']; 62 } 63 64 /** 65 * Get the last received result or exception. 66 * 67 * @return ResultInterface|AwsException 68 * @throws \LogicException if no return values have been received. 69 */ 70 public function getLastReturn() 71 { 72 if (!$this->entries) { 73 throw new \LogicException('No entries'); 74 } 75 76 $last = end($this->entries); 77 78 if (isset($last['result'])) { 79 return $last['result']; 80 } 81 82 if (isset($last['exception'])) { 83 return $last['exception']; 84 } 85 86 throw new \LogicException('No return value for last entry.'); 87 } 88 89 /** 90 * Initiate an entry being added to the history. 91 * 92 * @param CommandInterface $cmd Command be executed. 93 * @param RequestInterface $req Request being sent. 94 * 95 * @return string Returns the ticket used to finish the entry. 96 */ 97 public function start(CommandInterface $cmd, RequestInterface $req) 98 { 99 $ticket = uniqid(); 100 $this->entries[$ticket] = [ 101 'command' => $cmd, 102 'request' => $req, 103 'result' => null, 104 'exception' => null, 105 ]; 106 107 return $ticket; 108 } 109 110 /** 111 * Finish adding an entry to the history container. 112 * 113 * @param string $ticket Ticket returned from the start call. 114 * @param mixed $result The result (an exception or AwsResult). 115 */ 116 public function finish($ticket, $result) 117 { 118 if (!isset($this->entries[$ticket])) { 119 throw new \InvalidArgumentException('Invalid history ticket'); 120 } 121 122 if (isset($this->entries[$ticket]['result']) 123 || isset($this->entries[$ticket]['exception']) 124 ) { 125 throw new \LogicException('History entry is already finished'); 126 } 127 128 if ($result instanceof \Exception) { 129 $this->entries[$ticket]['exception'] = $result; 130 } else { 131 $this->entries[$ticket]['result'] = $result; 132 } 133 134 if (count($this->entries) >= $this->maxEntries) { 135 $this->entries = array_slice($this->entries, -$this->maxEntries, null, true); 136 } 137 } 138 139 /** 140 * Flush the history 141 */ 142 public function clear() 143 { 144 $this->entries = []; 145 } 146 147 /** 148 * Converts the history to an array. 149 * 150 * @return array 151 */ 152 public function toArray() 153 { 154 return array_values($this->entries); 155 } 156} 157