GH-18345: adding Locale::isRightToLeft.

Checks is the locale is written left to right.
It makes sure all the needed likely subtags are included (maximization)
then determines the direction by known matches.

close GH-18351
This commit is contained in:
David Carlier 2025-04-18 19:10:23 +01:00
parent ba83d5daeb
commit fcd0f72cdd
No known key found for this signature in database
GPG key ID: 2FB76A8CE6CD2B41
8 changed files with 59 additions and 2 deletions

2
NEWS
View file

@ -85,6 +85,8 @@ PHP NEWS
with uninitialised classes or clone failure. (David Carlier) with uninitialised classes or clone failure. (David Carlier)
. Added DECIMAL_COMPACT_SHORT/DECIMAL_COMPACT_LONG for NumberFormatter class. . Added DECIMAL_COMPACT_SHORT/DECIMAL_COMPACT_LONG for NumberFormatter class.
(BogdanUngureanu) (BogdanUngureanu)
. Added Locale::isRightToLeft to check if a locale is written right to left.
(David Carlier)
- MySQLi: - MySQLi:
. Fixed bugs GH-17900 and GH-8084 (calling mysqli::__construct twice). . Fixed bugs GH-17900 and GH-8084 (calling mysqli::__construct twice).

View file

@ -309,6 +309,10 @@ PHP 8.5 UPGRADE NOTES
. Added enchant_dict_remove() to put a word on the exclusion list and . Added enchant_dict_remove() to put a word on the exclusion list and
remove it from the session dictionary. remove it from the session dictionary.
- Intl:
. Added locale_is_right_to_left/Locale::isRightToLeft, returns true if
the locale is written right to left (after its enrichment with likely subtags).
- Pdo\Sqlite: - Pdo\Sqlite:
. Added support for Pdo\Sqlite::setAuthorizer(), which is the equivalent of . Added support for Pdo\Sqlite::setAuthorizer(), which is the equivalent of
SQLite3::setAuthorizer(). The only interface difference is that the SQLite3::setAuthorizer(). The only interface difference is that the

View file

@ -133,4 +133,9 @@ class Locale
* @alias locale_accept_from_http * @alias locale_accept_from_http
*/ */
public static function acceptFromHttp(string $header): string|false {} public static function acceptFromHttp(string $header): string|false {}
/**
* @alias locale_is_right_to_left
*/
public static function isRightToLeft(string $locale): bool {}
} }

View file

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead. /* This is a generated file, edit the .stub.php file instead.
* Stub hash: 59861342e0075231d2a576afb2d5df6973d70684 */ * Stub hash: f09cfd61f3e20576c7f6d5da17a6d9c009d6ab64 */
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Locale_getDefault, 0, 0, IS_STRING, 0) ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Locale_getDefault, 0, 0, IS_STRING, 0)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
@ -62,6 +62,10 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_Locale_acceptFro
ZEND_ARG_TYPE_INFO(0, header, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, header, IS_STRING, 0)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Locale_isRightToLeft, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0)
ZEND_END_ARG_INFO()
ZEND_FUNCTION(locale_get_default); ZEND_FUNCTION(locale_get_default);
ZEND_FUNCTION(locale_set_default); ZEND_FUNCTION(locale_set_default);
ZEND_FUNCTION(locale_get_primary_language); ZEND_FUNCTION(locale_get_primary_language);
@ -80,6 +84,7 @@ ZEND_FUNCTION(locale_filter_matches);
ZEND_FUNCTION(locale_lookup); ZEND_FUNCTION(locale_lookup);
ZEND_FUNCTION(locale_canonicalize); ZEND_FUNCTION(locale_canonicalize);
ZEND_FUNCTION(locale_accept_from_http); ZEND_FUNCTION(locale_accept_from_http);
ZEND_FUNCTION(locale_is_right_to_left);
static const zend_function_entry class_Locale_methods[] = { static const zend_function_entry class_Locale_methods[] = {
ZEND_RAW_FENTRY("getDefault", zif_locale_get_default, arginfo_class_Locale_getDefault, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL) ZEND_RAW_FENTRY("getDefault", zif_locale_get_default, arginfo_class_Locale_getDefault, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL)
@ -100,6 +105,7 @@ static const zend_function_entry class_Locale_methods[] = {
ZEND_RAW_FENTRY("lookup", zif_locale_lookup, arginfo_class_Locale_lookup, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL) ZEND_RAW_FENTRY("lookup", zif_locale_lookup, arginfo_class_Locale_lookup, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL)
ZEND_RAW_FENTRY("canonicalize", zif_locale_canonicalize, arginfo_class_Locale_canonicalize, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL) ZEND_RAW_FENTRY("canonicalize", zif_locale_canonicalize, arginfo_class_Locale_canonicalize, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL)
ZEND_RAW_FENTRY("acceptFromHttp", zif_locale_accept_from_http, arginfo_class_Locale_acceptFromHttp, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL) ZEND_RAW_FENTRY("acceptFromHttp", zif_locale_accept_from_http, arginfo_class_Locale_acceptFromHttp, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL)
ZEND_RAW_FENTRY("isRightToLeft", zif_locale_is_right_to_left, arginfo_class_Locale_isRightToLeft, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC, NULL, NULL)
ZEND_FE_END ZEND_FE_END
}; };

View file

@ -1619,3 +1619,19 @@ PHP_FUNCTION(locale_accept_from_http)
RETURN_STRINGL(resultLocale, len); RETURN_STRINGL(resultLocale, len);
} }
/* }}} */ /* }}} */
PHP_FUNCTION(locale_is_right_to_left)
{
char *locale;
size_t locale_len;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_STRING(locale, locale_len)
ZEND_PARSE_PARAMETERS_END();
if (!locale_len) {
locale = (char *)intl_locale_get_default();
}
RETURN_BOOL(uloc_isRightToLeft(locale));
}

View file

@ -501,6 +501,8 @@ function locale_lookup(array $languageTag, string $locale, bool $canonicalize =
function locale_accept_from_http(string $header): string|false {} function locale_accept_from_http(string $header): string|false {}
function locale_is_right_to_left(string $locale): bool {}
/* msgformat */ /* msgformat */
function msgfmt_create(string $locale, string $pattern): ?MessageFormatter {} function msgfmt_create(string $locale, string $pattern): ?MessageFormatter {}

View file

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead. /* This is a generated file, edit the .stub.php file instead.
* Stub hash: 168eabfdcbf29189f2327448f104ea98752d1c5a */ * Stub hash: 4fb44fc170e74af2e9fb52c5a1029004f708fcda */
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_intlcal_create_instance, 0, 0, IntlCalendar, 1) ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_intlcal_create_instance, 0, 0, IntlCalendar, 1)
ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timezone, "null") ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timezone, "null")
@ -566,6 +566,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_locale_accept_from_http, 0, 1, M
ZEND_ARG_TYPE_INFO(0, header, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, header, IS_STRING, 0)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_locale_is_right_to_left, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_msgfmt_create, 0, 2, MessageFormatter, 1) ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_msgfmt_create, 0, 2, MessageFormatter, 1)
ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, pattern, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, pattern, IS_STRING, 0)
@ -920,6 +924,7 @@ ZEND_FUNCTION(locale_filter_matches);
ZEND_FUNCTION(locale_canonicalize); ZEND_FUNCTION(locale_canonicalize);
ZEND_FUNCTION(locale_lookup); ZEND_FUNCTION(locale_lookup);
ZEND_FUNCTION(locale_accept_from_http); ZEND_FUNCTION(locale_accept_from_http);
ZEND_FUNCTION(locale_is_right_to_left);
ZEND_FUNCTION(msgfmt_create); ZEND_FUNCTION(msgfmt_create);
ZEND_FUNCTION(msgfmt_format); ZEND_FUNCTION(msgfmt_format);
ZEND_FUNCTION(msgfmt_format_message); ZEND_FUNCTION(msgfmt_format_message);
@ -1107,6 +1112,7 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(locale_canonicalize, arginfo_locale_canonicalize) ZEND_FE(locale_canonicalize, arginfo_locale_canonicalize)
ZEND_FE(locale_lookup, arginfo_locale_lookup) ZEND_FE(locale_lookup, arginfo_locale_lookup)
ZEND_FE(locale_accept_from_http, arginfo_locale_accept_from_http) ZEND_FE(locale_accept_from_http, arginfo_locale_accept_from_http)
ZEND_FE(locale_is_right_to_left, arginfo_locale_is_right_to_left)
ZEND_FE(msgfmt_create, arginfo_msgfmt_create) ZEND_FE(msgfmt_create, arginfo_msgfmt_create)
ZEND_FE(msgfmt_format, arginfo_msgfmt_format) ZEND_FE(msgfmt_format, arginfo_msgfmt_format)
ZEND_FE(msgfmt_format_message, arginfo_msgfmt_format_message) ZEND_FE(msgfmt_format_message, arginfo_msgfmt_format_message)

View file

@ -0,0 +1,16 @@
--TEST--
locale_is_right_to_left
--EXTENSIONS--
intl
--FILE--
<?php
var_dump(Locale::isRightToLeft("en-US"));
var_dump(Locale::isRightToLeft("\INVALID\\"));
var_dump(Locale::isRightToLeft(""));
var_dump(Locale::isRightToLeft("ar"));
?>
--EXPECT--
bool(false)
bool(false)
bool(false)
bool(true)