1 /*
2 +----------------------------------------------------------------------+
3 | Yet Another Framework |
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 | Author: Xinchen Hui <laruence@php.net> |
14 +----------------------------------------------------------------------+
15 */
16
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #include "php.h"
22 #include "Zend/zend_smart_str.h" /* for smart_str */
23 #include "Zend/zend_interfaces.h" /* for zend_class_serialize_deny */
24
25 #include "php_yaf.h"
26 #include "yaf_namespace.h"
27 #include "yaf_exception.h"
28 #include "yaf_application.h" /* for yaf_application_is_module_name */
29 #include "yaf_request.h"
30 #include "yaf_router.h"
31
32 #include "routes/yaf_route_interface.h"
33 #include "routes/yaf_route_simple.h"
34
35 zend_class_entry *yaf_route_simple_ce;
36 static zend_object_handlers yaf_route_simple_obj_handlers;
37
38 /** {{{ ARG_INFO
39 */
40 ZEND_BEGIN_ARG_INFO_EX(yaf_route_simple_construct_arginfo, 0, 0, 3)
41 ZEND_ARG_INFO(0, module_name)
42 ZEND_ARG_INFO(0, controller_name)
43 ZEND_ARG_INFO(0, action_name)
ZEND_END_ARG_INFO()44 ZEND_END_ARG_INFO()
45 /* }}} */
46
47 static HashTable *yaf_route_simple_get_properties(yaf_object *object) /* {{{ */ {
48 zval rv;
49 HashTable *ht;
50 yaf_route_simple_object *simple = (yaf_route_simple_object*)(yaf_strip_obj(object));
51
52 if (!simple->properties) {
53 ALLOC_HASHTABLE(simple->properties);
54 zend_hash_init(simple->properties, 4, NULL, ZVAL_PTR_DTOR, 0);
55
56 ht = simple->properties;
57 ZVAL_STR_COPY(&rv, simple->m);
58 zend_hash_str_add(ht, "module:protected", sizeof("module:protected") - 1, &rv);
59
60 ZVAL_STR_COPY(&rv, simple->c);
61 zend_hash_str_add(ht, "controller:protected", sizeof("controller:protected") - 1, &rv);
62
63 ZVAL_STR_COPY(&rv, simple->a);
64 zend_hash_str_add(ht, "action:protected", sizeof("action:protected") - 1, &rv);
65 }
66
67 return simple->properties;
68 }
69 /* }}} */
70
yaf_route_simple_new(zend_class_entry * ce)71 static zend_object *yaf_route_simple_new(zend_class_entry *ce) /* {{{ */ {
72 yaf_route_simple_object *simple = emalloc(sizeof(yaf_route_simple_object));
73
74 zend_object_std_init(&simple->std, ce);
75
76 simple->std.handlers = &yaf_route_simple_obj_handlers;
77 simple->m = simple->c = simple->a = NULL;
78 simple->properties = NULL;
79
80 return &simple->std;
81 }
82 /* }}} */
83
yaf_route_simple_object_free(zend_object * object)84 static void yaf_route_simple_object_free(zend_object *object) /* {{{ */ {
85 yaf_route_simple_object *simple = (yaf_route_simple_object*)object;
86
87 if (simple->m) {
88 zend_string_release(simple->m);
89 }
90
91 if (simple->c) {
92 zend_string_release(simple->c);
93 }
94
95 if (simple->a) {
96 zend_string_release(simple->a);
97 }
98
99 if (simple->properties) {
100 if (GC_DELREF(simple->properties) == 0) {
101 GC_REMOVE_FROM_BUFFER(simple->properties);
102 zend_array_destroy(simple->properties);
103 }
104 }
105
106 zend_object_std_dtor(&simple->std);
107 }
108 /* }}} */
109
yaf_route_simple_init(yaf_route_simple_object * simple,zend_string * m,zend_string * c,zend_string * a)110 static void yaf_route_simple_init(yaf_route_simple_object *simple, zend_string *m, zend_string *c, zend_string *a) /* {{{ */ {
111 simple->m = zend_string_copy(m);
112 simple->c = zend_string_copy(c);
113 simple->a = zend_string_copy(a);
114 }
115 /* }}} */
116
yaf_route_simple_instance(yaf_route_t * route,zend_string * m,zend_string * c,zend_string * a)117 void yaf_route_simple_instance(yaf_route_t *route, zend_string *m, zend_string *c, zend_string *a) /* {{{ */ {
118 zend_object *simple = yaf_route_simple_new(yaf_route_simple_ce);
119
120 yaf_route_simple_init((yaf_route_simple_object*)simple, m, c, a);
121
122 ZVAL_OBJ(route, simple);
123 }
124 /* }}} */
125
yaf_route_simple_route(yaf_route_t * route,yaf_request_t * req)126 int yaf_route_simple_route(yaf_route_t *route, yaf_request_t *req) /* {{{ */ {
127 zval *module, *controller, *action;
128 yaf_request_object *request = Z_YAFREQUESTOBJ_P(req);
129 yaf_route_simple_object *simple = Z_YAFROUTESIMPLEOBJ_P(route);
130
131 module = yaf_request_query(YAF_GLOBAL_VARS_GET, simple->m);
132 controller = yaf_request_query(YAF_GLOBAL_VARS_GET, simple->c);
133 action = yaf_request_query(YAF_GLOBAL_VARS_GET, simple->a);
134
135 if (!module && !controller && !action) {
136 return 0;
137 }
138
139 if (module && Z_TYPE_P(module) == IS_STRING && yaf_application_is_module_name(Z_STR_P(module))) {
140 yaf_request_set_module(request, Z_STR_P(module));
141 }
142
143 if (controller && Z_TYPE_P(controller) == IS_STRING) {
144 yaf_request_set_controller(request, Z_STR_P(controller));
145 }
146
147 if (action && Z_TYPE_P(action) == IS_STRING) {
148 yaf_request_set_action(request, Z_STR_P(action));
149 }
150
151 return 1;
152 }
153 /* }}} */
154
155 /** {{{ proto public Yaf_Route_Simple::route(Yaf_Request $req)
156 */
PHP_METHOD(yaf_route_simple,route)157 PHP_METHOD(yaf_route_simple, route) {
158 yaf_request_t *request;
159
160 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &request, yaf_request_ce) == FAILURE) {
161 return;
162 } else {
163 RETURN_BOOL(yaf_route_simple_route(getThis(), request));
164 }
165 }
166 /* }}} */
167
yaf_route_simple_assemble(yaf_route_simple_object * simple,zval * info,zval * query)168 zend_string * yaf_route_simple_assemble(yaf_route_simple_object *simple, zval *info, zval *query) /* {{{ */ {
169 zval *zv;
170 smart_str uri = {0};
171 zend_string *val;
172
173 smart_str_appendc(&uri, '?');
174
175 if ((zv = zend_hash_str_find(Z_ARRVAL_P(info), ZEND_STRL(YAF_ROUTE_ASSEMBLE_MOUDLE_FORMAT))) != NULL) {
176 val = zval_get_string(zv);
177 smart_str_appendl(&uri, ZSTR_VAL(simple->m), ZSTR_LEN(simple->m));
178 smart_str_appendc(&uri, '=');
179 smart_str_appendl(&uri, ZSTR_VAL(val), ZSTR_LEN(val));
180 smart_str_appendc(&uri, '&');
181 zend_string_release(val);
182 }
183
184 if ((zv = zend_hash_str_find(Z_ARRVAL_P(info), ZEND_STRL(YAF_ROUTE_ASSEMBLE_CONTROLLER_FORMAT))) == NULL) {
185 yaf_trigger_error(YAF_ERR_TYPE_ERROR, "%s", "You need to specify the controller by ':c'");
186 smart_str_free(&uri);
187 return NULL;
188 }
189
190 val = zval_get_string(zv);
191 smart_str_appendl(&uri, ZSTR_VAL(simple->c), ZSTR_LEN(simple->c));
192 smart_str_appendc(&uri, '=');
193 smart_str_appendl(&uri, ZSTR_VAL(val), ZSTR_LEN(val));
194 smart_str_appendc(&uri, '&');
195 zend_string_release(val);
196
197 if ((zv = zend_hash_str_find(Z_ARRVAL_P(info), ZEND_STRL(YAF_ROUTE_ASSEMBLE_ACTION_FORMAT))) == NULL) {
198 yaf_trigger_error(YAF_ERR_TYPE_ERROR, "%s", "You need to specify the action by ':a'");
199 smart_str_free(&uri);
200 return NULL;
201 }
202
203 val = zval_get_string(zv);
204 smart_str_appendl(&uri, ZSTR_VAL(simple->a), ZSTR_LEN(simple->a));
205 smart_str_appendc(&uri, '=');
206 smart_str_appendl(&uri, ZSTR_VAL(val), ZSTR_LEN(val));
207 zend_string_release(val);
208
209 if (query && IS_ARRAY == Z_TYPE_P(query)) {
210 zend_string *key;
211
212 ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(query), key, zv) {
213 if (key) {
214 val = zval_get_string(zv);
215 smart_str_appendc(&uri, '&');
216 smart_str_appendl(&uri, ZSTR_VAL(key), ZSTR_LEN(key));
217 smart_str_appendc(&uri, '=');
218 smart_str_appendl(&uri, ZSTR_VAL(val), ZSTR_LEN(val));
219 zend_string_release(val);
220 }
221 } ZEND_HASH_FOREACH_END();
222 }
223
224 smart_str_0(&uri);
225 return uri.s;
226 }
227 /* }}} */
228
229 /** {{{ proto public Yaf_Route_Simple::__construct(string $module, string $controller, string $action)
230 */
PHP_METHOD(yaf_route_simple,__construct)231 PHP_METHOD(yaf_route_simple, __construct) {
232 zend_string *m, *c, *a;
233
234 if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "SSS", &m, &c, &a) == FAILURE) {
235 return;
236 }
237
238 yaf_route_simple_init(Z_YAFROUTESIMPLEOBJ_P(getThis()), m, c, a);
239 }
240 /* }}} */
241
242 /** {{{ proto public Yaf_Route_Simple::assemble(array $info[, array $query = NULL])
243 */
PHP_METHOD(yaf_route_simple,assemble)244 PHP_METHOD(yaf_route_simple, assemble) {
245 zend_string *str;
246 zval *info, *query = NULL;
247
248 if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|a", &info, &query) == FAILURE) {
249 return;
250 }
251
252 if ((str = yaf_route_simple_assemble(Z_YAFROUTESIMPLEOBJ_P(getThis()), info, query))) {
253 RETURN_STR(str);
254 }
255
256 RETURN_NULL();
257 }
258 /* }}} */
259
260 /** {{{ yaf_route_simple_methods
261 */
262 zend_function_entry yaf_route_simple_methods[] = {
263 PHP_ME(yaf_route_simple, __construct, yaf_route_simple_construct_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
264 PHP_ME(yaf_route_simple, route, yaf_route_route_arginfo, ZEND_ACC_PUBLIC)
265 PHP_ME(yaf_route_simple, assemble, yaf_route_assemble_arginfo, ZEND_ACC_PUBLIC)
266 {NULL, NULL, NULL}
267 };
268 /* }}} */
269
270 /** {{{ YAF_STARTUP_FUNCTION
271 */
YAF_STARTUP_FUNCTION(route_simple)272 YAF_STARTUP_FUNCTION(route_simple) {
273 zend_class_entry ce;
274
275 YAF_INIT_CLASS_ENTRY(ce, "Yaf_Route_Simple", "Yaf\\Route\\Simple", yaf_route_simple_methods);
276 yaf_route_simple_ce = zend_register_internal_class(&ce);
277 yaf_route_simple_ce->create_object = yaf_route_simple_new;
278 yaf_route_simple_ce->ce_flags |= ZEND_ACC_FINAL;
279 yaf_route_simple_ce->serialize = zend_class_serialize_deny;
280 yaf_route_simple_ce->unserialize = zend_class_unserialize_deny;
281
282 zend_class_implements(yaf_route_simple_ce, 1, yaf_route_ce);
283
284 memcpy(&yaf_route_simple_obj_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
285 yaf_route_simple_obj_handlers.free_obj = yaf_route_simple_object_free;
286 yaf_route_simple_obj_handlers.clone_obj = NULL;
287 yaf_route_simple_obj_handlers.get_gc = yaf_fake_get_gc;
288 yaf_route_simple_obj_handlers.get_properties = yaf_route_simple_get_properties;
289
290 return SUCCESS;
291 }
292 /* }}} */
293
294 /*
295 * Local variables:
296 * tab-width: 4
297 * c-basic-offset: 4
298 * End:
299 * vim600: noet sw=4 ts=4 fdm=marker
300 * vim<600: noet sw=4 ts=4
301 */
302