xref: /template/strap/ComboStrap/DateTag.php (revision d8add9b6d6dddc5a1630f969f72a7f91a2da8f6d)
104fd306cSNickeau<?php
204fd306cSNickeau
304fd306cSNickeaunamespace ComboStrap;
404fd306cSNickeau
504fd306cSNickeau
604fd306cSNickeauuse syntax_plugin_combo_variable;
704fd306cSNickeau
804fd306cSNickeau/**
904fd306cSNickeau * Format a date
1090fad5ffSgerardnico * @deprecated use the pipline instead
1104fd306cSNickeau */
1204fd306cSNickeauclass DateTag
1304fd306cSNickeau{
1404fd306cSNickeau    public const CANONICAL = "variable:date";
1504fd306cSNickeau    public const FORMAT_ATTRIBUTE = "format";
1604fd306cSNickeau    public const DATE_ATTRIBUTE = "date";
1704fd306cSNickeau    public const TAG = "date";
1804fd306cSNickeau    /**
1904fd306cSNickeau     * https://www.php.net/manual/en/function.strftime.php
2004fd306cSNickeau     */
2104fd306cSNickeau    public const DEFAULT_FORMAT = "%A, %d %B %Y";
2204fd306cSNickeau
2304fd306cSNickeau
2404fd306cSNickeau    /**
2504fd306cSNickeau     * @param string $date
2604fd306cSNickeau     * @param string $format
2704fd306cSNickeau     * @param string|null $lang
2804fd306cSNickeau     * @return string
2904fd306cSNickeau     * @throws ExceptionBadSyntax
3004fd306cSNickeau     */
3104fd306cSNickeau    public static function formatDateString(string $date, string $format = DateTag::DEFAULT_FORMAT, string $lang = null): string
3204fd306cSNickeau    {
3304fd306cSNickeau        // https://www.php.net/manual/en/function.date.php
3404fd306cSNickeau        // To format dates in other languages, you should use the setlocale() and strftime() functions instead of date().
3504fd306cSNickeau        $localeSeparator = '_';
3604fd306cSNickeau        if ($lang === null) {
3704fd306cSNickeau            try {
3804fd306cSNickeau                $lang = Lang::createFromRequestedMarkup()->getValueOrDefault();
3904fd306cSNickeau            } catch (ExceptionNotFound $e) {
4004fd306cSNickeau                // should never happen but yeah
4104fd306cSNickeau                LogUtility::error("Internal Error: The requested page was not found. We were unable to get the page language. Defaulting to the site language");
4204fd306cSNickeau                $lang = Site::getLang();
4304fd306cSNickeau            }
4404fd306cSNickeau        }
4504fd306cSNickeau        $actualLocale = setlocale(LC_ALL, 0);
4604fd306cSNickeau        try {
4704fd306cSNickeau            if ($lang !== null && trim($lang) !== "") {
4804fd306cSNickeau                // Set local takes several possible locales value
4904fd306cSNickeau                // The lang just works fine but the second argument can be seen in the doc
5004fd306cSNickeau                if (strlen(trim($lang)) === 2) {
51*d8add9b6SNicolas GERARD                    $region = Site::getLanguageRegion();
52*d8add9b6SNicolas GERARD                    $derivedLocale = strtolower($region) . $localeSeparator . strtoupper($lang);
5304fd306cSNickeau                } else {
5404fd306cSNickeau                    $derivedLocale = $lang;
5504fd306cSNickeau                }
5604fd306cSNickeau                $newLocale = setlocale(LC_TIME, $lang, $derivedLocale);
5704fd306cSNickeau                if ($newLocale === false) {
5804fd306cSNickeau                    $newLocale = setlocale(LC_TIME, $lang);
5904fd306cSNickeau                    if ($newLocale === false) {
60*d8add9b6SNicolas GERARD                        LogUtility::warning("The language ($lang) / locale ($derivedLocale) is not available as locale on the server. You can't then format the value ($date) in this language.");
6104fd306cSNickeau                    }
6204fd306cSNickeau                }
6304fd306cSNickeau            }
6404fd306cSNickeau            $date = syntax_plugin_combo_variable::replaceVariablesWithValuesFromContext($date);
6504fd306cSNickeau            $timeStamp = Iso8601Date::createFromString($date)->getDateTime()->getTimestamp();
6604fd306cSNickeau            $formatted = strftime($format, $timeStamp);
6704fd306cSNickeau            if ($formatted === false) {
6804fd306cSNickeau                if ($lang === null) {
6904fd306cSNickeau                    $lang = "";
7004fd306cSNickeau                }
7104fd306cSNickeau                throw new ExceptionBadSyntax("Unable to format the date ($date) with the format ($format) and lang ($lang)");
7204fd306cSNickeau            }
7304fd306cSNickeau            return $formatted;
7404fd306cSNickeau        } finally {
7504fd306cSNickeau            /**
7604fd306cSNickeau             * Restore the locale
7704fd306cSNickeau             */
7804fd306cSNickeau            setlocale(LC_ALL, $actualLocale);
7904fd306cSNickeau        }
8004fd306cSNickeau
8104fd306cSNickeau    }
8204fd306cSNickeau
8304fd306cSNickeau    public static function handleEnterAndSpecial()
8404fd306cSNickeau    {
8504fd306cSNickeau        LogUtility::warning("The date component has been deprecated for the date variable", DateTag::CANONICAL);
8604fd306cSNickeau    }
8704fd306cSNickeau
8804fd306cSNickeau    public static function renderHtml(TagAttributes $tagAttributes): string
8904fd306cSNickeau    {
9004fd306cSNickeau        /**
9104fd306cSNickeau         * Locale
9204fd306cSNickeau         */
9304fd306cSNickeau        $lang = $tagAttributes->getComponentAttributeValue(Lang::PROPERTY_NAME);
9404fd306cSNickeau
9504fd306cSNickeau        /**
9604fd306cSNickeau         * The format
9704fd306cSNickeau         */
9804fd306cSNickeau        $format = $tagAttributes->getValue(DateTag::FORMAT_ATTRIBUTE, DateTag::DEFAULT_FORMAT);
9904fd306cSNickeau        /**
10004fd306cSNickeau         * The date
10104fd306cSNickeau         */
10204fd306cSNickeau        $defaultDateTime = Iso8601Date::createFromNow()->toString();
10304fd306cSNickeau        $date = $tagAttributes->getComponentAttributeValue(DateTag::DATE_ATTRIBUTE, $defaultDateTime);
10404fd306cSNickeau        try {
10504fd306cSNickeau            return DateTag::formatDateString($date, $format, $lang);
10604fd306cSNickeau        } catch (ExceptionBadSyntax $e) {
10704fd306cSNickeau            $message = "Error while formatting a date. Error: {$e->getMessage()}";
10804fd306cSNickeau            LogUtility::error($message, DateTag::CANONICAL);
10904fd306cSNickeau            return LogUtility::wrapInRedForHtml($message);
11004fd306cSNickeau        }
11104fd306cSNickeau    }
11204fd306cSNickeau
11304fd306cSNickeau    public static function handleExit(\Doku_Handler $handler)
11404fd306cSNickeau    {
11504fd306cSNickeau        $callStack = CallStack::createFromHandler($handler);
11604fd306cSNickeau        $openingTag = $callStack->moveToPreviousCorrespondingOpeningCall();
11704fd306cSNickeau        $call = $callStack->next();
11804fd306cSNickeau        if ($call !== false) {
11904fd306cSNickeau            $date = $call->getCapturedContent();
12004fd306cSNickeau            $openingTag->addAttribute(DateTag::DATE_ATTRIBUTE, $date);
12104fd306cSNickeau            $callStack->deleteActualCallAndPrevious();
12204fd306cSNickeau        }
12304fd306cSNickeau    }
12404fd306cSNickeau}
125