1<?php 2 3namespace ComboStrap; 4 5 6use syntax_plugin_combo_variable; 7 8/** 9 * Format a date 10 * @deprecated use the pipline instead 11 */ 12class DateTag 13{ 14 public const CANONICAL = "variable:date"; 15 public const FORMAT_ATTRIBUTE = "format"; 16 public const DATE_ATTRIBUTE = "date"; 17 public const TAG = "date"; 18 /** 19 * https://www.php.net/manual/en/function.strftime.php 20 */ 21 public const DEFAULT_FORMAT = "%A, %d %B %Y"; 22 23 24 /** 25 * @param string $date 26 * @param string $format 27 * @param string|null $lang 28 * @return string 29 * @throws ExceptionBadSyntax 30 */ 31 public static function formatDateString(string $date, string $format = DateTag::DEFAULT_FORMAT, string $lang = null): string 32 { 33 // https://www.php.net/manual/en/function.date.php 34 // To format dates in other languages, you should use the setlocale() and strftime() functions instead of date(). 35 $localeSeparator = '_'; 36 if ($lang === null) { 37 try { 38 $lang = Lang::createFromRequestedMarkup()->getValueOrDefault(); 39 } catch (ExceptionNotFound $e) { 40 // should never happen but yeah 41 LogUtility::error("Internal Error: The requested page was not found. We were unable to get the page language. Defaulting to the site language"); 42 $lang = Site::getLang(); 43 } 44 } 45 $actualLocale = setlocale(LC_ALL, 0); 46 try { 47 if ($lang !== null && trim($lang) !== "") { 48 // Set local takes several possible locales value 49 // The lang just works fine but the second argument can be seen in the doc 50 if (strlen(trim($lang)) === 2) { 51 $region = Site::getLanguageRegion(); 52 $derivedLocale = strtolower($region) . $localeSeparator . strtoupper($lang); 53 } else { 54 $derivedLocale = $lang; 55 } 56 $newLocale = setlocale(LC_TIME, $lang, $derivedLocale); 57 if ($newLocale === false) { 58 $newLocale = setlocale(LC_TIME, $lang); 59 if ($newLocale === false) { 60 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."); 61 } 62 } 63 } 64 $date = syntax_plugin_combo_variable::replaceVariablesWithValuesFromContext($date); 65 $timeStamp = Iso8601Date::createFromString($date)->getDateTime()->getTimestamp(); 66 $formatted = strftime($format, $timeStamp); 67 if ($formatted === false) { 68 if ($lang === null) { 69 $lang = ""; 70 } 71 throw new ExceptionBadSyntax("Unable to format the date ($date) with the format ($format) and lang ($lang)"); 72 } 73 return $formatted; 74 } finally { 75 /** 76 * Restore the locale 77 */ 78 setlocale(LC_ALL, $actualLocale); 79 } 80 81 } 82 83 public static function handleEnterAndSpecial() 84 { 85 LogUtility::warning("The date component has been deprecated for the date variable", DateTag::CANONICAL); 86 } 87 88 public static function renderHtml(TagAttributes $tagAttributes): string 89 { 90 /** 91 * Locale 92 */ 93 $lang = $tagAttributes->getComponentAttributeValue(Lang::PROPERTY_NAME); 94 95 /** 96 * The format 97 */ 98 $format = $tagAttributes->getValue(DateTag::FORMAT_ATTRIBUTE, DateTag::DEFAULT_FORMAT); 99 /** 100 * The date 101 */ 102 $defaultDateTime = Iso8601Date::createFromNow()->toString(); 103 $date = $tagAttributes->getComponentAttributeValue(DateTag::DATE_ATTRIBUTE, $defaultDateTime); 104 try { 105 return DateTag::formatDateString($date, $format, $lang); 106 } catch (ExceptionBadSyntax $e) { 107 $message = "Error while formatting a date. Error: {$e->getMessage()}"; 108 LogUtility::error($message, DateTag::CANONICAL); 109 return LogUtility::wrapInRedForHtml($message); 110 } 111 } 112 113 public static function handleExit(\Doku_Handler $handler) 114 { 115 $callStack = CallStack::createFromHandler($handler); 116 $openingTag = $callStack->moveToPreviousCorrespondingOpeningCall(); 117 $call = $callStack->next(); 118 if ($call !== false) { 119 $date = $call->getCapturedContent(); 120 $openingTag->addAttribute(DateTag::DATE_ATTRIBUTE, $date); 121 $callStack->deleteActualCallAndPrevious(); 122 } 123 } 124} 125