Improve API for `{time}`
authorTim Düsterhus <duesterhus@woltlab.com>
Thu, 27 Apr 2023 10:47:08 +0000 (12:47 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Thu, 27 Apr 2023 10:54:35 +0000 (12:54 +0200)
wcfsetup/install/files/lib/system/template/plugin/TimeFunctionTemplatePlugin.class.php

index 157065aa03ab2bde44e44bb7b71faf24a936042a..85fc14e016103ef865c7afbdca60426534de4168 100644 (file)
@@ -4,18 +4,21 @@ namespace wcf\system\template\plugin;
 
 use wcf\system\template\TemplateEngine;
 use wcf\system\WCF;
-use wcf\util\DateUtil;
 
 /**
  * Template function plugin which renders a \DateTimeInterface or
  * a unix timestamp into a human readable format.
  *
+ * The timezone will be set to the current user's timezone for all
+ * output types.
+ *
  * Usage:
  *  {time time=$timestamp}
- *  {time time=$timestamp type='plain'}
- *  {time time=$timestamp type='date' format='Y-d-m'}
+ *  {time time=$timestamp type='plainTime'}
+ *  {time time=$timestamp type='plainDate'}
+ *  {time time=$timestamp type='custom' format='Y-m-d'}
  *
- * @author Marcel Werk
+ * @author Tim Duesterhus, Marcel Werk
  * @copyright 2001-2023 WoltLab GmbH
  * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @since 6.0
@@ -24,50 +27,65 @@ final class TimeFunctionTemplatePlugin implements IFunctionTemplatePlugin
 {
     public function execute($tagArgs, TemplateEngine $tplObj): string
     {
-        $time = $tagArgs['time'] ?? '';
-        $type = $tagArgs['type'] ?? '';
+        $time = $tagArgs['time'];
+        $type = $tagArgs['type'] ?? 'interactive';
 
-        if ($time instanceof \DateTimeInterface) {
+        if ($time instanceof \DateTimeImmutable) {
             $dateTime = $time;
-        } else {
+        } else if ($time instanceof \DateTime) {
+            // Ensure we do not modify the original object.
+            $dateTime = \DateTimeImmutable::createFromMutable($time);
+        } else if (\is_string($time) || \is_int($time)) {
             $timestamp = \intval($time);
-            $dateTime = new \DateTimeImmutable('@' . $timestamp);
+            $dateTime = (new \DateTimeImmutable('@' . $timestamp));
+        } else {
+            throw new \InvalidArgumentException("Unknown data type for 'time' given.");
         }
 
-        if ($type === '') {
-            $isFutureDate = $dateTime->getTimestamp() > TIME_NOW;
+        $dateTime = $dateTime->setTimezone(WCF::getUser()->getTimeZone());
+        $locale = WCF::getLanguage()->getLocale();
 
-            $dateAndTime = \IntlDateFormatter::create(
-                WCF::getLanguage()->getLocale(),
-                \IntlDateFormatter::LONG,
-                \IntlDateFormatter::SHORT,
-                WCF::getUser()->getTimeZone()
-            )->format($dateTime);
+        switch ($type) {
+            case 'interactive':
+                $isFutureDate = $dateTime->getTimestamp() > TIME_NOW;
 
-            return \sprintf(
-                '<woltlab-core-date-time date="%s"%s>%s</woltlab-core-date-time>',
-                $dateTime->format('c'),
-                $isFutureDate ? ' static' : '',
-                $dateAndTime
-            );
-        } else if ($type === 'plain') {
-            return \str_replace(
-                '%time%',
-                DateUtil::format($dateTime, DateUtil::TIME_FORMAT),
-                \str_replace(
-                    '%date%',
-                    DateUtil::format($dateTime, DateUtil::DATE_FORMAT),
-                    WCF::getLanguage()->get('wcf.date.dateTimeFormat')
-                )
-            );
-        } else if ($type === 'date') {
-            $format = $tagArgs['format'] ?? '';
-            return DateUtil::format(
-                $dateTime,
-                $format ?: DateUtil::DATE_FORMAT
-            );
-        } else {
-            throw new \InvalidArgumentException("Invalid type '{$type}' given.");
+                $dateAndTime = \IntlDateFormatter::formatObject(
+                    $dateTime,
+                    [
+                        \IntlDateFormatter::LONG,
+                        \IntlDateFormatter::SHORT,
+                    ],
+                    $locale
+                );
+
+                return \sprintf(
+                    '<woltlab-core-date-time date="%s"%s>%s</woltlab-core-date-time>',
+                    $dateTime->format('c'),
+                    $isFutureDate ? ' static' : '',
+                    $dateAndTime
+                );
+            case 'plainTime':
+                return \IntlDateFormatter::formatObject(
+                    $dateTime,
+                    [
+                        \IntlDateFormatter::LONG,
+                        \IntlDateFormatter::SHORT,
+                    ],
+                    $locale
+                );
+            case 'plainDate':
+                return \IntlDateFormatter::formatObject(
+                    $dateTime,
+                    [
+                        \IntlDateFormatter::LONG,
+                        \IntlDateFormatter::NONE,
+                    ],
+                    $locale
+                );
+            case 'custom':
+                return $dateTime->format($tagArgs['format']);
+            default:
+                throw new \InvalidArgumentException("Invalid type '{$type}' given.");
         }
     }
 }