Passed
Push — master ( c13757...19c3c0 )
by Borislav
04:44
created

BookController::showAction()   D

Complexity

Conditions 21
Paths 20

Size

Total Lines 58
Code Lines 50

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 21
eloc 50
c 2
b 0
f 0
nc 20
nop 3
dl 0
loc 58
rs 4.1666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php namespace App\Controller;
2
3
use App\Entity\BaseWork;
4
use App\Entity\Book;
5
use App\Generator\DownloadFile;
6
use App\Generator\DownloadUrlGenerator;
7
use App\Legacy\Setup;
8
use App\Pagination\Pager;
9
use App\Service\ContentService;
10
use App\Service\SearchService;
11
use App\Util\Stringy;
12
use Doctrine\ORM\NoResultException;
13
use Symfony\Component\HttpFoundation\Request;
14
use Symfony\Component\Routing\Annotation\Route;
15
16
/**
17
 * @Route("/books")
18
 */
19
class BookController extends Controller {
20
21
	const PAGE_COUNT_DEFAULT = 30;
22
	const PAGE_COUNT_LIMIT = 300;
23
24
	public function indexAction($_format) {
25
		if (in_array($_format, ['html', 'json'])) {
26
			return [
27
				'categories' => $this->em()->getCategoryRepository()->getAllAsTree(),
28
			];
29
		}
30
		return [];
31
	}
32
33
	public function listByCategoryIndexAction($_format) {
34
		switch ($_format) {
35
			case 'html':
36
			case 'opds':
37
				return [
38
					'categories' => $this->em()->getCategoryRepository()->getAll(),
39
				];
40
		}
41
	}
42
43
	public function listByAlphaIndexAction() {
44
		return [];
45
	}
46
47
	public function listByCategoryAction(Request $request, $slug, $page) {
48
		$slug = Stringy::slugify($slug);
49
		$bookRepo = $this->em()->getBookRepository();
50
		$categoryRepo = $this->em()->getCategoryRepository();
51
		$category = $categoryRepo->findBySlug($slug);
52
		if ($category === null) {
53
			throw $this->createNotFoundException("Няма категория с код $slug.");
54
		}
55
		$limit = min($request->query->get('limit', static::PAGE_COUNT_DEFAULT), static::PAGE_COUNT_LIMIT);
56
		return [
57
			'category' => $category,
58
			'parents' => array_reverse($categoryRepo->findCategoryAncestors($category)),
59
			'books' => $bookRepo->findByCategory($categoryRepo->getCategoryDescendantIdsWithSelf($category), $page, $limit),
60
			'pager' => new Pager($page, $category->getNrOfBooks(), $limit),
61
			'route_params' => ['slug' => $slug],
62
		];
63
	}
64
65
	public function listByAlphaAction(Request $request, $letter, $page) {
66
		$bookRepo = $this->em()->getBookRepository();
67
		$limit = min($request->query->get('limit', static::PAGE_COUNT_DEFAULT), static::PAGE_COUNT_LIMIT);
68
		$prefix = $letter == '-' ? null : $letter;
69
		return [
70
			'letter' => $letter,
71
			'books' => $bookRepo->findByPrefix($prefix, $page, $limit),
72
			'pager'    => new Pager($page, $bookRepo->countByPrefix($prefix), $limit),
73
			'route_params' => ['letter' => $letter],
74
		];
75
	}
76
77
	public function listWoCoverAction(Request $request, $page) {
78
		$limit = min($request->query->get('limit', static::PAGE_COUNT_DEFAULT), static::PAGE_COUNT_LIMIT);
79
		$bookRepo = $this->em()->getBookRepository();
80
		return [
81
			'books' => $bookRepo->findWithMissingCover($page, $limit),
82
			'pager' => new Pager($page, $bookRepo->getCountWithMissingCover(), $limit),
83
		];
84
	}
85
86
	/**
87
	 * @Route("/wo-biblioman/{page}.{_format}", name="books_wo_biblioman", defaults={"page": 1, "_format": "html"})
88
	 */
89
	public function listWoBibliomanAction(Request $request, $page) {
90
		$limit = min($request->query->get('limit', static::PAGE_COUNT_DEFAULT), static::PAGE_COUNT_LIMIT);
91
		$bookRepo = $this->em()->getBookRepository();
92
		return [
93
			'books' => $bookRepo->findWithMissingBibliomanId($page, $limit),
94
			'pager' => new Pager($page, $bookRepo->getCountWithMissingBibliomanId(), $limit),
95
		];
96
	}
97
98
	public function listByIsbnAction($isbn) {
99
		$books = $this->em()->getBookRepository()->findByIsbn($isbn);
100
		if (count($books) == 1) {
101
			return $this->redirectToRoute('book_show', ['id' => $books[0]->getId()]);
102
		}
103
		return [
104
			'isbn' => $isbn,
105
			'books' => $books,
106
		];
107
	}
108
109
	public function showAction(Request $request, $id, $_format) {
110
		list($id) = explode('-', $id); // remove optional slug
111
		try {
112
			$book = $this->em()->getBookRepository()->get($id);
0 ignored issues
show
Bug introduced by
$id of type string is incompatible with the type integer expected by parameter $id of App\Entity\BookRepository::get(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

112
			$book = $this->em()->getBookRepository()->get(/** @scrutinizer ignore-type */ $id);
Loading history...
113
		} catch (NoResultException $e) {
114
			throw $this->createNotFoundException("Няма книга с номер $id.");
115
		}
116
117
		switch ($_format) {
118
			case 'sfb.zip':
119
			case 'txt.zip':
120
			case 'fb2.zip':
121
			case 'epub':
122
				Setup::doSetup($this->container);
123
				return $this->urlRedirect($this->processDownload($book, $_format));
124
			case 'djvu':
125
				return $this->urlRedirect($this->processDownload($book, $_format));
126
			case 'pdf':
127
				if ($book->hasCustomPdf()) {
128
					return $this->urlRedirect($this->processDownload($book, $_format));
129
				}
130
				if ( ! $this->container->getParameter('pdf_download_enabled')) {
131
					throw $this->createNotFoundException("Няма поддръжка на формата PDF.");
132
				}
133
				return $this->urlRedirect($this->generateConverterUrl($this->container->getParameter('pdf_converter_url'), $book));
134
			case 'mobi':
135
				if ( ! $this->container->getParameter('mobi_download_enabled')) {
136
					throw $this->createNotFoundException("Няма поддръжка на формата MOBI.");
137
				}
138
				return $this->urlRedirect($this->generateConverterUrl($this->container->getParameter('mobi_converter_url'), $book));
139
			case 'txt':
140
				Setup::doSetup($this->container);
141
				return $this->asText($book->getContentAsTxt());
142
			case 'fb2':
143
				Setup::doSetup($this->container);
144
				return $this->asText($book->getContentAsFb2(), 'application/xml');
145
			case 'sfb':
146
				Setup::doSetup($this->container);
147
				return $this->asText($book->getContentAsSfb());
148
			case 'data':
149
				return $this->asText($book->getDataAsPlain());
150
			case 'opds':
151
				break;
152
			case 'pic':
153
				Setup::doSetup($this->container);
154
				break;
155
			case 'cover':
156
				return $this->urlRedirect('/'.ContentService::getCover($book->hasCover() ? $book->getId() : 0, $request->get('size', 300)));
157
			case 'html':
158
			default:
159
		}
160
161
		return [
162
			'book' => $book,
163
			'authors' => $book->getAuthors(),
164
			'template' => $book->getTemplateAsXhtml(),
165
			'info' => $book->getExtraInfoAsXhtml(),
166
			'js_extra' => ['book'],
167
		];
168
	}
169
170
	public function searchAction(Request $request, $_format) {
171
		if ($_format == 'osd') {
172
			return [];
173
		}
174
		if ($_format == 'suggest') {
175
			$query = $request->query->get('q');
176
			$books = $this->findByQuery([
177
				'text'  => $query,
178
				'by'    => 'title,subtitle,origTitle',
179
				'match' => 'prefix',
180
				'limit' => self::PAGE_COUNT_LIMIT,
181
			]);
182
			$items = $descs = $urls = [];
183
			foreach ($books as $book) {
184
				$authors = $book->getAuthorNamesString();
185
				$items[] = $book->getTitle() . ($authors ? " – $authors" : '');
186
				$descs[] = '';
187
				$urls[] = $this->generateAbsoluteUrl('book_show', ['id' => $book->getId()]);
188
			}
189
190
			return [$query, $items, $descs, $urls];
191
		}
192
		$searchService = new SearchService($this->em());
193
		$query = $searchService->prepareQuery($request, $_format);
194
		if (isset($query['_template'])) {
195
			return $query;
196
		}
197
198
		if (empty($query['by'])) {
199
			$query['by'] = 'title,subtitle,origTitle';
200
		}
201
		$books = $this->findByQuery($query);
202
		$found = count($books) > 0;
203
		return [
204
			'query' => $query,
205
			'books' => $books,
206
			'found' => $found,
207
			'_status' => !$found ? 404 : null,
208
		];
209
	}
210
211
	public function randomAction() {
212
		$id = $this->em()->getBookRepository()->getRandomId();
213
214
		return $this->urlRedirect($this->generateUrl('book_show', ['id' => $id]));
215
	}
216
217
	/**
218
	 * @param Book $book
219
	 * @param string $format
220
	 * @return string File URL
221
	 */
222
	protected function processDownload(Book $book, $format) {
223
		$dlSite = $this->getMirrorServer();
224
		if ( $dlSite !== false ) {
225
			return "$dlSite/book/{$book->getId()}.$format";
226
		}
227
228
		$dlFile = new DownloadFile;
229
		switch ($format) {
230
			case 'sfb.zip':
231
				return $this->getWebRoot() . $dlFile->getSfbForBook($book);
232
			case 'txt.zip':
233
				return $this->getWebRoot() . $dlFile->getTxtForBook($book);
234
			case 'fb2.zip':
235
				return $this->getWebRoot() . $dlFile->getFb2ForBook($book);
236
			case 'epub':
237
				return $this->getWebRoot() . $dlFile->getEpubForBook($book);
238
			case 'djvu':
239
			case 'pdf':
240
				return $this->getWebRoot() . $dlFile->getStaticFileForBook($book, $format);
241
		}
242
		throw $this->createNotFoundException("Книгата не е налична във формат {$format}.");
243
	}
244
245
	protected function generateConverterUrl(string $urlTemplate, Book $book): string {
246
		$epubUrl = $this->generateAbsoluteUrl('book_show', ['id' => $book->getId(), '_format' => Book::FORMAT_EPUB]);
247
		return (new DownloadUrlGenerator())->generateConverterUrl($urlTemplate, $epubUrl);
248
	}
249
250
	/**
251
	 * @param array $query
252
	 * @return Book[]
253
	 */
254
	protected function findByQuery(array $query) {
255
		return $this->em()->getBookRepository()->findByQuery($query);
256
	}
257
}
258