diff --git a/ext/date/php_date.c b/ext/date/php_date.c index e74a1ec22fc32..366249e7b5c78 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -4124,28 +4124,16 @@ static int date_period_initialize(timelib_time **st, timelib_time **et, timelib_ return retval; } /* }}} */ -/* {{{ Creates new DatePeriod object. */ -PHP_METHOD(DatePeriod, __construct) -{ - php_period_obj *dpobj; - php_date_obj *dateobj; - zval *start, *end = NULL, *interval; - zend_long recurrences = 0, options = 0; - char *isostr = NULL; - size_t isostr_len = 0; +static void construct_date_period( + INTERNAL_FUNCTION_PARAMETERS, zval *object, zval *start, zval *end, zval *interval, zend_long recurrences, + zend_long options, char *isostr, size_t isostr_len +) { + php_period_obj *dpobj; + php_date_obj *dateobj; timelib_time *clone; zend_error_handling error_handling; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "OOl|l", &start, date_ce_interface, &interval, date_ce_interval, &recurrences, &options) == FAILURE) { - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "OOO|l", &start, date_ce_interface, &interval, date_ce_interval, &end, date_ce_interface, &options) == FAILURE) { - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "s|l", &isostr, &isostr_len, &options) == FAILURE) { - zend_type_error("DatePeriod::__construct() accepts (DateTimeInterface, DateInterval, int [, int]), or (DateTimeInterface, DateInterval, DateTime [, int]), or (string [, int]) as arguments"); - RETURN_THROWS(); - } - } - } - - dpobj = Z_PHPPERIOD_P(ZEND_THIS); + dpobj = Z_PHPPERIOD_P(object); dpobj->current = NULL; if (isostr) { @@ -4225,7 +4213,90 @@ PHP_METHOD(DatePeriod, __construct) dpobj->initialized = 1; } -/* }}} */ + +PHP_METHOD(DatePeriod, createFromRecurrences) +{ + zval *start, *interval; + zend_long recurrences, options = 0; + zval object; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OOl|l", &start, date_ce_interface, &interval, date_ce_interval, &recurrences, &options) == FAILURE) { + RETURN_THROWS(); + } + + object_init_ex(&object, zend_get_called_scope(execute_data)); + + construct_date_period(INTERNAL_FUNCTION_PARAM_PASSTHRU, &object, start, NULL, interval, recurrences, options, NULL, 0); + if (EG(exception)) { + zval_ptr_dtor(&object); + RETURN_THROWS(); + } + + ZVAL_COPY_VALUE(return_value, &object); +} + +PHP_METHOD(DatePeriod, createFromDates) +{ + zval *start, *end, *interval; + zend_long options = 0; + zval object; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OOO|l", &start, date_ce_interface, &interval, date_ce_interval, &end, date_ce_interface, &options) == FAILURE) { + RETURN_THROWS(); + } + + object_init_ex(&object, zend_get_called_scope(execute_data)); + + construct_date_period(INTERNAL_FUNCTION_PARAM_PASSTHRU, &object, start, end, interval, 0, options, NULL, 0); + if (EG(exception)) { + zval_ptr_dtor(&object); + RETURN_THROWS(); + } + + ZVAL_COPY_VALUE(return_value, &object); +} + +PHP_METHOD(DatePeriod, createFromIso8601) +{ + char *isostr; + size_t isostr_len; + zend_long options = 0; + zval object; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &isostr, &isostr_len, &options) == FAILURE) { + RETURN_THROWS(); + } + + object_init_ex(&object, zend_get_called_scope(execute_data)); + + construct_date_period(INTERNAL_FUNCTION_PARAM_PASSTHRU, &object, NULL, NULL, NULL, 0, options, isostr, isostr_len); + if (EG(exception)) { + zval_ptr_dtor(&object); + RETURN_THROWS(); + } + + ZVAL_COPY_VALUE(return_value, &object); +} + +/* Creates new DatePeriod object. */ +PHP_METHOD(DatePeriod, __construct) +{ + zval *start, *end = NULL, *interval; + zend_long recurrences = 0, options = 0; + char *isostr = NULL; + size_t isostr_len = 0; + + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "OOl|l", &start, date_ce_interface, &interval, date_ce_interval, &recurrences, &options) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "OOO|l", &start, date_ce_interface, &interval, date_ce_interval, &end, date_ce_interface, &options) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "s|l", &isostr, &isostr_len, &options) == FAILURE) { + zend_type_error("DatePeriod::__construct() accepts (DateTimeInterface, DateInterval, int [, int]), or (DateTimeInterface, DateInterval, DateTime [, int]), or (string [, int]) as arguments"); + RETURN_THROWS(); + } + } + } + + construct_date_period(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_THIS, start, end, interval, recurrences, options, isostr, isostr_len); +} /* {{{ Get start date. */ PHP_METHOD(DatePeriod, getStartDate) diff --git a/ext/date/php_date.stub.php b/ext/date/php_date.stub.php index 63d590d9c9909..eb6a264d8a42e 100644 --- a/ext/date/php_date.stub.php +++ b/ext/date/php_date.stub.php @@ -398,6 +398,12 @@ public static function __set_state(array $array) {} class DatePeriod implements IteratorAggregate { + public static function createFromRecurrences(DateTimeInterface $start, DateInterval $interval, int $recurrences, int $options = 0): static {} + + public static function createFromDates(DateTimeInterface $start, DateInterval $interval, DateTimeInterface $end, int $options = 0): static {} + + public static function createFromIso8601(string $specification, int $options = 0): static {} + /** * @param DateTimeInterface|string $start * @param DateInterval|int $interval diff --git a/ext/date/php_date_arginfo.h b/ext/date/php_date_arginfo.h index 8f90dd8cbadd6..770aa1a9c8d9a 100644 --- a/ext/date/php_date_arginfo.h +++ b/ext/date/php_date_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 108136459e578cc699cffcb84d3335a11f8d5c9d */ + * Stub hash: 0affb8dcab45c4067e2dfd30b34d0aa240de746e */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strtotime, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, datetime, IS_STRING, 0) @@ -403,6 +403,25 @@ ZEND_END_ARG_INFO() #define arginfo_class_DateInterval___set_state arginfo_class_DateTime___set_state +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DatePeriod_createFromRecurrences, 0, 3, IS_STATIC, 0) + ZEND_ARG_OBJ_INFO(0, start, DateTimeInterface, 0) + ZEND_ARG_OBJ_INFO(0, interval, DateInterval, 0) + ZEND_ARG_TYPE_INFO(0, recurrences, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DatePeriod_createFromDates, 0, 3, IS_STATIC, 0) + ZEND_ARG_OBJ_INFO(0, start, DateTimeInterface, 0) + ZEND_ARG_OBJ_INFO(0, interval, DateInterval, 0) + ZEND_ARG_OBJ_INFO(0, end, DateTimeInterface, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DatePeriod_createFromIso8601, 0, 1, IS_STATIC, 0) + ZEND_ARG_TYPE_INFO(0, specification, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DatePeriod___construct, 0, 0, 1) ZEND_ARG_INFO(0, start) ZEND_ARG_INFO(0, interval) @@ -498,6 +517,9 @@ ZEND_METHOD(DateTimeZone, __set_state); ZEND_METHOD(DateInterval, __construct); ZEND_METHOD(DateInterval, __wakeup); ZEND_METHOD(DateInterval, __set_state); +ZEND_METHOD(DatePeriod, createFromRecurrences); +ZEND_METHOD(DatePeriod, createFromDates); +ZEND_METHOD(DatePeriod, createFromIso8601); ZEND_METHOD(DatePeriod, __construct); ZEND_METHOD(DatePeriod, getStartDate); ZEND_METHOD(DatePeriod, getEndDate); @@ -647,6 +669,9 @@ static const zend_function_entry class_DateInterval_methods[] = { static const zend_function_entry class_DatePeriod_methods[] = { + ZEND_ME(DatePeriod, createFromRecurrences, arginfo_class_DatePeriod_createFromRecurrences, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(DatePeriod, createFromDates, arginfo_class_DatePeriod_createFromDates, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(DatePeriod, createFromIso8601, arginfo_class_DatePeriod_createFromIso8601, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME(DatePeriod, __construct, arginfo_class_DatePeriod___construct, ZEND_ACC_PUBLIC) ZEND_ME(DatePeriod, getStartDate, arginfo_class_DatePeriod_getStartDate, ZEND_ACC_PUBLIC) ZEND_ME(DatePeriod, getEndDate, arginfo_class_DatePeriod_getEndDate, ZEND_ACC_PUBLIC) diff --git a/ext/date/tests/DatePeriod_createFromDates.phpt b/ext/date/tests/DatePeriod_createFromDates.phpt new file mode 100644 index 0000000000000..f89a69b611e19 --- /dev/null +++ b/ext/date/tests/DatePeriod_createFromDates.phpt @@ -0,0 +1,23 @@ +--TEST-- +Test DatePeriod::createFromDates() +--FILE-- + +--EXPECT-- +string(12) "MyDatePeriod" +bool(true) diff --git a/ext/date/tests/DatePeriod_createFromIso8601.phpt b/ext/date/tests/DatePeriod_createFromIso8601.phpt new file mode 100644 index 0000000000000..e495aaee18faa --- /dev/null +++ b/ext/date/tests/DatePeriod_createFromIso8601.phpt @@ -0,0 +1,26 @@ +--TEST-- +Test DatePeriod::createFromIso8601() +--FILE-- +getMessage() . "\n"; +} + +?> +--EXPECT-- +string(12) "MyDatePeriod" +bool(true) +DatePeriod::createFromIso8601(): Unknown or bad format () diff --git a/ext/date/tests/DatePeriod_createFromRecurrences.phpt b/ext/date/tests/DatePeriod_createFromRecurrences.phpt new file mode 100644 index 0000000000000..c32e4bd257c41 --- /dev/null +++ b/ext/date/tests/DatePeriod_createFromRecurrences.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test DatePeriod::createFromRecurrences() +--FILE-- +getMessage() . "\n"; +} + +?> +--EXPECT-- +string(12) "MyDatePeriod" +bool(true) +DatePeriod::createFromRecurrences(): Recurrence count must be greater than 0 diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 280b3fc06c4de..e66d3358c5fa6 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -3043,13 +3043,9 @@ ZEND_METHOD(ReflectionUnionType, getTypes) } /* }}} */ -/* {{{ Constructor. Throws an Exception in case the given method does not exist */ -ZEND_METHOD(ReflectionMethod, __construct) -{ - zend_object *arg1_obj; - zend_string *arg1_str; - zend_string *arg2_str = NULL; - +static void construct_reflection_method( + INTERNAL_FUNCTION_PARAMETERS, zval *object, zend_object *arg1_obj, zend_string *arg1_str, zend_string *arg2_str +) { zend_object *orig_obj = NULL; zend_class_entry *ce = NULL; zend_string *class_name = NULL; @@ -3057,15 +3053,9 @@ ZEND_METHOD(ReflectionMethod, __construct) size_t method_name_len; char *lcname; - zval *object; reflection_object *intern; zend_function *mptr; - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_OBJ_OR_STR(arg1_obj, arg1_str) - Z_PARAM_OPTIONAL - Z_PARAM_STR_OR_NULL(arg2_str) - ZEND_PARSE_PARAMETERS_END(); if (arg1_obj) { if (!arg2_str) { @@ -3109,7 +3099,6 @@ ZEND_METHOD(ReflectionMethod, __construct) zend_string_release(class_name); } - object = ZEND_THIS; intern = Z_REFLECTION_P(object); lcname = zend_str_tolower_dup(method_name, method_name_len); @@ -3133,7 +3122,42 @@ ZEND_METHOD(ReflectionMethod, __construct) intern->ref_type = REF_TYPE_FUNCTION; intern->ce = ce; } -/* }}} */ + +ZEND_METHOD(ReflectionMethod, createFromMethodName) +{ + zend_string *method_name; + zval object; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(method_name) + ZEND_PARSE_PARAMETERS_END(); + + object_init_ex(&object, zend_get_called_scope(execute_data)); + + construct_reflection_method(INTERNAL_FUNCTION_PARAM_PASSTHRU, &object, NULL, method_name, NULL); + if (EG(exception)) { + zval_ptr_dtor(&object); + RETURN_THROWS(); + } + + ZVAL_COPY_VALUE(return_value, &object); +} + +/* {{{ Constructor. Throws an Exception in case the given method does not exist */ +ZEND_METHOD(ReflectionMethod, __construct) +{ + zend_object *arg1_obj; + zend_string *arg1_str; + zend_string *arg2_str = NULL; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_OBJ_OR_STR(arg1_obj, arg1_str) + Z_PARAM_OPTIONAL + Z_PARAM_STR_OR_NULL(arg2_str) + ZEND_PARSE_PARAMETERS_END(); + + construct_reflection_method(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_THIS, arg1_obj, arg1_str, arg2_str); +} /* {{{ Returns a string representation */ ZEND_METHOD(ReflectionMethod, __toString) diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php index e9815558d61b9..93fc06b5de605 100644 --- a/ext/reflection/php_reflection.stub.php +++ b/ext/reflection/php_reflection.stub.php @@ -151,6 +151,8 @@ class ReflectionMethod extends ReflectionFunctionAbstract { public string $class; + public static function createFromMethodName(string $method): static {} + public function __construct(object|string $objectOrMethod, ?string $method = null) {} public function __toString(): string {} diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h index 36e6dc3cec004..89a26f7d90876 100644 --- a/ext/reflection/php_reflection_arginfo.h +++ b/ext/reflection/php_reflection_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 3594ec0b0c3ed7266223be9c6b426aac56e3aabe */ + * Stub hash: eed674aa76185f0f66c6dcc6d2da96d8388dd873 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0) @@ -101,6 +101,10 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionGenerator_getExecutingGenerator arginfo_class_ReflectionFunctionAbstract_inNamespace +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionMethod_createFromMethodName, 0, 1, IS_STATIC, 0) + ZEND_ARG_TYPE_INFO(0, method, IS_STRING, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionMethod___construct, 0, 0, 1) ZEND_ARG_TYPE_MASK(0, objectOrMethod, MAY_BE_OBJECT|MAY_BE_STRING, NULL) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, method, IS_STRING, 1, "null") @@ -565,6 +569,7 @@ ZEND_METHOD(ReflectionGenerator, getTrace); ZEND_METHOD(ReflectionGenerator, getFunction); ZEND_METHOD(ReflectionGenerator, getThis); ZEND_METHOD(ReflectionGenerator, getExecutingGenerator); +ZEND_METHOD(ReflectionMethod, createFromMethodName); ZEND_METHOD(ReflectionMethod, __construct); ZEND_METHOD(ReflectionMethod, __toString); ZEND_METHOD(ReflectionMethod, isPublic); @@ -810,6 +815,7 @@ static const zend_function_entry class_ReflectionGenerator_methods[] = { static const zend_function_entry class_ReflectionMethod_methods[] = { + ZEND_ME(ReflectionMethod, createFromMethodName, arginfo_class_ReflectionMethod_createFromMethodName, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME(ReflectionMethod, __construct, arginfo_class_ReflectionMethod___construct, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionMethod, __toString, arginfo_class_ReflectionMethod___toString, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionMethod, isPublic, arginfo_class_ReflectionMethod_isPublic, ZEND_ACC_PUBLIC) diff --git a/ext/reflection/tests/ReflectionMethod_createFromMethodName.phpt b/ext/reflection/tests/ReflectionMethod_createFromMethodName.phpt new file mode 100644 index 0000000000000..064fa48d64ce5 --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_createFromMethodName.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test ReflectionMethod::createFromMethodName() +--FILE-- +getMessage() . "\n"; +} + +?> +--EXPECT-- +string(18) "MyReflectionMethod" +bool(true) +Method Foo::baz() does not exist