split off property proxy
[m6w6/ext-http] / php_http_env_request.c
1 /*
2 +--------------------------------------------------------------------+
3 | PECL :: http |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2004-2011, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 #include "php_http_api.h"
14
15
16 #undef PHP_HTTP_BEGIN_ARGS
17 #undef PHP_HTTP_EMPTY_ARGS
18 #define PHP_HTTP_BEGIN_ARGS(method, req_args) PHP_HTTP_BEGIN_ARGS_EX(HttpEnvRequest, method, 0, req_args)
19 #define PHP_HTTP_EMPTY_ARGS(method) PHP_HTTP_EMPTY_ARGS_EX(HttpEnvRequest, method, 0)
20 #define PHP_HTTP_ENV_REQUEST_ME(method, visibility) PHP_ME(HttpEnvRequest, method, PHP_HTTP_ARGS(HttpEnvRequest, method), visibility)
21
22 PHP_HTTP_EMPTY_ARGS(__construct);
23
24 PHP_HTTP_BEGIN_ARGS(getQuery, 0)
25 PHP_HTTP_ARG_VAL(name, 0)
26 PHP_HTTP_ARG_VAL(type, 0)
27 PHP_HTTP_ARG_VAL(defval, 0)
28 PHP_HTTP_ARG_VAL(delete, 0)
29 PHP_HTTP_END_ARGS;
30
31 PHP_HTTP_BEGIN_ARGS(getForm, 0)
32 PHP_HTTP_ARG_VAL(name, 0)
33 PHP_HTTP_ARG_VAL(type, 0)
34 PHP_HTTP_ARG_VAL(defval, 0)
35 PHP_HTTP_ARG_VAL(delete, 0)
36 PHP_HTTP_END_ARGS;
37
38 PHP_HTTP_EMPTY_ARGS(getFiles);
39
40 static zend_class_entry *php_http_env_request_class_entry;
41
42 zend_class_entry *php_http_env_request_get_class_entry(void)
43 {
44 return php_http_env_request_class_entry;
45 }
46
47 zend_function_entry php_http_env_request_method_entry[] = {
48 PHP_HTTP_ENV_REQUEST_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
49 PHP_HTTP_ENV_REQUEST_ME(getForm, ZEND_ACC_PUBLIC)
50 PHP_HTTP_ENV_REQUEST_ME(getQuery, ZEND_ACC_PUBLIC)
51 PHP_HTTP_ENV_REQUEST_ME(getFiles, ZEND_ACC_PUBLIC)
52
53 EMPTY_FUNCTION_ENTRY
54 };
55
56 static int grab_file(void *zpp TSRMLS_DC, int argc, va_list argv, zend_hash_key *key)
57 {
58 zval *zfiles, **name, **zname, **error, **zerror, **type, **ztype, **size, **zsize, **tmp_name = zpp;
59 zend_hash_key *file_key;
60
61 zfiles = (zval *) va_arg(argv, zval *);
62 file_key = (zend_hash_key *) va_arg(argv, zend_hash_key *);
63 name = (zval **) va_arg(argv, zval **);
64 size = (zval **) va_arg(argv, zval **);
65 type = (zval **) va_arg(argv, zval **);
66 error = (zval **) va_arg(argv, zval **);
67
68 if (SUCCESS == zend_hash_index_find(Z_ARRVAL_PP(name), key->h, (void *) &zname)
69 && SUCCESS == zend_hash_index_find(Z_ARRVAL_PP(size), key->h, (void *) &zsize)
70 && SUCCESS == zend_hash_index_find(Z_ARRVAL_PP(type), key->h, (void *) &ztype)
71 && SUCCESS == zend_hash_index_find(Z_ARRVAL_PP(error), key->h, (void *) &zerror)
72 ) {
73 zval *entry, **array;
74
75 MAKE_STD_ZVAL(entry);
76 array_init(entry);
77
78 Z_ADDREF_PP(tmp_name);
79 add_assoc_zval_ex(entry, ZEND_STRS("file"), *tmp_name);
80 Z_ADDREF_PP(zname);
81 add_assoc_zval_ex(entry, ZEND_STRS("name"), *zname);
82 Z_ADDREF_PP(zsize);
83 add_assoc_zval_ex(entry, ZEND_STRS("size"), *zsize);
84 Z_ADDREF_PP(ztype);
85 add_assoc_zval_ex(entry, ZEND_STRS("type"), *ztype);
86 Z_ADDREF_PP(zerror);
87 add_assoc_zval_ex(entry, ZEND_STRS("error"), *zerror);
88
89 if (SUCCESS == zend_hash_quick_find(Z_ARRVAL_P(zfiles), file_key->arKey, file_key->nKeyLength, file_key->h, (void *) &array)) {
90 add_next_index_zval(*array, entry);
91 } else {
92 zval *tmp;
93
94 MAKE_STD_ZVAL(tmp);
95 array_init(tmp);
96 add_next_index_zval(tmp, entry);
97 zend_hash_quick_update(Z_ARRVAL_P(zfiles), file_key->arKey, file_key->nKeyLength, file_key->h, (void *) &tmp, sizeof(zval *), NULL);
98 }
99 }
100
101 return ZEND_HASH_APPLY_KEEP;
102 }
103
104 static int grab_files(void *zpp TSRMLS_DC, int argc, va_list argv, zend_hash_key *key)
105 {
106 zval *zfiles, **name, **tmp_name, **error, **type, **size, **val = zpp;
107
108 zfiles = (zval *) va_arg(argv, zval *);
109
110 if (Z_TYPE_PP(val) == IS_ARRAY
111 && SUCCESS == zend_hash_find(Z_ARRVAL_PP(val), ZEND_STRS("tmp_name"), (void *) &tmp_name)
112 && SUCCESS == zend_hash_find(Z_ARRVAL_PP(val), ZEND_STRS("name"), (void *) &name)
113 && SUCCESS == zend_hash_find(Z_ARRVAL_PP(val), ZEND_STRS("size"), (void *) &size)
114 && SUCCESS == zend_hash_find(Z_ARRVAL_PP(val), ZEND_STRS("type"), (void *) &type)
115 && SUCCESS == zend_hash_find(Z_ARRVAL_PP(val), ZEND_STRS("error"), (void *) &error)
116 ) {
117 int count;
118
119 if (Z_TYPE_PP(tmp_name) == IS_ARRAY && (count = zend_hash_num_elements(Z_ARRVAL_PP(tmp_name))) > 1) {
120 if (count == zend_hash_num_elements(Z_ARRVAL_PP(name))
121 && count == zend_hash_num_elements(Z_ARRVAL_PP(size))
122 && count == zend_hash_num_elements(Z_ARRVAL_PP(type))
123 && count == zend_hash_num_elements(Z_ARRVAL_PP(error))
124 ) {
125 zend_hash_apply_with_arguments(Z_ARRVAL_PP(tmp_name) TSRMLS_CC, grab_file, 6, zfiles, key, name, size, type, error);
126 } else {
127 /* wat?! */
128 return ZEND_HASH_APPLY_STOP;
129 }
130 } else {
131 zval *cpy, **tmp;
132
133 MAKE_STD_ZVAL(cpy);
134 MAKE_COPY_ZVAL(val, cpy);
135 if (SUCCESS == zend_hash_find(Z_ARRVAL_P(cpy), ZEND_STRS("tmp_name"), (void *) &tmp)) {
136 Z_ADDREF_PP(tmp);
137 add_assoc_zval_ex(cpy, ZEND_STRS("file"), *tmp);
138 zend_hash_del_key_or_index(Z_ARRVAL_P(cpy), ZEND_STRS("tmp_name"), 0, HASH_DEL_KEY);
139 }
140 zend_hash_quick_update(Z_ARRVAL_P(zfiles), key->arKey, key->nKeyLength, key->h, (void *) &cpy, sizeof(zval *), NULL);
141 }
142 }
143
144 return ZEND_HASH_APPLY_KEEP;
145 }
146
147 #define PHP_HTTP_ENV_REQUEST_OBJECT_INIT(obj) \
148 do { \
149 if (!obj->message) { \
150 obj->message = php_http_message_init_env(NULL, PHP_HTTP_REQUEST TSRMLS_CC); \
151 } \
152 } while(0)
153
154 PHP_METHOD(HttpEnvRequest, __construct)
155 {
156 with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
157 php_http_message_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
158
159 if (SUCCESS == zend_parse_parameters_none()) {
160 zval *zsg, *zqs;
161
162 obj->message = php_http_message_init_env(obj->message, PHP_HTTP_REQUEST TSRMLS_CC);
163 obj->body.handle = 0;
164
165 zsg = php_http_env_get_superglobal(ZEND_STRL("_GET") TSRMLS_CC);
166 MAKE_STD_ZVAL(zqs);
167 object_init_ex(zqs, php_http_querystring_get_class_entry());
168 if (SUCCESS == php_http_querystring_ctor(zqs, zsg TSRMLS_CC)) {
169 zend_update_property(php_http_env_request_class_entry, getThis(), ZEND_STRL("query"), zqs TSRMLS_CC);
170 }
171 zval_ptr_dtor(&zqs);
172
173 zsg = php_http_env_get_superglobal(ZEND_STRL("_POST") TSRMLS_CC);
174 MAKE_STD_ZVAL(zqs);
175 object_init_ex(zqs, php_http_querystring_get_class_entry());
176 if (SUCCESS == php_http_querystring_ctor(zqs, zsg TSRMLS_CC)) {
177 zend_update_property(php_http_env_request_class_entry, getThis(), ZEND_STRL("form"), zqs TSRMLS_CC);
178 }
179 zval_ptr_dtor(&zqs);
180
181 MAKE_STD_ZVAL(zqs);
182 array_init(zqs);
183 if ((zsg = php_http_env_get_superglobal(ZEND_STRL("_FILES") TSRMLS_CC))) {
184 zend_hash_apply_with_arguments(Z_ARRVAL_P(zsg) TSRMLS_CC, grab_files, 1, zqs);
185 }
186
187 zend_update_property(php_http_env_request_class_entry, getThis(), ZEND_STRL("files"), zqs TSRMLS_CC);
188 zval_ptr_dtor(&zqs);
189 }
190 PHP_HTTP_ENV_REQUEST_OBJECT_INIT(obj);
191 } end_error_handling();
192 }
193
194 #define call_querystring_get(prop) \
195 do {\
196 zend_fcall_info fci; \
197 zend_fcall_info_cache fcc; \
198 zval *rv, mn, ***args = ecalloc(sizeof(zval **), ZEND_NUM_ARGS()); \
199 zval *qs = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL(prop), 0 TSRMLS_CC); \
200 \
201 INIT_PZVAL(&mn); \
202 array_init(&mn); \
203 Z_ADDREF_P(qs); \
204 add_next_index_zval(&mn, qs); \
205 add_next_index_stringl(&mn, ZEND_STRL("get"), 1); \
206 zend_fcall_info_init(&mn, 0, &fci, &fcc, NULL, NULL TSRMLS_CC); \
207 zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args); \
208 zend_fcall_info_argp(&fci TSRMLS_CC, ZEND_NUM_ARGS(), args); \
209 zend_fcall_info_call(&fci, &fcc, &rv, NULL TSRMLS_CC); \
210 zend_fcall_info_args_clear(&fci, 1); \
211 efree(args); \
212 zval_dtor(&mn); \
213 RETVAL_ZVAL(rv, 0, 1); \
214 } while(0);
215
216 PHP_METHOD(HttpEnvRequest, getForm)
217 {
218 if (ZEND_NUM_ARGS()) {
219 call_querystring_get("form");
220 } else {
221 RETURN_PROP(php_http_env_request_class_entry, "form");
222 }
223 }
224
225 PHP_METHOD(HttpEnvRequest, getQuery)
226 {
227 if (ZEND_NUM_ARGS()) {
228 call_querystring_get("query");
229 } else {
230 RETURN_PROP(php_http_env_request_class_entry, "query");
231 }
232 }
233
234 PHP_METHOD(HttpEnvRequest, getFiles)
235 {
236 if (SUCCESS == zend_parse_parameters_none()) {
237 RETURN_PROP(php_http_env_request_class_entry, "files");
238 }
239 }
240
241
242 PHP_MINIT_FUNCTION(http_env_request)
243 {
244 PHP_HTTP_REGISTER_CLASS(http\\Env, Request, http_env_request, php_http_message_get_class_entry(), 0);
245 zend_declare_property_null(php_http_env_request_class_entry, ZEND_STRL("query"), ZEND_ACC_PROTECTED TSRMLS_CC);
246 zend_declare_property_null(php_http_env_request_class_entry, ZEND_STRL("form"), ZEND_ACC_PROTECTED TSRMLS_CC);
247 zend_declare_property_null(php_http_env_request_class_entry, ZEND_STRL("files"), ZEND_ACC_PROTECTED TSRMLS_CC);
248
249 return SUCCESS;
250 }
251
252
253 /*
254 * Local variables:
255 * tab-width: 4
256 * c-basic-offset: 4
257 * End:
258 * vim600: noet sw=4 ts=4 fdm=marker
259 * vim<600: noet sw=4 ts=4
260 */