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: 16:
17: class MockPlugin extends AbstractHasDispatcher implements EventSubscriberInterface, \Countable
18: {
19: 20: 21:
22: protected $queue = array();
23:
24: 25: 26:
27: protected $temporary = false;
28:
29: 30: 31:
32: protected $received = array();
33:
34: 35: 36:
37: protected $readBodies;
38:
39: 40: 41: 42: 43: 44: 45:
46: public function __construct(array $items = null, $temporary = false, $readBodies = false)
47: {
48: $this->readBodies = $readBodies;
49: $this->temporary = $temporary;
50: if ($items) {
51: foreach ($items as $item) {
52: if ($item instanceof \Exception) {
53: $this->addException($item);
54: } else {
55: $this->addResponse($item);
56: }
57: }
58: }
59: }
60:
61: 62: 63:
64: public static function getSubscribedEvents()
65: {
66: return array('client.create_request' => 'onRequestCreate');
67: }
68:
69: 70: 71:
72: public static function getAllEvents()
73: {
74: return array('mock.request');
75: }
76:
77: 78: 79: 80: 81: 82: 83: 84:
85: public static function getMockFile($path)
86: {
87: if (!file_exists($path)) {
88: throw new InvalidArgumentException('Unable to open mock file: ' . $path);
89: }
90:
91: return Response::fromMessage(file_get_contents($path));
92: }
93:
94: 95: 96: 97: 98: 99: 100: 101:
102: public function readBodies($readBodies)
103: {
104: $this->readBodies = $readBodies;
105:
106: return $this;
107: }
108:
109: 110: 111: 112: 113:
114: public function count()
115: {
116: return count($this->queue);
117: }
118:
119: 120: 121: 122: 123: 124: 125: 126:
127: public function addResponse($response)
128: {
129: if (!($response instanceof Response)) {
130: if (!is_string($response)) {
131: throw new InvalidArgumentException('Invalid response');
132: }
133: $response = self::getMockFile($response);
134: }
135:
136: $this->queue[] = $response;
137:
138: return $this;
139: }
140:
141: 142: 143: 144: 145: 146: 147:
148: public function addException(CurlException $e)
149: {
150: $this->queue[] = $e;
151:
152: return $this;
153: }
154:
155: 156: 157: 158: 159:
160: public function clearQueue()
161: {
162: $this->queue = array();
163:
164: return $this;
165: }
166:
167: 168: 169: 170: 171:
172: public function getQueue()
173: {
174: return $this->queue;
175: }
176:
177: 178: 179: 180: 181:
182: public function isTemporary()
183: {
184: return $this->temporary;
185: }
186:
187: 188: 189: 190: 191: 192: 193: 194:
195: public function dequeue(RequestInterface $request)
196: {
197: $this->dispatch('mock.request', array(
198: 'plugin' => $this,
199: 'request' => $request
200: ));
201:
202: $item = array_shift($this->queue);
203: if ($item instanceof Response) {
204: if ($this->readBodies && $request instanceof EntityEnclosingRequestInterface) {
205: $request->getEventDispatcher()->addListener('request.sent', function (Event $event) {
206: while ($data = $event['request']->getBody()->read(8096));
207: });
208: }
209: $request->setResponse($item, true);
210: } elseif ($item instanceof CurlException) {
211: $request->getEventDispatcher()->addListener(
212: 'request.before_send',
213: function (Event $event) use ($request, $item) {
214:
215: $item->setRequest($request);
216: $request->setState(RequestInterface::STATE_ERROR);
217: $request->dispatch('request.exception', array('request' => $request, 'exception' => $item));
218:
219: if ($request->getState() == RequestInterface::STATE_ERROR) {
220: throw $item;
221: }
222: },
223:
224: -999
225: );
226: }
227:
228: return $this;
229: }
230:
231: 232: 233:
234: public function flush()
235: {
236: $this->received = array();
237: }
238:
239: 240: 241: 242: 243:
244: public function getReceivedRequests()
245: {
246: return $this->received;
247: }
248:
249: 250: 251: 252: 253:
254: public function onRequestCreate(Event $event)
255: {
256: if (!empty($this->queue)) {
257: $request = $event['request'];
258: $this->dequeue($request);
259: $this->received[] = $request;
260:
261: if ($this->temporary && empty($this->queue) && $request->getClient()) {
262: $request->getClient()->getEventDispatcher()->removeSubscriber($this);
263: }
264: }
265: }
266: }
267: