]> git.immae.eu Git - github/shaarli/Shaarli.git/blame - application/helper/DailyPageHelper.php
Daily RSS - Remove relative description (today, yesterday)
[github/shaarli/Shaarli.git] / application / helper / DailyPageHelper.php
CommitLineData
36e6d88d
A
1<?php
2
3declare(strict_types=1);
4
5namespace Shaarli\Helper;
6
7use Shaarli\Bookmark\Bookmark;
8use Slim\Http\Request;
9
10class DailyPageHelper
11{
12 public const MONTH = 'month';
13 public const WEEK = 'week';
14 public const DAY = 'day';
15
16 /**
17 * Extracts the type of the daily to display from the HTTP request parameters
18 *
19 * @param Request $request HTTP request
20 *
21 * @return string month/week/day
22 */
23 public static function extractRequestedType(Request $request): string
24 {
25 if ($request->getQueryParam(static::MONTH) !== null) {
26 return static::MONTH;
27 } elseif ($request->getQueryParam(static::WEEK) !== null) {
28 return static::WEEK;
29 }
30
31 return static::DAY;
32 }
33
34 /**
35 * Extracts a DateTimeImmutable from provided HTTP request.
36 * If no parameter is provided, we rely on the creation date of the latest provided created bookmark.
37 * If the datastore is empty or no bookmark is provided, we use the current date.
38 *
39 * @param string $type month/week/day
40 * @param string|null $requestedDate Input string extracted from the request
41 * @param Bookmark|null $latestBookmark Latest bookmark found in the datastore (by date)
42 *
43 * @return \DateTimeImmutable from input or latest bookmark.
44 *
45 * @throws \Exception Type not supported.
46 */
47 public static function extractRequestedDateTime(
48 string $type,
49 ?string $requestedDate,
50 Bookmark $latestBookmark = null
51 ): \DateTimeImmutable {
52 $format = static::getFormatByType($type);
53 if (empty($requestedDate)) {
54 return $latestBookmark instanceof Bookmark
55 ? new \DateTimeImmutable($latestBookmark->getCreated()->format(\DateTime::ATOM))
56 : new \DateTimeImmutable()
57 ;
58 }
59
60 // W is not supported by createFromFormat...
61 if ($type === static::WEEK) {
62 return (new \DateTimeImmutable())
63 ->setISODate((int) substr($requestedDate, 0, 4), (int) substr($requestedDate, 4, 2))
64 ;
65 }
66
67 return \DateTimeImmutable::createFromFormat($format, $requestedDate);
68 }
69
70 /**
71 * Get the DateTime format used by provided type
72 * Examples:
73 * - day: 20201016 (<year><month><day>)
74 * - week: 202041 (<year><week number>)
75 * - month: 202010 (<year><month>)
76 *
77 * @param string $type month/week/day
78 *
79 * @return string DateTime compatible format
80 *
81 * @see https://www.php.net/manual/en/datetime.format.php
82 *
83 * @throws \Exception Type not supported.
84 */
85 public static function getFormatByType(string $type): string
86 {
87 switch ($type) {
88 case static::MONTH:
89 return 'Ym';
90 case static::WEEK:
91 return 'YW';
92 case static::DAY:
93 return 'Ymd';
94 default:
95 throw new \Exception('Unsupported daily format type');
96 }
97 }
98
99 /**
100 * Get the first DateTime of the time period depending on given datetime and type.
101 * Note: DateTimeImmutable is required because we rely heavily on DateTime->modify() syntax
102 * and we don't want to alter original datetime.
103 *
104 * @param string $type month/week/day
105 * @param \DateTimeImmutable $requested DateTime extracted from request input
106 * (should come from extractRequestedDateTime)
107 *
108 * @return \DateTimeInterface First DateTime of the time period
109 *
110 * @throws \Exception Type not supported.
111 */
112 public static function getStartDateTimeByType(string $type, \DateTimeImmutable $requested): \DateTimeInterface
113 {
114 switch ($type) {
115 case static::MONTH:
116 return $requested->modify('first day of this month midnight');
117 case static::WEEK:
118 return $requested->modify('Monday this week midnight');
119 case static::DAY:
120 return $requested->modify('Today midnight');
121 default:
122 throw new \Exception('Unsupported daily format type');
123 }
124 }
125
126 /**
127 * Get the last DateTime of the time period depending on given datetime and type.
128 * Note: DateTimeImmutable is required because we rely heavily on DateTime->modify() syntax
129 * and we don't want to alter original datetime.
130 *
131 * @param string $type month/week/day
132 * @param \DateTimeImmutable $requested DateTime extracted from request input
133 * (should come from extractRequestedDateTime)
134 *
135 * @return \DateTimeInterface Last DateTime of the time period
136 *
137 * @throws \Exception Type not supported.
138 */
139 public static function getEndDateTimeByType(string $type, \DateTimeImmutable $requested): \DateTimeInterface
140 {
141 switch ($type) {
142 case static::MONTH:
143 return $requested->modify('last day of this month 23:59:59');
144 case static::WEEK:
145 return $requested->modify('Sunday this week 23:59:59');
146 case static::DAY:
147 return $requested->modify('Today 23:59:59');
148 default:
149 throw new \Exception('Unsupported daily format type');
150 }
151 }
152
153 /**
154 * Get localized description of the time period depending on given datetime and type.
155 * Example: for a month period, it returns `October, 2020`.
156 *
2883c6d0
A
157 * @param string $type month/week/day
158 * @param \DateTimeImmutable $requested DateTime extracted from request input
159 * (should come from extractRequestedDateTime)
160 * @param bool $includeRelative Include relative date description (today, yesterday, etc.)
36e6d88d
A
161 *
162 * @return string Localized time period description
163 *
164 * @throws \Exception Type not supported.
165 */
2883c6d0
A
166 public static function getDescriptionByType(
167 string $type,
168 \DateTimeImmutable $requested,
169 bool $includeRelative = true
170 ): string {
36e6d88d
A
171 switch ($type) {
172 case static::MONTH:
173 return $requested->format('F') . ', ' . $requested->format('Y');
174 case static::WEEK:
175 $requested = $requested->modify('Monday this week');
176 return t('Week') . ' ' . $requested->format('W') . ' (' . format_date($requested, false) . ')';
177 case static::DAY:
178 $out = '';
2883c6d0 179 if ($includeRelative && $requested->format('Ymd') === date('Ymd')) {
36e6d88d 180 $out = t('Today') . ' - ';
2883c6d0 181 } elseif ($includeRelative && $requested->format('Ymd') === date('Ymd', strtotime('-1 days'))) {
36e6d88d
A
182 $out = t('Yesterday') . ' - ';
183 }
184 return $out . format_date($requested, false);
185 default:
186 throw new \Exception('Unsupported daily format type');
187 }
188 }
189
190 /**
191 * Get the number of items to display in the RSS feed depending on the given type.
192 *
193 * @param string $type month/week/day
194 *
195 * @return int number of elements
196 *
197 * @throws \Exception Type not supported.
198 */
199 public static function getRssLengthByType(string $type): int
200 {
201 switch ($type) {
202 case static::MONTH:
203 return 12; // 1 year
204 case static::WEEK:
205 return 26; // ~6 months
206 case static::DAY:
207 return 30; // ~1 month
208 default:
209 throw new \Exception('Unsupported daily format type');
210 }
211 }
212}