Completed
Push — master ( 125148...6e4e8e )
by Timothy
16:08
created

Anime::sort_by_name()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 11
Ratio 100 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
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
10
 * @link        https://github.com/timw4mail/HummingBirdAnimeClient
11
 * @license     MIT
12
 */
13
14
namespace Aviat\AnimeClient\Model;
15
16
use Aviat\AnimeClient\Hummingbird\Enum\AnimeWatchingStatus;
17
use Aviat\AnimeClient\Hummingbird\Transformer\AnimeListTransformer;
18
19
/**
20
 * Model for handling requests dealing with the anime list
21
 */
22
class Anime extends API {
23
24
	// Display constants
25
	const WATCHING = 'Watching';
26
	const PLAN_TO_WATCH = 'Plan to Watch';
27
	const DROPPED = 'Dropped';
28
	const ON_HOLD = 'On Hold';
29
	const COMPLETED = 'Completed';
30
31
	/**
32
	 * The base url for api requests
33
	 * @var string $base_url
34
	 */
35
	protected $base_url = "https://hummingbird.me/api/v1/";
36
37
	/**
38
	 * Map of API status constants to display constants
39
	 * @var array
40
	 */
41
	protected $const_map = [
42
		AnimeWatchingStatus::WATCHING => self::WATCHING,
43
		AnimeWatchingStatus::PLAN_TO_WATCH => self::PLAN_TO_WATCH,
44
		AnimeWatchingStatus::ON_HOLD => self::ON_HOLD,
45
		AnimeWatchingStatus::DROPPED => self::DROPPED,
46
		AnimeWatchingStatus::COMPLETED => self::COMPLETED,
47
	];
48
49
	/**
50
	 * Update the selected anime
51
	 *
52
	 * @param array $data
53
	 * @return array|false
54
	 */
55
	public function update($data)
56
	{
57
		$auth = $this->container->get('auth');
58
		/*if ( ! $auth->is_authenticated() || ! array_key_exists('id', $data))
0 ignored issues
show
Unused Code Comprehensibility introduced by
61% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
59
		{
60
			return FALSE;
61
		}*/
62
63
		$id = $data['id'];
64
		$data['auth_token'] = $auth->get_auth_token();
65
66
		$response = $this->client->post("libraries/{$id}", [
67
			'form_params' => $data
68
		]);
69
70
		$output = [
71
			'statusCode' => $response->getStatusCode(),
72
			'body' => json_decode($response->getBody(), TRUE)
73
		];
74
75
		return $output;
76
	}
77
78
	/**
79
	 * Get the full set of anime lists
80
	 *
81
	 * @return array
82
	 */
83
	public function get_all_lists()
84
	{
85
		$output = [
86
			self::WATCHING => [],
87
			self::PLAN_TO_WATCH => [],
88
			self::ON_HOLD => [],
89
			self::DROPPED => [],
90
			self::COMPLETED => [],
91
		];
92
93
		$data = $this->_get_list_from_api();
94
95
		foreach ($data as $datum)
96
		{
97
			$output[$this->const_map[$datum['watching_status']]][] = $datum;
98
		}
99
100
		// Sort anime by name
101
		foreach ($output as &$status_list)
102
		{
103
			$this->sort_by_name($status_list);
104
		}
105
106
		return $output;
107
	}
108
109
	/**
110
	 * Get a category out of the full list
111
	 *
112
	 * @param string $status
113
	 * @return array
114
	 */
115
	public function get_list($status)
116
	{
117
		$data = $this->_get_list_from_api($status);
118
		$this->sort_by_name($data);
119
120
		$output = [];
121
		$output[$this->const_map[$status]] = $data;
122
123
		return $output;
124
	}
125
126
	/**
127
	 * Get the data for the specified library entry
128
	 *
129
	 * @param  string $id
130
	 * @param  string $status
131
	 * @return array
132
	 */
133
	public function get_library_anime($id, $status)
134
	{
135
		$data = $this->_get_list_from_api($status);
136
		$index_array = array_column($data, 'id');
137
138
		$key = array_search($id, $index_array);
139
140
		return $key !== FALSE
141
			? $data[$key]
142
			: [];
143
	}
144
145
	/**
146
	 * Get information about an anime from its id
147
	 *
148
	 * @param string $anime_id
149
	 * @return array
150
	 */
151
	public function get_anime($anime_id)
152
	{
153
		$config = [
154
			'query' => [
155
				'id' => $anime_id
156
			]
157
		];
158
159
		$response = $this->client->get("anime/{$anime_id}", $config);
160
161
		return json_decode($response->getBody(), TRUE);
162
	}
163
164
	/**
165
	 * Search for anime by name
166
	 *
167
	 * @param string $name
168
	 * @return array
169
	 */
170
	public function search($name)
171
	{
172
		$errorHandler = $this->container->get('error-handler');
173
174
		$config = [
175
			'query' => [
176
				'query' => $name
177
			]
178
		];
179
180
		$response = $this->get('search/anime', $config);
181
		$errorHandler->addDataTable('anime_search_response', (array)$response);
182
183
		if ($response->getStatusCode() != 200)
184
		{
185
			throw new RuntimeException($response->getEffectiveUrl());
186
		}
187
188
		return json_decode($response->getBody(), TRUE);
189
	}
190
191
	/**
192
	 * Retrieve data from the api
193
	 *
194
	 * @codeCoverageIgnore
195
	 * @param string $status
196
	 * @return array
197
	 */
198
	protected function _get_list_from_api($status = "all")
199
	{
200
		$config = [
201
			'allow_redirects' => FALSE
202
		];
203
204
		if ($status != "all")
205
		{
206
			$config['query']['status'] = $status;
207
		}
208
209
		$username = $this->config->get('hummingbird_username');
210
		$auth = $this->container->get('auth');
211
		if ($auth->is_authenticated())
212
		{
213
			$config['query']['auth_token'] = $auth->get_auth_token();
214
		}
215
216
		$response = $this->get("users/{$username}/library", $config);
217
		$output = $this->_check_cache($status, $response);
218
219
		foreach ($output as &$row)
220
		{
221
			$row['anime']['image'] = $this->get_cached_image($row['anime']['image'], $row['anime']['slug'], 'anime');
222
		}
223
224
		return $output;
225
	}
226
227
	/**
228
	 * Handle caching of transformed api data
229
	 *
230
	 * @codeCoverageIgnore
231
	 * @param string $status
232
	 * @param \GuzzleHttp\Message\Response
233
	 * @return array
234
	 */
235
	protected function _check_cache($status, $response)
236
	{
237
		$cache_file = _dir($this->config->get('data_cache_path'), "anime-{$status}.json");
238
		$transformed_cache_file = _dir($this->config->get('data_cache_path'), "anime-{$status}-transformed.json");
239
240
		$cached = (file_exists($cache_file))
241
			? json_decode(file_get_contents($cache_file), TRUE)
242
			: [];
243
		$api_data = json_decode($response->getBody(), TRUE);
244
245 View Code Duplication
		if ($api_data === $cached && 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...
246
		{
247
			return json_decode(file_get_contents($transformed_cache_file), TRUE);
248
		}
249
		else
250
		{
251
			file_put_contents($cache_file, json_encode($api_data));
252
			$transformer = new AnimeListTransformer();
253
			$transformed = $transformer->transform_collection($api_data);
254
			file_put_contents($transformed_cache_file, json_encode($transformed));
255
			return $transformed;
256
		}
257
	}
258
259
	/**
260
	 * Sort the list by title
261
	 *
262
	 * @codeCoverageIgnore
263
	 * @param array $array
264
	 * @return void
265
	 */
266 View Code Duplication
	protected function sort_by_name(&$array)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
267
	{
268
		$sort = array();
269
270
		foreach ($array as $key => $item)
271
		{
272
			$sort[$key] = $item['anime']['title'];
273
		}
274
275
		array_multisort($sort, SORT_ASC, $array);
276
	}
277
}
278
// End of AnimeModel.php