PageRenderTime 46ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Frontend/Modules/Blog/Actions/Archive.php

http://github.com/forkcms/forkcms
PHP | 200 lines | 153 code | 33 blank | 14 comment | 9 complexity | aeea0cda7256026f0a979b2bc0af64d4 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, MIT, AGPL-3.0, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. namespace Frontend\Modules\Blog\Actions;
  3. use DateTimeImmutable;
  4. use Frontend\Core\Engine\Base\Block as FrontendBaseBlock;
  5. use Frontend\Core\Engine\Model;
  6. use Frontend\Core\Engine\Navigation;
  7. use Frontend\Core\Language\Language as FL;
  8. use Frontend\Core\Engine\Navigation as FrontendNavigation;
  9. use Frontend\Modules\Blog\Engine\Model as FrontendBlogModel;
  10. use Symfony\Component\HttpFoundation\Response;
  11. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  12. class Archive extends FrontendBaseBlock
  13. {
  14. /** @var array */
  15. private $articles;
  16. /** @var DateTimeImmutable */
  17. private $startDate;
  18. /** @var DateTimeImmutable */
  19. private $endDate;
  20. /** @var bool */
  21. private $hasMonth;
  22. /** @var string */
  23. private $format;
  24. public function execute(): void
  25. {
  26. parent::execute();
  27. $this->loadTemplate();
  28. $this->getData();
  29. $this->parse();
  30. }
  31. private function buildUrl(): string
  32. {
  33. return FrontendNavigation::getUrlForBlock($this->getModule(), $this->getAction())
  34. . '/' . $this->startDate->format($this->format);
  35. }
  36. private function buildPaginationConfig(): array
  37. {
  38. $requestedPage = $this->url->getParameter('page', 'int', 1);
  39. $numberOfItems = FrontendBlogModel::getAllForDateRangeCount(
  40. $this->startDate->getTimestamp(),
  41. $this->endDate->getTimestamp()
  42. );
  43. $limit = $this->get('fork.settings')->get($this->getModule(), 'overview_num_items', 10);
  44. $numberOfPages = (int) ceil($numberOfItems / $limit);
  45. // Check if the page exists
  46. if ($requestedPage > $numberOfPages || $requestedPage < 1) {
  47. throw new NotFoundHttpException();
  48. }
  49. return [
  50. 'url' => $this->buildUrl(),
  51. 'limit' => $limit,
  52. 'offset' => ($requestedPage * $limit) - $limit,
  53. 'requested_page' => $requestedPage,
  54. 'num_items' => $numberOfItems,
  55. 'num_pages' => $numberOfPages,
  56. ];
  57. }
  58. /**
  59. * Complete the slug to prevent wrong months when the current day is higher than possible in the requested month
  60. *
  61. * @param string $slug
  62. *
  63. * @return string
  64. */
  65. private function getStartDateSlug(string $slug):string
  66. {
  67. if (!$this->hasMonth) {
  68. $slug .= '/01';
  69. }
  70. return $slug . '/01 00:00:00';
  71. }
  72. private function getSlug(): string
  73. {
  74. $yearIndex = $this->url->getParameter(0) === FL::act('Archive') ? 1 : 0;
  75. $monthIndex = $yearIndex + 1;
  76. $this->hasMonth = !empty($this->url->getParameter($monthIndex));
  77. if ($this->hasMonth) {
  78. $this->format = 'Y/m';
  79. return $this->url->getParameter($yearIndex) . '/' . $this->url->getParameter($monthIndex);
  80. }
  81. $this->format = 'Y';
  82. return $this->url->getParameter($yearIndex);
  83. }
  84. private function setDateRange(): void
  85. {
  86. $slug = $this->getSlug();
  87. $this->startDate = DateTimeImmutable::createFromFormat('Y/m/d H:i:s', $this->getStartDateSlug($slug));
  88. if (!$this->startDate instanceof DateTimeImmutable) {
  89. throw new NotFoundHttpException();
  90. }
  91. if ($slug !== $this->startDate->format($this->format)) {
  92. // redirect /2010/6 to /2010/06 to avoid duplicate content
  93. $redirectUrl = Navigation::getUrlForBlock($this->getModule(), $this->getAction())
  94. . '/' . $this->startDate->format($this->format);
  95. if ($this->getRequest()->getQueryString() !== null) {
  96. $redirectUrl .= '?' . $this->getRequest()->getQueryString();
  97. }
  98. $this->redirect($redirectUrl, Response::HTTP_MOVED_PERMANENTLY);
  99. }
  100. $this->endDate = $this->startDate
  101. ->setDate($this->startDate->format('Y'), 12, 31)
  102. ->setTime(23, 59, 59, 999999);
  103. }
  104. private function getData(): void
  105. {
  106. $this->setDateRange();
  107. $this->pagination = $this->buildPaginationConfig();
  108. $this->articles = FrontendBlogModel::getAllForDateRange(
  109. $this->startDate->getTimestamp(),
  110. $this->endDate->getTimestamp(),
  111. $this->pagination['limit'],
  112. $this->pagination['offset']
  113. );
  114. }
  115. private function parse(): void
  116. {
  117. $this->addLinkToRssFeed();
  118. $this->addPageToBreadcrumb();
  119. $this->setPageTitle();
  120. $this->parsePagination();
  121. $this->template->assign(
  122. 'archive',
  123. [
  124. 'start_date' => $this->startDate->getTimestamp(),
  125. 'end_date' => $this->endDate->getTimestamp(),
  126. 'year' => $this->startDate->format('Y'),
  127. 'month' => $this->hasMonth ? $this->startDate->format('m') : null,
  128. ]
  129. );
  130. $this->template->assign('items', $this->articles);
  131. $this->template->assign(
  132. 'allowComments',
  133. $this->get('fork.settings')->get($this->getModule(), 'allow_comments')
  134. );
  135. }
  136. private function setPageTitle(): void
  137. {
  138. $this->header->setPageTitle(\SpoonFilter::ucfirst(FL::lbl('Archive')));
  139. $this->header->setPageTitle($this->startDate->format('Y'));
  140. if ($this->hasMonth) {
  141. $this->header->setPageTitle(
  142. \SpoonDate::getDate('F', $this->startDate->getTimestamp(), LANGUAGE)
  143. );
  144. }
  145. }
  146. private function addPageToBreadcrumb(): void
  147. {
  148. $this->breadcrumb->addElement(\SpoonFilter::ucfirst(FL::lbl('Archive')));
  149. $this->breadcrumb->addElement($this->startDate->format('Y'));
  150. if ($this->hasMonth) {
  151. $this->breadcrumb->addElement(
  152. \SpoonDate::getDate(
  153. 'F',
  154. $this->startDate->getTimestamp(),
  155. LANGUAGE
  156. )
  157. );
  158. }
  159. }
  160. private function addLinkToRssFeed(): void
  161. {
  162. $this->header->addRssLink(
  163. $this->get('fork.settings')->get($this->getModule(), 'rss_title_' . LANGUAGE, SITE_DEFAULT_TITLE),
  164. FrontendNavigation::getUrlForBlock($this->getModule(), 'Rss')
  165. );
  166. }
  167. }