Completed
Push — master ( 645554...205c7a )
by Timothy
05:48
created

Manga::sort_by_name()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 11
Ratio 100 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 11
loc 11
rs 9.4286
cc 2
eloc 5
nc 2
nop 1
1
<?php
2
/**
3
 * Hummingbird Anime Client
4
 *
5
 * An API client for Hummingbird to manage anime and manga watch lists
6
 *
7
 * @package     HummingbirdAnimeClient
8
 * @author      Timothy J. Warren
9
 * @copyright   Copyright (c) 2015 - 2016
10
 * @link        https://github.com/timw4mail/HummingBirdAnimeClient
11
 * @license     MIT
12
 */
13
14
namespace Aviat\AnimeClient\Model;
15
16
use Aviat\AnimeClient\Model\API;
17
use Aviat\AnimeClient\Hummingbird\Transformer;
18
use Aviat\AnimeClient\Hummingbird\Enum\MangaReadingStatus;
19
20
use GuzzleHttp\Cookie\Cookiejar;
21
use GuzzleHttp\Cookie\SetCookie;
22
23
/**
24
 * Model for handling requests dealing with the manga list
25
 */
26
class Manga extends API {
27
28
	const READING = 'Reading';
29
	const PLAN_TO_READ = 'Plan to Read';
30
	const DROPPED = 'Dropped';
31
	const ON_HOLD = 'On Hold';
32
	const COMPLETED = 'Completed';
33
34
	/**
35
	 * Map API constants to display constants
36
	 * @var array
37
	 */
38
	protected $const_map = [
39
		MangaReadingStatus::READING => self::READING,
40
		MangaReadingStatus::PLAN_TO_READ => self::PLAN_TO_READ,
41
		MangaReadingStatus::ON_HOLD => self::ON_HOLD,
42
		MangaReadingStatus::DROPPED => self::DROPPED,
43
		MangaReadingStatus::COMPLETED => self::COMPLETED
44
	];
45
46
	/**
47
	 * The base url for api requests
48
	 * @var string
49
	 */
50
	protected $base_url = "https://hummingbird.me/";
51
52
	/**
53
	 * Update the selected manga
54
	 *
55
	 * @param array $data
56
	 * @return array
57
	 */
58
	public function update($data)
59
	{
60
		$id = $data['id'];
61
62
		$token = $this->container->get('auth')
63
			->get_auth_token();
64
65
		// Set the token cookie, with the authentication token
66
		// from the auth class.
67
		$cookieJar = $this->cookieJar;
68
		$cookie_data = new SetCookie([
69
			'Name' => 'token',
70
			'Value' => $token,
71
			'Domain' => 'hummingbird.me'
72
		]);
73
		$cookieJar->setCookie($cookie_data);
74
75
		$result = $this->put("manga_library_entries/{$id}", [
76
			'cookies' => $cookieJar,
77
			'json' => ['manga_library_entry' => $data]
78
		]);
79
80
		return [
81
			'statusCode' => $result->getStatusCode(),
82
			'body' => json_decode($result->getBody(), TRUE)
83
		];
84
	}
85
86
	/**
87
	 * Get the full set of anime lists
88
	 *
89
	 * @return array
90
	 */
91
	public function get_all_lists()
92
	{
93
		$data = $this->_get_list_from_api();
94
95
		foreach ($data as &$val)
96
		{
97
			$this->sort_by_name($val, 'manga');
98
		}
99
100
		return $data;
101
	}
102
103
	/**
104
	 * Get a category out of the full list
105
	 *
106
	 * @param string $status
107
	 * @return array
108
	 */
109
	public function get_list($status)
110
	{
111
		$data = $this->_get_list_from_api($status);
112
		$this->sort_by_name($data, 'manga');
113
114
		return $data;
115
	}
116
117
	/**
118
	 * Retrieve the list from the hummingbird api
119
	 *
120
	 * @param  string $status
121
	 * @return array
122
	 */
123
	protected function _get_list_from_api($status = "All")
124
	{
125
		$config = [
126
			'query' => [
127
				'user_id' => $this->config->get('hummingbird_username')
128
			],
129
			'allow_redirects' => FALSE
130
		];
131
132
		$response = $this->get('manga_library_entries', $config);
133
		$data = $this->_check_cache($response);
134
		$output = $this->map_by_status($data);
135
136
		return (array_key_exists($status, $output)) ? $output[$status] : $output;
137
	}
138
139
	/**
140
	 * Check the status of the cache and return the appropriate response
141
	 *
142
	 * @param \GuzzleHttp\Message\Response $response
143
	 * @codeCoverageIgnore
144
	 * @return array
145
	 */
146
	private function _check_cache($response)
147
	{
148
		// Bail out early if there isn't any manga data
149
		$api_data = json_decode($response->getBody(), TRUE);
150
		if ( ! array_key_exists('manga', $api_data))
151
		{
152
			return [];
153
		}
154
155
		$cache_file = _dir($this->config->get('data_cache_path'), 'manga.json');
156
		$transformed_cache_file = _dir($this->config->get('data_cache_path'), 'manga-transformed.json');
157
158
159
		$cached_data = file_exists($cache_file)
160
			? json_decode(file_get_contents($cache_file), TRUE)
161
			: [];
162
163 View Code Duplication
		if ($cached_data === $api_data && file_exists($transformed_cache_file))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
164
		{
165
			return json_decode(file_get_contents($transformed_cache_file), TRUE);
166
		}
167
		else
168
		{
169
			file_put_contents($cache_file, json_encode($api_data));
170
171
			$zippered_data = $this->zipper_lists($api_data);
172
			$transformer = new Transformer\MangaListTransformer();
173
			$transformed_data = $transformer->transform_collection($zippered_data);
174
			file_put_contents($transformed_cache_file, json_encode($transformed_data));
175
			return $transformed_data;
176
		}
177
	}
178
179
	/**
180
	 * Map transformed anime data to be organized by reading status
181
	 *
182
	 * @param array $data
183
	 * @return array
184
	 */
185
	private function map_by_status($data)
186
	{
187
		$output = [
188
			self::READING => [],
189
			self::PLAN_TO_READ => [],
190
			self::ON_HOLD => [],
191
			self::DROPPED => [],
192
			self::COMPLETED => [],
193
		];
194
195
		foreach ($data as &$entry)
196
		{
197
			$entry['manga']['image'] = $this->get_cached_image($entry['manga']['image'], $entry['manga']['slug'], 'manga');
198
			$key = $this->const_map[$entry['reading_status']];
199
			$output[$key][] = $entry;
200
		}
201
202
		return $output;
203
	}
204
205
	/**
206
	 * Combine the two manga lists into one
207
	 * @param  array $raw_data
208
	 * @return array
209
	 */
210
	private function zipper_lists($raw_data)
211
	{
212
		return (new Transformer\MangaListsZipper($raw_data))->transform();
213
	}
214
}
215
// End of MangaModel.php