diff --git a/Dockerfile.test b/Dockerfile.test
new file mode 100644
index 000000000..3729f6ac9
--- /dev/null
+++ b/Dockerfile.test
@@ -0,0 +1,3 @@
+FROM php:8.4-cli
+RUN apt-get update && apt-get install -y libicu-dev && docker-php-ext-install intl
+WORKDIR /app
\ No newline at end of file
diff --git a/app/Libraries/Token_lib.php b/app/Libraries/Token_lib.php
index cd5b72352..e260240e1 100644
--- a/app/Libraries/Token_lib.php
+++ b/app/Libraries/Token_lib.php
@@ -23,6 +23,7 @@ class Token_lib
'%D' => 'MM/dd/yy',
'%e' => 'd',
'%F' => 'yyyy-MM-dd',
+ '%h' => 'MMM',
'%j' => 'D',
'%m' => 'MM',
'%U' => 'w',
@@ -43,7 +44,6 @@ class Token_lib
'%X' => 'HH:mm:ss',
'%z' => 'ZZZZZ',
'%Z' => 'z',
- '%C' => 'yyyy',
'%g' => 'yy',
'%G' => 'yyyy',
'%u' => 'e',
@@ -51,7 +51,7 @@ class Token_lib
];
private array $validStrftimeFormats = [
- 'a', 'A', 'b', 'B', 'c', 'C', 'd', 'D', 'e', 'F', 'g', 'G',
+ 'a', 'A', 'b', 'B', 'c', 'd', 'D', 'e', 'F', 'g', 'G',
'h', 'H', 'I', 'j', 'm', 'M', 'n', 'p', 'P', 'r', 'R',
'S', 't', 'T', 'u', 'U', 'V', 'w', 'W', 'x', 'X', 'y', 'Y', 'z', 'Z'
];
@@ -92,19 +92,39 @@ class Token_lib
$dateTime = new DateTime();
return preg_replace_callback(
- '/%([a-zA-Z%]|%%)?/',
+ '/%([a-zA-Z%])/',
function ($match) use ($formatter, $dateTime) {
- if ($match[0] === '%%') {
- return '%';
- }
+ $formatChar = $match[1];
- $formatChar = $match[1] ?? '';
-
if ($formatChar === '%') {
return '%';
}
- if ($formatChar === '' || !in_array($formatChar, $this->validStrftimeFormats, true)) {
+ if ($formatChar === 'n') {
+ return "\n";
+ }
+
+ if ($formatChar === 't') {
+ return "\t";
+ }
+
+ if ($formatChar === 'C') {
+ return str_pad((string) intdiv((int) $dateTime->format('Y'), 100), 2, '0', STR_PAD_LEFT);
+ }
+
+ if ($formatChar === 'c') {
+ $formatter->setPattern('yyyy-MM-dd HH:mm:ss');
+ $result = $formatter->format($dateTime);
+ return $result !== false ? $result : $match[0];
+ }
+
+ if ($formatChar === 'x') {
+ $formatter->setPattern('yyyy-MM-dd');
+ $result = $formatter->format($dateTime);
+ return $result !== false ? $result : $match[0];
+ }
+
+ if (!in_array($formatChar, $this->validStrftimeFormats, true)) {
return $match[0];
}
diff --git a/build/.phpunit.cache/test-results b/build/.phpunit.cache/test-results
new file mode 100644
index 000000000..f218fd058
--- /dev/null
+++ b/build/.phpunit.cache/test-results
@@ -0,0 +1 @@
+{"version":2,"defects":{"Token_libTest::testRenderHandlesSpecialCharacters":8,"Token_libTest::testRenderHandlesUnicode":8,"Token_libTest::testRenderHandlesNewLines":8,"Token_libTest::testRenderHandlesTabs":8,"Token_libTest::testRenderHandlesDateAtStart":8,"Token_libTest::testRenderHandlesSqlInjectionAttempt":8,"Token_libTest::testRenderHandlesVeryLongStringWithDate":8,"Token_libTest::testRenderHandlesMultipleDates":8,"Token_libTest::testRenderDoesNotReplaceInvalidFormatSpecifiers":7},"times":{"Token_libTest::testRenderReturnsInputStringWhenNoTokens":0.002,"Token_libTest::testRenderHandlesStringWithPercentNotInDateFormat":0.004,"Token_libTest::testRenderHandlesInvalidDateFormatPercentDashPercent":0.001,"Token_libTest::testRenderHandlesInvalidDateFormatPercentYPercentQPercentBad":0,"Token_libTest::testRenderHandlesStringWithPercentAPercent":0,"Token_libTest::testRenderHandlesExtremelyLongString":0,"Token_libTest::testRenderHandlesStringWithMultiplePercentSymbols":0,"Token_libTest::testRenderHandlesStringWithOnlyPercentSymbol":0,"Token_libTest::testRenderPreservesTextWithValidDateTokensAndNoOtherTokens":0,"Token_libTest::testRenderHandlesEmptyString":0,"Token_libTest::testScanExtractsTokens":0,"Token_libTest::testScanExtractsTokensWithLength":0,"Token_libTest::testScanReturnsEmptyArrayForNoTokens":0,"Token_libTest::testRenderHandlesConsecutivePercentSigns":0,"Token_libTest::testRenderHandlesEscapedPercentSigns":0,"Token_libTest::testRenderHandlesSpecialCharacters":0.005,"Token_libTest::testRenderHandlesUnicode":0,"Token_libTest::testRenderHandlesNewLines":0,"Token_libTest::testRenderHandlesTabs":0,"Token_libTest::testRenderHandlesUnclosedBraces":0,"Token_libTest::testRenderHandlesUnopenedBraces":0,"Token_libTest::testRenderHandlesDateAtStart":0,"Token_libTest::testRenderHandlesSqlInjectionAttempt":0,"Token_libTest::testRenderHandlesVeryLongStringWithDate":0,"Token_libTest::testRenderHandlesMultipleDates":0,"Token_libTest::testRenderHandlesValidYearFormat":0,"Token_libTest::testRenderHandlesValidMonthFormat":0,"Token_libTest::testRenderHandlesValidDayFormat":0,"Token_libTest::testRenderHandlesFullDateFormat":0,"Token_libTest::testRenderHandlesPercentB":0,"Token_libTest::testRenderHandlesPercentA":0,"Token_libTest::testRenderHandlesComplexPercentFormat":0,"Token_libTest::testRenderDoesNotReplaceInvalidFormatSpecifiers":0,"Token_libTest::testScanWorksWithMixedContent":0,"Token_libTest::testRenderReplacesTimezoneFormat":0,"Tests\\Libraries\\Token_libTest::testRenderReturnsInputStringWhenNoTokens":0.001,"Tests\\Libraries\\Token_libTest::testRenderHandlesStringWithPercentNotInDateFormat":0.004,"Tests\\Libraries\\Token_libTest::testRenderHandlesInvalidDateFormatPercentDashPercent":0.001,"Tests\\Libraries\\Token_libTest::testRenderHandlesInvalidDateFormatPercentYPercentQPercentBad":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesStringWithPercentAPercent":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesExtremelyLongString":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesStringWithMultiplePercentSymbols":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesStringWithOnlyPercentSymbol":0,"Tests\\Libraries\\Token_libTest::testRenderPreservesTextWithValidDateTokensAndNoOtherTokens":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesEmptyString":0,"Tests\\Libraries\\Token_libTest::testScanExtractsTokens":0,"Tests\\Libraries\\Token_libTest::testScanExtractsTokensWithLength":0,"Tests\\Libraries\\Token_libTest::testScanReturnsEmptyArrayForNoTokens":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesConsecutivePercentSigns":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesEscapedPercentSigns":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesUnclosedBraces":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesUnopenedBraces":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesVeryLongStringWithDate":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesMultipleDates":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesValidYearFormat":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesValidMonthFormat":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesValidDayFormat":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesFullDateFormat":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesPercentB":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesPercentA":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesComplexPercentFormat":0,"Tests\\Libraries\\Token_libTest::testRenderDoesNotReplaceInvalidFormatSpecifiers":0,"Tests\\Libraries\\Token_libTest::testRenderReplacesTimezoneFormat":0,"Tests\\Libraries\\Token_libTest::testScanWorksWithMixedContent":0}}
\ No newline at end of file
diff --git a/build/logs/logfile.xml b/build/logs/logfile.xml
new file mode 100644
index 000000000..0620ddbf0
--- /dev/null
+++ b/build/logs/logfile.xml
@@ -0,0 +1,38 @@
+
+