├── .gitignore
├── phpunit.xml
├── .travis.yml
├── tests
├── Functional
│ ├── README.md
│ ├── SWAPITest.php
│ ├── FilmsTest.php
│ ├── VehiclesTest.php
│ ├── CharactersTest.php
│ └── FunctionalBase.php
└── Endpoints
│ ├── responses
│ ├── GET_vehicles_1
│ └── GET_vehicles_4
│ ├── EndpointBase.php
│ └── VehiclesTest.php
├── .php_cs
├── examples
└── vehicles.php
├── composer.json
├── src
├── Models
│ ├── Film.php
│ ├── Planet.php
│ ├── Species.php
│ ├── Vehicle.php
│ ├── Character.php
│ ├── Starship.php
│ └── Collection.php
├── Endpoints
│ ├── FilmsEndpoint.php
│ ├── PlanetsEndpoint.php
│ ├── SpeciesEndpoint.php
│ ├── VehiclesEndpoint.php
│ ├── CharactersEndpoint.php
│ ├── StarshipsEndpoint.php
│ └── Endpoint.php
└── SWAPI.php
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
2 | composer.lock
3 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | tests/
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - 5.4
5 | - 5.5
6 | - 5.6
7 | - hhvm
8 |
9 | install:
10 | - composer --prefer-source --dev install
11 |
12 | script:
13 | - vendor/bin/phpunit
14 |
--------------------------------------------------------------------------------
/tests/Functional/README.md:
--------------------------------------------------------------------------------
1 | # Functional API tests
2 |
3 | These tests use the live API to check the response is as expected.
4 |
5 | The JsonMapper instance is configured to throw an exception whenever a
6 | `@required` property is not present in the JSON payload, or if a new field is
7 | given that isn't on the model.
8 |
--------------------------------------------------------------------------------
/.php_cs:
--------------------------------------------------------------------------------
1 | level(Symfony\CS\FixerInterface::PSR2_LEVEL)
5 | ->fixers([
6 | '-psr0'
7 | ])
8 | ->finder(
9 | Symfony\CS\Finder\DefaultFinder::create()
10 | ->in(__DIR__ . '/src')
11 | ->in(__DIR__ . '/tests')
12 | )
13 | ;
14 |
--------------------------------------------------------------------------------
/tests/Functional/SWAPITest.php:
--------------------------------------------------------------------------------
1 | swapi->getFromUri("http://swapi.co/api/vehicles/4");
10 |
11 | $this->assertInstanceOf('SWAPI\Models\Vehicle', $vehicle);
12 | $this->assertEquals("Sand Crawler", $vehicle->name);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tests/Endpoints/responses/GET_vehicles_1:
--------------------------------------------------------------------------------
1 | HTTP/1.1 404 NOT FOUND
2 | Date: Sun, 21 Dec 2014 21:43:57 GMT
3 | Content-Type: application/json
4 | Transfer-Encoding: chunked
5 | Connection: keep-alive
6 | Set-Cookie: __cfduid=d9f0abaeee38cb1a9ac2025e9bd74bd881419198235; expires=Mon, 21-Dec-15 21:43:55 GMT; path=/; domain=.swapi.co; HttpOnly
7 | Allow: GET, HEAD, OPTIONS
8 | X-Frame-Options: SAMEORIGIN
9 | Vary: Accept, Cookie
10 | Via: 1.1 vegur
11 | Server: cloudflare-nginx
12 | CF-RAY: 19c7420ac9b00a72-LHR
13 |
14 | {"detail":"Not found"}
--------------------------------------------------------------------------------
/tests/Functional/FilmsTest.php:
--------------------------------------------------------------------------------
1 | swapi->films()->index();
10 |
11 | $this->assertInstanceOf('SWAPI\Models\Collection', $films);
12 | }
13 |
14 | public function testGet()
15 | {
16 | $film = $this->swapi->films()->get(1);
17 |
18 | $this->assertInstanceOf('SWAPI\Models\Film', $film);
19 | $this->assertEquals('http://swapi.co/api/films/1/', $film->url);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/tests/Functional/VehiclesTest.php:
--------------------------------------------------------------------------------
1 | swapi->vehicles()->index();
10 |
11 | $this->assertInstanceOf('SWAPI\Models\Collection', $vehicles);
12 | }
13 |
14 | public function testGet()
15 | {
16 | $vehicle = $this->swapi->vehicles()->get(4);
17 |
18 | $this->assertInstanceOf('SWAPI\Models\Vehicle', $vehicle);
19 | $this->assertEquals('http://swapi.co/api/vehicles/4/', $vehicle->url);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/tests/Functional/CharactersTest.php:
--------------------------------------------------------------------------------
1 | swapi->characters()->index();
10 |
11 | $this->assertInstanceOf('SWAPI\Models\Collection', $characters);
12 | }
13 |
14 | public function testGet()
15 | {
16 | $character = $this->swapi->characters()->get(4);
17 |
18 | $this->assertInstanceOf('SWAPI\Models\Character', $character);
19 | $this->assertEquals('http://swapi.co/api/people/4/', $character->url);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/examples/vehicles.php:
--------------------------------------------------------------------------------
1 | vehicles()->get(4)->name;
11 |
12 | // Iterate through all pages of vehicles
13 | do {
14 | if (!isset($vehicles)) {
15 | $vehicles = $swapi->vehicles()->index();
16 | } else {
17 | // The getNext, getPrevious of Collection indicate whether more pages follow
18 | $vehicles = $vehicles->getNext();
19 | }
20 |
21 | foreach ($vehicles as $v) {
22 | echo sprintf("%s - %s\n", $v->name, $v->url);
23 | }
24 | } while ($vehicles->hasNext());
25 |
--------------------------------------------------------------------------------
/tests/Functional/FunctionalBase.php:
--------------------------------------------------------------------------------
1 | bExceptionOnMissingData = true;
20 | $mapper->bExceptionOnUndefinedProperty = true;
21 |
22 | $this->swapi = new SWAPI;
23 | $this->swapi->setMapper($mapper);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rmasters/swapi",
3 | "license": "MIT",
4 | "copyright": "Ross Masters 2014",
5 | "authors": [
6 | {
7 | "name": "Ross Masters",
8 | "email": "ross@rossmasters.com",
9 | "homepage": "http://codinghobo.com/",
10 | "role": "Developer"
11 | }
12 | ],
13 | "require": {
14 | "guzzlehttp/guzzle": "~5.0",
15 | "psr/log": "~1.0",
16 | "netresearch/jsonmapper": "~0.4"
17 | },
18 | "require-dev": {
19 | "phpunit/phpunit": "~4.0",
20 | "fabpot/php-cs-fixer": "~1.3"
21 | },
22 | "autoload": {
23 | "psr-4": {
24 | "SWAPI\\": "src/",
25 | "SWAPI\\Tests\\": "tests/"
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/Endpoints/responses/GET_vehicles_4:
--------------------------------------------------------------------------------
1 | HTTP/1.1 200 OK
2 | Date: Sun, 21 Dec 2014 21:26:21 GMT
3 | Content-Type: application/json
4 | Transfer-Encoding: chunked
5 | Connection: keep-alive
6 | Set-Cookie: __cfduid=d099f1ce6123a9cadaebff711f19448f41419197180; expires=Mon, 21-Dec-15 21:26:20 GMT; path=/; domain=.swapi.co; HttpOnly
7 | Allow: GET, HEAD, OPTIONS
8 | X-Frame-Options: SAMEORIGIN
9 | Vary: Accept, Cookie
10 | Via: 1.1 vegur
11 | Server: cloudflare-nginx
12 | CF-RAY: 19c7284cfe3c0a78-LHR
13 |
14 | {"name":"Sand Crawler","model":"Digger Crawler","manufacturer":"Corellia Mining Corporation","cost_in_credits":"150000","length":"36.8 ","max_atmosphering_speed":"30","crew":"46","passengers":"30","cargo_capacity":"50000","consumables":"2 months","vehicle_class":"wheeled","pilots":[],"films":["http://swapi.co/api/films/1/","http://swapi.co/api/films/5/"],"created":"2014-12-10T15:36:25.724000Z","edited":"2014-12-20T21:30:21.661000Z","url":"http://swapi.co/api/vehicles/4/"}
--------------------------------------------------------------------------------
/src/Models/Film.php:
--------------------------------------------------------------------------------
1 | url = $url;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Models/Planet.php:
--------------------------------------------------------------------------------
1 | url = $url;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Models/Species.php:
--------------------------------------------------------------------------------
1 | url = $url;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Endpoints/FilmsEndpoint.php:
--------------------------------------------------------------------------------
1 | http->createRequest("GET", sprintf("films/?page=%d", $page));
13 | $response = $this->http->send($request);
14 |
15 | $collection = new Collection;
16 |
17 | if ($response->getStatusCode() == 200) {
18 | return $this->hydrateMany($response->json(), 'SWAPI\Models\Film');
19 | }
20 |
21 | return $this->handleResponse($response, $request, $collection);
22 | }
23 |
24 | public function get($id)
25 | {
26 | $request = $this->http->createRequest("GET", sprintf("films/%d/", $id));
27 | $response = $this->http->send($request);
28 |
29 | if ($response->getStatusCode() == 200) {
30 | return $this->hydrateOne($response->json(), new Film);
31 | }
32 |
33 | return $this->handleResponse($response, $request);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Models/Vehicle.php:
--------------------------------------------------------------------------------
1 | url = $url;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Endpoints/PlanetsEndpoint.php:
--------------------------------------------------------------------------------
1 | http->createRequest("GET", sprintf("planets/?page=%d", $page));
13 | $response = $this->http->send($request);
14 |
15 | $collection = new Collection;
16 |
17 | if ($response->getStatusCode() == 200) {
18 | return $this->hydrateMany($response->json(), 'SWAPI\Models\Planet');
19 | }
20 |
21 | return $this->handleResponse($response, $request, $collection);
22 | }
23 |
24 | public function get($id)
25 | {
26 | $request = $this->http->createRequest("GET", sprintf("planets/%d/", $id));
27 | $response = $this->http->send($request);
28 |
29 | if ($response->getStatusCode() == 200) {
30 | return $this->hydrateOne($response->json(), new Planet);
31 | }
32 |
33 | return $this->handleResponse($response, $request);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Endpoints/SpeciesEndpoint.php:
--------------------------------------------------------------------------------
1 | http->createRequest("GET", sprintf("species/?page=%d", $page));
13 | $response = $this->http->send($request);
14 |
15 | $collection = new Collection;
16 |
17 | if ($response->getStatusCode() == 200) {
18 | return $this->hydrateMany($response->json(), 'SWAPI\Models\Species');
19 | }
20 |
21 | return $this->handleResponse($response, $request, $collection);
22 | }
23 |
24 | public function get($id)
25 | {
26 | $request = $this->http->createRequest("GET", sprintf("species/%d/", $id));
27 | $response = $this->http->send($request);
28 |
29 | if ($response->getStatusCode() == 200) {
30 | return $this->hydrateOne($response->json(), new Species);
31 | }
32 |
33 | return $this->handleResponse($response, $request);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Endpoints/VehiclesEndpoint.php:
--------------------------------------------------------------------------------
1 | http->createRequest("GET", sprintf("vehicles/?page=%d", $page));
13 | $response = $this->http->send($request);
14 |
15 | $collection = new Collection;
16 |
17 | if ($response->getStatusCode() == 200) {
18 | return $this->hydrateMany($response->json(), 'SWAPI\Models\Vehicle');
19 | }
20 |
21 | return $this->handleResponse($response, $request, $collection);
22 | }
23 |
24 | public function get($id)
25 | {
26 | $request = $this->http->createRequest("GET", sprintf("vehicles/%d/", $id));
27 | $response = $this->http->send($request);
28 |
29 | if ($response->getStatusCode() == 200) {
30 | return $this->hydrateOne($response->json(), new Vehicle);
31 | }
32 |
33 | return $this->handleResponse($response, $request);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Endpoints/CharactersEndpoint.php:
--------------------------------------------------------------------------------
1 | http->createRequest("GET", sprintf("people/?page=%d", $page));
13 | $response = $this->http->send($request);
14 |
15 | $collection = new Collection;
16 |
17 | if ($response->getStatusCode() == 200) {
18 | return $this->hydrateMany($response->json(), 'SWAPI\Models\Character');
19 | }
20 |
21 | return $this->handleResponse($response, $request, $collection);
22 | }
23 |
24 | public function get($id)
25 | {
26 | $request = $this->http->createRequest("GET", sprintf("people/%d/", $id));
27 | $response = $this->http->send($request);
28 |
29 | if ($response->getStatusCode() == 200) {
30 | return $this->hydrateOne($response->json(), new Character);
31 | }
32 |
33 | return $this->handleResponse($response, $request);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Endpoints/StarshipsEndpoint.php:
--------------------------------------------------------------------------------
1 | http->createRequest("GET", sprintf("starships/?page=%d", $page));
13 | $response = $this->http->send($request);
14 |
15 | $collection = new Collection;
16 |
17 | if ($response->getStatusCode() == 200) {
18 | return $this->hydrateMany($response->json(), 'SWAPI\Models\Starship');
19 | }
20 |
21 | return $this->handleResponse($response, $request, $collection);
22 | }
23 |
24 | public function get($id)
25 | {
26 | $request = $this->http->createRequest("GET", sprintf("starships/%d/", $id));
27 | $response = $this->http->send($request);
28 |
29 | if ($response->getStatusCode() == 200) {
30 | return $this->hydrateOne($response->json(), new Starship);
31 | }
32 |
33 | return $this->handleResponse($response, $request);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Ross Masters
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/Models/Character.php:
--------------------------------------------------------------------------------
1 | url = $url;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Models/Starship.php:
--------------------------------------------------------------------------------
1 | url = $url;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PHP library for [SWAPI](http://swapi.co/)
2 |
3 | [](https://travis-ci.org/rmasters/swapi-php/)
4 | [](http://packagist.org/packages/rmasters/swapi)
5 | [](LICENSE)
6 |
7 | ## Usage
8 |
9 | Install with Composer: `composer require "rmasters/swapi:~1.0"`.
10 |
11 | ```php
12 | require_once __DIR__ . '/vendor/autoload.php';
13 | use SWAPI\SWAPI;
14 |
15 | $swapi = new SWAPI;
16 |
17 | $swapi->characters()->index(); => Character[]
18 | $swapi->characters()->index(2); => Character[]
19 |
20 | $swapi->vehicles()->get(1); => Vehicle
21 | $swapi->planets()->get(7); => Planet
22 |
23 | $swapi->people()->get(9999); => null (not-found)
24 |
25 | // Iteration
26 | do {
27 | if (!isset($starships)) {
28 | $starships = $swapi->starships()->index();
29 | } else {
30 | $starships = $starships->getNext();
31 | }
32 |
33 | foreach ($starships as $s) {
34 | echo "{$s->name}\n";
35 | }
36 | } while ($starships->hasNext());
37 | ```
38 |
39 | ## Running tests and contributing
40 |
41 | Install dependencies with `composer install --dev` and run `vendor/bin/phpunit`
42 | to run the testsuite. The test suite comprises of:
43 |
44 | - [tests/Endpoints](tests/Endpoints) - tests that use mocked sample responses,
45 | - [tests/Functional](tests/Functional) - tests that use the live API, to spot changes.
46 |
47 | ## License
48 |
49 | [MIT Licensed](LICENSE)
50 |
--------------------------------------------------------------------------------
/tests/Endpoints/EndpointBase.php:
--------------------------------------------------------------------------------
1 | client = $this->getClient();
23 | $this->mapper = $this->getMapper();
24 | }
25 |
26 | protected function getClient()
27 | {
28 | return new Client([
29 | 'base_url' => 'http://swapi.co/api/',
30 | 'defaults' => [
31 | 'exceptions' => false,
32 | 'headers' => [
33 | 'User-Agent' => sprintf('php-swapi/%s', 'testing'),
34 | 'Accept' => 'application/json',
35 | ],
36 |
37 | ],
38 | ]);
39 | }
40 |
41 | protected function getMapper()
42 | {
43 | $mapper = new JsonMapper;
44 | $mapper->bExceptionOnUndefinedProperty = true;
45 | $mapper->bExceptionOnMissingData = true;
46 |
47 | return $mapper;
48 | }
49 |
50 | protected function getMockResponse($method, $path)
51 | {
52 | // "get", "/vehicles/1/" becomes "GET_vehicles_1"
53 |
54 | return file_get_contents(sprintf(
55 | "%s/%s_%s",
56 | $this->getMockResponsesPath(),
57 | strtoupper($method),
58 | trim(preg_replace("/[^A-Za-z0-9]+/", "_", $path), "_")
59 | ), "r");
60 | }
61 |
62 | protected function getMockResponsesPath()
63 | {
64 | return __DIR__ . '/responses/';
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Endpoints/Endpoint.php:
--------------------------------------------------------------------------------
1 | http = $http;
26 | $this->logger = $logger;
27 | $this->mapper = $mapper;
28 | }
29 |
30 | public function setClient(Client $http)
31 | {
32 | $this->http = $http;
33 | }
34 |
35 | public function setLogger(LoggerInterface $logger)
36 | {
37 | $this->logger = $logger;
38 | }
39 |
40 | public function setMapper(JsonMapper $mapper)
41 | {
42 | $this->mapper = $mapper;
43 | }
44 |
45 | protected function handleResponse(Response $response, Request $request, $default = null)
46 | {
47 | switch ($response->getStatusCode()) {
48 | case 404:
49 | return $default;
50 | }
51 | }
52 |
53 | protected function hydrateOne(array $data, $modelInstance)
54 | {
55 | return $this->mapper->map($data, $modelInstance);
56 | }
57 |
58 | protected function hydrateMany(array $data, $modelName)
59 | {
60 | $collection = new Collection($this->mapper->mapArray($data['results'], [], $modelName));
61 | $collection->setEndpoint($this);
62 | $collection->setNext($data['next']);
63 | $collection->setPrevious($data['previous']);
64 |
65 | return $collection;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/tests/Endpoints/VehiclesTest.php:
--------------------------------------------------------------------------------
1 | vehicles = new VehiclesEndpoint($this->client, new NullLogger, $this->mapper);
24 | }
25 |
26 | public function testFindById()
27 | {
28 | $mock = new Mock([
29 | $this->getMockResponse('GET', '/vehicles/4'),
30 | $this->getMockResponse('GET', '/vehicles/1'),
31 | ]);
32 |
33 | $this->client->getEmitter()->attach($mock);
34 |
35 | $vehicle = $this->vehicles->get(4);
36 | $this->assertInstanceOf('SWAPI\Models\Vehicle', $vehicle);
37 | $this->assertEquals('Sand Crawler', $vehicle->name);
38 | $this->assertEquals('Digger Crawler', $vehicle->model);
39 | $this->assertEquals('Corellia Mining Corporation', $vehicle->manufacturer);
40 | $this->assertEquals(150000, $vehicle->cost_in_credits);
41 | $this->assertEquals(36.8, $vehicle->length);
42 | $this->assertEquals(30, $vehicle->max_atmosphering_speed);
43 | $this->assertEquals(46, $vehicle->crew);
44 | $this->assertEquals(30, $vehicle->passengers);
45 | $this->assertEquals(50000, $vehicle->cargo_capacity);
46 | $this->assertEquals("2 months", $vehicle->consumables);
47 | $this->assertEquals("wheeled", $vehicle->vehicle_class);
48 | $this->assertInternalType("array", $vehicle->pilots);
49 | $this->assertCount(0, $vehicle->pilots);
50 | $this->assertInternalType("array", $vehicle->films);
51 | $this->assertCount(2, $vehicle->films);
52 | $this->assertInstanceOf('SWAPI\Models\Film', $vehicle->films[0]);
53 | $this->assertEquals('http://swapi.co/api/films/1/', $vehicle->films[0]->url);
54 | $this->assertInstanceOf('DateTime', $vehicle->created);
55 | $this->assertEquals('2014-12-10T15:36:25+00:00', $vehicle->created->format('c'));
56 | $this->assertInstanceOf('DateTime', $vehicle->edited);
57 | $this->assertEquals('2014-12-20T21:30:21+00:00', $vehicle->edited->format('c'));
58 | $this->assertEquals('http://swapi.co/api/vehicles/4/', $vehicle->url);
59 |
60 | $this->assertNull($this->vehicles->get(1));
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/Models/Collection.php:
--------------------------------------------------------------------------------
1 | endpoint = $endpoint;
28 | }
29 |
30 | /**
31 | * @param string|int $url A URL with a page= query-string parameter, or a page number
32 | */
33 | public function setNext($url)
34 | {
35 | if ($url instanceof Collection) {
36 | $this->next =& $url;
37 | } elseif (is_numeric($url)) {
38 | $this->next = intval($url);
39 | } elseif (!is_null($url)) {
40 | // Attempt to get the page=%d value
41 | $this->next = self::getPageFromQueryString($url);
42 | }
43 | }
44 |
45 | public function setPrevious($url)
46 | {
47 | if ($url instanceof Collection) {
48 | $this->previous =& $url;
49 | } elseif (is_numeric($url)) {
50 | $this->previous = intval($url);
51 | } elseif (!is_null($url)) {
52 | // Attempt to get the page=%d value
53 | $this->previous = self::getPageFromQueryString($url);
54 | }
55 | }
56 |
57 | protected static function getPageFromQueryString($url, $parameter = 'page')
58 | {
59 | $qs = parse_url($url, PHP_URL_QUERY);
60 | $qs = explode("&", $qs);
61 | foreach ($qs as $q) {
62 | list($k, $v) = explode("=", $q, 2);
63 |
64 | if ($k == $parameter) {
65 | return intval($v);
66 | }
67 | }
68 | }
69 |
70 | public function hasNext()
71 | {
72 | return !is_null($this->next);
73 | }
74 |
75 | public function hasPrevious()
76 | {
77 | return !is_null($this->previous);
78 | }
79 |
80 | public function getNext()
81 | {
82 | if (is_int($this->next)) {
83 | $this->next = $this->endpoint->index($this->next);
84 | $this->next->setPrevious($this);
85 | }
86 | return $this->next;
87 | }
88 |
89 | public function getPrevious()
90 | {
91 | if (is_int($this->previous)) {
92 | $this->previous = $this->endpoint->index($this->next);
93 | $this->previous->setNext($this);
94 | }
95 |
96 | return $this->previous;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/SWAPI.php:
--------------------------------------------------------------------------------
1 | http = $this->createHttpClient();
26 | $this->logger = $this->createLogger();
27 | $this->mapper = $this->createMapper();
28 | }
29 |
30 | protected function createHttpClient()
31 | {
32 | return new Client([
33 | 'base_url' => 'http://swapi.co/api/',
34 | 'default' => [
35 | 'exceptions' => false,
36 | 'headers' => [
37 | 'User-Agent' => sprintf('php-swapi/%s', static::VERSION),
38 | 'Accept' => 'application/json',
39 | ],
40 | ],
41 | ]);
42 | }
43 |
44 | protected function createLogger()
45 | {
46 | return new NullLogger;
47 | }
48 |
49 | protected function createMapper()
50 | {
51 | return new JsonMapper;
52 | }
53 |
54 | public function setMapper(JsonMapper $mapper)
55 | {
56 | $this->mapper = $mapper;
57 | }
58 |
59 | /**
60 | * @param bool $fresh
61 | * @return Endpoints\CharactersEndpoint
62 | */
63 | public function characters($fresh = false)
64 | {
65 | if (!isset($this->characters) || $fresh) {
66 | $this->characters = new Endpoints\CharactersEndpoint($this->http, $this->logger, $this->mapper);
67 | }
68 | return $this->characters;
69 | }
70 |
71 | /**
72 | * @param bool $fresh
73 | * @return Endpoints\FilmsEndpoint
74 | */
75 | public function films($fresh = false)
76 | {
77 | if (!isset($this->films) || $fresh) {
78 | $this->films = new Endpoints\FilmsEndpoint($this->http, $this->logger, $this->mapper);
79 | }
80 | return $this->films;
81 | }
82 |
83 | /**
84 | * @param bool $fresh
85 | * @return Endpoints\PlanetsEndpoint
86 | */
87 | public function planets($fresh = false)
88 | {
89 | if (!isset($this->planets) || $fresh) {
90 | $this->planets = new Endpoints\PlanetsEndpoint($this->http, $this->logger, $this->mapper);
91 | }
92 | return $this->planets;
93 | }
94 |
95 | /**
96 | * @param bool $fresh
97 | * @return Endpoints\SpeciesEndpoint
98 | */
99 | public function species($fresh = false)
100 | {
101 | if (!isset($this->species) || $fresh) {
102 | $this->species = new Endpoints\SpeciesEndpoint($this->http, $this->logger, $this->mapper);
103 | }
104 | return $this->species;
105 | }
106 |
107 | /**
108 | * @param bool $fresh
109 | * @return Endpoints\StarshipsEndpoint
110 | */
111 | public function starships($fresh = false)
112 | {
113 | if (!isset($this->starships) || $fresh) {
114 | $this->starships = new Endpoints\StarshipsEndpoint($this->http, $this->logger, $this->mapper);
115 | }
116 | return $this->starships;
117 | }
118 |
119 | /**
120 | * @param bool $fresh
121 | * @return Endpoints\VehiclesEndpoint
122 | */
123 | public function vehicles($fresh = false)
124 | {
125 | if (!isset($this->vehicles) || $fresh) {
126 | $this->vehicles = new Endpoints\VehiclesEndpoint($this->http, $this->logger, $this->mapper);
127 | }
128 | return $this->vehicles;
129 | }
130 |
131 | /**
132 | * @param string $url
133 | * @return object SWAPI Model
134 | * @throws \UnexpectedValueException When given an unrecognised URI
135 | */
136 | public function getFromUri($uri)
137 | {
138 | if (preg_match("/\/api\/(\w+)\/(\d+)(\/|$)/", $uri, $matches) !== false) {
139 | switch (strtolower($matches[1])) {
140 | case "characters":
141 | return $this->characters()->get($matches[2]);
142 | case "films":
143 | return $this->films()->get($matches[2]);
144 | case "planets":
145 | return $this->planets()->get($matches[2]);
146 | case "species":
147 | return $this->species()->get($matches[2]);
148 | case "starships":
149 | return $this->starships()->get($matches[2]);
150 | case "vehicles":
151 | return $this->vehicles()->get($matches[2]);
152 | }
153 | }
154 |
155 | throw new \UnexpectedValueException(sprintf("Could not match a URI to an endpoint handler for %s", $uri));
156 | }
157 | }
158 |
--------------------------------------------------------------------------------