Browse Source

Rough start of Manga collection...need to set up proper structure for manga collection items

Timothy J. Warren 1 year ago
parent
commit
d798a057c7

+ 3
- 0
app/bootstrap.php View File

@@ -153,6 +153,9 @@ return function(array $configArray = []) {
153 153
 	$container->set('anime-collection-model', function($container) {
154 154
 		return new Model\AnimeCollection($container);
155 155
 	});
156
+	$container->set('manga-collection-model', function($container) {
157
+		return new Model\MangaCollection($container);
158
+	});
156 159
 
157 160
 	// Miscellaneous Classes
158 161
 	$container->set('auth', function($container) {

+ 3
- 3
app/views/collection/add.php View File

@@ -1,6 +1,6 @@
1 1
 <?php if ($auth->isAuthenticated()): ?>
2 2
 <main>
3
-	<h2>Add Anime to your Collection</h2>
3
+	<h2>Add <?= ucfirst($collection_type) ?> to your Collection</h2>
4 4
 	<form action="<?= $action_url ?>" method="post">
5 5
 		<section>
6 6
 			<div class="cssload-loader" hidden="hidden">
@@ -8,7 +8,7 @@
8 8
 				<div class="cssload-inner cssload-two"></div>
9 9
 				<div class="cssload-inner cssload-three"></div>
10 10
 			</div>
11
-			<label for="search">Search for anime by name:&nbsp;&nbsp;&nbsp;&nbsp;<input type="search" id="search" name="search" /></label>
11
+			<label for="search">Search for <?= $collection_type ?> by name:&nbsp;&nbsp;&nbsp;&nbsp;<input type="search" id="search" name="search" /></label>
12 12
 			<section id="series_list" class="media-wrap">
13 13
 			</section>
14 14
 		</section>
@@ -39,5 +39,5 @@
39 39
 		</table>
40 40
 	</form>
41 41
 </main>
42
-<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/anime_collection') ?>"></script>
42
+<script defer="defer" src="<?= $urlGenerator->assetUrl("js.php/g/{$collection_type}_collection") ?>"></script>
43 43
 <?php endif ?>

+ 6
- 0
app/views/main-menu.php View File

@@ -32,6 +32,12 @@ $extraSegment = $lastSegment === 'list' ? '/list' : '';
32 32
 			) ?>]
33 33
 		<?php else: ?>
34 34
 			<?= $whose . ucfirst($url_type) . ' Collection' ?>
35
+			<?php if($config->get("show_{$other_type}_collection")): ?>
36
+				[<?= $helper->a(
37
+					$url->generate("{$other_type}.collection.view") . $extraSegment,
38
+					ucfirst($other_type) . ' Collection'
39
+				) ?>]
40
+			<?php endif ?>
35 41
 			[<?= $helper->a($urlGenerator->defaultUrl('anime') . $extraSegment, 'Anime List') ?>]
36 42
 			[<?= $helper->a($urlGenerator->defaultUrl('manga') . $extraSegment, 'Manga List') ?>]
37 43
 		<?php endif ?>

+ 54
- 0
migrations/20170914200308_add_manga_collection_tables.php View File

@@ -0,0 +1,54 @@
1
+<?php
2
+
3
+use Phinx\Migration\AbstractMigration;
4
+
5
+class AddMangaCollectionTables extends AbstractMigration
6
+{
7
+    /**
8
+     * Change Method.
9
+     *
10
+     * Write your reversible migrations using this method.
11
+     *
12
+     * More information on writing migrations is available here:
13
+     * http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
14
+     *
15
+     * The following commands can be used in this method and Phinx will
16
+     * automatically reverse them when rolling back:
17
+     *
18
+     *    createTable
19
+     *    renameTable
20
+     *    addColumn
21
+     *    renameColumn
22
+     *    addIndex
23
+     *    addForeignKey
24
+     *
25
+     * Remember to call "create()" or "update()" and NOT "save()" when working
26
+     * with the Table class.
27
+     */
28
+	public function change()
29
+	{
30
+		// Create manga_set table
31
+		$manga_set = $this->table('manga_set', ['id' => FALSE, 'primary_key' => ['hummingbird_id']]);
32
+		$manga_set->addColumn('hummingbird_id', 'biginteger')
33
+			->addColumn('slug', 'string', ['comment' => "URL slug used for image caching and generating links"])
34
+			->addColumn('title', 'string')
35
+			->addColumn('alternate_title', 'string', ['null' => TRUE])
36
+			->addColumn('media_id', 'integer', ['default' => 3, 'null' => TRUE])
37
+			->addColumn('show_type', 'string', ['default' => 'TV', 'null' => TRUE, 'comment' => "TV Series/OVA/etc"])
38
+			->addColumn('age_rating', 'string', ['default' => 'PG13', 'null' => TRUE])
39
+			->addColumn('cover_image', 'string', ['null' => TRUE])
40
+			->addColumn('episode_count', 'integer', ['null' => TRUE])
41
+			->addColumn('episode_length', 'integer', ['null' => TRUE])
42
+			->addColumn('notes', 'text', ['null' => TRUE])
43
+			->addForeignKey('media_id', 'media', 'id')
44
+			->create();
45
+
46
+		// Create genre_manga_set_link table
47
+		$genre_manga_set_link = $this->table('genre_manga_set_link', ['id' => FALSE, 'primary_key' => ['hummingbird_id', 'genre_id']]);
48
+		$genre_manga_set_link->addColumn('hummingbird_id', 'biginteger')
49
+			->addColumn('genre_id', 'integer')
50
+			->addForeignKey('hummingbird_id', 'manga_set', 'hummingbird_id')
51
+			->addForeignKey('genre_id', 'genres', 'id')
52
+			->create();
53
+	}
54
+}

+ 184
- 0
src/Controller/MangaCollection.php View File

@@ -0,0 +1,184 @@
1
+<?php declare(strict_types=1);
2
+/**
3
+ * Hummingbird Anime List Client
4
+ *
5
+ * An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
6
+ *
7
+ * PHP version 7
8
+ *
9
+ * @package     HummingbirdAnimeClient
10
+ * @author      Timothy J. Warren <tim@timshomepage.net>
11
+ * @copyright   2015 - 2017  Timothy J. Warren
12
+ * @license     http://www.opensource.org/licenses/mit-license.html  MIT License
13
+ * @version     4.0
14
+ * @link        https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
15
+ */
16
+
17
+namespace Aviat\AnimeClient\Controller;
18
+
19
+use Aviat\AnimeClient\Controller as BaseController;
20
+use Aviat\AnimeClient\Model\{
21
+	manga as mangaModel,
22
+	mangaCollection as mangaCollectionModel
23
+};
24
+use Aviat\AnimeClient\UrlGenerator;
25
+use Aviat\Ion\Di\ContainerInterface;
26
+
27
+/**
28
+ * Controller for manga collection pages
29
+ */
30
+class MangaCollection extends BaseController {
31
+
32
+	/**
33
+	 * The manga collection model
34
+	 * @var mangaCollectionModel $mangaCollectionModel
35
+	 */
36
+	private $mangaCollectionModel;
37
+
38
+	/**
39
+	 * The manga API model
40
+	 * @var mangaModel $mangaModel
41
+	 */
42
+	private $mangaModel;
43
+
44
+	/**
45
+	 * Constructor
46
+	 *
47
+	 * @param ContainerInterface $container
48
+	 */
49
+	public function __construct(ContainerInterface $container)
50
+	{
51
+		parent::__construct($container);
52
+
53
+		$this->mangaModel = $container->get('manga-model');
54
+		$this->mangaCollectionModel = $container->get('manga-collection-model');
55
+		$this->baseData = array_merge($this->baseData, [
56
+			'collection_type' => 'manga',
57
+			'menu_name' => 'manga-collection',
58
+			'url_type' => 'manga',
59
+			'other_type' => 'anime',
60
+			'config' => $this->config,
61
+		]);
62
+	}
63
+
64
+	/**
65
+	 * Search for manga
66
+	 *
67
+	 * @return void
68
+	 */
69
+	public function search()
70
+	{
71
+		$queryParams = $this->request->getQueryParams();
72
+		$query = $queryParams['query'];
73
+		$this->outputJSON($this->mangaModel->search($query));
74
+	}
75
+
76
+	/**
77
+	 * Show the manga collection page
78
+	 *
79
+	 * @param string $view
80
+	 * @return void
81
+	 */
82
+	public function index($view)
83
+	{
84
+		$viewMap = [
85
+			'' => 'cover',
86
+			'list' => 'list'
87
+		];
88
+
89
+		$data = $this->mangaCollectionModel->getCollection();
90
+
91
+		$this->outputHTML('collection/' . $viewMap[$view], [
92
+			'title' => $this->config->get('whose_list') . "'s Manga Collection",
93
+			'sections' => $data,
94
+			'genres' => $this->mangaCollectionModel->getGenreList()
95
+		]);
96
+	}
97
+
98
+	/**
99
+	 * Show the manga collection add/edit form
100
+	 *
101
+	 * @param integer|null $id
102
+	 * @return void
103
+	 */
104
+	public function form($id = NULL)
105
+	{
106
+		$this->setSessionRedirect();
107
+
108
+		$action = (is_null($id)) ? "Add" : "Edit";
109
+		$urlAction = strtolower($action);
110
+
111
+		$this->outputHTML('collection/' . $urlAction, [
112
+			'action' => $action,
113
+			'action_url' => $this->url->generate("manga.collection.{$urlAction}.post"),
114
+			'title' => $this->formatTitle(
115
+				$this->config->get('whose_list') . "'s manga Collection",
116
+				$action
117
+			),
118
+			'media_items' => $this->mangaCollectionModel->getMediaTypeList(),
119
+			'item' => ($action === "Edit") ? $this->mangaCollectionModel->get($id) : []
120
+		]);
121
+	}
122
+
123
+	/**
124
+	 * Update a collection item
125
+	 *
126
+	 * @return void
127
+	 */
128
+	public function edit()
129
+	{
130
+		$data = $this->request->getParsedBody();
131
+		if (array_key_exists('hummingbird_id', $data))
132
+		{
133
+			$this->mangaCollectionModel->update($data);
134
+			$this->setFlashMessage('Successfully updated collection item.', 'success');
135
+		}
136
+		else
137
+		{
138
+			$this->setFlashMessage('Failed to update collection item', 'error');
139
+		}
140
+
141
+		$this->sessionRedirect();
142
+	}
143
+
144
+	/**
145
+	 * Add a collection item
146
+	 *
147
+	 * @return void
148
+	 */
149
+	public function add()
150
+	{
151
+		$data = $this->request->getParsedBody();
152
+		if (array_key_exists('id', $data))
153
+		{
154
+			$this->mangaCollectionModel->add($data);
155
+			$this->setFlashMessage('Successfully added collection item', 'success');
156
+		}
157
+		else
158
+		{
159
+			$this->setFlashMessage('Failed to add collection item.', 'error');
160
+		}
161
+
162
+		$this->sessionRedirect();
163
+	}
164
+
165
+	/**
166
+	 * Remove a collection item
167
+	 *
168
+	 * @return void
169
+	 */
170
+	public function delete()
171
+	{
172
+		$data = $this->request->getParsedBody();
173
+		if ( ! array_key_exists('hummingbird_id', $data))
174
+		{
175
+			$this->redirect("/manga-collection/view", 303);
176
+		}
177
+
178
+		$this->mangaCollectionModel->delete($data);
179
+		$this->setFlashMessage("Successfully removed manga from collection.", 'success');
180
+
181
+		$this->redirect("/manga-collection/view", 303);
182
+	}
183
+}
184
+// End of CollectionController.php

+ 17
- 0
src/Model/AnimeCollection.php View File

@@ -26,6 +26,23 @@ use PDO;
26 26
  */
27 27
 class AnimeCollection extends Collection {
28 28
 
29
+	/**
30
+	 * Anime API Model
31
+	 * @var object $animeModel
32
+	 */
33
+	protected $animeModel;
34
+
35
+	/**
36
+	 * Create the collection model
37
+	 *
38
+	 * @param ContainerInterface $container
39
+	 */
40
+	public function __construct(ContainerInterface $container)
41
+	{
42
+		parent::__construct($container);
43
+		$this->animeModel = $container->get('anime-model');
44
+	}
45
+
29 46
 	/**
30 47
 	 * Get collection from the database, and organize by media type
31 48
 	 *

+ 2
- 9
src/Model/Collection.php View File

@@ -25,14 +25,8 @@ use PDOException;
25 25
  * Base model for anime and manga collections
26 26
  */
27 27
 class Collection extends DB {
28
-	
29
-	use ContainerAware;
30 28
 
31
-	/**
32
-	 * Anime API Model
33
-	 * @var object $animeModel
34
-	 */
35
-	protected $animeModel;
29
+	use ContainerAware;
36 30
 
37 31
 	/**
38 32
 	 * Whether the database is valid for querying
@@ -46,7 +40,7 @@ class Collection extends DB {
46 40
 	 * @param ContainerInterface $container
47 41
 	 */
48 42
 	public function __construct(ContainerInterface $container)
49
-	{	
43
+	{
50 44
 		parent::__construct($container);
51 45
 
52 46
 		try
@@ -58,7 +52,6 @@ class Collection extends DB {
58 52
 			//$this->validDatabase = FALSE;
59 53
 			//return FALSE;
60 54
 		}
61
-		$this->animeModel = $container->get('anime-model');
62 55
 
63 56
 		// Is database valid? If not, set a flag so the
64 57
 		// app can be run without a valid database

+ 304
- 0
src/Model/MangaCollection.php View File

@@ -0,0 +1,304 @@
1
+<?php declare(strict_types=1);
2
+/**
3
+ * Hummingbird Anime List Client
4
+ *
5
+ * An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
6
+ *
7
+ * PHP version 7
8
+ *
9
+ * @package     HummingbirdAnimeClient
10
+ * @author      Timothy J. Warren <tim@timshomepage.net>
11
+ * @copyright   2015 - 2017  Timothy J. Warren
12
+ * @license     http://www.opensource.org/licenses/mit-license.html  MIT License
13
+ * @version     4.0
14
+ * @link        https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
15
+ */
16
+
17
+namespace Aviat\AnimeClient\Model;
18
+
19
+use Aviat\AnimeClient\API\Kitsu;
20
+use Aviat\Ion\Di\ContainerInterface;
21
+use Aviat\Ion\Json;
22
+use PDO;
23
+
24
+/**
25
+ * Model for getting anime collection data
26
+ */
27
+class MangaCollection extends Collection {
28
+
29
+	/**
30
+	 * Manga API Model
31
+	 * @var object $mangaModel
32
+	 */
33
+	protected $mangaModel;
34
+
35
+	/**
36
+	 * Create the collection model
37
+	 *
38
+	 * @param ContainerInterface $container
39
+	 */
40
+	public function __construct(ContainerInterface $container)
41
+	{
42
+		parent::__construct($container);
43
+		$this->mangaModel = $container->get('manga-model');
44
+	}
45
+
46
+	/**
47
+	 * Get collection from the database, and organize by media type
48
+	 *
49
+	 * @return array
50
+	 */
51
+	public function getCollection()
52
+	{
53
+		$rawCollection = $this->getCollectionFromDatabase();
54
+
55
+		$collection = [];
56
+
57
+		foreach ($rawCollection as $row)
58
+		{
59
+			if (array_key_exists($row['media'], $collection))
60
+			{
61
+				$collection[$row['media']][] = $row;
62
+			}
63
+			else
64
+			{
65
+				$collection[$row['media']] = [$row];
66
+			}
67
+		}
68
+
69
+		return $collection;
70
+	}
71
+
72
+	/**
73
+	 * Get list of media types
74
+	 *
75
+	 * @return array
76
+	 */
77
+	public function getMediaTypeList()
78
+	{
79
+		$output = [];
80
+
81
+		$query = $this->db->select('id, type')
82
+			->from('media')
83
+			->get();
84
+
85
+		foreach ($query->fetchAll(PDO::FETCH_ASSOC) as $row)
86
+		{
87
+			$output[$row['id']] = $row['type'];
88
+		}
89
+
90
+		return $output;
91
+	}
92
+
93
+	/**
94
+	 * Get item from collection for editing
95
+	 *
96
+	 * @param int $id
97
+	 * @return array
98
+	 */
99
+	public function getCollectionEntry($id)
100
+	{
101
+		$query = $this->db->from('anime_set')
102
+			->where('hummingbird_id', (int)$id)
103
+			->get();
104
+
105
+		return $query->fetch(PDO::FETCH_ASSOC);
106
+	}
107
+
108
+	/**
109
+	 * Get full collection from the database
110
+	 *
111
+	 * @return array
112
+	 */
113
+	private function getCollectionFromDatabase()
114
+	{
115
+		if ( ! $this->validDatabase)
116
+		{
117
+			return [];
118
+		}
119
+
120
+		$query = $this->db->select('hummingbird_id, slug, title, alternate_title, show_type,
121
+			 age_rating, episode_count, episode_length, cover_image, notes, media.type as media')
122
+			->from('manga_set a')
123
+			->join('media', 'media.id=a.media_id', 'inner')
124
+			->order_by('media')
125
+			->order_by('title')
126
+			->get();
127
+
128
+		return $query->fetchAll(PDO::FETCH_ASSOC);
129
+	}
130
+
131
+	/**
132
+	 * Add an item to the anime collection
133
+	 *
134
+	 * @param array $data
135
+	 * @return void
136
+	 */
137
+	public function add($data)
138
+	{
139
+		$anime = (object)$this->mangaModel->getMangaById($data['id']);
140
+		$this->db->set([
141
+			'hummingbird_id' => $data['id'],
142
+			'slug' => $anime->slug,
143
+			'title' => array_shift($anime->titles),
144
+			'alternate_title' => implode('<br />', $anime->titles),
145
+			'show_type' => $anime->show_type,
146
+			'age_rating' => $anime->age_rating,
147
+			'cover_image' => $anime->cover_image,
148
+			'episode_count' => $anime->episode_count,
149
+			'episode_length' => $anime->episode_length,
150
+			'media_id' => $data['media_id'],
151
+			'notes' => $data['notes']
152
+		])->insert('manga_set');
153
+
154
+		$this->updateGenre($data['id']);
155
+	}
156
+
157
+	/**
158
+	 * Update a collection item
159
+	 *
160
+	 * @param array $data
161
+	 * @return void
162
+	 */
163
+	public function update($data)
164
+	{
165
+		// If there's no id to update, don't update
166
+		if ( ! array_key_exists('hummingbird_id', $data))
167
+		{
168
+			return;
169
+		}
170
+
171
+		$id = $data['hummingbird_id'];
172
+		unset($data['hummingbird_id']);
173
+
174
+		$this->db->set($data)
175
+			->where('hummingbird_id', $id)
176
+			->update('manga_set');
177
+	}
178
+
179
+	/**
180
+	 * Remove a collection item
181
+	 *
182
+	 * @param  array $data
183
+	 * @return void
184
+	 */
185
+	public function delete($data)
186
+	{
187
+		// If there's no id to update, don't delete
188
+		if ( ! array_key_exists('hummingbird_id', $data))
189
+		{
190
+			return;
191
+		}
192
+
193
+		$this->db->where('hummingbird_id', $data['hummingbird_id'])
194
+			->delete('genre_manga_set_link');
195
+
196
+		$this->db->where('hummingbird_id', $data['hummingbird_id'])
197
+			->delete('manga_set');
198
+	}
199
+
200
+	/**
201
+	 * Get the details of a collection item
202
+	 *
203
+	 * @param int $kitsuId
204
+	 * @return array
205
+	 */
206
+	public function get($kitsuId)
207
+	{
208
+		$query = $this->db->from('manga_set')
209
+			->where('hummingbird_id', $kitsuId)
210
+			->get();
211
+
212
+		return $query->fetch(PDO::FETCH_ASSOC);
213
+	}
214
+
215
+	/**
216
+	 * Update genre information for selected manga
217
+	 *
218
+	 * @param int $mangaId The current manga
219
+	 * @return void
220
+	 */
221
+	private function updateGenre($mangaId)
222
+	{
223
+		$genreInfo = $this->getGenreData();
224
+		extract($genreInfo);
225
+
226
+		// Get api information
227
+		$manga = $this->mangaModel->getMangaById($mangaId);
228
+
229
+		foreach ($anime['genres'] as $genre)
230
+		{
231
+			// Add genres that don't currently exist
232
+			if ( ! in_array($genre, $genres))
233
+			{
234
+				$this->db->set('genre', $genre)
235
+					->insert('genres');
236
+
237
+				$genres[] = $genre;
238
+			}
239
+
240
+			// Update link table
241
+			// Get id of genre to put in link table
242
+			$flippedGenres = array_flip($genres);
243
+
244
+			$insertArray = [
245
+				'hummingbird_id' => $mangaId,
246
+				'genre_id' => $flippedGenres[$genre]
247
+			];
248
+
249
+			if (array_key_exists($mangaId, $links))
250
+			{
251
+				if ( ! in_array($flippedGenres[$genre], $links[$mangaId]))
252
+				{
253
+					$this->db->set($insertArray)->insert('genre_manga_set_link');
254
+				}
255
+			}
256
+			else
257
+			{
258
+				$this->db->set($insertArray)->insert('genre_manga_set_link');
259
+			}
260
+		}
261
+	}
262
+
263
+	/**
264
+	 * Get list of existing genres
265
+	 *
266
+	 * @return array
267
+	 */
268
+	private function getGenreData()
269
+	{
270
+		$genres = [];
271
+		$links = [];
272
+
273
+		// Get existing genres
274
+		$query = $this->db->select('id, genre')
275
+			->from('genres')
276
+			->get();
277
+		foreach ($query->fetchAll(PDO::FETCH_ASSOC) as $genre)
278
+		{
279
+			$genres[$genre['id']] = $genre['genre'];
280
+		}
281
+
282
+		// Get existing link table entries
283
+		$query = $this->db->select('hummingbird_id, genre_id')
284
+			->from('genre_manga_set_link')
285
+			->get();
286
+		foreach ($query->fetchAll(PDO::FETCH_ASSOC) as $link)
287
+		{
288
+			if (array_key_exists($link['hummingbird_id'], $links))
289
+			{
290
+				$links[$link['hummingbird_id']][] = $link['genre_id'];
291
+			}
292
+			else
293
+			{
294
+				$links[$link['hummingbird_id']] = [$link['genre_id']];
295
+			}
296
+		}
297
+
298
+		return [
299
+			'genres' => $genres,
300
+			'links' => $links
301
+		];
302
+	}
303
+}
304
+// End of MangaCollectionModel.php

+ 7
- 2
tests/ControllerTest.php View File

@@ -22,7 +22,8 @@ use Aviat\AnimeClient\Controller;
22 22
 use Aviat\AnimeClient\Controller\{
23 23
 	Anime as AnimeController,
24 24
 	Character as CharacterController,
25
-	Collection as CollectionController,
25
+	AnimeCollection as AnimeCollectionController,
26
+	MangaCollection as MangaCollectionController,
26 27
 	Manga as MangaController
27 28
 };
28 29
 
@@ -71,7 +72,11 @@ class ControllerTest extends AnimeClientTestCase {
71 72
 		);
72 73
 		$this->assertInstanceOf(
73 74
 			'Aviat\AnimeClient\Controller',
74
-			new CollectionController($this->container)
75
+			new AnimeCollectionController($this->container)
76
+		);
77
+		$this->assertInstanceOf(
78
+			'Aviat\AnimeClient\Controller',
79
+			new MangaCollectionController($this->container)
75 80
 		);
76 81
 	}
77 82
 

+ 4
- 2
tests/DispatcherTest.php View File

@@ -227,7 +227,8 @@ class DispatcherTest extends AnimeClientTestCase {
227 227
 				'expected' => [
228 228
 					'anime' => 'Aviat\AnimeClient\Controller\Anime',
229 229
 					'manga' => 'Aviat\AnimeClient\Controller\Manga',
230
-					'collection' => 'Aviat\AnimeClient\Controller\Collection',
230
+					'anime-collection' => 'Aviat\AnimeClient\Controller\AnimeCollection',
231
+					'manga-collection' => 'Aviat\AnimeClient\Controller\MangaCollection',
231 232
 					'character' => 'Aviat\AnimeClient\Controller\Character',
232 233
 					'index' => 'Aviat\AnimeClient\Controller\Index',
233 234
 				]
@@ -248,7 +249,8 @@ class DispatcherTest extends AnimeClientTestCase {
248 249
 				'expected' => [
249 250
 					'anime' => 'Aviat\AnimeClient\Controller\Anime',
250 251
 					'manga' => 'Aviat\AnimeClient\Controller\Manga',
251
-					'collection' => 'Aviat\AnimeClient\Controller\Collection',
252
+					'anime-collection' => 'Aviat\AnimeClient\Controller\AnimeCollection',
253
+					'manga-collection' => 'Aviat\AnimeClient\Controller\MangaCollection',
252 254
 					'character' => 'Aviat\AnimeClient\Controller\Character',
253 255
 					'index' => 'Aviat\AnimeClient\Controller\Index',
254 256
 				]