├── .gitignore
├── src
└── AmazonWishlistExporter
│ ├── Command
│ ├── CommandInterface.php
│ └── ExportCommand.php
│ └── Logger
│ ├── LoggerInterface.php
│ └── StandardOutputLogger.php
├── .travis.yml
├── test
└── AmazonWishlistExporter
│ └── Test
│ ├── Logger
│ └── StandardOutputLoggerTest.php
│ └── Command
│ └── ExportCommandTest.php
├── phpunit.dist.xml
├── composer.json
├── README.md
├── awx
└── composer.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | *.csv
3 | vendor
4 | phpunit.xml
--------------------------------------------------------------------------------
/src/AmazonWishlistExporter/Command/CommandInterface.php:
--------------------------------------------------------------------------------
1 | expectOutputString("$messageFixture\n");
13 | $logger = new StandardOutputLogger();
14 | $logger->log($messageFixture);
15 | }
16 | }
--------------------------------------------------------------------------------
/phpunit.dist.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
19 | test
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "yuriteixeira/amazon-wishlist-exporter",
3 | "description": "Simple script that parses a public amazon wishlist and export the items to a CSV file.",
4 | "keywords": [
5 | "amazon",
6 | "wishlist",
7 | "export",
8 | "csv"
9 | ],
10 | "bin": [
11 | "awx"
12 | ],
13 | "config": {
14 | "bin-dir": "bin"
15 | },
16 | "autoload": {
17 | "psr-0": {
18 | "AmazonWishlistExporter": "src/",
19 | "AmazonWishlistExporter\\Test": "test/"
20 | }
21 | },
22 | "require": {
23 | "guzzlehttp/guzzle": "*",
24 | "symfony/dom-crawler": "*",
25 | "symfony/css-selector": "*"
26 | },
27 | "require-dev": {
28 | "phpunit/phpunit": "3.7.*"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Amazon Wishlist Exporter
2 |
3 | [](https://travis-ci.org/yuriteixeira/amazon-wishlist-exporter)
4 |
5 | Simple script that parses a public amazon wishlist and export the items to a CSV file.
6 |
7 | ## Requirements
8 |
9 | - PHP 5.4
10 |
11 | ## Installing
12 |
13 | - Clone this repository
14 | - Go to the cloned repo directory
15 | - Download composer: `php -r "readfile('https://getcomposer.org/installer');" | php`
16 | - Run `php composer.phar install`
17 |
18 | ## Running
19 |
20 | - Just type inside the cloned repo directory: `./awx ` (you can get the id visiting your wishlist, it's part of the URL).
21 |
22 |
23 | ## Next steps
24 |
25 | - Export to Google Docs (with images of the products, options to convert the price into any other currency)
26 | - Access private lists
27 |
--------------------------------------------------------------------------------
/awx:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | execute();
35 |
36 | // Saving each item row to the file
37 | $fh = fopen($pathToSave, 'w');
38 |
39 | foreach ($items as $item) {
40 | fputcsv($fh, $item);
41 | }
42 |
43 | fclose($fh);
--------------------------------------------------------------------------------
/src/AmazonWishlistExporter/Command/ExportCommand.php:
--------------------------------------------------------------------------------
1 | countryCode = $countryCode;
38 | $this->whishlistId = $wishlistId;
39 | $this->client = $client;
40 | $this->logger = $logger;
41 | }
42 |
43 | public function execute()
44 | {
45 | $page = 1;
46 | $lastItemsContent = null;
47 | $rows = [];
48 | $baseUrl = $this->getBaseUrlForCountry($this->countryCode);
49 | $wishlistBaseUrl = "{$baseUrl}/registry/wishlist/{$this->whishlistId}?layout=standard";
50 |
51 | if (!$baseUrl) {
52 | throw new \InvalidArgumentException("Country code {$this->countryCode} is not supported.");
53 | }
54 |
55 | $this->logger->log("Exporting: {$wishlistBaseUrl}");
56 |
57 | while (true) {
58 | $url = "{$wishlistBaseUrl}&page={$page}";
59 | $response = $this->client->get($url);
60 | $responseContent = (string) $response->getBody();
61 | $crawler = new Crawler($responseContent);
62 | $items = $crawler->filter('[id^=item_]');
63 |
64 | if ($response->getStatusCode() != 200 || !$items->count()) {
65 | $this->logger->log('Empty content (are you sure that you set your list as public?)');
66 | break;
67 | }
68 |
69 | if ($items->text() == $lastItemsContent) {
70 | $this->logger->log('Current content is repeating last content');
71 | break;
72 | }
73 |
74 | $items->each(function (Crawler $item) use (&$rows, $baseUrl) {
75 | $name = trim($item->filter('[id^=itemName_]')->text());
76 | $price = (float) str_replace('$', '', trim($item->filter('[id^=itemPrice_]')->text()));
77 |
78 | $url =
79 | $item->filter('[id^=itemName_]')->attr('href') ?
80 | $baseUrl . $item->filter('[id^=itemName_]')->attr('href') :
81 | $item->filter('[id^=itemInfo_] .a-link-normal')->attr('href');
82 |
83 | $image = trim($item->filter('[id^=itemImage_] img')->attr('src'));
84 | $rows[] = array($name, $price, $url, $image);
85 | });
86 |
87 | $this->logger->log("Parsed page {$page} - Url: {$url}");
88 |
89 | $lastItemsContent = $items->text();
90 | ++$page;
91 | }
92 |
93 | $this->logger->log("Finished");
94 |
95 | return $rows;
96 | }
97 |
98 | /**
99 | * @param $countryCode
100 | * @return string|null
101 | */
102 | private function getBaseUrlForCountry($countryCode)
103 | {
104 | $baseUrlsByCountry = [
105 | 'US' => 'http://www.amazon.com',
106 | 'UK' => 'http://www.amazon.co.uk',
107 | ];
108 |
109 | $baseUrl = !empty($baseUrlsByCountry[$countryCode]) ? $baseUrlsByCountry[$countryCode] : null;
110 |
111 | return $baseUrl;
112 | }
113 | }
--------------------------------------------------------------------------------
/test/AmazonWishlistExporter/Test/Command/ExportCommandTest.php:
--------------------------------------------------------------------------------
1 | clientMock = $this->getMock('\\GuzzleHttp\\ClientInterface');
37 | $this->loggerMock = $this->getMock('\\AmazonWishlistExporter\\Logger\\LoggerInterface');
38 |
39 | $this->responseContentPage1Fixture = <<
41 | Product 1
42 | $ 1.99
43 | 
44 |
45 |
50 |
55 | RESPONSE;
56 |
57 | $this->responseContentPage2Fixture = <<
59 | Product 4
60 | $ 4.99
61 | 
62 |
63 |
68 |
73 | RESPONSE;
74 |
75 | $this->responseContentPage3Fixture = <<
77 | Product 7
78 | $ 7.99
79 | 
80 |
81 |
86 |
91 | RESPONSE;
92 |
93 | $this->unexpectedResponse = <<
95 | No donut for you...
96 |
97 | RESPONSE;
98 | }
99 |
100 | public function testExecuteWithInvalidArguments()
101 | {
102 | $this->setExpectedException('\\InvalidArgumentException');
103 | $command = new ExportCommand('XX', 'ABC123', $this->clientMock, $this->loggerMock);
104 | $command->execute();
105 | }
106 |
107 | public function testExecuteWithInvalidWishlistId()
108 | {
109 | $responseMock = $this->getMock('\\GuzzleHttp\\Message\\ResponseInterface');
110 | $responseMock
111 | ->expects($this->once())
112 | ->method('getStatusCode')
113 | ->will($this->returnValue(404))
114 | ;
115 |
116 | $this->clientMock
117 | ->expects($this->once())
118 | ->method('get')
119 | ->will($this->returnValue($responseMock))
120 | ;
121 |
122 | // TODO: Check how to check multiple calls with different parameters
123 | $this->loggerMock
124 | ->expects($this->exactly(3))
125 | ->method('log')
126 | ->withAnyParameters()
127 | ;
128 |
129 | $command = new ExportCommand('US', 'ABC123', $this->clientMock, $this->loggerMock);
130 | $rows = $command->execute();
131 | $this->assertEmpty($rows);
132 | }
133 |
134 | public function testExecuteWithNotPublicWishlistOrUnexpectedContent()
135 | {
136 | $responseMock = $this->getMock('\\GuzzleHttp\\Message\\ResponseInterface');
137 | $responseMock
138 | ->expects($this->once())
139 | ->method('getStatusCode')
140 | ->will($this->returnValue(200))
141 | ;
142 |
143 | $responseMock
144 | ->expects($this->exactly(1))
145 | ->method('getBody')
146 | ->will($this->returnValue($this->unexpectedResponse))
147 | ;
148 |
149 | $this->clientMock
150 | ->expects($this->once())
151 | ->method('get')
152 | ->will($this->returnValue($responseMock))
153 | ;
154 |
155 | // TODO: Check how to check multiple calls with different parameters
156 | $this->loggerMock
157 | ->expects($this->exactly(3))
158 | ->method('log')
159 | ->withAnyParameters()
160 | ;
161 |
162 | $command = new ExportCommand('US', 'ABC123', $this->clientMock, $this->loggerMock);
163 | $rows = $command->execute();
164 | $this->assertEmpty($rows);
165 | }
166 |
167 | public function testExecuteOnUsWithSinglePageOfItems()
168 | {
169 | $responseMock = $this->getMock('\\GuzzleHttp\\Message\\ResponseInterface');
170 | $responseMock
171 | ->expects($this->exactly(2))
172 | ->method('getStatusCode')
173 | ->will($this->returnValue(200))
174 | ;
175 |
176 | $responseMock
177 | ->expects($this->exactly(2))
178 | ->method('getBody')
179 | ->will($this->returnValue($this->responseContentPage1Fixture))
180 | ;
181 |
182 | $this->clientMock
183 | ->expects($this->exactly(2))
184 | ->method('get')
185 | ->will($this->returnValue($responseMock))
186 | ;
187 |
188 | $this->loggerMock
189 | ->expects($this->exactly(4))
190 | ->method('log')
191 | ->withAnyParameters()
192 | ;
193 |
194 | $command = new ExportCommand('US', 'ABC123', $this->clientMock, $this->loggerMock);
195 | $result = $command->execute();
196 |
197 | $expectedResult = [
198 | ['Product 1', 1.99, 'http://www.amazon.com/product-1', 'test://product-1.png'],
199 | ['Product 2', 2.99, 'http://www.amazon.com/product-2', 'test://product-2.png'],
200 | ['Product 3', 3.99, 'http://www.amazon.com/product-3', 'test://product-3.png'],
201 | ];
202 |
203 | $this->assertEquals($expectedResult, $result);
204 | }
205 |
206 | public function testExecuteOnUkWithSinglePageOfItems()
207 | {
208 | $responseMock = $this->getMock('\\GuzzleHttp\\Message\\ResponseInterface');
209 | $responseMock
210 | ->expects($this->exactly(2))
211 | ->method('getStatusCode')
212 | ->will($this->returnValue(200))
213 | ;
214 |
215 | $responseMock
216 | ->expects($this->exactly(2))
217 | ->method('getBody')
218 | ->will($this->returnValue($this->responseContentPage1Fixture))
219 | ;
220 |
221 | $this->clientMock
222 | ->expects($this->exactly(2))
223 | ->method('get')
224 | ->will($this->returnValue($responseMock))
225 | ;
226 |
227 | $this->loggerMock
228 | ->expects($this->exactly(4))
229 | ->method('log')
230 | ->withAnyParameters()
231 | ;
232 |
233 | $command = new ExportCommand('UK', 'ABC123', $this->clientMock, $this->loggerMock);
234 | $result = $command->execute();
235 |
236 | $expectedResult = [
237 | ['Product 1', 1.99, 'http://www.amazon.co.uk/product-1', 'test://product-1.png'],
238 | ['Product 2', 2.99, 'http://www.amazon.co.uk/product-2', 'test://product-2.png'],
239 | ['Product 3', 3.99, 'http://www.amazon.co.uk/product-3', 'test://product-3.png'],
240 | ];
241 |
242 | $this->assertEquals($expectedResult, $result);
243 | }
244 |
245 | public function testExecuteOnUsWithMultiplePagesOfItems()
246 | {
247 | $responseMock = $this->getMock('\\GuzzleHttp\\Message\\ResponseInterface');
248 | $responseMock
249 | ->expects($this->exactly(4))
250 | ->method('getStatusCode')
251 | ->will($this->returnValue(200))
252 | ;
253 |
254 | $responseMock
255 | ->expects($this->exactly(4))
256 | ->method('getBody')
257 | ->will($this->onConsecutiveCalls(
258 | $this->responseContentPage1Fixture,
259 | $this->responseContentPage2Fixture,
260 | $this->responseContentPage3Fixture,
261 | $this->responseContentPage3Fixture
262 | ))
263 | ;
264 |
265 | $this->clientMock
266 | ->expects($this->exactly(4))
267 | ->method('get')
268 | ->will($this->returnValue($responseMock))
269 | ;
270 |
271 | $this->loggerMock
272 | ->expects($this->exactly(6))
273 | ->method('log')
274 | ->withAnyParameters()
275 | ;
276 |
277 | $command = new ExportCommand('US', 'ABC123', $this->clientMock, $this->loggerMock);
278 | $result = $command->execute();
279 |
280 | $expectedResult = [
281 | ['Product 1', 1.99, 'http://www.amazon.com/product-1', 'test://product-1.png'],
282 | ['Product 2', 2.99, 'http://www.amazon.com/product-2', 'test://product-2.png'],
283 | ['Product 3', 3.99, 'http://www.amazon.com/product-3', 'test://product-3.png'],
284 | ['Product 4', 4.99, 'http://www.amazon.com/product-4', 'test://product-4.png'],
285 | ['Product 5', 5.99, 'http://www.amazon.com/product-5', 'test://product-5.png'],
286 | ['Product 6', 6.99, 'http://www.amazon.com/product-6', 'test://product-6.png'],
287 | ['Product 7', 7.99, 'http://www.amazon.com/product-7', 'test://product-7.png'],
288 | ['Product 8', 8.99, 'http://www.amazon.com/product-8', 'test://product-8.png'],
289 | ['Product 9', 9.99, 'http://www.amazon.com/product-9', 'test://product-9.png'],
290 | ];
291 |
292 | $this->assertEquals($expectedResult, $result);
293 | }
294 |
295 | public function testExecuteOnUkWithMultiplePagesOfItems()
296 | {
297 | $responseMock = $this->getMock('\\GuzzleHttp\\Message\\ResponseInterface');
298 | $responseMock
299 | ->expects($this->exactly(4))
300 | ->method('getStatusCode')
301 | ->will($this->returnValue(200))
302 | ;
303 |
304 | $responseMock
305 | ->expects($this->exactly(4))
306 | ->method('getBody')
307 | ->will($this->onConsecutiveCalls(
308 | $this->responseContentPage1Fixture,
309 | $this->responseContentPage2Fixture,
310 | $this->responseContentPage3Fixture,
311 | $this->responseContentPage3Fixture
312 | ))
313 | ;
314 |
315 | $this->clientMock
316 | ->expects($this->exactly(4))
317 | ->method('get')
318 | ->will($this->returnValue($responseMock))
319 | ;
320 |
321 | $this->loggerMock
322 | ->expects($this->exactly(6))
323 | ->method('log')
324 | ->withAnyParameters()
325 | ;
326 |
327 | $command = new ExportCommand('UK', 'ABC123', $this->clientMock, $this->loggerMock);
328 | $result = $command->execute();
329 |
330 | $expectedResult = [
331 | ['Product 1', 1.99, 'http://www.amazon.co.uk/product-1', 'test://product-1.png'],
332 | ['Product 2', 2.99, 'http://www.amazon.co.uk/product-2', 'test://product-2.png'],
333 | ['Product 3', 3.99, 'http://www.amazon.co.uk/product-3', 'test://product-3.png'],
334 | ['Product 4', 4.99, 'http://www.amazon.co.uk/product-4', 'test://product-4.png'],
335 | ['Product 5', 5.99, 'http://www.amazon.co.uk/product-5', 'test://product-5.png'],
336 | ['Product 6', 6.99, 'http://www.amazon.co.uk/product-6', 'test://product-6.png'],
337 | ['Product 7', 7.99, 'http://www.amazon.co.uk/product-7', 'test://product-7.png'],
338 | ['Product 8', 8.99, 'http://www.amazon.co.uk/product-8', 'test://product-8.png'],
339 | ['Product 9', 9.99, 'http://www.amazon.co.uk/product-9', 'test://product-9.png'],
340 | ];
341 |
342 | $this->assertEquals($expectedResult, $result);
343 | }
344 | }
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
5 | ],
6 | "hash": "7d630595ac7ff7ee12c4fd84013cbb9c",
7 | "packages": [
8 | {
9 | "name": "guzzlehttp/guzzle",
10 | "version": "4.0.2",
11 | "source": {
12 | "type": "git",
13 | "url": "https://github.com/guzzle/guzzle.git",
14 | "reference": "40db53833aaea528347994acd4578d7b9b2211ee"
15 | },
16 | "dist": {
17 | "type": "zip",
18 | "url": "https://api.github.com/repos/guzzle/guzzle/zipball/40db53833aaea528347994acd4578d7b9b2211ee",
19 | "reference": "40db53833aaea528347994acd4578d7b9b2211ee",
20 | "shasum": ""
21 | },
22 | "require": {
23 | "guzzlehttp/streams": "~1.0",
24 | "php": ">=5.4.0"
25 | },
26 | "require-dev": {
27 | "ext-curl": "*",
28 | "phpunit/phpunit": "~4.0",
29 | "psr/log": "~1.0"
30 | },
31 | "type": "library",
32 | "extra": {
33 | "branch-alias": {
34 | "dev-master": "4.0.x-dev"
35 | }
36 | },
37 | "autoload": {
38 | "psr-4": {
39 | "GuzzleHttp\\": "src/"
40 | },
41 | "files": [
42 | "src/functions.php"
43 | ]
44 | },
45 | "notification-url": "https://packagist.org/downloads/",
46 | "license": [
47 | "MIT"
48 | ],
49 | "authors": [
50 | {
51 | "name": "Michael Dowling",
52 | "email": "mtdowling@gmail.com",
53 | "homepage": "https://github.com/mtdowling"
54 | }
55 | ],
56 | "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients",
57 | "homepage": "http://guzzlephp.org/",
58 | "keywords": [
59 | "client",
60 | "curl",
61 | "framework",
62 | "http",
63 | "http client",
64 | "rest",
65 | "web service"
66 | ],
67 | "time": "2014-04-16 17:33:22"
68 | },
69 | {
70 | "name": "guzzlehttp/streams",
71 | "version": "1.1.0",
72 | "source": {
73 | "type": "git",
74 | "url": "https://github.com/guzzle/streams.git",
75 | "reference": "cf0c8c33ca95cc147efba4c714f630ee44767180"
76 | },
77 | "dist": {
78 | "type": "zip",
79 | "url": "https://api.github.com/repos/guzzle/streams/zipball/cf0c8c33ca95cc147efba4c714f630ee44767180",
80 | "reference": "cf0c8c33ca95cc147efba4c714f630ee44767180",
81 | "shasum": ""
82 | },
83 | "require": {
84 | "php": ">=5.4.0"
85 | },
86 | "require-dev": {
87 | "phpunit/phpunit": "~4.0"
88 | },
89 | "type": "library",
90 | "extra": {
91 | "branch-alias": {
92 | "dev-master": "1.0.x-dev"
93 | }
94 | },
95 | "autoload": {
96 | "psr-4": {
97 | "GuzzleHttp\\Stream\\": "src/"
98 | },
99 | "files": [
100 | "src/functions.php"
101 | ]
102 | },
103 | "notification-url": "https://packagist.org/downloads/",
104 | "license": [
105 | "MIT"
106 | ],
107 | "authors": [
108 | {
109 | "name": "Michael Dowling",
110 | "email": "mtdowling@gmail.com",
111 | "homepage": "https://github.com/mtdowling"
112 | }
113 | ],
114 | "description": "Provides a simple abstraction over streams of data (Guzzle 4+)",
115 | "homepage": "http://guzzlephp.org/",
116 | "keywords": [
117 | "Guzzle",
118 | "stream"
119 | ],
120 | "time": "2014-04-03 04:48:24"
121 | },
122 | {
123 | "name": "symfony/css-selector",
124 | "version": "v2.4.4",
125 | "target-dir": "Symfony/Component/CssSelector",
126 | "source": {
127 | "type": "git",
128 | "url": "https://github.com/symfony/CssSelector.git",
129 | "reference": "479a5b409723f596ffc3b5178034e4d76ce615b3"
130 | },
131 | "dist": {
132 | "type": "zip",
133 | "url": "https://api.github.com/repos/symfony/CssSelector/zipball/479a5b409723f596ffc3b5178034e4d76ce615b3",
134 | "reference": "479a5b409723f596ffc3b5178034e4d76ce615b3",
135 | "shasum": ""
136 | },
137 | "require": {
138 | "php": ">=5.3.3"
139 | },
140 | "type": "library",
141 | "extra": {
142 | "branch-alias": {
143 | "dev-master": "2.4-dev"
144 | }
145 | },
146 | "autoload": {
147 | "psr-0": {
148 | "Symfony\\Component\\CssSelector\\": ""
149 | }
150 | },
151 | "notification-url": "https://packagist.org/downloads/",
152 | "license": [
153 | "MIT"
154 | ],
155 | "authors": [
156 | {
157 | "name": "Fabien Potencier",
158 | "email": "fabien@symfony.com",
159 | "homepage": "http://fabien.potencier.org",
160 | "role": "Lead Developer"
161 | },
162 | {
163 | "name": "Symfony Community",
164 | "homepage": "http://symfony.com/contributors"
165 | },
166 | {
167 | "name": "Jean-François Simon",
168 | "email": "jeanfrancois.simon@sensiolabs.com"
169 | }
170 | ],
171 | "description": "Symfony CssSelector Component",
172 | "homepage": "http://symfony.com",
173 | "time": "2014-04-18 20:37:09"
174 | },
175 | {
176 | "name": "symfony/dom-crawler",
177 | "version": "v2.4.4",
178 | "target-dir": "Symfony/Component/DomCrawler",
179 | "source": {
180 | "type": "git",
181 | "url": "https://github.com/symfony/DomCrawler.git",
182 | "reference": "e94b29c7cac964e58c406408d238ceeaa3604e78"
183 | },
184 | "dist": {
185 | "type": "zip",
186 | "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/e94b29c7cac964e58c406408d238ceeaa3604e78",
187 | "reference": "e94b29c7cac964e58c406408d238ceeaa3604e78",
188 | "shasum": ""
189 | },
190 | "require": {
191 | "php": ">=5.3.3"
192 | },
193 | "require-dev": {
194 | "symfony/css-selector": "~2.0"
195 | },
196 | "suggest": {
197 | "symfony/css-selector": ""
198 | },
199 | "type": "library",
200 | "extra": {
201 | "branch-alias": {
202 | "dev-master": "2.4-dev"
203 | }
204 | },
205 | "autoload": {
206 | "psr-0": {
207 | "Symfony\\Component\\DomCrawler\\": ""
208 | }
209 | },
210 | "notification-url": "https://packagist.org/downloads/",
211 | "license": [
212 | "MIT"
213 | ],
214 | "authors": [
215 | {
216 | "name": "Fabien Potencier",
217 | "email": "fabien@symfony.com",
218 | "homepage": "http://fabien.potencier.org",
219 | "role": "Lead Developer"
220 | },
221 | {
222 | "name": "Symfony Community",
223 | "homepage": "http://symfony.com/contributors"
224 | }
225 | ],
226 | "description": "Symfony DomCrawler Component",
227 | "homepage": "http://symfony.com",
228 | "time": "2014-04-18 20:37:09"
229 | }
230 | ],
231 | "packages-dev": [
232 | {
233 | "name": "phpunit/php-code-coverage",
234 | "version": "1.2.17",
235 | "source": {
236 | "type": "git",
237 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
238 | "reference": "6ef2bf3a1c47eca07ea95f0d8a902a6340390b34"
239 | },
240 | "dist": {
241 | "type": "zip",
242 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6ef2bf3a1c47eca07ea95f0d8a902a6340390b34",
243 | "reference": "6ef2bf3a1c47eca07ea95f0d8a902a6340390b34",
244 | "shasum": ""
245 | },
246 | "require": {
247 | "php": ">=5.3.3",
248 | "phpunit/php-file-iterator": ">=1.3.0@stable",
249 | "phpunit/php-text-template": ">=1.2.0@stable",
250 | "phpunit/php-token-stream": ">=1.1.3@stable"
251 | },
252 | "require-dev": {
253 | "phpunit/phpunit": "3.7.*@dev"
254 | },
255 | "suggest": {
256 | "ext-dom": "*",
257 | "ext-xdebug": ">=2.0.5"
258 | },
259 | "type": "library",
260 | "extra": {
261 | "branch-alias": {
262 | "dev-master": "1.2.x-dev"
263 | }
264 | },
265 | "autoload": {
266 | "classmap": [
267 | "PHP/"
268 | ]
269 | },
270 | "notification-url": "https://packagist.org/downloads/",
271 | "include-path": [
272 | ""
273 | ],
274 | "license": [
275 | "BSD-3-Clause"
276 | ],
277 | "authors": [
278 | {
279 | "name": "Sebastian Bergmann",
280 | "email": "sb@sebastian-bergmann.de",
281 | "role": "lead"
282 | }
283 | ],
284 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
285 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
286 | "keywords": [
287 | "coverage",
288 | "testing",
289 | "xunit"
290 | ],
291 | "time": "2014-03-28 10:53:45"
292 | },
293 | {
294 | "name": "phpunit/php-file-iterator",
295 | "version": "1.3.4",
296 | "source": {
297 | "type": "git",
298 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
299 | "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb"
300 | },
301 | "dist": {
302 | "type": "zip",
303 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb",
304 | "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb",
305 | "shasum": ""
306 | },
307 | "require": {
308 | "php": ">=5.3.3"
309 | },
310 | "type": "library",
311 | "autoload": {
312 | "classmap": [
313 | "File/"
314 | ]
315 | },
316 | "notification-url": "https://packagist.org/downloads/",
317 | "include-path": [
318 | ""
319 | ],
320 | "license": [
321 | "BSD-3-Clause"
322 | ],
323 | "authors": [
324 | {
325 | "name": "Sebastian Bergmann",
326 | "email": "sb@sebastian-bergmann.de",
327 | "role": "lead"
328 | }
329 | ],
330 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
331 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
332 | "keywords": [
333 | "filesystem",
334 | "iterator"
335 | ],
336 | "time": "2013-10-10 15:34:57"
337 | },
338 | {
339 | "name": "phpunit/php-text-template",
340 | "version": "1.2.0",
341 | "source": {
342 | "type": "git",
343 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
344 | "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a"
345 | },
346 | "dist": {
347 | "type": "zip",
348 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
349 | "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
350 | "shasum": ""
351 | },
352 | "require": {
353 | "php": ">=5.3.3"
354 | },
355 | "type": "library",
356 | "autoload": {
357 | "classmap": [
358 | "Text/"
359 | ]
360 | },
361 | "notification-url": "https://packagist.org/downloads/",
362 | "include-path": [
363 | ""
364 | ],
365 | "license": [
366 | "BSD-3-Clause"
367 | ],
368 | "authors": [
369 | {
370 | "name": "Sebastian Bergmann",
371 | "email": "sb@sebastian-bergmann.de",
372 | "role": "lead"
373 | }
374 | ],
375 | "description": "Simple template engine.",
376 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
377 | "keywords": [
378 | "template"
379 | ],
380 | "time": "2014-01-30 17:20:04"
381 | },
382 | {
383 | "name": "phpunit/php-timer",
384 | "version": "1.0.5",
385 | "source": {
386 | "type": "git",
387 | "url": "https://github.com/sebastianbergmann/php-timer.git",
388 | "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c"
389 | },
390 | "dist": {
391 | "type": "zip",
392 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
393 | "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
394 | "shasum": ""
395 | },
396 | "require": {
397 | "php": ">=5.3.3"
398 | },
399 | "type": "library",
400 | "autoload": {
401 | "classmap": [
402 | "PHP/"
403 | ]
404 | },
405 | "notification-url": "https://packagist.org/downloads/",
406 | "include-path": [
407 | ""
408 | ],
409 | "license": [
410 | "BSD-3-Clause"
411 | ],
412 | "authors": [
413 | {
414 | "name": "Sebastian Bergmann",
415 | "email": "sb@sebastian-bergmann.de",
416 | "role": "lead"
417 | }
418 | ],
419 | "description": "Utility class for timing",
420 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
421 | "keywords": [
422 | "timer"
423 | ],
424 | "time": "2013-08-02 07:42:54"
425 | },
426 | {
427 | "name": "phpunit/php-token-stream",
428 | "version": "1.2.2",
429 | "source": {
430 | "type": "git",
431 | "url": "https://github.com/sebastianbergmann/php-token-stream.git",
432 | "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32"
433 | },
434 | "dist": {
435 | "type": "zip",
436 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ad4e1e23ae01b483c16f600ff1bebec184588e32",
437 | "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32",
438 | "shasum": ""
439 | },
440 | "require": {
441 | "ext-tokenizer": "*",
442 | "php": ">=5.3.3"
443 | },
444 | "type": "library",
445 | "extra": {
446 | "branch-alias": {
447 | "dev-master": "1.2-dev"
448 | }
449 | },
450 | "autoload": {
451 | "classmap": [
452 | "PHP/"
453 | ]
454 | },
455 | "notification-url": "https://packagist.org/downloads/",
456 | "include-path": [
457 | ""
458 | ],
459 | "license": [
460 | "BSD-3-Clause"
461 | ],
462 | "authors": [
463 | {
464 | "name": "Sebastian Bergmann",
465 | "email": "sb@sebastian-bergmann.de",
466 | "role": "lead"
467 | }
468 | ],
469 | "description": "Wrapper around PHP's tokenizer extension.",
470 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
471 | "keywords": [
472 | "tokenizer"
473 | ],
474 | "time": "2014-03-03 05:10:30"
475 | },
476 | {
477 | "name": "phpunit/phpunit",
478 | "version": "3.7.37",
479 | "source": {
480 | "type": "git",
481 | "url": "https://github.com/sebastianbergmann/phpunit.git",
482 | "reference": "ae6cefd7cc84586a5ef27e04bae11ee940ec63dc"
483 | },
484 | "dist": {
485 | "type": "zip",
486 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ae6cefd7cc84586a5ef27e04bae11ee940ec63dc",
487 | "reference": "ae6cefd7cc84586a5ef27e04bae11ee940ec63dc",
488 | "shasum": ""
489 | },
490 | "require": {
491 | "ext-ctype": "*",
492 | "ext-dom": "*",
493 | "ext-json": "*",
494 | "ext-pcre": "*",
495 | "ext-reflection": "*",
496 | "ext-spl": "*",
497 | "php": ">=5.3.3",
498 | "phpunit/php-code-coverage": "~1.2",
499 | "phpunit/php-file-iterator": "~1.3",
500 | "phpunit/php-text-template": "~1.1",
501 | "phpunit/php-timer": "~1.0",
502 | "phpunit/phpunit-mock-objects": "~1.2",
503 | "symfony/yaml": "~2.0"
504 | },
505 | "require-dev": {
506 | "pear-pear.php.net/pear": "1.9.4"
507 | },
508 | "suggest": {
509 | "phpunit/php-invoker": "~1.1"
510 | },
511 | "bin": [
512 | "composer/bin/phpunit"
513 | ],
514 | "type": "library",
515 | "extra": {
516 | "branch-alias": {
517 | "dev-master": "3.7.x-dev"
518 | }
519 | },
520 | "autoload": {
521 | "classmap": [
522 | "PHPUnit/"
523 | ]
524 | },
525 | "notification-url": "https://packagist.org/downloads/",
526 | "include-path": [
527 | "",
528 | "../../symfony/yaml/"
529 | ],
530 | "license": [
531 | "BSD-3-Clause"
532 | ],
533 | "authors": [
534 | {
535 | "name": "Sebastian Bergmann",
536 | "email": "sebastian@phpunit.de",
537 | "role": "lead"
538 | }
539 | ],
540 | "description": "The PHP Unit Testing framework.",
541 | "homepage": "http://www.phpunit.de/",
542 | "keywords": [
543 | "phpunit",
544 | "testing",
545 | "xunit"
546 | ],
547 | "time": "2014-04-30 12:24:19"
548 | },
549 | {
550 | "name": "phpunit/phpunit-mock-objects",
551 | "version": "1.2.3",
552 | "source": {
553 | "type": "git",
554 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
555 | "reference": "5794e3c5c5ba0fb037b11d8151add2a07fa82875"
556 | },
557 | "dist": {
558 | "type": "zip",
559 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/5794e3c5c5ba0fb037b11d8151add2a07fa82875",
560 | "reference": "5794e3c5c5ba0fb037b11d8151add2a07fa82875",
561 | "shasum": ""
562 | },
563 | "require": {
564 | "php": ">=5.3.3",
565 | "phpunit/php-text-template": ">=1.1.1@stable"
566 | },
567 | "suggest": {
568 | "ext-soap": "*"
569 | },
570 | "type": "library",
571 | "autoload": {
572 | "classmap": [
573 | "PHPUnit/"
574 | ]
575 | },
576 | "notification-url": "https://packagist.org/downloads/",
577 | "include-path": [
578 | ""
579 | ],
580 | "license": [
581 | "BSD-3-Clause"
582 | ],
583 | "authors": [
584 | {
585 | "name": "Sebastian Bergmann",
586 | "email": "sb@sebastian-bergmann.de",
587 | "role": "lead"
588 | }
589 | ],
590 | "description": "Mock Object library for PHPUnit",
591 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
592 | "keywords": [
593 | "mock",
594 | "xunit"
595 | ],
596 | "time": "2013-01-13 10:24:48"
597 | },
598 | {
599 | "name": "symfony/yaml",
600 | "version": "v2.4.4",
601 | "target-dir": "Symfony/Component/Yaml",
602 | "source": {
603 | "type": "git",
604 | "url": "https://github.com/symfony/Yaml.git",
605 | "reference": "65539ecde838f9c0d18b006b2101e3deb4b5c9ff"
606 | },
607 | "dist": {
608 | "type": "zip",
609 | "url": "https://api.github.com/repos/symfony/Yaml/zipball/65539ecde838f9c0d18b006b2101e3deb4b5c9ff",
610 | "reference": "65539ecde838f9c0d18b006b2101e3deb4b5c9ff",
611 | "shasum": ""
612 | },
613 | "require": {
614 | "php": ">=5.3.3"
615 | },
616 | "type": "library",
617 | "extra": {
618 | "branch-alias": {
619 | "dev-master": "2.4-dev"
620 | }
621 | },
622 | "autoload": {
623 | "psr-0": {
624 | "Symfony\\Component\\Yaml\\": ""
625 | }
626 | },
627 | "notification-url": "https://packagist.org/downloads/",
628 | "license": [
629 | "MIT"
630 | ],
631 | "authors": [
632 | {
633 | "name": "Fabien Potencier",
634 | "email": "fabien@symfony.com",
635 | "homepage": "http://fabien.potencier.org",
636 | "role": "Lead Developer"
637 | },
638 | {
639 | "name": "Symfony Community",
640 | "homepage": "http://symfony.com/contributors"
641 | }
642 | ],
643 | "description": "Symfony Yaml Component",
644 | "homepage": "http://symfony.com",
645 | "time": "2014-04-18 20:37:09"
646 | }
647 | ],
648 | "aliases": [
649 |
650 | ],
651 | "minimum-stability": "stable",
652 | "stability-flags": [
653 |
654 | ],
655 | "platform": [
656 |
657 | ],
658 | "platform-dev": [
659 |
660 | ]
661 | }
662 |
--------------------------------------------------------------------------------