Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ PHP NEWS
. Added gmp_powm_sec(). (Weilin Du)

- Intl:
. Added static methods IntlDatePatternGenerator::getSkeleton() and
IntlDatePatternGenerator::getBaseSkeleton(). (Weilin Du)
. Fixed Collator::sort(), collator_sort(), Collator::asort(), and
collator_asort() to report UTF-8/UTF-16 conversion errors through the intl
error handler instead of emitting a warning and continuing with an empty
Expand Down
5 changes: 5 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,9 @@ PHP 8.6 UPGRADE NOTES
on official Windows builds using MPIR.

- Intl:
. Added the static methods IntlDatePatternGenerator::getSkeleton() and
IntlDatePatternGenerator::getBaseSkeleton() to generate the unique skeleton
and base skeleton for a date/time pattern.
. Added Locale::getDisplayKeyword() and Locale::getDisplayKeywordValue(),
with the alias of locale_get_display_keyword() and
locale_get_display_keyword_value() respectively.
Expand Down Expand Up @@ -489,6 +492,8 @@ PHP 8.6 UPGRADE NOTES
- Intl:
. grapheme_strrev()
RFC: https://wiki.php.net/rfc/grapheme_strrev
. IntlDatePatternGenerator::getSkeleton()
. IntlDatePatternGenerator::getBaseSkeleton()
. Locale::getDisplayKeyword() and Locale::getDisplayKeywordValue()
RFC: https://wiki.php.net/rfc/getdisplaykeyword_and_getdisplaykeywordvalue
. SpoofChecker::areBidiConfusable()
Expand Down
4 changes: 4 additions & 0 deletions ext/intl/dateformat/datepatterngenerator.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ public function __construct(?string $locale = null) {}
public static function create(?string $locale = null): ?IntlDatePatternGenerator {}

public function getBestPattern(string $skeleton): string|false {}

public static function getSkeleton(string $pattern): string|false {}

public static function getBaseSkeleton(string $pattern): string|false {}
}
12 changes: 11 additions & 1 deletion ext/intl/dateformat/datepatterngenerator_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 48 additions & 1 deletion ext/intl/dateformat/datepatterngenerator_methods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ U_CFUNC PHP_METHOD( IntlDatePatternGenerator, getBestPattern )

INTL_METHOD_CHECK_STATUS(dtpgo, "Skeleton is not a valid UTF-8 string");

UnicodeString skeleton = dtpgo->dtpg->getSkeleton(skeleton_uncleaned, DTPATTERNGEN_ERROR_CODE(dtpgo));
UnicodeString skeleton = DateTimePatternGenerator::staticGetSkeleton(
skeleton_uncleaned, DTPATTERNGEN_ERROR_CODE(dtpgo));

INTL_METHOD_CHECK_STATUS(dtpgo, "Error getting cleaned skeleton");

Expand All @@ -132,3 +133,49 @@ U_CFUNC PHP_METHOD( IntlDatePatternGenerator, getBestPattern )

RETVAL_STR(u8str);
}

template <typename F>
static void dtpg_get_skeleton(INTERNAL_FUNCTION_PARAMETERS, F&& skeletonfn, const char *errmsg)
{
zend_string *pattern_str;
UnicodeString pattern;
UErrorCode status = U_ZERO_ERROR;

intl_error_reset(NULL);

ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_STR(pattern_str)
ZEND_PARSE_PARAMETERS_END();

intl_stringFromChar(pattern, ZSTR_VAL(pattern_str), ZSTR_LEN(pattern_str), &status);

INTL_CHECK_STATUS(status, "Pattern is not a valid UTF-8 string");

UnicodeString result = skeletonfn(pattern, status);

INTL_CHECK_STATUS(status, errmsg);

zend_string *u8str = intl_charFromString(result, &status);

INTL_CHECK_STATUS(status, "Error converting result to UTF-8");

RETVAL_STR(u8str);
}

U_CFUNC PHP_METHOD(IntlDatePatternGenerator, getSkeleton)
{
dtpg_get_skeleton(INTERNAL_FUNCTION_PARAM_PASSTHRU,
[](const UnicodeString &pattern, UErrorCode &status) {
return DateTimePatternGenerator::staticGetSkeleton(pattern, status);
},
"Error getting skeleton");
}

U_CFUNC PHP_METHOD(IntlDatePatternGenerator, getBaseSkeleton)
{
dtpg_get_skeleton(INTERNAL_FUNCTION_PARAM_PASSTHRU,
[](const UnicodeString &pattern, UErrorCode &status) {
return DateTimePatternGenerator::staticGetBaseSkeleton(pattern, status);
},
"Error getting base skeleton");
}
48 changes: 48 additions & 0 deletions ext/intl/tests/datepatterngenerator_get_skeleton.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
--TEST--
IntlDatePatternGenerator::getSkeleton() and getBaseSkeleton()
--EXTENSIONS--
intl
--FILE--
<?php

var_dump(IntlDatePatternGenerator::getSkeleton("dd/MMM"));
var_dump(IntlDatePatternGenerator::getSkeleton("MMM-dd"));
var_dump(IntlDatePatternGenerator::getBaseSkeleton("dd/MMM"));
var_dump(IntlDatePatternGenerator::getBaseSkeleton("MMM-dd"));
var_dump(IntlDatePatternGenerator::getSkeleton(""));
var_dump(IntlDatePatternGenerator::getBaseSkeleton(""));

$patterns = [
"'at' HH:mm",
"y年M月d日",
"yyyy-MM-dd",
"MMMMM",
"MMM",
"HH:mm:ss zzz dd/MM/y",
"'at HH:mm",
];

foreach ($patterns as $pattern) {
printf(
"%s => [%s] [%s]\n",
$pattern,
IntlDatePatternGenerator::getSkeleton($pattern),
IntlDatePatternGenerator::getBaseSkeleton($pattern),
);
}

?>
--EXPECT--
string(5) "MMMdd"
string(5) "MMMdd"
string(4) "MMMd"
string(4) "MMMd"
string(0) ""
string(0) ""
'at' HH:mm => [HHmm] [Hm]
y年M月d日 => [yMd] [yMd]
yyyy-MM-dd => [yyyyMMdd] [yMd]
MMMMM => [MMMMM] [MMMMM]
MMM => [MMM] [MMM]
HH:mm:ss zzz dd/MM/y => [yMMddHHmmsszzz] [yMdHmsz]
'at HH:mm => [] []
18 changes: 18 additions & 0 deletions ext/intl/tests/datepatterngenerator_skeleton_error.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--TEST--
IntlDatePatternGenerator::getSkeleton() and getBaseSkeleton(): errors
--EXTENSIONS--
intl
--FILE--
<?php

foreach (["getSkeleton", "getBaseSkeleton"] as $method) {
var_dump(IntlDatePatternGenerator::$method("dd/MMM\x80"));
echo intl_get_error_message(), "\n";
}

?>
--EXPECT--
bool(false)
IntlDatePatternGenerator::getSkeleton(): Pattern is not a valid UTF-8 string: U_INVALID_CHAR_FOUND
bool(false)
IntlDatePatternGenerator::getBaseSkeleton(): Pattern is not a valid UTF-8 string: U_INVALID_CHAR_FOUND
Loading