Skip to content

Commit d55c59b

Browse files
Add error methods, update error messages and tests
1 parent 8519a01 commit d55c59b

File tree

7 files changed

+636
-24
lines changed

7 files changed

+636
-24
lines changed

ext/intl/rangeformatter/rangeformatter.stub.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @strict-properties
88
*/
99
final class IntlNumberRangeFormatter {
10-
10+
#if U_ICU_VERSION_MAJOR_NUM >= 63
1111
/** @cvalue UNUM_RANGE_COLLAPSE_AUTO */
1212
public const int COLLAPSE_AUTO = UNKNOWN;
1313

@@ -31,10 +31,31 @@ final class IntlNumberRangeFormatter {
3131

3232
/** @cvalue UNUM_IDENTITY_FALLBACK_RANGE */
3333
public const int IDENTITY_FALLBACK_RANGE = UNKNOWN;
34+
#else
35+
public const int COLLAPSE_AUTO = 0;
36+
37+
public const int COLLAPSE_NONE = 1;
38+
39+
public const int COLLAPSE_UNIT = 2;
40+
41+
public const int COLLAPSE_ALL = 3;
42+
43+
public const int IDENTITY_FALLBACK_SINGLE_VALUE = 0;
44+
45+
public const int IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE = 1;
46+
47+
public const int IDENTITY_FALLBACK_APPROXIMATELY = 2;
48+
49+
public const int IDENTITY_FALLBACK_RANGE = 3;
50+
#endif
3451

3552
private function __construct() {}
3653

3754
public static function createFromSkeleton(string $skeleton, string $locale, int $collapse, int $identityFallback): IntlNumberRangeFormatter {}
3855

3956
public function format(float|int $start, float|int $end): string {}
57+
58+
public function getErrorCode(): int {}
59+
60+
public function getErrorMessage(): string {}
4061
}

ext/intl/rangeformatter/rangeformatter_arginfo.h

Lines changed: 63 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/intl/rangeformatter/rangeformatter_class.cpp

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020

2121
extern "C" {
2222
#include "php.h"
23+
#include "zend_API.h"
24+
#include "../intl_common.h"
25+
#include "../intl_error.h"
2326
#include "../php_intl.h"
2427
#include "../intl_data.h"
2528
#include "rangeformatter_arginfo.h"
@@ -45,16 +48,28 @@ zend_object *IntlNumberRangeFormatter_object_create(zend_class_entry *ce)
4548
zend_object_std_init(&intern->zo, ce);
4649
object_properties_init(&intern->zo, ce);
4750

51+
// Initialize rangeformatter_data structure
52+
intl_error_init(&intern->nrf_data.error);
53+
intern->nrf_data.unumrf = nullptr;
54+
55+
intern->zo.handlers = &rangeformatter_handlers;
56+
4857
return &intern->zo;
4958
}
5059

5160
U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, __construct)
5261
{
53-
62+
ZEND_PARSE_PARAMETERS_NONE();
63+
zend_throw_error(NULL, "Cannot directly construct %s, use createFromSkeleton method instead", ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name));
5464
}
5565

5666
U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton)
5767
{
68+
#if U_ICU_VERSION_MAJOR_NUM < 63
69+
zend_throw_error(NULL, "IntlNumberRangeFormatter is not available in ICU 62 and earlier");
70+
RETURN_THROWS();
71+
#endif
72+
5873
char* skeleton;
5974
char* locale;
6075
size_t locale_len;
@@ -74,12 +89,12 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton)
7489
}
7590

7691
if (skeleton_len == 0) {
77-
zend_argument_value_error(1, "Skeleton string cannot be empty");
92+
zend_argument_must_not_be_empty_error(1);
7893
RETURN_THROWS();
7994
}
8095

8196
if (locale_len > INTL_MAX_LOCALE_LEN) {
82-
zend_argument_value_error(2, "Locale string too long, should be no longer than %d characters", INTL_MAX_LOCALE_LEN);
97+
zend_argument_value_error(2, "must be no longer than %d characters", INTL_MAX_LOCALE_LEN);
8398
RETURN_THROWS();
8499
}
85100

@@ -89,20 +104,26 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton)
89104
}
90105

91106
if (collapse != UNUM_RANGE_COLLAPSE_AUTO && collapse != UNUM_RANGE_COLLAPSE_NONE && collapse != UNUM_RANGE_COLLAPSE_UNIT && collapse != UNUM_RANGE_COLLAPSE_ALL) {
92-
zend_argument_value_error(3, "Invalid collapse value");
107+
zend_argument_value_error(3, "must be one of IntlNumberRangeFormatter::COLLAPSE_AUTO, IntlNumberRangeFormatter::COLLAPSE_NONE, IntlNumberRangeFormatter::COLLAPSE_UNIT, or IntlNumberRangeFormatter::COLLAPSE_ALL");
93108
RETURN_THROWS();
94109
}
95110

96111
if (identityFallback != UNUM_IDENTITY_FALLBACK_SINGLE_VALUE && identityFallback != UNUM_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE && identityFallback != UNUM_IDENTITY_FALLBACK_APPROXIMATELY && identityFallback != UNUM_IDENTITY_FALLBACK_RANGE) {
97-
zend_argument_value_error(4, "Invalid identity fallback value");
112+
zend_argument_value_error(4, "must be one of IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY, or IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE");
98113
RETURN_THROWS();
99114
}
100115

101-
UErrorCode error = U_ZERO_ERROR;
116+
UErrorCode status = U_ZERO_ERROR;
102117

103118
UnicodeString skeleton_ustr(skeleton, skeleton_len);
104119

105-
UnlocalizedNumberFormatter nf = NumberFormatter::forSkeleton(skeleton_ustr, error);
120+
UnlocalizedNumberFormatter nf = NumberFormatter::forSkeleton(skeleton_ustr, status);
121+
122+
if (U_FAILURE(status)) {
123+
intl_error_set(NULL, status, "Failed to create the number skeleton", 0);
124+
zend_throw_exception(IntlException_ce_ptr, "Failed to create the number skeleton", 0);
125+
RETURN_THROWS();
126+
}
106127

107128
LocalizedNumberRangeFormatter* nrf = new LocalizedNumberRangeFormatter(
108129
NumberRangeFormatter::with()
@@ -113,7 +134,6 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton)
113134
);
114135

115136
zend_object* obj = IntlNumberRangeFormatter_object_create(class_entry_IntlNumberRangeFormatter);
116-
obj->handlers = &rangeformatter_handlers;
117137

118138
RANGEFORMATTER_OBJECT(php_intl_numberrangeformatter_fetch_object(obj)) = nrf;
119139

@@ -123,37 +143,58 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton)
123143

124144
U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, format)
125145
{
126-
double start;
127-
double end;
146+
zval *start;
147+
zval *end;
128148

129149
IntlNumberRangeFormatter_object* obj = Z_INTL_RANGEFORMATTER_P(ZEND_THIS);
130150

131151
ZEND_PARSE_PARAMETERS_START(2, 2)
132-
Z_PARAM_DOUBLE(start)
133-
Z_PARAM_DOUBLE(end)
152+
Z_PARAM_NUMBER(start)
153+
Z_PARAM_NUMBER(end)
134154
ZEND_PARSE_PARAMETERS_END();
135155

136156
UErrorCode error = U_ZERO_ERROR;
137157

138-
UnicodeString result = RANGEFORMATTER_OBJECT(obj)->formatFormattableRange(start, end, error).toString(error);
158+
icu::Formattable start_formattable(Z_TYPE_P(start) == IS_DOUBLE ? Z_DVAL_P(start) : Z_LVAL_P(start));
159+
icu::Formattable end_formattable(Z_TYPE_P(end) == IS_DOUBLE ? Z_DVAL_P(end) : Z_LVAL_P(end));
160+
161+
UnicodeString result = RANGEFORMATTER_OBJECT(obj)->formatFormattableRange(start_formattable, end_formattable, error).toString(error);
139162

140163
if (U_FAILURE(error)) {
141164
intl_error_set(NULL, error, "Failed to format number range", 0);
142-
143-
return;
165+
zend_throw_exception(IntlException_ce_ptr, "Failed to format number range", 0);
166+
RETURN_THROWS();
144167
}
145168

146169
zend_string *ret = intl_charFromString(result, &error);
147170

148-
if (!ret) {
171+
if (U_FAILURE(error)) {
149172
intl_error_set(NULL, error, "Failed to convert result to UTF-8", 0);
150-
// RETVAL_FALSE;
151-
return;
173+
zend_throw_exception(IntlException_ce_ptr, "Failed to convert result to UTF-8", 0);
174+
RETURN_THROWS();
152175
}
153176

154177
RETVAL_NEW_STR(ret);
155178
}
156179

180+
U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, getErrorCode)
181+
{
182+
ZEND_PARSE_PARAMETERS_NONE();
183+
184+
IntlNumberRangeFormatter_object* obj = Z_INTL_RANGEFORMATTER_P(ZEND_THIS);
185+
186+
RETURN_LONG(intl_error_get_code(&obj->nrf_data.error));
187+
}
188+
189+
U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, getErrorMessage)
190+
{
191+
ZEND_PARSE_PARAMETERS_NONE();
192+
193+
IntlNumberRangeFormatter_object* obj = Z_INTL_RANGEFORMATTER_P(ZEND_THIS);
194+
195+
RETURN_STR(intl_error_get_message(&obj->nrf_data.error));
196+
}
197+
157198
void IntlNumberRangeFormatter_object_free(zend_object *object)
158199
{
159200
IntlNumberRangeFormatter_object* nfo = php_intl_numberrangeformatter_fetch_object(object);

0 commit comments

Comments
 (0)