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 "main/php_output.h"
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_loader.h"
29 #include "yaf_request.h"
30 #include "yaf_view.h"
31 
32 #include "views/yaf_view_interface.h"
33 #include "views/yaf_view_simple.h"
34 
35 zend_class_entry *yaf_view_simple_ce;
36 static zend_object_handlers yaf_view_simple_obj_handlers;
37 
38 /** {{{ ARG_INFO */
39 ZEND_BEGIN_ARG_INFO_EX(yaf_view_simple_construct_arginfo, 0, 0, 1)
40 	ZEND_ARG_INFO(0, template_dir)
41 	ZEND_ARG_ARRAY_INFO(0, options, 1)
42 ZEND_END_ARG_INFO();
43 
44 ZEND_BEGIN_ARG_INFO_EX(yaf_view_simple_get_arginfo, 0, 0, 0)
45 	ZEND_ARG_INFO(0, name)
46 ZEND_END_ARG_INFO()
47 
48 ZEND_BEGIN_ARG_INFO_EX(yaf_view_simple_isset_arginfo, 0, 0, 1)
49 	ZEND_ARG_INFO(0, name)
50 ZEND_END_ARG_INFO();
51 
52 ZEND_BEGIN_ARG_INFO_EX(yaf_view_simple_assign_by_ref_arginfo, 0, 0, 2)
53 	ZEND_ARG_INFO(0, name)
54 	ZEND_ARG_INFO(1, value)
55 ZEND_END_ARG_INFO();
56 
57 ZEND_BEGIN_ARG_INFO_EX(yaf_view_simple_eval_arginfo, 0, 0, 1)
58 	ZEND_ARG_INFO(0, tpl_str)
59 	ZEND_ARG_INFO(0, vars)
60 ZEND_END_ARG_INFO();
61 
62 ZEND_BEGIN_ARG_INFO_EX(yaf_view_simple_clear_arginfo, 0, 0, 0)
63 	ZEND_ARG_INFO(0, name)
64 ZEND_END_ARG_INFO();
65 /* }}} */
66 
yaf_view_simple_get_properties(yaf_object * obj)67 static HashTable *yaf_view_simple_get_properties(yaf_object *obj) /* {{{ */ {
68 	zval rv;
69 	HashTable *ht;
70 	yaf_view_object *view = php_yaf_view_fetch_object(yaf_strip_obj(obj));
71 
72 	if (!view->properties) {
73 		ALLOC_HASHTABLE(view->properties);
74 		zend_hash_init(view->properties, 2, NULL, ZVAL_PTR_DTOR, 0);
75 		YAF_ALLOW_VIOLATION(view->properties);
76 	}
77 
78 	ht = view->properties;
79 	if (view->tpl_dir) {
80 		ZVAL_STR_COPY(&rv, view->tpl_dir);
81 	} else {
82 		ZVAL_NULL(&rv);
83 	}
84 	zend_hash_str_update(ht, "tpl_dir:protected", sizeof("tpl_dir:protected") - 1, &rv);
85 
86 	ZVAL_ARR(&rv, zend_array_dup(&view->tpl_vars));
87 	zend_hash_str_update(ht, "tpl_vars:protected", sizeof("tpl_vars:protected") - 1, &rv);
88 
89 	return ht;
90 }
91 /* }}} */
92 
yaf_view_simple_read_property(yaf_object * obj,void * name,int type,void ** cache_slot,zval * rv)93 static zval* yaf_view_simple_read_property(yaf_object *obj, void *name, int type, void **cache_slot, zval *rv) /* {{{ */ {
94 	zval *var;
95 	zend_string *member;
96 	yaf_view_object *view = php_yaf_view_fetch_object(yaf_strip_obj(obj));
97 
98 #if PHP_VERSION_ID < 80000
99 	if (UNEXPECTED(Z_TYPE_P((zval*)name) != IS_STRING)) {
100 		return &EG(uninitialized_zval);
101 	}
102 
103 	member = Z_STR_P((zval*)name);
104 #else
105 	member = (zend_string*)name;
106 #endif
107 
108 	if ((var = zend_hash_find(&view->tpl_vars, member))) {
109 		return var;
110 	}
111 
112 	return &EG(uninitialized_zval);
113 }
114 /* }}} */
115 
yaf_view_simple_write_property(yaf_object * obj,void * name,zval * value,void ** cache_slot)116 static YAF_WRITE_HANDLER yaf_view_simple_write_property(yaf_object *obj, void *name, zval *value, void **cache_slot) /* {{{ */ {
117 	zend_string *member;
118 	yaf_view_object *view = php_yaf_view_fetch_object(yaf_strip_obj(obj));
119 
120 #if PHP_VERSION_ID < 80000
121 	if (UNEXPECTED(Z_TYPE_P((zval*)name) != IS_STRING)) {
122 		YAF_WHANDLER_RET(value);
123 	}
124 
125 	member = Z_STR_P((zval*)name);
126 #else
127 	member = (zend_string*)name;
128 #endif
129 
130 	zend_hash_update(&view->tpl_vars, member, value);
131 	Z_TRY_ADDREF_P(value);
132 
133 	YAF_WHANDLER_RET(value);
134 }
135 /* }}} */
136 
yaf_view_simple_new(zend_class_entry * ce)137 static zend_object *yaf_view_simple_new(zend_class_entry *ce) /* {{{ */ {
138 	yaf_view_object *view = emalloc(sizeof(yaf_view_object) + zend_object_properties_size(ce));
139 
140 	zend_object_std_init(&view->std, ce);
141 	view->std.handlers = &yaf_view_simple_obj_handlers;
142 
143 	view->tpl_dir = NULL;
144 	zend_hash_init(&view->tpl_vars, 8, NULL, ZVAL_PTR_DTOR, 0);
145 	view->properties = NULL;
146 
147 	return &view->std;
148 }
149 /* }}} */
150 
yaf_view_object_free(zend_object * object)151 static void yaf_view_object_free(zend_object *object) /* {{{ */ {
152 	yaf_view_object *view = php_yaf_view_fetch_object(object);
153 
154 	if (view->tpl_dir) {
155 		zend_string_release(view->tpl_dir);
156 	}
157 	zend_hash_destroy(&view->tpl_vars);
158 	if (view->properties) {
159 		if (GC_DELREF(view->properties) == 0) {
160 			GC_REMOVE_FROM_BUFFER(view->properties);
161 			zend_array_destroy(view->properties);
162 		}
163 	}
164 
165 	zend_object_std_dtor(object);
166 }
167 /* }}} */
168 
yaf_view_simple_init(yaf_view_object * view,zend_string * tpl_dir,zend_array * options)169 int yaf_view_simple_init(yaf_view_object *view, zend_string *tpl_dir, zend_array *options) /* {{{ */ {
170 	if (!IS_ABSOLUTE_PATH(ZSTR_VAL(tpl_dir), ZSTR_LEN(tpl_dir))) {
171 		yaf_trigger_error(YAF_ERR_TYPE_ERROR, "Expects an absolute path for templates directory");
172 		return 0;
173 	}
174 
175 	view->tpl_dir = zend_string_copy(tpl_dir);
176 	return 1;
177 }
178 /* }}} */
179 
yaf_view_simple_instance(yaf_view_t * view,zend_string * tpl_dir)180 void yaf_view_simple_instance(yaf_view_t *view, zend_string *tpl_dir) /* {{{ */ {
181 	zend_object *v = yaf_view_simple_new(yaf_view_simple_ce);
182 	ZVAL_OBJ(view, v);
183 }
184 /* }}} */
185 
yaf_view_simple_valid_var_name(zend_string * var_name)186 static int yaf_view_simple_valid_var_name(zend_string *var_name) /* {{{ */ {
187 	int i, ch;
188 
189 	if (UNEXPECTED(zend_string_equals_literal(var_name, "GLOBALS"))) {
190 		return 0;
191 	}
192 
193 	if (UNEXPECTED(zend_string_equals_literal(var_name, "this"))) {
194 		return 0;
195 	}
196 
197 	/* These are allowed as first char: [a-zA-Z_\x7f-\xff] */
198 	ch = (int)((unsigned char *)ZSTR_VAL(var_name))[0];
199 	if (ch != '_' &&
200 			(ch < 65  /* A    */ || /* Z    */ ch > 90)  &&
201 			(ch < 97  /* a    */ || /* z    */ ch > 122) &&
202 			(ch < 127 /* 0x7f */ || /* 0xff */ ch > 255)
203 	   ) {
204 		return 0;
205 	}
206 
207 	/* And these as the rest: [a-zA-Z0-9_\x7f-\xff] */
208 	if (ZSTR_LEN(var_name) > 1) {
209 		for (i = 1; i < ZSTR_LEN(var_name); i++) {
210 			ch = (int)((unsigned char *)ZSTR_VAL(var_name))[i];
211 			if (ch != '_' &&
212 					(ch < 48  /* 0    */ || /* 9    */ ch > 57)  &&
213 					(ch < 65  /* A    */ || /* Z    */ ch > 90)  &&
214 					(ch < 97  /* a    */ || /* z    */ ch > 122) &&
215 					(ch < 127 /* 0x7f */ || /* 0xff */ ch > 255)
216 			   ) {
217 				return 0;
218 			}
219 		}
220 	}
221 	return 1;
222 }
223 /* }}} */
224 
yaf_view_build_symtable(zend_array * symbol_table,zend_array * tpl_vars,zval * vars)225 static void yaf_view_build_symtable(zend_array *symbol_table, zend_array *tpl_vars, zval *vars) /* {{{ */ {
226 	zval *entry;
227 	zend_string *var_name;
228 
229 	zend_hash_init(symbol_table, 8, NULL, ZVAL_PTR_DTOR, 0);
230 
231 	if (EXPECTED(tpl_vars)) {
232 	    ZEND_HASH_FOREACH_STR_KEY_VAL(tpl_vars, var_name, entry) {
233 			if (var_name == NULL) {
234 				continue;
235 			}
236 			if (yaf_view_simple_valid_var_name(var_name)) {
237 				if (EXPECTED(zend_hash_add_new(symbol_table, var_name, entry))) {
238 					Z_TRY_ADDREF_P(entry);
239 				}
240 			}
241 		} ZEND_HASH_FOREACH_END();
242 	}
243 
244 	if (vars && Z_TYPE_P(vars) == IS_ARRAY) {
245 	    ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(vars), var_name, entry) {
246 			if (var_name == NULL) {
247 				continue;
248 			}
249 			if (yaf_view_simple_valid_var_name(var_name)) {
250 				if (EXPECTED(zend_hash_update(symbol_table, var_name, entry))) {
251 					Z_TRY_ADDREF_P(entry);
252 				}
253 			}
254 		} ZEND_HASH_FOREACH_END();
255 	}
256 }
257 /* }}} */
258 
yaf_view_exec_tpl(yaf_view_t * view,zend_op_array * op_array,zend_array * symbol_table,zval * ret)259 static int yaf_view_exec_tpl(yaf_view_t *view, zend_op_array *op_array, zend_array *symbol_table, zval* ret) /* {{{ */ {
260 	zend_execute_data *call;
261 	zval result;
262 	uint32_t call_info;
263 
264 	ZVAL_UNDEF(&result);
265 
266 	op_array->scope = Z_OBJCE_P(view);
267 
268 	zend_function *func = (zend_function *)op_array;
269 
270 #if PHP_VERSION_ID >= 70400
271 	call_info = ZEND_CALL_HAS_THIS | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE;
272 #elif PHP_VERSION_ID >= 70100
273 	call_info = ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE;
274 #else
275 	call_info = ZEND_CALL_NESTED_CODE;
276 #endif
277 
278 #if PHP_VERSION_ID < 70400
279 	call = zend_vm_stack_push_call_frame(call_info, func, 0, op_array->scope, Z_OBJ_P(view));
280 #else
281     call = zend_vm_stack_push_call_frame(call_info, func, 0, Z_OBJ_P(view));
282 #endif
283 
284 	call->symbol_table = symbol_table;
285 
286 	if (ret && php_output_start_user(NULL, 0, PHP_OUTPUT_HANDLER_STDFLAGS) == FAILURE) {
287 		php_error_docref("ref.outcontrol", E_WARNING, "failed to create buffer");
288 		return 0;
289 	}
290 
291 	zend_init_execute_data(call, op_array, &result);
292 
293 	ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
294 	zend_execute_ex(call);
295 	zend_vm_stack_free_call_frame(call);
296 
297 	zval_ptr_dtor(&result);
298 
299 	if (UNEXPECTED(EG(exception) != NULL)) {
300 		if (ret) {
301 			php_output_discard();
302 		}
303 		return 0;
304 	}
305 
306 	if (ret) {
307 		if (php_output_get_contents(ret) == FAILURE) {
308 			php_output_end();
309 			php_error_docref(NULL, E_WARNING, "Unable to fetch ob content");
310 			return 0;
311 		}
312 
313 		if (php_output_discard() != SUCCESS ) {
314 			return 0;
315 		}
316 	}
317 
318 	return 1;
319 }
320 /* }}} */
321 
yaf_view_render_tpl(yaf_view_t * view,const char * tpl,uint32_t tpl_len,zend_array * symbol_table,zval * ret)322 static int yaf_view_render_tpl(yaf_view_t *view, const char *tpl, uint32_t tpl_len, zend_array *symbol_table, zval *ret) /* {{{ */ {
323 	int status = 0;
324 	zend_stat_t sb;
325 	zend_file_handle file_handle;
326 	zend_op_array *op_array;
327 
328 	if (UNEXPECTED(VCWD_STAT(tpl, &sb) == -1)) {
329 		yaf_trigger_error(YAF_ERR_NOTFOUND_VIEW, "Failed opening template %s: %s", tpl, strerror(errno));
330 		return 0;
331 	}
332 
333 #if PHP_VERSION_ID < 70400
334 	file_handle.filename = tpl;
335 	file_handle.type = ZEND_HANDLE_FILENAME;
336 	file_handle.free_filename = 0;
337 	file_handle.opened_path = NULL;
338 	file_handle.handle.fp = NULL;
339 #else
340 	/* setup file-handle */
341 	zend_stream_init_filename(&file_handle, tpl);
342 #endif
343 
344 	op_array = zend_compile_file(&file_handle, ZEND_INCLUDE);
345 
346 	if (op_array) {
347 		if (file_handle.handle.stream.handle) {
348 			if (!file_handle.opened_path) {
349 				file_handle.opened_path = zend_string_init(tpl, tpl_len, 0);
350 			}
351 			zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path);
352 		}
353 
354 		status = yaf_view_exec_tpl(view, op_array, symbol_table, ret);
355 
356 		destroy_op_array(op_array);
357 		efree_size(op_array, sizeof(zend_op_array));
358 	}
359 
360 	zend_destroy_file_handle(&file_handle);
361 
362 	return status;
363 }
364 /* }}} */
365 
yaf_view_simple_render(yaf_view_t * view,zend_string * tpl,zval * vars,zval * ret)366 int yaf_view_simple_render(yaf_view_t *view, zend_string *tpl, zval *vars, zval *ret) /* {{{ */ {
367 	zend_array symbol_table;
368 	char directory[MAXPATHLEN];
369 	char *tpl_dir;
370 	uint32_t tpl_len;
371 	yaf_view_object *v = Z_YAFVIEWOBJ_P(view);
372 
373 	yaf_view_build_symtable(&symbol_table, &v->tpl_vars, vars);
374 
375 	tpl_dir = ZSTR_VAL(tpl);
376 	tpl_len = ZSTR_LEN(tpl);
377 	if (!IS_ABSOLUTE_PATH(tpl_dir, tpl_len)) {
378 		if (UNEXPECTED(v->tpl_dir == NULL)) {
379 			zend_hash_destroy(&symbol_table);
380 			yaf_trigger_error(YAF_ERR_NOTFOUND_VIEW,
381 					"Could not determine the view script path, you should call %s::setScriptPath to specific it",
382 					ZSTR_VAL(yaf_view_simple_ce->name));
383 			return 0;
384 		} else {
385 			zend_string *v_tpl = v->tpl_dir;
386 			tpl_len = yaf_compose_2_pathes(directory, v_tpl, tpl_dir, tpl_len);
387 			directory[tpl_len] = '\0';
388 			tpl_dir = directory;
389 		}
390 	}
391 
392 	if (EXPECTED(yaf_view_render_tpl(view, tpl_dir, tpl_len, &symbol_table, ret))) {
393 		zend_hash_destroy(&symbol_table);
394 		return 1;
395 	}
396 
397 	zend_hash_destroy(&symbol_table);
398 	return 0;
399 }
400 /* }}} */
401 
yaf_view_simple_eval(yaf_view_t * view,zend_string * tpl,zval * vars,zval * ret)402 static int yaf_view_simple_eval(yaf_view_t *view, zend_string *tpl, zval * vars, zval *ret) /* {{{ */ {
403 	zend_array symbol_table;
404 
405 	if (ZSTR_LEN(tpl)) {
406 		zval phtml;
407 		zend_op_array *op_array;
408 		char *eval_desc = zend_make_compiled_string_description("template code");
409 
410 		/* eval require code mustn't be wrapped in opening and closing PHP tags */
411 		ZVAL_STR(&phtml, strpprintf(0, "?>%s", ZSTR_VAL(tpl)));
412 #if PHP_VERSION_ID < 80000
413 		op_array = zend_compile_string(&phtml, eval_desc);
414 #else
415         op_array = zend_compile_string(Z_STR(phtml), eval_desc);
416 #endif
417 		zval_dtor(&phtml);
418 		efree(eval_desc);
419 
420 		if (op_array) {
421 			yaf_view_build_symtable(&symbol_table, &(Z_YAFVIEWOBJ_P(view))->tpl_vars, vars);
422 			yaf_view_exec_tpl(view, op_array, &symbol_table, ret);
423 			destroy_op_array(op_array);
424 			efree_size(op_array, sizeof(zend_op_array));
425 		}
426 	}
427 
428 	zend_hash_destroy(&symbol_table);
429 
430 	return 1;
431 }
432 /* }}} */
433 
yaf_view_simple_assign_single(yaf_view_object * view,zend_string * name,zval * value)434 static zend_always_inline void yaf_view_simple_assign_single(yaf_view_object *view, zend_string *name, zval *value) /* {{{ */ {
435 	zend_hash_update(&view->tpl_vars, name, value);
436 	Z_TRY_ADDREF_P(value);
437 }
438 /* }}} */
439 
yaf_view_simple_assign_multi(yaf_view_object * view,zval * value)440 static void yaf_view_simple_assign_multi(yaf_view_object *view, zval *value) /* {{{ */ {
441 	zend_hash_copy(&view->tpl_vars, Z_ARRVAL_P(value), (copy_ctor_func_t) zval_add_ref);
442 }
443 /* }}} */
444 
yaf_view_simple_clear_assign(yaf_view_object * view,zend_string * name)445 static void yaf_view_simple_clear_assign(yaf_view_object *view, zend_string *name) /* {{{ */ {
446 	if (name) {
447 		zend_hash_del(&view->tpl_vars, name);
448 	} else {
449 		zend_hash_clean(&view->tpl_vars);
450 	}
451 }
452 /* }}} */
453 
454 /** {{{ proto public Yaf_View_Simple::__construct(string $tpl_dir, array $options = NULL)
455 */
PHP_METHOD(yaf_view_simple,__construct)456 PHP_METHOD(yaf_view_simple, __construct) {
457 	zend_string *tpl_dir;
458 	zval *options = NULL;
459 
460 	if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "S|a!", &tpl_dir, &options) == FAILURE) {
461 		return;
462 	}
463 
464 	yaf_view_simple_init(Z_YAFVIEWOBJ_P(getThis()), tpl_dir, options? Z_ARRVAL_P(options) : NULL);
465 }
466 /* }}} */
467 
468 /** {{{ proto public Yaf_View_Simple::setScriptPath(string $tpl_dir)
469 */
PHP_METHOD(yaf_view_simple,setScriptPath)470 PHP_METHOD(yaf_view_simple, setScriptPath) {
471 	zend_string *tpl_dir;
472 	yaf_view_object *view = Z_YAFVIEWOBJ_P(getThis());
473 
474 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &tpl_dir) == FAILURE) {
475 		return;
476 	}
477 
478 	if (IS_ABSOLUTE_PATH(ZSTR_VAL(tpl_dir), ZSTR_LEN(tpl_dir))) {
479 		if (view->tpl_dir) {
480 			zend_string_release(view->tpl_dir);
481 		}
482 		view->tpl_dir = zend_string_copy(tpl_dir);
483 		RETURN_ZVAL(getThis(), 1, 0);
484 	}
485 
486 	RETURN_FALSE;
487 }
488 /* }}} */
489 
490 /** {{{ proto public Yaf_View_Simple::getScriptPath(Yaf_Request_Abstarct $request = NULL)
491 */
PHP_METHOD(yaf_view_simple,getScriptPath)492 PHP_METHOD(yaf_view_simple, getScriptPath) {
493 	yaf_request_t *request = NULL;
494 	yaf_view_object *view = Z_YAFVIEWOBJ_P(getThis());
495 
496 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "|O!", &request, yaf_request_ce) == FAILURE) {
497 		return;
498 	}
499 
500 	if (view->tpl_dir) {
501 		RETURN_STR_COPY(view->tpl_dir);
502 	}
503 
504 	RETURN_NULL();
505 }
506 /* }}} */
507 
508 /** {{{ proto public Yaf_View_Simple::assign(mixed $value, mixed $value = null)
509 */
PHP_METHOD(yaf_view_simple,assign)510 PHP_METHOD(yaf_view_simple, assign) {
511 	yaf_view_object *view = Z_YAFVIEWOBJ_P(getThis());
512 
513 	if (ZEND_NUM_ARGS() == 2) {
514 		zval *value;
515 		zend_string *name;
516 		if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sz", &name, &value) == FAILURE) {
517 			return;
518 		}
519 	    yaf_view_simple_assign_single(view, name, value);
520 		RETURN_ZVAL(getThis(), 1, 0);
521 	} else if (ZEND_NUM_ARGS() == 1) {
522 		zval *value;
523 		if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &value) == FAILURE) {
524 			return;
525 		}
526 		yaf_view_simple_assign_multi(view, value);
527 		RETURN_ZVAL(getThis(), 1, 0);
528 	} else {
529 		WRONG_PARAM_COUNT;
530 		RETURN_FALSE;
531 	}
532 }
533 /* }}} */
534 
535 /** {{{ proto public Yaf_View_Simple::assignRef(mixed $value, mixed &$value)
536 */
PHP_METHOD(yaf_view_simple,assignRef)537 PHP_METHOD(yaf_view_simple, assignRef) {
538 	zend_string *name;
539 	zval *value;
540 	yaf_view_object *view = Z_YAFVIEWOBJ_P(getThis());
541 
542 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sz", &name, &value) == FAILURE) {
543 		return;
544 	}
545 
546 	yaf_view_simple_assign_single(view, name, value);
547 
548 	RETURN_ZVAL(getThis(), 1, 0);
549 }
550 /* }}} */
551 
552 /** {{{ proto public Yaf_View_Simple::get($name)
553 */
PHP_METHOD(yaf_view_simple,get)554 PHP_METHOD(yaf_view_simple, get) {
555 	zend_string *name = NULL;
556 	yaf_view_object *view = Z_YAFVIEWOBJ_P(getThis());
557 
558 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!", &name) == FAILURE) {
559 		return;
560 	}
561 
562 	if (name && ZSTR_LEN(name)) {
563 		zval *val = zend_hash_find(&view->tpl_vars, name);
564 		if (val) {
565 			RETURN_ZVAL(val, 1, 0);
566 		} else {
567 			RETURN_NULL();
568 		}
569 	} else {
570 		RETURN_ARR(zend_array_dup(&view->tpl_vars));
571 	}
572 }
573 /* }}} */
574 
575 /** {{{ proto public Yaf_View_Simple::render(string $tpl, array $vars = NULL)
576 */
PHP_METHOD(yaf_view_simple,render)577 PHP_METHOD(yaf_view_simple, render) {
578 	zval *tpl;
579 	zval *vars = NULL;
580 
581 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|a!", &tpl, &vars) == FAILURE) {
582 		return;
583 	}
584 
585 	if (UNEXPECTED(Z_TYPE_P(tpl) != IS_STRING || Z_STRLEN_P(tpl) == 0)) {
586 		RETURN_FALSE;
587 	}
588 
589 	if (!yaf_view_simple_render(getThis(), Z_STR_P(tpl), vars, return_value)) {
590 		RETURN_FALSE;
591 	}
592 }
593 /* }}} */
594 
595 /** {{{ proto public Yaf_View_Simple::eval(string $tpl_content, array $vars = NULL)
596 */
PHP_METHOD(yaf_view_simple,eval)597 PHP_METHOD(yaf_view_simple, eval) {
598 	zend_string *tpl;
599 	zval *vars = NULL;
600 
601 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|a!", &tpl, &vars) == FAILURE) {
602 		return;
603 	}
604 
605 	if (!yaf_view_simple_eval(getThis(), tpl, vars, return_value)) {
606 		RETURN_FALSE;
607 	}
608 }
609 /* }}} */
610 
611 /** {{{ proto public Yaf_View_Simple::display(string $tpl, array $vars = NULL)
612 */
PHP_METHOD(yaf_view_simple,display)613 PHP_METHOD(yaf_view_simple, display) {
614 	zval *tpl;
615 	zval *vars = NULL;
616 
617 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|a!", &tpl, &vars) == FAILURE) {
618 		return;
619 	}
620 
621 	if (UNEXPECTED(Z_TYPE_P(tpl) != IS_STRING || Z_STRLEN_P(tpl) == 0)) {
622 		RETURN_FALSE;
623 	}
624 
625 	if (!yaf_view_simple_render(getThis(), Z_STR_P(tpl), vars, NULL)) {
626 		RETURN_FALSE;
627 	}
628 
629 	RETURN_TRUE;
630 }
631 /* }}} */
632 
633 /** {{{ proto public Yaf_View_Simple::clear(string $name)
634 */
PHP_METHOD(yaf_view_simple,clear)635 PHP_METHOD(yaf_view_simple, clear) {
636 	zend_string *name = NULL;
637 	yaf_view_object *view = Z_YAFVIEWOBJ_P(getThis());
638 
639 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!", &name) == FAILURE) {
640 		return;
641 	}
642 
643 	yaf_view_simple_clear_assign(view, name);
644 
645 	RETURN_ZVAL(getThis(), 1, 0);
646 }
647 /* }}} */
648 
649 /** {{{ yaf_view_simple_methods
650 */
651 zend_function_entry yaf_view_simple_methods[] = {
652 	PHP_ME(yaf_view_simple, __construct, yaf_view_simple_construct_arginfo, ZEND_ACC_CTOR|ZEND_ACC_FINAL|ZEND_ACC_PUBLIC)
653 	PHP_ME(yaf_view_simple, get, yaf_view_simple_get_arginfo, ZEND_ACC_PUBLIC)
654 	PHP_ME(yaf_view_simple, assign, yaf_view_assign_arginfo, ZEND_ACC_PUBLIC)
655 	PHP_ME(yaf_view_simple, render, yaf_view_render_arginfo, ZEND_ACC_PUBLIC)
656 	PHP_ME(yaf_view_simple, eval,  yaf_view_simple_eval_arginfo, ZEND_ACC_PUBLIC)
657 	PHP_ME(yaf_view_simple, display, yaf_view_display_arginfo, ZEND_ACC_PUBLIC)
658 	PHP_ME(yaf_view_simple, assignRef, yaf_view_simple_assign_by_ref_arginfo, ZEND_ACC_PUBLIC)
659 	PHP_ME(yaf_view_simple, clear, yaf_view_simple_clear_arginfo, ZEND_ACC_PUBLIC)
660 	PHP_ME(yaf_view_simple, setScriptPath, yaf_view_setpath_arginfo, ZEND_ACC_PUBLIC)
661 	PHP_ME(yaf_view_simple, getScriptPath, yaf_view_getpath_arginfo, ZEND_ACC_PUBLIC)
662 	PHP_MALIAS(yaf_view_simple, __get, get, yaf_view_simple_get_arginfo, ZEND_ACC_PUBLIC)
663 	PHP_MALIAS(yaf_view_simple, __set, assign, yaf_view_assign_arginfo, ZEND_ACC_PUBLIC)
664 	{NULL, NULL, NULL}
665 };
666 /* }}} */
667 
668 /** {{{ YAF_STARTUP_FUNCTION
669 */
YAF_STARTUP_FUNCTION(view_simple)670 YAF_STARTUP_FUNCTION(view_simple) {
671 	zend_class_entry ce;
672 
673 	YAF_INIT_CLASS_ENTRY(ce, "Yaf_View_Simple", "Yaf\\View\\Simple", yaf_view_simple_methods);
674 	yaf_view_simple_ce = zend_register_internal_class_ex(&ce, NULL);
675 	yaf_view_simple_ce->create_object = yaf_view_simple_new;
676 	yaf_view_simple_ce->serialize = zend_class_serialize_deny;
677 	yaf_view_simple_ce->unserialize = zend_class_unserialize_deny;
678 
679 	zend_class_implements(yaf_view_simple_ce, 1, yaf_view_interface_ce);
680 
681 	memcpy(&yaf_view_simple_obj_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
682 	yaf_view_simple_obj_handlers.offset = XtOffsetOf(yaf_view_object, std);
683 	yaf_view_simple_obj_handlers.free_obj = yaf_view_object_free;
684 	yaf_view_simple_obj_handlers.get_properties = yaf_view_simple_get_properties;
685 	yaf_view_simple_obj_handlers.read_property = (zend_object_read_property_t)yaf_view_simple_read_property;
686 	yaf_view_simple_obj_handlers.write_property = (zend_object_write_property_t)yaf_view_simple_write_property;
687 	yaf_view_simple_obj_handlers.clone_obj = NULL;
688 	yaf_view_simple_obj_handlers.get_gc = yaf_fake_get_gc;
689 
690 
691 	return SUCCESS;
692 }
693 /* }}} */
694 
695 /*
696  * Local variables:
697  * tab-width: 4
698  * c-basic-offset: 4
699  * End:
700  * vim600: noet sw=4 ts=4 fdm=marker
701  * vim<600: noet sw=4 ts=4
702  */
703 
704