1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | http://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Authors: Kirti Velankar <kirtig@yahoo-inc.com> |
14 | Gustavo Lopes <cataphract@php.net> |
15 +----------------------------------------------------------------------+
16 */
17
18 #include "../intl_cppshims.h"
19
20 #include <unicode/timezone.h>
21 #include <unicode/calendar.h>
22 #include <unicode/datefmt.h>
23
24 extern "C" {
25 #include <unicode/ustring.h>
26 #include <unicode/udat.h>
27
28 #include "php_intl.h"
29 #include "dateformat_create.h"
30 #include "dateformat_class.h"
31 #define USE_TIMEZONE_POINTER 1
32 #include "../timezone/timezone_class.h"
33 #include "../intl_convert.h"
34 }
35
36 #include "dateformat_helpers.h"
37
38 /* {{{ */
datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS)39 static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
40 {
41 zval *object;
42
43 const char *locale_str;
44 int locale_len = 0;
45 Locale locale;
46 long date_type = 0;
47 long time_type = 0;
48 zval *calendar_zv = NULL;
49 Calendar *calendar = NULL;
50 long calendar_type;
51 bool calendar_owned;
52 zval **timezone_zv = NULL;
53 TimeZone *timezone = NULL;
54 bool explicit_tz;
55 char* pattern_str = NULL;
56 int pattern_str_len = 0;
57 UChar* svalue = NULL; /* UTF-16 pattern_str */
58 int slength = 0;
59 IntlDateFormatter_object* dfo;
60
61 intl_error_reset(NULL TSRMLS_CC);
62 object = return_value;
63 /* Parse parameters. */
64 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll|Zzs",
65 &locale_str, &locale_len, &date_type, &time_type, &timezone_zv,
66 &calendar_zv, &pattern_str, &pattern_str_len) == FAILURE) {
67 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: "
68 "unable to parse input parameters", 0 TSRMLS_CC);
69 zval_dtor(return_value);
70 RETURN_NULL();
71 }
72
73 INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value);
74 if (locale_len == 0) {
75 locale_str = intl_locale_get_default(TSRMLS_C);
76 }
77 locale = Locale::createFromName(locale_str);
78
79 DATE_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK;
80
81 if (DATE_FORMAT_OBJECT(dfo) != NULL) {
82 intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR,
83 "datefmt_create: cannot call constructor twice", 0 TSRMLS_CC);
84 return;
85 }
86
87 /* process calendar */
88 if (datefmt_process_calendar_arg(calendar_zv, locale, "datefmt_create",
89 INTL_DATA_ERROR_P(dfo), calendar, calendar_type,
90 calendar_owned TSRMLS_CC)
91 == FAILURE) {
92 goto error;
93 }
94
95 /* process timezone */
96 explicit_tz = timezone_zv != NULL && Z_TYPE_PP(timezone_zv) != IS_NULL;
97
98 if (explicit_tz || calendar_owned ) {
99 //we have an explicit time zone or a non-object calendar
100 timezone = timezone_process_timezone_argument(timezone_zv,
101 INTL_DATA_ERROR_P(dfo), "datefmt_create" TSRMLS_CC);
102 if (timezone == NULL) {
103 goto error;
104 }
105 }
106
107 /* Convert pattern (if specified) to UTF-16. */
108 if (pattern_str && pattern_str_len > 0) {
109 intl_convert_utf8_to_utf16(&svalue, &slength,
110 pattern_str, pattern_str_len, &INTL_DATA_ERROR_CODE(dfo));
111 if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
112 /* object construction -> only set global error */
113 intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: "
114 "error converting pattern to UTF-16", 0 TSRMLS_CC);
115 goto error;
116 }
117 }
118
119 if (pattern_str && pattern_str_len > 0) {
120 DATE_FORMAT_OBJECT(dfo) = udat_open(UDAT_IGNORE, UDAT_IGNORE,
121 locale_str, NULL, 0, svalue, slength,
122 &INTL_DATA_ERROR_CODE(dfo));
123 } else {
124 DATE_FORMAT_OBJECT(dfo) = udat_open((UDateFormatStyle)time_type,
125 (UDateFormatStyle)date_type, locale_str, NULL, 0, svalue,
126 slength, &INTL_DATA_ERROR_CODE(dfo));
127 }
128
129 if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
130 DateFormat *df = (DateFormat*)DATE_FORMAT_OBJECT(dfo);
131 if (calendar_owned) {
132 df->adoptCalendar(calendar);
133 calendar_owned = false;
134 } else {
135 df->setCalendar(*calendar);
136 }
137
138 if (timezone != NULL) {
139 df->adoptTimeZone(timezone);
140 }
141 } else {
142 intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: date "
143 "formatter creation failed", 0 TSRMLS_CC);
144 goto error;
145 }
146
147 /* Set the class variables */
148 dfo->date_type = date_type;
149 dfo->time_type = time_type;
150 dfo->calendar = calendar_type;
151 dfo->requested_locale = estrdup(locale_str);
152
153 error:
154 if (svalue) {
155 efree(svalue);
156 }
157 if (timezone != NULL && DATE_FORMAT_OBJECT(dfo) == NULL) {
158 delete timezone;
159 }
160 if (calendar != NULL && calendar_owned) {
161 delete calendar;
162 }
163 if (U_FAILURE(intl_error_get_code(NULL TSRMLS_CC))) {
164 /* free_object handles partially constructed instances fine */
165 zval_dtor(return_value);
166 RETVAL_NULL();
167 }
168 }
169 /* }}} */
170
171 /* {{{ proto IntlDateFormatter IntlDateFormatter::create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern] )
172 * Create formatter. }}} */
173 /* {{{ proto IntlDateFormatter datefmt_create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern)
174 * Create formatter.
175 */
PHP_FUNCTION(datefmt_create)176 U_CFUNC PHP_FUNCTION( datefmt_create )
177 {
178 object_init_ex( return_value, IntlDateFormatter_ce_ptr );
179 datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
180 }
181 /* }}} */
182
183 /* {{{ proto void IntlDateFormatter::__construct(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern])
184 * IntlDateFormatter object constructor.
185 */
PHP_METHOD(IntlDateFormatter,__construct)186 U_CFUNC PHP_METHOD( IntlDateFormatter, __construct )
187 {
188 /* return_value param is being changed, therefore we will always return
189 * NULL here */
190 return_value = getThis();
191 datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
192 }
193 /* }}} */
194