summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2011-08-30 10:58:19 +0000
committerXinchen Hui <laruence@php.net>2011-08-30 10:58:19 +0000
commita9144cc299d2e1d92e146dd1d4e830beef9879d7 (patch)
tree1234de1f1ab72e3fdaf3b204fd98c1e23860886b
downloadphp-git-a9144cc299d2e1d92e146dd1d4e830beef9879d7.tar.gz
Tagging the 2.1.0 releaseyaf-2.1.0
-rw-r--r--CREDITS2
-rw-r--r--EXPERIMENTAL0
-rw-r--r--config.m445
-rw-r--r--config.w3210
-rw-r--r--configs/ini.c793
-rw-r--r--configs/simple.c369
-rw-r--r--package2.xml193
-rw-r--r--php_yaf.h144
-rw-r--r--requests/http.c284
-rw-r--r--requests/simple.c269
-rw-r--r--response/cli.c49
-rw-r--r--response/http.c51
-rw-r--r--routes/interface.c145
-rw-r--r--routes/map.c178
-rw-r--r--routes/regex.c270
-rw-r--r--routes/rewrite.c324
-rw-r--r--routes/simple.c149
-rw-r--r--routes/static.c206
-rw-r--r--routes/supervar.c241
-rw-r--r--tests/001.phpt21
-rw-r--r--tests/002.phpt53
-rw-r--r--tests/003.phpt31
-rw-r--r--tests/004.phpt28
-rw-r--r--tests/005.phpt35
-rw-r--r--tests/006.phpt41
-rw-r--r--tests/007.phpt94
-rw-r--r--tests/008.phpt70
-rw-r--r--tests/009.phpt37
-rw-r--r--tests/010.phpt315
-rw-r--r--tests/011.phpt37
-rw-r--r--tests/012.phpt42
-rw-r--r--tests/013.phpt122
-rw-r--r--tests/014.phpt142
-rw-r--r--tests/015.phpt17
-rw-r--r--tests/016.phpt42
-rw-r--r--tests/simple.ini31
-rw-r--r--views/interface.c77
-rw-r--r--views/simple.c687
-rw-r--r--yaf.c275
-rw-r--r--yaf.dsp276
-rw-r--r--yaf.php21
-rw-r--r--yaf_action.c81
-rw-r--r--yaf_action.h37
-rw-r--r--yaf_application.c650
-rw-r--r--yaf_application.h34
-rw-r--r--yaf_bootstrap.c59
-rw-r--r--yaf_bootstrap.h38
-rw-r--r--yaf_config.c401
-rw-r--r--yaf_config.h52
-rw-r--r--yaf_controller.c542
-rw-r--r--yaf_controller.h44
-rw-r--r--yaf_dispatcher.c1359
-rw-r--r--yaf_dispatcher.h73
-rw-r--r--yaf_exception.c209
-rw-r--r--yaf_exception.h79
-rw-r--r--yaf_loader.c882
-rw-r--r--yaf_loader.h107
-rw-r--r--yaf_logo.h182
-rw-r--r--yaf_namespace.h62
-rw-r--r--yaf_plugin.c149
-rw-r--r--yaf_plugin.h33
-rw-r--r--yaf_registry.c230
-rw-r--r--yaf_registry.h36
-rw-r--r--yaf_request.c835
-rw-r--r--yaf_request.h103
-rw-r--r--yaf_response.c383
-rw-r--r--yaf_response.h39
-rw-r--r--yaf_router.c378
-rw-r--r--yaf_router.h45
-rw-r--r--yaf_session.c376
-rw-r--r--yaf_session.h38
-rw-r--r--yaf_view.c93
-rw-r--r--yaf_view.h42
73 files changed, 13887 insertions, 0 deletions
diff --git a/CREDITS b/CREDITS
new file mode 100644
index 0000000000..29fb21531a
--- /dev/null
+++ b/CREDITS
@@ -0,0 +1,2 @@
+Yaf
+Xinchen Hui<Laruence@php.net>
diff --git a/EXPERIMENTAL b/EXPERIMENTAL
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/EXPERIMENTAL
diff --git a/config.m4 b/config.m4
new file mode 100644
index 0000000000..fe97b239a7
--- /dev/null
+++ b/config.m4
@@ -0,0 +1,45 @@
+PHP_ARG_ENABLE(yaf, whether to enable yaf support,
+[ --enable-yaf Enable yaf support])
+
+AC_ARG_ENABLE(yaf-debug,
+[ --enable-yaf-debug Enable yaf debug mode default=no],
+[PHP_YAF_DEBUG=$enableval],
+[PHP_YAF_DEBUG="no"])
+
+if test "$PHP_YAF" != "no"; then
+
+ if test "$PHP_YAF_DEBUG" = "yes"; then
+ AC_DEFINE(PHP_YAF_DEBUG,1,[define to 1 if you want to change the POST/GET by php script])
+ else
+ AC_DEFINE(PHP_YAF_DEBUG,0,[define to 1 if you want to change the POST/GET by php script])
+ fi
+
+ AC_MSG_CHECKING([PHP version])
+
+ tmp_version=$PHP_VERSION
+ if test -z "$tmp_version"; then
+ if test -z "$PHP_CONFIG"; then
+ AC_MSG_ERROR([php-config not found])
+ fi
+ php_version=`$PHP_CONFIG --version 2>/dev/null|head -n 1|sed -e 's#\([0-9]\.[0-9]*\.[0-9]*\)\(.*\)#\1#'`
+ else
+ php_version=`echo "$tmp_version"|sed -e 's#\([0-9]\.[0-9]*\.[0-9]*\)\(.*\)#\1#'`
+ fi
+
+ if test -z "$php_version"; then
+ AC_MSG_ERROR([failed to detect PHP version, please report])
+ fi
+
+ ac_IFS=$IFS
+ IFS="."
+ set $php_version
+ IFS=$ac_IFS
+ yaf_php_version=`expr [$]1 \* 1000000 + [$]2 \* 1000 + [$]3`
+
+ if test "$yaf_php_version" -le "5002000"; then
+ AC_MSG_ERROR([You need at least PHP 5.2.0 to be able to use this version of Yaf. PHP $php_version found])
+ else
+ AC_MSG_RESULT([$php_version, ok])
+ fi
+ PHP_NEW_EXTENSION(yaf, yaf.c yaf_application.c yaf_bootstrap.c yaf_dispatcher.c yaf_exception.c yaf_config.c yaf_request.c yaf_response.c yaf_view.c yaf_controller.c yaf_action.c yaf_router.c yaf_loader.c yaf_registry.c yaf_plugin.c yaf_session.c, $ext_shared)
+fi
diff --git a/config.w32 b/config.w32
new file mode 100644
index 0000000000..76cf1e4f26
--- /dev/null
+++ b/config.w32
@@ -0,0 +1,10 @@
+// $Id: config.w32 765 2010-10-21 13:04:03Z huixinchen $
+// vim:ft=javascript
+
+ARG_ENABLE("yaf", "enable yaf support", "no");
+
+if (PHP_YAF == "yes") {
+ EXTENSION("yaf", "yaf.c yaf_application.c yaf_loader.c yaf_bootstrap.c yaf_config.c yaf_dispatcher.c yaf_registry.c yaf_controller.c yaf_action.c yaf_view.c yaf_request.c yaf_response.c yaf_router.c yaf_exception.c yaf_plugin.c yaf_session.c");
+
+ AC_DEFINE("HAVE_YAF", 1, "Have Yaf Support");
+}
diff --git a/configs/ini.c b/configs/ini.c
new file mode 100644
index 0000000000..6054b3aa83
--- /dev/null
+++ b/configs/ini.c
@@ -0,0 +1,793 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+zend_class_entry *yaf_config_ini_ce;
+
+yaf_config_t * yaf_config_ini_instance(yaf_config_t *this_ptr, zval *filename, zval *section TSRMLS_DC);
+
+/** {{{ ARG_INFO
+ */
+ZEND_BEGIN_ARG_INFO_EX(yaf_config_ini_construct_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, config_file)
+ ZEND_ARG_INFO(0, section)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_config_ini_get_arginfo, 0, 0, 0)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_config_ini_rget_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_config_ini_unset_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_config_ini_set_arginfo, 0, 0, 2)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_config_ini_isset_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/** {{{ static unsigned int numerics[256]
+*/
+static unsigned int numerics[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3,
+ 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+/* }}} */
+
+/** {{{ static int yaf_config_is_numeric(char *str TSRMLS_DC)
+*/
+static inline int yaf_config_ini_is_numeric(char *str TSRMLS_DC) {
+ int i,j;
+ int ret = 0;
+
+ for(i=0, j=strlen(str); i<j; i++) {
+ if ((numerics[(unsigned char)str[i]])) {
+ ret = ret*10 + (numerics[(unsigned char)str[i]] - 1);
+ } else {
+ return -1;
+ }
+ }
+ return ret;
+}
+/* }}} */
+
+/** {{{ zval * yaf_config_ini_format(yaf_config_t *instance, zval **ppzval TSRMLS_DC)
+*/
+zval * yaf_config_ini_format(yaf_config_t *instance, zval **ppzval TSRMLS_DC) {
+ zval *readonly, *ret;
+ readonly = zend_read_property(yaf_config_ini_ce, instance, ZEND_STRL(YAF_CONFIG_PROPERT_NAME_READONLY), 1 TSRMLS_CC);
+ ret = yaf_config_ini_instance(NULL, *ppzval, NULL TSRMLS_CC);
+ return ret;
+}
+/* }}} */
+
+/** {{{ static zval * yaf_config_ini_parse_entry(HashTable * ht, char * name, int start, int name_len, long index TSRMLS_DC)
+ * parse string to array
+ */
+static zval * yaf_config_ini_parse_entry(HashTable *ht, char *name, int start, int name_len, long index TSRMLS_DC) {
+ char *key;
+ uint keylen;
+ long idx;
+ HashPointer position;
+ zval **ppzval, *ret = NULL;
+ int found = 0;
+
+ if (index) {
+ /* HASH_KEY_IS_LONG */
+ for(zend_hash_internal_pointer_reset(ht);
+ zend_hash_has_more_elements(ht) == SUCCESS;
+ zend_hash_move_forward(ht)) {
+
+ if (zend_hash_get_current_key_ex(ht, &key, &keylen, &idx, 0, NULL) != HASH_KEY_IS_LONG) {
+ continue;
+ }
+ if (idx != index) {
+ continue;
+ }
+ if (zend_hash_get_current_data(ht, (void**)&ppzval) == FAILURE) {
+ continue;
+ }
+ ret = *ppzval;
+ Z_ADDREF_P(ret);
+ }
+ } else {
+ /* HASH_KEY_IS_STRING */
+ for(zend_hash_internal_pointer_reset(ht);
+ zend_hash_has_more_elements(ht) == SUCCESS;
+ zend_hash_move_forward(ht)) {
+ if (zend_hash_get_current_key_ex(ht, &key, &keylen, &idx, 0, NULL) != HASH_KEY_IS_STRING) {
+ continue;
+ }
+ if (keylen != name_len || strncasecmp(key, name, name_len)) {
+ continue;
+ }
+ if (zend_hash_get_current_data(ht, (void**)&ppzval) == FAILURE) {
+ continue;
+ }
+
+ found = 1;
+ ret = *ppzval;
+ Z_ADDREF_P(ret);
+ }
+
+ if (!found) {
+ char * record_name = emalloc(name_len + 1);
+
+ memcpy(record_name, name, name_len - 1);
+ record_name[name_len - 1] = '.';
+ record_name[name_len] = '\0';
+
+ MAKE_STD_ZVAL(ret);
+ array_init(ret);
+ for(zend_hash_internal_pointer_reset(ht);
+ zend_hash_has_more_elements(ht) == SUCCESS;
+ zend_hash_move_forward(ht)) {
+ if (zend_hash_get_current_key_ex(ht, &key, &keylen, &idx, 0, NULL) != HASH_KEY_IS_STRING) {
+ continue;
+ }
+ if (strncasecmp(key, record_name, name_len)) {
+ continue;
+ } else {
+ zval *son = NULL;
+ int real_key_len, long_key;
+ char *real_key = strstr(key + name_len + 1, ".");
+
+ zend_hash_get_pointer(ht, &position);
+ if (real_key == NULL) {
+ son = yaf_config_ini_parse_entry(ht, key, name_len - 1, keylen, 0 TSRMLS_CC);
+ real_key = estrdup(key + name_len);
+ real_key_len = strlen(real_key) + 1;
+ } else {
+ son = yaf_config_ini_parse_entry(ht, key, name_len - 1 , real_key - key + 1, 0 TSRMLS_CC);
+ real_key_len = real_key - (key + name_len) + 1;
+ real_key = estrdup(key + name_len);
+ *(real_key + real_key_len - 1) = '\0';
+ }
+
+ if (!son) {
+ efree(real_key);
+ continue;
+ }
+
+ zend_hash_set_pointer(ht, &position);
+ if((long_key = yaf_config_ini_is_numeric(real_key TSRMLS_CC)) >= 0) {
+ zend_hash_index_update(Z_ARRVAL_P(ret), long_key, (void **)&son, sizeof(zval *), NULL);
+ } else {
+ zend_hash_update(Z_ARRVAL_P(ret), real_key, real_key_len , (void **)&son, sizeof(zval *), NULL);
+ }
+ efree(real_key);
+ }
+ }
+ efree(record_name);
+ }
+ }
+
+ return ret;
+}
+/* }}} */
+
+/** {{{ static HashTable * yaf_config_ini_parse_record(HashTable * ht TSRMLS_DC)
+ * parse string to array
+ */
+static HashTable * yaf_config_ini_parse_record(HashTable *ht TSRMLS_DC) {
+ char *key, *real_key;
+ uint keylen;
+ long idx;
+ zval *tmp, *dummy;
+ HashTable *ret;
+
+ ALLOC_HASHTABLE(ret);
+ zend_hash_init(ret, 64, NULL, ZVAL_PTR_DTOR, 0);
+
+ MAKE_STD_ZVAL(dummy);
+ ZVAL_NULL(dummy);
+ for(zend_hash_internal_pointer_reset(ht);
+ zend_hash_has_more_elements(ht) == SUCCESS;
+ zend_hash_move_forward(ht)) {
+ switch (zend_hash_get_current_key_ex(ht, &key, &keylen, &idx, 0, NULL)) {
+ case HASH_KEY_IS_STRING:
+ if ((real_key = strstr(key, "."))) {
+ keylen = real_key - key;
+ real_key = estrndup(key, keylen);
+ if (zend_hash_exists(ret, real_key, keylen + 1)) {
+ efree(real_key);
+ continue;
+ }
+
+ Z_ADDREF_P(dummy);
+ zend_hash_update(ret, real_key, keylen + 1, (void **)&dummy, sizeof(zval *), NULL);
+ efree(real_key);
+ } else {
+ if (zend_hash_exists(ret, key, keylen)) {
+ continue;
+ }
+ Z_ADDREF_P(dummy);
+ zend_hash_update(ret, key, keylen, (void **)&dummy, sizeof(zval *), NULL);
+ }
+ break;
+ case HASH_KEY_IS_LONG:
+ Z_ADDREF_P(dummy);
+ zend_hash_index_update(ret, idx, (void **)&dummy, sizeof(zval *), NULL);
+ break;
+ default:
+ continue;
+ }
+ }
+ zval_ptr_dtor(&dummy);
+
+ for(zend_hash_internal_pointer_reset(ret);
+ zend_hash_has_more_elements(ret) == SUCCESS;
+ zend_hash_move_forward(ret)) {
+ switch (zend_hash_get_current_key_ex(ret, &key, &keylen, &idx, 0, NULL)) {
+ case HASH_KEY_IS_STRING:
+ if ((tmp = yaf_config_ini_parse_entry(ht, key, 0, keylen, 0 TSRMLS_CC))) {
+ zend_hash_update(ret, key, keylen , (void **)&tmp, sizeof(zval *), NULL);
+ }
+ break;
+ case HASH_KEY_IS_LONG:
+ if ((tmp = yaf_config_ini_parse_entry(ht, NULL, 0, 0, idx TSRMLS_CC))) {
+ zend_hash_index_update(ret, idx, (void **)&tmp, sizeof(zval *), NULL);
+ }
+ break;
+ default:
+ continue;
+ }
+ }
+
+ return ret;
+}
+/* }}} */
+
+/** {{{static zval * yaf_config_ini_parse_section(HashTable *ht, char *name, int len, long index TSRMLS_DC)
+*/
+static zval * yaf_config_ini_parse_section(HashTable *ht, char *name, int len, long index TSRMLS_DC) {
+ zval *parent, **ppzval;
+ char *key, *buf;
+ long idx;
+ uint keylen;
+ HashPointer position;
+ zval *section;
+
+ MAKE_STD_ZVAL(section);
+ array_init(section);
+
+ if (name) {
+ for(zend_hash_internal_pointer_reset(ht);
+ zend_hash_has_more_elements(ht) == SUCCESS;
+ zend_hash_move_forward(ht)) {
+
+ if (zend_hash_get_current_key_ex(ht, &key, &keylen, &idx, 0, NULL) != HASH_KEY_IS_STRING) {
+ continue;
+ }
+
+ if (strncasecmp(key, name, len)) {
+ continue;
+ }
+
+ if (zend_hash_get_current_data(ht, (void**)&ppzval) == FAILURE) {
+ continue;
+ }
+
+ if (Z_TYPE_PP(ppzval) != IS_ARRAY) {
+ continue;
+ }
+
+ zend_hash_merge(Z_ARRVAL_P(section), Z_ARRVAL_PP(ppzval), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *), 0);
+
+ if ((buf = strstr(key, ":"))) {
+ char *parent_section, *tmp;
+ uint parent_len;
+ while((++buf)[0] == ' ');
+
+ parent_section = buf;
+
+ if ((tmp = strstr(parent_section, ":"))) {
+ parent_len = tmp - parent_section;
+ } else {
+ parent_len = strlen(parent_section);
+ }
+
+ /* in case of nesting like "section : section" */
+ if (strncasecmp(buf, name, len)) {
+ zend_hash_get_pointer(ht, &position);
+ parent = yaf_config_ini_parse_section(ht, parent_section, parent_len, 0 TSRMLS_CC);
+ zend_hash_set_pointer(ht, &position);
+ zend_hash_merge(Z_ARRVAL_P(parent), Z_ARRVAL_P(section), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *), 1);
+ zval_ptr_dtor(&section);
+ section = parent;
+ parent = NULL;
+ }
+ }
+
+ break;
+ }
+ } else {
+ /* HASH_KEY_IS_LONG */
+ for(zend_hash_internal_pointer_reset(ht);
+ zend_hash_has_more_elements(ht) == SUCCESS;
+ zend_hash_move_forward(ht)) {
+
+ if (zend_hash_get_current_key_ex(ht, &key, &keylen, &idx, 0, NULL) != HASH_KEY_IS_LONG) {
+ continue;
+ }
+
+ if (idx != index) {
+ continue;
+ }
+
+ if (zend_hash_get_current_data(ht, (void**)&ppzval) == FAILURE) {
+ continue;
+ }
+
+ if (Z_TYPE_PP(ppzval) != IS_ARRAY) {
+ continue;
+ }
+
+ zend_hash_merge(Z_ARRVAL_P(section), Z_ARRVAL_PP(ppzval), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *), 0);
+ }
+ }
+
+ return section;
+}
+/* }}} */
+
+/** {{{ yaf_config_t * yaf_config_ini_instance(yaf_config_t *this_ptr, zval *filename, zval *section_name TSRMLS_DC)
+*/
+yaf_config_t * yaf_config_ini_instance(yaf_config_t *this_ptr, zval *filename, zval *section_name TSRMLS_DC) {
+ yaf_config_t *instance;
+ zval *configs;
+
+ if (filename && Z_TYPE_P(filename) == IS_ARRAY) {
+ if (this_ptr) {
+ instance = this_ptr;
+ } else {
+ MAKE_STD_ZVAL(instance);
+ object_init_ex(instance, yaf_config_ini_ce);
+ }
+
+ zend_update_property(yaf_config_ini_ce, instance, ZEND_STRL(YAF_CONFIG_PROPERT_NAME), filename TSRMLS_CC);
+
+ return instance;
+ } else if (filename && Z_TYPE_P(filename) == IS_STRING) {
+ zval *ini_entries, *process_section;
+ zval function = {{0}, 0}; /* missing braces around initializer */
+ zval *params[2] = {0};
+
+ MAKE_STD_ZVAL(process_section);
+ ZVAL_TRUE(process_section);
+
+ params[0] = filename;
+ params[1] = process_section;
+
+ ZVAL_STRING(&function, "parse_ini_file", 0);
+
+ MAKE_STD_ZVAL(ini_entries);
+ ZVAL_FALSE(ini_entries);
+ /* since config need section parsing
+ * so it's difficult to call zend_parse_ini_file directly
+ */
+ if (call_user_function(EG(function_table), NULL, &function, ini_entries, 2, params TSRMLS_CC) == FAILURE) {
+ efree(process_section);
+ if (ini_entries) {
+ zval_ptr_dtor(&ini_entries);
+ }
+ yaf_trigger_error(E_ERROR TSRMLS_CC, "Call to parse_ini_file failed");
+ return NULL;
+ }
+ efree(process_section);
+
+ if (Z_TYPE_P(ini_entries) != IS_ARRAY) {
+ zval_ptr_dtor(&ini_entries);
+ yaf_trigger_error(E_ERROR TSRMLS_CC, "Unable to find config file %s or it is not in INI file format", Z_STRVAL_P(filename));
+ return NULL;
+ }
+
+ if (section_name && Z_STRLEN_P(section_name)) {
+ HashTable *garbage;
+ configs = yaf_config_ini_parse_section(Z_ARRVAL_P(ini_entries), Z_STRVAL_P(section_name), Z_STRLEN_P(section_name), 0 TSRMLS_CC);
+ if (!configs) {
+ zval_ptr_dtor(&ini_entries);
+ yaf_trigger_error(E_ERROR TSRMLS_CC, "There is no section %s in %s", Z_STRVAL_P(section_name), Z_STRVAL_P(filename));
+ return NULL;
+ }
+ garbage = Z_ARRVAL_P(configs);
+ Z_ARRVAL_P(configs) = yaf_config_ini_parse_record(Z_ARRVAL_P(configs) TSRMLS_CC);
+ zend_hash_destroy(garbage);
+ efree(garbage);
+ } else {
+ uint len, section = 0;
+ long idx;
+ char *key, *tmp, *ex;
+ zval *sec, **ppzv;
+ HashTable *ht;
+ HashPointer pot = {0};
+
+ ex = ":";
+ MAKE_STD_ZVAL(configs);
+ array_init(configs);
+
+ ht = Z_ARRVAL_P(ini_entries);
+ for(zend_hash_internal_pointer_reset(ht);
+ zend_hash_has_more_elements(ht) == SUCCESS;
+ zend_hash_move_forward(ht)) {
+ switch (zend_hash_get_current_key_ex(ht, &key, &len, &idx, 0, NULL)) {
+ case HASH_KEY_IS_STRING:
+ if ((tmp = strstr(key, ex))) {
+ while(strlen(tmp) && (*(tmp - 1) == ' ' || *(tmp - 1) == ' ')) tmp--;
+ len = tmp - key;
+ } else {
+ len -= 1;
+ }
+
+ if (zend_hash_get_current_data(ht, (void **)&ppzv) == FAILURE) {
+ continue;
+ }
+ if (Z_TYPE_PP(ppzv) == IS_ARRAY) {
+ section = 1;
+ zend_hash_get_pointer(ht, &pot);
+ sec = yaf_config_ini_parse_section(ht, key, len, 0 TSRMLS_CC);
+ zend_hash_set_pointer(ht, &pot);
+ if (sec) {
+ HashTable *garbage = Z_ARRVAL_P(sec);
+ Z_ARRVAL_P(sec) = yaf_config_ini_parse_record(Z_ARRVAL_P(sec) TSRMLS_CC);
+ zend_hash_destroy(garbage);
+ efree(garbage);
+
+ if (tmp) {
+ key = estrndup(key, len);
+ zend_hash_update(Z_ARRVAL_P(configs), key, len + 1, (void **)&sec, sizeof(zval *), NULL);
+ efree(key);
+ } else {
+ zend_hash_update(Z_ARRVAL_P(configs), key, len + 1, (void **)&sec, sizeof(zval *), NULL);
+ }
+ }
+ }
+ break;
+ case HASH_KEY_IS_LONG:
+ if (zend_hash_get_current_data(ht, (void **)&ppzv) == FAILURE) {
+ continue;
+ }
+ if (Z_TYPE_PP(ppzv) == IS_ARRAY) {
+ section = 1;
+ zend_hash_get_pointer(ht, &pot);
+ sec = yaf_config_ini_parse_section(ht, NULL, 0, idx TSRMLS_CC);
+ zend_hash_set_pointer(ht, &pot);
+ if (sec) {
+ HashTable *garbage = Z_ARRVAL_P(sec);
+ Z_ARRVAL_P(sec) = yaf_config_ini_parse_record(Z_ARRVAL_P(sec) TSRMLS_CC);
+ zend_hash_destroy(garbage);
+ efree(garbage);
+ zend_hash_index_update(Z_ARRVAL_P(configs), idx, (void **)&sec, sizeof(zval *), NULL);
+ }
+ }
+ break;
+ default:
+ continue;
+ }
+
+ }
+
+ if (!section) {
+ zend_hash_copy(Z_ARRVAL_P(configs), ht, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
+ Z_ARRVAL_P(configs) = yaf_config_ini_parse_record(Z_ARRVAL_P(configs) TSRMLS_CC);
+ }
+ }
+
+ zval_ptr_dtor(&ini_entries);
+
+ if (this_ptr) {
+ instance = this_ptr;
+ } else {
+ MAKE_STD_ZVAL(instance);
+ object_init_ex(instance, yaf_config_ini_ce);
+ }
+
+ if (!configs) {
+ MAKE_STD_ZVAL(configs);
+ array_init(configs);
+ zend_update_property(yaf_config_ini_ce, instance, ZEND_STRL(YAF_CONFIG_PROPERT_NAME), configs TSRMLS_CC);
+ } else {
+ zend_update_property(yaf_config_ini_ce, instance, ZEND_STRL(YAF_CONFIG_PROPERT_NAME), configs TSRMLS_CC);
+ }
+ zval_ptr_dtor(&configs);
+
+ return instance;
+ } else {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "Invalid parameters provided, must be path of ini file");
+ return NULL;
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Ini::__construct(mixed $config_path, string $section_name)
+*/
+PHP_METHOD(yaf_config_ini, __construct) {
+ zval *filename, *section = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &filename, &section) == FAILURE) {
+ zval *prop;
+ MAKE_STD_ZVAL(prop);
+ array_init(prop);
+ zend_update_property(yaf_config_ini_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), prop TSRMLS_CC);
+ zval_ptr_dtor(&prop);
+ return;
+ }
+
+ (void)yaf_config_ini_instance(getThis(), filename, section TSRMLS_CC);
+}
+/** }}} */
+
+/** {{{ proto public Yaf_Config_Ini::get(string $name = NULL)
+*/
+PHP_METHOD(yaf_config_ini, get) {
+ zval *ret, **ppzval;
+ char *name;
+ uint len = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &len) == FAILURE) {
+ return;
+ }
+
+ if (!len) {
+ RETURN_ZVAL(getThis(), 1, 0);
+ } else {
+ zval *properties;
+ char *entry, *seg, *pptr;
+
+ properties = zend_read_property(yaf_config_ini_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+
+ if (Z_TYPE_P(properties) != IS_ARRAY) {
+ RETURN_NULL();
+ }
+
+ entry = estrndup(name, len);
+ if ((seg = php_strtok_r(entry, ".", &pptr))) {
+ while (seg) {
+ if (zend_hash_find(Z_ARRVAL_P(properties), seg, strlen(seg) + 1, (void **) &ppzval) == FAILURE) {
+ efree(entry);
+ RETURN_NULL();
+ }
+
+ properties = *ppzval;
+ seg = php_strtok_r(NULL, ".", &pptr);
+ }
+ } else {
+ if (zend_hash_find(Z_ARRVAL_P(properties), name, len + 1, (void **)&ppzval) == FAILURE) {
+ efree(entry);
+ RETURN_NULL();
+ }
+ }
+
+ efree(entry);
+
+ if (Z_TYPE_PP(ppzval) == IS_ARRAY) {
+ if ((ret = yaf_config_ini_format(getThis(), ppzval TSRMLS_CC))) {
+ RETURN_ZVAL(ret, 1, 1);
+ } else {
+ RETURN_NULL();
+ }
+ } else {
+ RETURN_ZVAL(*ppzval, 1, 0);
+ }
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Ini::toArray(void)
+*/
+PHP_METHOD(yaf_config_ini, toArray) {
+ zval *properties = zend_read_property(yaf_config_ini_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ RETURN_ZVAL(properties, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Ini::set($name, $value)
+*/
+PHP_METHOD(yaf_config_ini, set) {
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Ini::__isset($name)
+*/
+PHP_METHOD(yaf_config_ini, __isset) {
+ char * name;
+ int len;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &len) == FAILURE) {
+ return;
+ } else {
+ zval *prop = zend_read_property(yaf_config_ini_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ RETURN_BOOL(zend_hash_exists(Z_ARRVAL_P(prop), name, len + 1));
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Ini::count($name)
+*/
+PHP_METHOD(yaf_config_ini, count) {
+ zval *prop = zend_read_property(yaf_config_ini_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ RETURN_LONG(zend_hash_num_elements(Z_ARRVAL_P(prop)));
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Ini::offsetUnset($index)
+*/
+PHP_METHOD(yaf_config_ini, offsetUnset) {
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Ini::rewind(void)
+*/
+PHP_METHOD(yaf_config_ini, rewind) {
+ zval *prop = zend_read_property(yaf_config_ini_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ zend_hash_internal_pointer_reset(Z_ARRVAL_P(prop));
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Ini::current(void)
+*/
+PHP_METHOD(yaf_config_ini, current) {
+ zval *prop, **ppzval, *ret;
+
+ prop = zend_read_property(yaf_config_ini_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ if (zend_hash_get_current_data(Z_ARRVAL_P(prop), (void **)&ppzval) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ if (Z_TYPE_PP(ppzval) == IS_ARRAY) {
+ if ((ret = yaf_config_ini_format(getThis(), ppzval TSRMLS_CC))) {
+ RETURN_ZVAL(ret, 1, 1);
+ } else {
+ RETURN_NULL();
+ }
+ } else {
+ RETURN_ZVAL(*ppzval, 1, 0);
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Ini::key(void)
+*/
+PHP_METHOD(yaf_config_ini, key) {
+ zval *prop;
+ char *string;
+ long index;
+
+ prop = zend_read_property(yaf_config_ini_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ if (zend_hash_get_current_key(Z_ARRVAL_P(prop), &string, &index, 0) == HASH_KEY_IS_LONG) {
+ RETURN_LONG(index);
+ } else {
+ RETURN_STRING(string, 1);
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Ini::next(void)
+*/
+PHP_METHOD(yaf_config_ini, next) {
+ zval *prop = zend_read_property(yaf_config_ini_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ zend_hash_move_forward(Z_ARRVAL_P(prop));
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Ini::valid(void)
+*/
+PHP_METHOD(yaf_config_ini, valid) {
+ zval *prop = zend_read_property(yaf_config_ini_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ RETURN_LONG(zend_hash_has_more_elements(Z_ARRVAL_P(prop)) == SUCCESS);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Ini::readonly(void)
+*/
+PHP_METHOD(yaf_config_ini, readonly) {
+ RETURN_TRUE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Ini::__destruct
+*/
+PHP_METHOD(yaf_config_ini, __destruct) {
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Config_Ini::__clone
+*/
+PHP_METHOD(yaf_config_ini, __clone) {
+}
+/* }}} */
+
+/** {{{ yaf_config_ini_methods
+*/
+zend_function_entry yaf_config_ini_methods[] = {
+ PHP_ME(yaf_config_ini, __construct, yaf_config_ini_construct_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ /* PHP_ME(yaf_config_ini, __destruct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR) */
+ PHP_ME(yaf_config_ini, __isset, yaf_config_ini_isset_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_ini, get, yaf_config_ini_get_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_ini, set, yaf_config_ini_set_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_ini, count, yaf_config_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_ini, rewind, yaf_config_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_ini, current, yaf_config_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_ini, next, yaf_config_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_ini, valid, yaf_config_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_ini, key, yaf_config_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_ini, toArray, yaf_config_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_ini, readonly, yaf_config_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_ini, offsetUnset, yaf_config_ini_unset_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_config_ini, offsetGet, get, yaf_config_ini_rget_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_config_ini, offsetExists, __isset, yaf_config_ini_isset_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_config_ini, offsetSet, set, yaf_config_ini_set_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_config_ini, __get, get, yaf_config_ini_get_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_config_ini, __set, set, yaf_config_ini_set_arginfo, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(config_ini) {
+ zend_class_entry ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Config_Ini", "Yaf\\Config\\Ini", yaf_config_ini_methods);
+ yaf_config_ini_ce = zend_register_internal_class_ex(&ce, yaf_config_ce, NULL TSRMLS_CC);
+
+#ifdef HAVE_SPL
+ zend_class_implements(yaf_config_ini_ce TSRMLS_CC, 3, zend_ce_iterator, zend_ce_arrayaccess, spl_ce_Countable);
+#else
+ zend_class_implements(yaf_config_ini_ce TSRMLS_CC, 2, zend_ce_iterator, zend_ce_arrayaccess);
+#endif
+
+ yaf_config_ini_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/configs/simple.c b/configs/simple.c
new file mode 100644
index 0000000000..021ee85ff7
--- /dev/null
+++ b/configs/simple.c
@@ -0,0 +1,369 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+zend_class_entry *yaf_config_simple_ce;
+
+/** {{{ ARG_INFO
+ */
+ZEND_BEGIN_ARG_INFO_EX(yaf_config_simple_construct_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, config_file)
+ ZEND_ARG_INFO(0, section)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_config_simple_get_arginfo, 0, 0, 0)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_config_simple_rget_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_config_simple_set_arginfo, 0, 0, 2)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_config_simple_isset_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_config_simple_unset_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/** {{{ yaf_config_t * yaf_config_simple_instance(yaf_config_t *this_ptr, zval *values, zval *readonly TSRMLS_DC)
+*/
+yaf_config_t * yaf_config_simple_instance(yaf_config_t *this_ptr, zval *values, zval *readonly TSRMLS_DC) {
+ yaf_config_t *instance;
+
+ switch (Z_TYPE_P(values)) {
+ case IS_ARRAY:
+ if (this_ptr) {
+ instance = this_ptr;
+ } else {
+ MAKE_STD_ZVAL(instance);
+ object_init_ex(instance, yaf_config_simple_ce);
+ }
+ zend_update_property(yaf_config_simple_ce, instance, ZEND_STRL(YAF_CONFIG_PROPERT_NAME), values TSRMLS_CC);
+ if (readonly) {
+ convert_to_boolean(readonly);
+ zend_update_property_bool(yaf_config_simple_ce, instance, ZEND_STRL(YAF_CONFIG_PROPERT_NAME_READONLY), Z_BVAL_P(readonly) TSRMLS_CC);
+ }
+ return instance;
+ break;
+ default:
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "Invalid parameters provided, must be an array");
+ return NULL;
+ }
+}
+/* }}} */
+
+/** {{{ zval * yaf_config_simple_format(yaf_config_t *instance, zval **ppzval TSRMLS_DC)
+ */
+zval * yaf_config_simple_format(yaf_config_t *instance, zval **ppzval TSRMLS_DC) {
+ zval *readonly, *ret;
+ readonly = zend_read_property(yaf_config_simple_ce, instance, ZEND_STRL(YAF_CONFIG_PROPERT_NAME_READONLY), 1 TSRMLS_CC);
+ ret = yaf_config_simple_instance(NULL, *ppzval, readonly TSRMLS_CC);
+ return ret;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Simple::__construct(mixed $array, string $readonly)
+*/
+PHP_METHOD(yaf_config_simple, __construct) {
+ zval *values, *readonly = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &values, &readonly) == FAILURE) {
+ zval *prop;
+
+ MAKE_STD_ZVAL(prop);
+ array_init(prop);
+ zend_update_property(yaf_config_simple_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), prop TSRMLS_CC);
+ zval_ptr_dtor(&prop);
+
+ return;
+ }
+
+ (void)yaf_config_simple_instance(getThis(), values, readonly TSRMLS_CC);
+}
+/** }}} */
+
+/** {{{ proto public Yaf_Config_Simple::get(string $name = NULL)
+*/
+PHP_METHOD(yaf_config_simple, get) {
+ zval *ret, **ppzval;
+ char *name;
+ uint len = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &len) == FAILURE) {
+ return;
+ }
+
+ if (!len) {
+ RETURN_ZVAL(getThis(), 1, 0);
+ } else {
+ zval *properties;
+ HashTable *hash;
+
+ properties = zend_read_property(yaf_config_simple_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ hash = Z_ARRVAL_P(properties);
+
+ if (zend_hash_find(hash, name, len + 1, (void **) &ppzval) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ if (Z_TYPE_PP(ppzval) == IS_ARRAY) {
+ if ((ret = yaf_config_simple_format(getThis(), ppzval TSRMLS_CC))) {
+ RETURN_ZVAL(ret, 1, 1);
+ } else {
+ RETURN_NULL();
+ }
+ } else {
+ RETURN_ZVAL(*ppzval, 1, 0);
+ }
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Simple::toArray(void)
+*/
+PHP_METHOD(yaf_config_simple, toArray) {
+ zval *properties = zend_read_property(yaf_config_simple_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ RETURN_ZVAL(properties, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Simple::set($name, $value)
+*/
+PHP_METHOD(yaf_config_simple, set) {
+ zval *readonly = zend_read_property(yaf_config_simple_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME_READONLY), 1 TSRMLS_CC);
+
+ if (!Z_BVAL_P(readonly)) {
+ zval *name, *value, *props;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &name, &value) == FAILURE) {
+ return;
+ }
+
+ if (Z_TYPE_P(name) != IS_STRING || Z_TYPE_P(name) != IS_STRING) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expect a string key name");
+ RETURN_FALSE;
+ }
+
+ Z_ADDREF_P(value);
+ props = zend_read_property(yaf_config_simple_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ if (zend_hash_update(Z_ARRVAL_P(props), Z_STRVAL_P(name), Z_STRLEN_P(name) + 1, (void **)&value, sizeof(zval*), NULL) == SUCCESS) {
+ RETURN_TRUE;
+ } else {
+ Z_DELREF_P(value);
+ }
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Simple::__isset($name)
+*/
+PHP_METHOD(yaf_config_simple, __isset) {
+ char *name;
+ uint len;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &len) == FAILURE) {
+ return;
+ } else {
+ zval *prop = zend_read_property(yaf_config_simple_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ RETURN_BOOL(zend_hash_exists(Z_ARRVAL_P(prop), name, len + 1));
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Simple::offsetUnset($index)
+*/
+PHP_METHOD(yaf_config_simple, offsetUnset) {
+ zval *readonly = zend_read_property(yaf_config_simple_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME_READONLY), 1 TSRMLS_CC);
+
+ if (Z_BVAL_P(readonly)) {
+ zval *name, *props;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &name) == FAILURE) {
+ return;
+ }
+
+ if (Z_TYPE_P(name) != IS_STRING || Z_TYPE_P(name) != IS_STRING) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expect a string key name");
+ RETURN_FALSE;
+ }
+
+ props = zend_read_property(yaf_config_simple_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ if (zend_hash_del(Z_ARRVAL_P(props), Z_STRVAL_P(name), Z_STRLEN_P(name)) == SUCCESS) {
+ RETURN_TRUE;
+ }
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Simple::count($name)
+*/
+PHP_METHOD(yaf_config_simple, count) {
+ zval *prop = zend_read_property(yaf_config_simple_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ RETURN_LONG(zend_hash_num_elements(Z_ARRVAL_P(prop)));
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Simple::rewind(void)
+*/
+PHP_METHOD(yaf_config_simple, rewind) {
+ zval *prop = zend_read_property(yaf_config_simple_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ zend_hash_internal_pointer_reset(Z_ARRVAL_P(prop));
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Simple::current(void)
+*/
+PHP_METHOD(yaf_config_simple, current) {
+ zval *prop, **ppzval, *ret;
+
+ prop = zend_read_property(yaf_config_simple_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ if (zend_hash_get_current_data(Z_ARRVAL_P(prop), (void **)&ppzval) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ if (Z_TYPE_PP(ppzval) == IS_ARRAY) {
+ if ((ret = yaf_config_simple_format(getThis(), ppzval TSRMLS_CC))) {
+ RETURN_ZVAL(ret, 1, 1);
+ } else {
+ RETURN_NULL();
+ }
+ } else {
+ RETURN_ZVAL(*ppzval, 1, 0);
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Simple::key(void)
+*/
+PHP_METHOD(yaf_config_simple, key) {
+ zval *prop;
+ char *string;
+ long index;
+
+ prop = zend_read_property(yaf_config_simple_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ zend_hash_get_current_key(Z_ARRVAL_P(prop), &string, &index, 0);
+ if (zend_hash_get_current_key_type(Z_ARRVAL_P(prop)) == HASH_KEY_IS_LONG) {
+ RETURN_LONG(index);
+ } else {
+ RETURN_STRING(string, 1);
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Simple::next(void)
+*/
+PHP_METHOD(yaf_config_simple, next) {
+ zval *prop = zend_read_property(yaf_config_simple_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ zend_hash_move_forward(Z_ARRVAL_P(prop));
+ RETURN_TRUE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Simple::valid(void)
+*/
+PHP_METHOD(yaf_config_simple, valid) {
+ zval *prop = zend_read_property(yaf_config_simple_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ RETURN_LONG(zend_hash_has_more_elements(Z_ARRVAL_P(prop)) == SUCCESS);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Simple::readonly(void)
+*/
+PHP_METHOD(yaf_config_simple, readonly) {
+ zval *readonly = zend_read_property(yaf_config_simple_ce, getThis(), ZEND_STRL(YAF_CONFIG_PROPERT_NAME_READONLY), 1 TSRMLS_CC);
+ RETURN_BOOL(Z_LVAL_P(readonly));
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Config_Simple::__destruct
+*/
+PHP_METHOD(yaf_config_simple, __destruct) {
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Config_Simple::__clone
+*/
+PHP_METHOD(yaf_config_simple, __clone) {
+}
+/* }}} */
+
+/** {{{ yaf_config_simple_methods
+*/
+zend_function_entry yaf_config_simple_methods[] = {
+ PHP_ME(yaf_config_simple, __construct, yaf_config_simple_construct_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ /* PHP_ME(yaf_config_simple, __destruct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR) */
+ PHP_ME(yaf_config_simple, __isset, yaf_config_simple_isset_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_simple, get, yaf_config_simple_get_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_simple, set, yaf_config_simple_set_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_simple, count, yaf_config_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_simple, offsetUnset, yaf_config_simple_unset_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_simple, rewind, yaf_config_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_simple, current, yaf_config_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_simple, next, yaf_config_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_simple, valid, yaf_config_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_simple, key, yaf_config_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_simple, readonly, yaf_config_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_config_simple, toArray, yaf_config_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_config_simple, __set, set, yaf_config_simple_set_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_config_simple, __get, get, yaf_config_simple_get_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_config_simple, offsetGet, get, yaf_config_simple_rget_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_config_simple, offsetExists, __isset, yaf_config_simple_isset_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_config_simple, offsetSet, set, yaf_config_simple_set_arginfo, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(config_simple) {
+ zend_class_entry ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Config_Simple", "Yaf\\Config\\Simple", yaf_config_simple_methods);
+ yaf_config_simple_ce = zend_register_internal_class_ex(&ce, yaf_config_ce, NULL TSRMLS_CC);
+
+#ifdef HAVE_SPL
+ zend_class_implements(yaf_config_simple_ce TSRMLS_CC, 3, zend_ce_iterator, zend_ce_arrayaccess, spl_ce_Countable);
+#else
+ zend_class_implements(yaf_config_simple_ce TSRMLS_CC, 2, zend_ce_iterator, zend_ce_arrayaccess);
+#endif
+ zend_declare_property_bool(yaf_config_simple_ce, YAF_STRL(YAF_CONFIG_PROPERT_NAME_READONLY), 0, ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ yaf_config_simple_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/package2.xml b/package2.xml
new file mode 100644
index 0000000000..473fdd94fb
--- /dev/null
+++ b/package2.xml
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.4.7" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
+ <name>yaf</name>
+ <channel>pecl.php.net</channel>
+ <summary>PHP Framework in PHP extension</summary>
+ <description>Yaf is a PHP framework similar to zend framework, which is written in c and built as PHP extension</description>
+ <lead>
+ <name>Xinchen Hui</name>
+ <user>laruence</user>
+ <email>laruence@php.net</email>
+ <active>yes</active>
+ </lead>
+ <date>2011-08-30</date>
+ <time>18:48:25</time>
+ <version>
+ <release>2.1.0</release>
+ <api>2.1.0</api>
+ </version>
+ <stability>
+ <release>beta</release>
+ <api>beta</api>
+ </stability>
+ <license uri="http://www.php.net/license">PHP</license>
+ <notes>
+- Avoided calling to get_class_entry for higher performance
+- Remove unnecessary stack variable initialization
+- Fixed mem leak reproted by test scripts
+- Added arginfo for all methods
+- Standardize error message
+- Add Yaf_Request::setRequstUri
+- Fixed build broken with PHP 5.4
+- many other litte improvements
+ </notes>
+ <contents>
+ <dir name="/">
+ <file name="config.m4" role="src" />
+ <file name="yaf_action.c" role="src" />
+ <file name="yaf_action.h" role="src" />
+ <file name="yaf_application.c" role="src" />
+ <file name="yaf_application.h" role="src" />
+ <file name="yaf_bootstrap.c" role="src" />
+ <file name="yaf_bootstrap.h" role="src" />
+ <file name="yaf.c" role="src" />
+ <file name="yaf_config.c" role="src" />
+ <file name="yaf_config.h" role="src" />
+ <file name="yaf_controller.c" role="src" />
+ <file name="yaf_controller.h" role="src" />
+ <file name="yaf_dispatcher.c" role="src" />
+ <file name="yaf_dispatcher.h" role="src" />
+ <file name="yaf.dsp" role="src" />
+ <file name="yaf_exception.c" role="src" />
+ <file name="yaf_exception.h" role="src" />
+ <file name="yaf_loader.c" role="src" />
+ <file name="yaf_loader.h" role="src" />
+ <file name="yaf_logo.h" role="src" />
+ <file name="yaf_namespace.h" role="src" />
+ <file name="yaf.php" role="src" />
+ <file name="yaf_plugin.c" role="src" />
+ <file name="yaf_plugin.h" role="src" />
+ <file name="yaf_registry.c" role="src" />
+ <file name="yaf_registry.h" role="src" />
+ <file name="yaf_request.c" role="src" />
+ <file name="yaf_request.h" role="src" />
+ <file name="yaf_response.c" role="src" />
+ <file name="yaf_response.h" role="src" />
+ <file name="yaf_router.c" role="src" />
+ <file name="yaf_router.h" role="src" />
+ <file name="yaf_session.c" role="src" />
+ <file name="yaf_session.h" role="src" />
+ <file name="yaf_view.c" role="src" />
+ <file name="yaf_view.h" role="src" />
+ <dir name="configs">
+ <file name="ini.c" role="src" />
+ <file name="simple.c" role="src" />
+ </dir>
+ <file name="config.w32" role="src" />
+ <file name="CREDITS" role="src" />
+ <file name="EXPERIMENTAL" role="src" />
+ <file name="php_yaf.h" role="src" />
+ <dir name="requests">
+ <file name="http.c" role="src" />
+ <file name="simple.c" role="src" />
+ </dir>
+ <dir name="response">
+ <file name="http.c" role="src" />
+ <file name="cli.c" role="src" />
+ </dir>
+ <dir name="routes">
+ <file name="interface.c" role="src" />
+ <file name="rewrite.c" role="src" />
+ <file name="supervar.c" role="src" />
+ <file name="static.c" role="src" />
+ <file name="simple.c" role="src" />
+ <file name="regex.c" role="src" />
+ <file name="map.c" role="src" />
+ </dir>
+ <dir name="views">
+ <file name="interface.c" role="src" />
+ <file name="simple.c" role="src" />
+ </dir>
+ <dir name="tests">
+ <file name="001.phpt" role="test" />
+ <file name="002.phpt" role="test" />
+ <file name="003.phpt" role="test" />
+ <file name="004.phpt" role="test" />
+ <file name="005.phpt" role="test" />
+ <file name="006.phpt" role="test" />
+ <file name="007.phpt" role="test" />
+ <file name="008.phpt" role="test" />
+ <file name="009.phpt" role="test" />
+ <file name="010.phpt" role="test" />
+ <file name="011.phpt" role="test" />
+ <file name="012.phpt" role="test" />
+ <file name="013.phpt" role="test" />
+ <file name="014.phpt" role="test" />
+ <file name="015.phpt" role="test" />
+ <file name="016.phpt" role="test" />
+ <file name="simple.ini" role="test" />
+ </dir>
+ </dir>
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.2.0</min>
+ <max>5.4.0</max>
+ </php>
+ <pearinstaller>
+ <min>1.4.0</min>
+ </pearinstaller>
+ </required>
+ </dependencies>
+ <providesextension>yaf</providesextension>
+ <extsrcrelease />
+ <changelog>
+ <release>
+ <date>2011-08-28</date>
+ <version>
+ <release>2.1.0</release>
+ <api>2.1.0</api>
+ </version>
+ <stability>
+ <release>beta</release>
+ <api>beta</api>
+ </stability>
+ <license uri="http://www.php.net/license">PHP License</license>
+ <notes>
+- Avoided calling to get_class_entry for higher performance
+- Added arginfo for all methods
+- Remove unnecessary stack variable initialization
+- Standardize error message
+- Add Yaf_Request::setRequstUri
+- Fixed build broken with PHP 5.4
+ </notes>
+ </release>
+ <release>
+ <date>2011-06-28</date>
+ <version>
+ <release>2.0.1</release>
+ <api>2.0.1</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.php.net/license">PHP License</license>
+ <notes>
+- Fixed Bug that when call to Yaf_Config_Ini/Yaf_Config_Simple with freaky paramters then invoke its methods cause crash (thanks to Felipe Pena)
+- Yaf_Application::execute call Zend_API call_user_func instead of call zif_call_user_func, since zif_call_user_func was not declared with dllexport
+- Built on windows with PHP-5.3.6 and PHP-5.2.15 (you can download the dll on Yaf Google Code)
+- Corrected some broken C89 statements
+ </notes>
+ </release>
+ <release>
+ <date>2011-06-24</date>
+ <version>
+ <release>2.0.0</release>
+ <api>2.0.0</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.php.net/license">PHP License</license>
+ <notes>
+ - First release version
+ </notes>
+ </release>
+ </changelog>
+</package>
+<!--
+vim:et:ts=1:sw=1
+-->
diff --git a/php_yaf.h b/php_yaf.h
new file mode 100644
index 0000000000..5c22d95dcd
--- /dev/null
+++ b/php_yaf.h
@@ -0,0 +1,144 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef PHP_YAF_H
+#define PHP_YAF_H
+
+extern zend_module_entry yaf_module_entry;
+#define phpext_yaf_ptr &yaf_module_entry
+
+#ifdef PHP_WIN32
+#define PHP_YAF_API __declspec(dllexport)
+#ifndef _MSC_VER
+#define _MSC_VER 1600
+#endif
+#else
+#define PHP_YAF_API
+#endif
+
+#ifdef ZTS
+#include "TSRM.h"
+#endif
+
+#ifdef ZTS
+#define YAF_G(v) TSRMG(yaf_globals_id, zend_yaf_globals *, v)
+#else
+#define YAF_G(v) (yaf_globals.v)
+#endif
+
+#define YAF_STARTUP_FUNCTION(module) ZEND_MINIT_FUNCTION(yaf_##module)
+#define YAF_RINIT_FUNCTION(modle) ZEND_RINIT_FUNCTION(yaf_##module)
+#define YAF_STARTUP(module) ZEND_MODULE_STARTUP_N(yaf_##module)(INIT_FUNC_ARGS_PASSTHRU)
+#define YAF_SHUTDOWN_FUNCTION(module) ZEND_MINIT_FUNCTION(yaf_##module)
+#define YAF_SHUTDOWN(module) ZEND_MODULE_SHUTDOWN_N(yaf_##module)(INIT_FUNC_ARGS_PASSTHRU)
+
+#define YAF_VERSION "2.1.0"
+
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION > 2)) || (PHP_MAJOR_VERSION > 5)
+#define YAF_HAVE_NAMESPACE
+#else
+#define Z_ADDREF_P ZVAL_ADDREF
+#define Z_REFCOUNT_P ZVAL_REFCOUNT
+#define Z_DELREF_P ZVAL_DELREF
+#endif
+
+#define yaf_application_t zval
+#define yaf_view_t zval
+#define yaf_controller_t zval
+#define yaf_request_t zval
+#define yaf_router_t zval
+#define yaf_route_t zval
+#define yaf_dispatcher_t zval
+#define yaf_action_t zval
+#define yaf_loader_t zval
+#define yaf_response_t zval
+#define yaf_config_t zval
+#define yaf_registry_t zval
+#define yaf_plugin_t zval
+#define yaf_session_t zval
+#define yaf_exception_t zval
+
+extern PHPAPI int php_register_info_logo(char *logo_string, const char *mimetype, const unsigned char *data, int size);
+extern PHPAPI void php_var_dump(zval **struc, int level TSRMLS_DC);
+extern PHPAPI void php_debug_zval_dump(zval **struc, int level TSRMLS_DC);
+
+#define YAF_STRS ZEND_STRS
+#define YAF_STRL ZEND_STRL
+
+#define YAF_PSTRS(z) Z_STRVAL_P(z), Z_STRLEN_P(z) + 1
+#define YAF_PSTRL(z) Z_STRVAL_P(z), Z_STRLEN_P(z)
+
+#define YAF_PPSTRS(z) \
+ Z_STRVAL_PP(z), Z_STRLEN_PP(z) + 1
+#define YAF_PPSTRL(z) \
+ Z_STRVAL_PP(z), Z_STRLEN_PP(z)
+
+ZEND_BEGIN_MODULE_GLOBALS(yaf)
+ char *ext;
+ char *base_uri;
+ char *environ;
+ char *directory;
+ char *library_directory;
+ char *global_library;
+ char *view_ext;
+ char *default_module;
+ char *default_controller;
+ char *default_action;
+ char *bootstrap;
+ char *name_separator;
+ zend_bool lowcase_path;
+ zend_bool use_spl_autoload;
+ zend_bool throw_exception;
+ zend_bool cache_config;
+ zend_bool action_prefer;
+ zend_bool name_suffix;
+ zend_bool autoload_started;
+ zend_bool running;
+ zend_bool in_exception;
+ zend_bool catch_exception;
+/* {{{ This only effects internally */
+ zend_bool st_compatible;
+/* }}} */
+ long forward_limit;
+ HashTable *configs;
+ zval *modules;
+ uint buf_nesting;
+ void *buffer;
+ void *owrite_handler;
+#ifdef YAF_HAVE_NAMESPACE
+ zend_bool use_namespace;
+#endif
+ZEND_END_MODULE_GLOBALS(yaf)
+
+PHP_MINIT_FUNCTION(yaf);
+PHP_MSHUTDOWN_FUNCTION(yaf);
+PHP_RINIT_FUNCTION(yaf);
+PHP_RSHUTDOWN_FUNCTION(yaf);
+PHP_MINFO_FUNCTION(yaf);
+
+extern ZEND_DECLARE_MODULE_GLOBALS(yaf);
+
+#endif
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/requests/http.c b/requests/http.c
new file mode 100644
index 0000000000..2ec59e101a
--- /dev/null
+++ b/requests/http.c
@@ -0,0 +1,284 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#include "ext/standard/url.h"
+
+static zend_class_entry * yaf_request_http_ce;
+
+/** {{{ yaf_request_t * yaf_request_http_instance(yaf_request_t *this_ptr, char *request_uri, char *base_uri TSRMLS_DC)
+*/
+yaf_request_t * yaf_request_http_instance(yaf_request_t *this_ptr, char *request_uri, char *base_uri TSRMLS_DC) {
+ yaf_request_t *instance;
+ zval *method, *params, *settled_uri = NULL;
+
+ if (this_ptr) {
+ instance = this_ptr;
+ } else {
+ MAKE_STD_ZVAL(instance);
+ object_init_ex(instance, yaf_request_http_ce);
+ }
+
+ MAKE_STD_ZVAL(method);
+ if (SG(request_info).request_method) {
+ ZVAL_STRING(method, (char *)SG(request_info).request_method, 1);
+ } else if (strncasecmp(sapi_module.name, "cli", 3)) {
+ ZVAL_STRING(method, "Unknow", 1);
+ } else {
+ ZVAL_STRING(method, "Cli", 1);
+ }
+ zend_update_property(yaf_request_http_ce, instance, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_METHOD), method TSRMLS_CC);
+ zval_ptr_dtor(&method);
+
+ if (request_uri) {
+ MAKE_STD_ZVAL(settled_uri);
+ ZVAL_STRING(settled_uri, request_uri, 1);
+ } else {
+ zval *uri;
+ do {
+#ifdef PHP_WIN32
+ /* check this first so IIS will catch */
+ uri = yaf_request_query(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("HTTP_X_REWRITE_URL") TSRMLS_CC);
+ if (Z_TYPE_P(uri) != IS_NULL) {
+ settled_uri = uri;
+ break;
+ }
+ zval_ptr_dtor(&uri);
+
+ /* IIS7 with URL Rewrite: make sure we get the unencoded url (double slash problem) */
+ uri = yaf_request_query(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("IIS_WasUrlRewritten") TSRMLS_CC);
+ if (Z_TYPE_P(uri) != IS_NULL) {
+ zval *rewrited = yaf_request_query(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("IIS_WasUrlRewritten") TSRMLS_CC);
+ zval *unencode = yaf_request_query(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("UNENCODED_URL") TSRMLS_CC);
+ if (Z_TYPE_P(rewrited) = IS_LONG
+ && Z_LVAL_P(rewrited) == 1
+ && Z_TYPE_P(unencode) == IS_STRING
+ && Z_STRLEN_P(unencode) > 0) {
+ settled_uri = uri;
+ }
+ break;
+ }
+ zval_ptr_dtor(&uri);
+#endif
+ uri = yaf_request_query(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("PATH_INFO") TSRMLS_CC);
+ if (Z_TYPE_P(uri) != IS_NULL) {
+ settled_uri = uri;
+ break;
+ }
+ zval_ptr_dtor(&uri);
+
+ uri = yaf_request_query(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("REQUEST_URI") TSRMLS_CC);
+ if (Z_TYPE_P(uri) != IS_NULL) {
+ /* Http proxy reqs setup request uri with scheme and host [and port] + the url path, only use url path */
+ if (strstr(Z_STRVAL_P(uri), "http") == Z_STRVAL_P(uri)) {
+ php_url *url_info = php_url_parse(Z_STRVAL_P(uri));
+ zval_ptr_dtor(&uri);
+
+ if (url_info && url_info->path) {
+ MAKE_STD_ZVAL(settled_uri);
+ ZVAL_STRING(settled_uri, url_info->path, 1);
+ }
+
+ php_url_free(url_info);
+ } else {
+ char *pos = NULL;
+ if ((pos = strstr(Z_STRVAL_P(uri), "?"))) {
+ MAKE_STD_ZVAL(settled_uri);
+ ZVAL_STRINGL(settled_uri, Z_STRVAL_P(uri), pos - Z_STRVAL_P(uri), 1);
+ zval_ptr_dtor(&uri);
+ } else {
+ settled_uri = uri;
+ }
+ }
+ break;
+ }
+ zval_ptr_dtor(&uri);
+
+ uri = yaf_request_query(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("ORIG_PATH_INFO") TSRMLS_CC);
+ if (Z_TYPE_P(uri) != IS_NULL) {
+ /* intended do nothing */
+ /* zval *query = yaf_request_query(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("QUERY_STRING") TSRMLS_CC);
+ if (Z_TYPE_P(query) != IS_NULL) {
+ }
+ */
+ settled_uri = uri;
+ break;
+ }
+ zval_ptr_dtor(&uri);
+
+ } while (0);
+ }
+
+ if (settled_uri) {
+ zend_update_property(yaf_request_http_ce, instance, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_URI), settled_uri TSRMLS_CC);
+ yaf_request_set_base_uri(instance, base_uri, Z_STRVAL_P(settled_uri) TSRMLS_CC);
+ zval_ptr_dtor(&settled_uri);
+ }
+
+ MAKE_STD_ZVAL(params);
+ array_init(params);
+ zend_update_property(yaf_request_http_ce, instance, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_PARAMS), params TSRMLS_CC);
+ zval_ptr_dtor(&params);
+
+ return instance;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Http::getQuery(mixed $name, mixed $default = NULL)
+*/
+YAF_REQUEST_METHOD(yaf_request_http, Query, YAF_GLOBAL_VARS_GET);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Http::getPost(mixed $name, mixed $default = NULL)
+*/
+YAF_REQUEST_METHOD(yaf_request_http, Post, YAF_GLOBAL_VARS_POST);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Http::getRequet(mixed $name, mixed $default = NULL)
+*/
+YAF_REQUEST_METHOD(yaf_request_http, Request, YAF_GLOBAL_VARS_REQUEST);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Http::getFiles(mixed $name, mixed $default = NULL)
+*/
+YAF_REQUEST_METHOD(yaf_request_http, Files, YAF_GLOBAL_VARS_FILES);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Http::getCookie(mixed $name, mixed $default = NULL)
+*/
+YAF_REQUEST_METHOD(yaf_request_http, Cookie, YAF_GLOBAL_VARS_COOKIE);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Http::isXmlHttpRequest()
+*/
+PHP_METHOD(yaf_request_http, isXmlHttpRequest) {
+ zval * header = yaf_request_query(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("HTTP_X_REQUESTED_WITH") TSRMLS_CC);
+ if (Z_TYPE_P(header) == IS_STRING
+ && strncasecmp("XMLHttpRequest", Z_STRVAL_P(header), Z_STRLEN_P(header)) == 0) {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Http::get(mixed $name, mixed $default)
+ * params -> post -> get -> cookie -> server
+ */
+PHP_METHOD(yaf_request_http, get) {
+ char *name = NULL;
+ int len = 0;
+ zval *def = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &name, &len, &def) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ } else {
+ zval *value = yaf_request_get_param(getThis(), name, len TSRMLS_CC);
+ if (value) {
+ RETURN_ZVAL(value, 1, 0);
+ } else {
+ zval *params = NULL;
+ zval **ppzval = NULL;
+
+ YAF_GLOBAL_VARS_TYPE methods[4] = {
+ YAF_GLOBAL_VARS_POST,
+ YAF_GLOBAL_VARS_GET,
+ YAF_GLOBAL_VARS_COOKIE,
+ YAF_GLOBAL_VARS_SERVER
+ };
+
+ {
+ int i = 0;
+ for (;i<4; i++) {
+ params = PG(http_globals)[methods[i]];
+ if (params && Z_TYPE_P(params) == IS_ARRAY) {
+ if (zend_hash_find(Z_ARRVAL_P(params), name, len + 1, (void **)&ppzval) == SUCCESS ){
+ RETURN_ZVAL(*ppzval, 1, 0);
+ }
+ }
+ }
+
+ }
+ if (def) {
+ RETURN_ZVAL(def, 1, 0);
+ }
+ }
+ }
+ RETURN_NULL();
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Http::__construct(string $request_uri, string $base_uri)
+*/
+PHP_METHOD(yaf_request_http, __construct) {
+ char *request_uri = NULL;
+ char *base_uri = NULL;
+ int rlen = 0;
+ int blen = 0;
+
+ yaf_request_t *self = getThis();
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &request_uri, &rlen, &base_uri, &blen) == FAILURE) {
+ return;
+ }
+
+ (void)yaf_request_http_instance(self, request_uri, base_uri TSRMLS_CC);
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Request_Http::__clone
+ */
+PHP_METHOD(yaf_request_http, __clone) {
+}
+/* }}} */
+
+/** {{{ yaf_request_http_methods
+ */
+zend_function_entry yaf_request_http_methods[] = {
+ PHP_ME(yaf_request_http, getQuery, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request_http, getRequest, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request_http, getPost, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request_http, getCookie, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request_http, getFiles, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request_http, get, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request_http, isXmlHttpRequest,NULL,ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request_http, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(yaf_request_http, __clone, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CLONE)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+ */
+YAF_STARTUP_FUNCTION(request_http){
+ zend_class_entry ce;
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Request_Http", "Yaf\\Request\\Http", yaf_request_http_methods);
+ yaf_request_http_ce = zend_register_internal_class_ex(&ce, yaf_request_ce, NULL TSRMLS_CC);
+
+ zend_declare_class_constant_string(yaf_request_ce, ZEND_STRL("SCHEME_HTTP"), "http" TSRMLS_CC);
+ zend_declare_class_constant_string(yaf_request_ce, ZEND_STRL("SCHEME_HTTPS"), "https" TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/requests/simple.c b/requests/simple.c
new file mode 100644
index 0000000000..6a75b2ca6a
--- /dev/null
+++ b/requests/simple.c
@@ -0,0 +1,269 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+static zend_class_entry *yaf_request_simple_ce;
+
+/** {{{ yaf_request_t * yaf_request_simple_instance(yaf_request_t *this_ptr, zval *module, zval *controller, zval *action, zval *method, zval *params TSRMLS_DC)
+*/
+yaf_request_t * yaf_request_simple_instance(yaf_request_t *this_ptr, zval *module, zval *controller, zval *action, zval *method, zval *params TSRMLS_DC) {
+ yaf_request_t *instance;
+
+ if (!method) {
+ MAKE_STD_ZVAL(method);
+ if (!SG(request_info).request_method) {
+ if (!strncasecmp(sapi_module.name, "cli", 3)) {
+ ZVAL_STRING(method, "CLI", 1);
+ } else {
+ ZVAL_STRING(method, "Unknow", 1);
+ }
+ } else {
+ ZVAL_STRING(method, (char *)SG(request_info).request_method, 1);
+ }
+ }
+
+ if (this_ptr) {
+ instance = this_ptr;
+ } else {
+ MAKE_STD_ZVAL(instance);
+ object_init_ex(instance, yaf_request_simple_ce);
+ }
+
+ zend_update_property(yaf_request_simple_ce, instance, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_METHOD), method TSRMLS_CC);
+
+ if (module || controller || action) {
+ if (!module || Z_TYPE_P(module) != IS_STRING) {
+ zend_update_property_string(yaf_request_simple_ce, instance,
+ ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), YAF_G(default_module) TSRMLS_CC);
+ } else {
+ zend_update_property(yaf_request_simple_ce, instance, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), module TSRMLS_CC);
+ }
+
+ if (!controller || Z_TYPE_P(controller) != IS_STRING) {
+ zend_update_property_string(yaf_request_simple_ce, instance,
+ ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), YAF_G(default_controller) TSRMLS_CC);
+ } else {
+ zend_update_property(yaf_request_simple_ce, instance,
+ ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), controller TSRMLS_CC);
+ }
+
+ if (!action || Z_TYPE_P(action) != IS_STRING) {
+ zend_update_property_string(yaf_request_simple_ce, instance,
+ ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), YAF_G(default_action) TSRMLS_CC);
+ } else {
+ zend_update_property(yaf_request_simple_ce, instance,
+ ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), action TSRMLS_CC);
+ }
+
+ zend_update_property_bool(yaf_request_simple_ce, instance, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ROUTED), 1 TSRMLS_CC);
+ } else {
+ zval *argv, **ppzval;
+ char *query = NULL;
+
+ argv = yaf_request_query(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("argv") TSRMLS_CC);
+ if (IS_ARRAY == Z_TYPE_P(argv)) {
+ for(zend_hash_internal_pointer_reset(Z_ARRVAL_P(argv));
+ zend_hash_has_more_elements(Z_ARRVAL_P(argv)) == SUCCESS;
+ zend_hash_move_forward(Z_ARRVAL_P(argv))) {
+ if (zend_hash_get_current_data(Z_ARRVAL_P(argv), (void**)&ppzval) == FAILURE) {
+ continue;
+ } else {
+ if (Z_TYPE_PP(ppzval) == IS_STRING) {
+ if (strncasecmp(Z_STRVAL_PP(ppzval), YAF_REQUEST_SERVER_URI, sizeof(YAF_REQUEST_SERVER_URI) - 1)) {
+ continue;
+ }
+
+ query = estrdup(Z_STRVAL_PP(ppzval) + sizeof(YAF_REQUEST_SERVER_URI));
+ break;
+ }
+ }
+ }
+ }
+
+ if (query) {
+ zend_update_property_string(yaf_request_simple_ce, instance, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_URI), query TSRMLS_CC);
+ } else {
+ zend_update_property_string(yaf_request_simple_ce, instance, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_URI), "" TSRMLS_CC);
+ }
+ }
+
+ if (!params || IS_ARRAY != Z_TYPE_P(params)) {
+ MAKE_STD_ZVAL(params);
+ array_init(params);
+ zend_update_property(yaf_request_simple_ce, instance, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_PARAMS), params TSRMLS_CC);
+ zval_ptr_dtor(&params);
+ } else {
+ Z_ADDREF_P(params);
+ zend_update_property(yaf_request_simple_ce, instance, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_PARAMS), params TSRMLS_CC);
+ }
+
+ return instance;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Simple::__construct(string $method, string $module, string $controller, string $action, array $params = NULL)
+*/
+PHP_METHOD(yaf_request_simple, __construct) {
+ zval *module = NULL;
+ zval *controller = NULL;
+ zval *action = NULL;
+ zval *params = NULL;
+ zval *method = NULL;
+ zval *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|zzzzz", &method, &module, &controller, &action, &params) == FAILURE) {
+ return;
+ } else {
+ if ((params && IS_ARRAY != Z_TYPE_P(params))) {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC,
+ "Expects the params is an array", yaf_request_simple_ce->name);
+ RETURN_FALSE;
+ }
+
+ (void)yaf_request_simple_instance(self, module, controller, action, method, params TSRMLS_CC);
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Simple::getQuery(mixed $name, mixed $default = NULL)
+*/
+YAF_REQUEST_METHOD(yaf_request_simple, Query, YAF_GLOBAL_VARS_GET);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Simple::getPost(mixed $name, mixed $default = NULL)
+*/
+YAF_REQUEST_METHOD(yaf_request_simple, Post, YAF_GLOBAL_VARS_POST);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Simple::getRequet(mixed $name, mixed $default = NULL)
+*/
+YAF_REQUEST_METHOD(yaf_request_simple, Request, YAF_GLOBAL_VARS_REQUEST);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Simple::getFiles(mixed $name, mixed $default = NULL)
+*/
+YAF_REQUEST_METHOD(yaf_request_simple, Files, YAF_GLOBAL_VARS_FILES);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Simple::getCookie(mixed $name, mixed $default = NULL)
+*/
+YAF_REQUEST_METHOD(yaf_request_simple, Cookie, YAF_GLOBAL_VARS_COOKIE);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Simple::isXmlHttpRequest()
+*/
+PHP_METHOD(yaf_request_simple, isXmlHttpRequest) {
+ zval * header = yaf_request_query(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("X-Requested-With") TSRMLS_CC);
+ if (Z_TYPE_P(header) == IS_STRING
+ && strncasecmp("XMLHttpRequest", Z_STRVAL_P(header), Z_STRLEN_P(header)) == 0) {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Simple::get(mixed $name, mixed $default)
+ * params -> post -> get -> cookie -> server
+ */
+PHP_METHOD(yaf_request_simple, get) {
+ char *name = NULL;
+ int len = 0;
+ zval *def = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &name, &len, &def) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ } else {
+ zval *value = yaf_request_get_param(getThis(), name, len TSRMLS_CC);
+ if (value) {
+ RETURN_ZVAL(value, 1, 0);
+ } else {
+ zval *params = NULL;
+ zval **ppzval = NULL;
+
+ YAF_GLOBAL_VARS_TYPE methods[4] = {
+ YAF_GLOBAL_VARS_POST,
+ YAF_GLOBAL_VARS_GET,
+ YAF_GLOBAL_VARS_COOKIE,
+ YAF_GLOBAL_VARS_SERVER
+ };
+
+ {
+ int i = 0;
+ for (;i<4; i++) {
+ params = PG(http_globals)[methods[i]];
+ if (params && Z_TYPE_P(params) == IS_ARRAY) {
+ if (zend_hash_find(Z_ARRVAL_P(params), name, len + 1, (void **)&ppzval) == SUCCESS ){
+ RETURN_ZVAL(*ppzval, 1, 0);
+ }
+ }
+ }
+
+ }
+ if (def) {
+ RETURN_ZVAL(def, 1, 0);
+ }
+ }
+ }
+ RETURN_NULL();
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Request_Simple::__clone
+ */
+PHP_METHOD(yaf_request_simple, __clone) {
+}
+/* }}} */
+
+/** {{{ yaf_request_simple_methods
+ */
+zend_function_entry yaf_request_simple_methods[] = {
+ PHP_ME(yaf_request_simple, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(yaf_request_simple, __clone, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CLONE)
+ PHP_ME(yaf_request_simple, getQuery, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request_simple, getRequest, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request_simple, getPost, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request_simple, getCookie, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request_simple, getFiles, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request_simple, get, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request_simple, isXmlHttpRequest,NULL,ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+ */
+YAF_STARTUP_FUNCTION(request_simple){
+ zend_class_entry ce;
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Request_Simple", "Yaf\\Request\\Simple", yaf_request_simple_methods);
+ yaf_request_simple_ce = zend_register_internal_class_ex(&ce, yaf_request_ce, NULL TSRMLS_CC);
+ yaf_request_simple_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+
+ zend_declare_class_constant_string(yaf_request_simple_ce, ZEND_STRL("SCHEME_HTTP"), "http" TSRMLS_CC);
+ zend_declare_class_constant_string(yaf_request_simple_ce, ZEND_STRL("SCHEME_HTTPS"), "https" TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/response/cli.c b/response/cli.c
new file mode 100644
index 0000000000..1b1aaf6817
--- /dev/null
+++ b/response/cli.c
@@ -0,0 +1,49 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+
+zend_class_entry * yaf_response_cli_ce;
+
+/** {{{ yaf_response_methods
+*/
+zend_function_entry yaf_response_cli_methods[] = {
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(response_cli) {
+ zend_class_entry ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Response_Cli", "Yaf\\Response\\Cli", yaf_response_cli_methods);
+
+ yaf_response_cli_ce = zend_register_internal_class_ex(&ce, yaf_response_ce, NULL TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/response/http.c b/response/http.c
new file mode 100644
index 0000000000..a59e52eea9
--- /dev/null
+++ b/response/http.c
@@ -0,0 +1,51 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+zend_class_entry *yaf_response_http_ce;
+
+/** {{{ yaf_response_methods
+*/
+zend_function_entry yaf_response_http_methods[] = {
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(response_http) {
+ zend_class_entry ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Response_Http", "Yaf\\Response\\Http", yaf_response_http_methods);
+
+ yaf_response_http_ce = zend_register_internal_class_ex(&ce, yaf_response_ce, NULL TSRMLS_CC);
+
+ zend_declare_property_bool(yaf_response_http_ce, YAF_STRL(YAF_RESPONSE_PROPERTY_NAME_HEADEREXCEPTION), 1, ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_long(yaf_response_http_ce, YAF_STRL(YAF_RESPONSE_PROPERTY_NAME_RESPONSECODE), 200, ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/routes/interface.c b/routes/interface.c
new file mode 100644
index 0000000000..a870fed669
--- /dev/null
+++ b/routes/interface.c
@@ -0,0 +1,145 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#include "ext/standard/php_smart_str.h"
+
+#define YAF_ROUTE_PROPETY_NAME_MATCH "_route"
+#define YAF_ROUTE_PROPETY_NAME_ROUTE "_default"
+#define YAF_ROUTE_PROPETY_NAME_MAP "_maps"
+#define YAF_ROUTE_PROPETY_NAME_VERIFY "_verify"
+
+#define YAF_ROUTER_URL_DELIMIETER "/"
+#define YAF_ROUTE_REGEX_DILIMITER '#'
+
+/* {{{ YAF_ARG_INFO
+ */
+YAF_BEGIN_ARG_INFO_EX(yaf_route_route_arginfo, 0, 0, 1)
+ YAF_ARG_INFO(0, request)
+YAF_END_ARG_INFO()
+/* }}} */
+
+zend_class_entry *yaf_route_ce;
+
+#include "static.c"
+#include "simple.c"
+#include "supervar.c"
+#include "rewrite.c"
+#include "regex.c"
+#include "map.c"
+
+/* {{{ yaf_route_t * yaf_route_instance(yaf_route_t *this_ptr, zval *config TSRMLS_DC)
+ */
+yaf_route_t * yaf_route_instance(yaf_route_t *this_ptr, zval *config TSRMLS_DC) {
+ zval **match, **def, **map, **ppzval;
+ yaf_route_t *instance = NULL;
+
+ if (!config || IS_ARRAY != Z_TYPE_P(config)) {
+ return NULL;
+ }
+
+ if (zend_hash_find(Z_ARRVAL_P(config), ZEND_STRS("type"), (void **)&ppzval) == FAILURE
+ || IS_STRING != Z_TYPE_PP(ppzval)) {
+ return NULL;
+ }
+
+ if (strncasecmp(Z_STRVAL_PP(ppzval), "rewrite", sizeof("rewrite") - 1) == 0) {
+ if (zend_hash_find(Z_ARRVAL_P(config), ZEND_STRS("match"), (void **)&match) == FAILURE
+ || Z_TYPE_PP(match) != IS_STRING) {
+ return NULL;
+ }
+ if (zend_hash_find(Z_ARRVAL_P(config), ZEND_STRS("route"), (void **)&def) == FAILURE
+ || Z_TYPE_PP(def) != IS_ARRAY) {
+ return NULL;
+ }
+
+ instance = yaf_route_rewrite_instance(NULL, *match, *def, NULL TSRMLS_CC);
+ } else if (strncasecmp(Z_STRVAL_PP(ppzval), "regex", sizeof("regex") - 1) == 0) {
+ if (zend_hash_find(Z_ARRVAL_P(config), ZEND_STRS("match"), (void **)&match) == FAILURE || Z_TYPE_PP(match) != IS_STRING) {
+ return NULL;
+ }
+ if (zend_hash_find(Z_ARRVAL_P(config), ZEND_STRS("route"), (void **)&def) == FAILURE
+ || Z_TYPE_PP(def) != IS_ARRAY) {
+ return NULL;
+ }
+ if (zend_hash_find(Z_ARRVAL_P(config), ZEND_STRS("map"), (void **)&map) == FAILURE || Z_TYPE_PP(map) != IS_ARRAY) {
+ return NULL;
+ }
+
+ instance = yaf_route_regex_instance(NULL, *match, *def, *map, NULL TSRMLS_CC);
+ } else if (strncasecmp(Z_STRVAL_PP(ppzval), "simple", sizeof("simple") - 1) == 0) {
+ if (zend_hash_find(Z_ARRVAL_P(config), ZEND_STRS("module"), (void **)&match) == FAILURE
+ || Z_TYPE_PP(match) != IS_STRING) {
+ return NULL;
+ }
+ if (zend_hash_find(Z_ARRVAL_P(config), ZEND_STRS("controller"), (void **)&def) == FAILURE
+ || Z_TYPE_PP(def) != IS_STRING) {
+ return NULL;
+ }
+ if (zend_hash_find(Z_ARRVAL_P(config), ZEND_STRS("action"), (void **)&map) == FAILURE
+ || Z_TYPE_PP(map) != IS_STRING) {
+ return NULL;
+ }
+
+ instance = yaf_route_simple_instance(NULL, *match, *def, *map TSRMLS_CC);
+ } else if (strncasecmp(Z_STRVAL_PP(ppzval), "supervar", sizeof("supervar") - 1) == 0) {
+ if (zend_hash_find(Z_ARRVAL_P(config), ZEND_STRS("varname"), (void **)&match) == FAILURE
+ || Z_TYPE_PP(match) != IS_STRING) {
+ return NULL;
+ }
+
+ instance = yaf_route_supervar_instance(NULL, *match TSRMLS_CC);
+ }
+
+ return instance;
+}
+/* }}} */
+
+/** {{{ yaf_route_methods
+ */
+zend_function_entry yaf_route_methods[] = {
+ PHP_ABSTRACT_ME(yaf_route, route, yaf_route_route_arginfo)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+ */
+YAF_STARTUP_FUNCTION(route) {
+ zend_class_entry ce;
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Route_Interface", "Yaf\\Route_Interface", yaf_route_methods);
+ yaf_route_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+
+ YAF_STARTUP(route_static);
+ YAF_STARTUP(route_simple);
+ YAF_STARTUP(route_supervar);
+ YAF_STARTUP(route_rewrite);
+ YAF_STARTUP(route_regex);
+ YAF_STARTUP(route_map);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/routes/map.c b/routes/map.c
new file mode 100644
index 0000000000..87cb9f4797
--- /dev/null
+++ b/routes/map.c
@@ -0,0 +1,178 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$*/
+
+zend_class_entry *yaf_route_map_ce;
+
+#define YAF_ROUTE_MAP_VAR_NAME_DELIMETER "_delimeter"
+#define YAF_ROUTE_MAP_VAR_NAME_CTL_PREFER "_ctl_router"
+
+/** {{{ ARG_INFO
+ */
+ZEND_BEGIN_ARG_INFO_EX(yaf_route_map_construct_arginfo, 0, 0, 0)
+ ZEND_ARG_INFO(0, controller_prefer)
+ ZEND_ARG_INFO(0, delimiter)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/** {{{ int yaf_route_map_route(yaf_route_t *route, yaf_request_t *request TSRMLS_DC)
+*/
+int yaf_route_map_route(yaf_route_t *route, yaf_request_t *request TSRMLS_DC) {
+ zval *ctl_prefer, *delimer, *zuri, *base_uri, *params;
+ char *req_uri, *tmp, *rest, *ptrptr, *seg;
+ char *query_str = NULL;
+ uint seg_len = 0;
+
+ smart_str route_result = {0};
+
+ zuri = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_URI), 1 TSRMLS_CC);
+ base_uri = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_BASE), 1 TSRMLS_CC);
+
+ ctl_prefer = zend_read_property(yaf_route_map_ce, route, ZEND_STRL(YAF_ROUTE_MAP_VAR_NAME_CTL_PREFER), 1 TSRMLS_CC);
+ delimer = zend_read_property(yaf_route_map_ce, route, ZEND_STRL(YAF_ROUTE_MAP_VAR_NAME_DELIMETER), 1 TSRMLS_CC);
+
+ if (base_uri && IS_STRING == Z_TYPE_P(base_uri)
+ && strstr(Z_STRVAL_P(zuri), Z_STRVAL_P(base_uri)) == Z_STRVAL_P(zuri)) {
+ req_uri = estrdup(Z_STRVAL_P(zuri) + Z_STRLEN_P(base_uri));
+ } else {
+ req_uri = estrdup(Z_STRVAL_P(zuri));
+ }
+
+ if (Z_TYPE_P(delimer) == IS_STRING
+ && Z_STRLEN_P(delimer)) {
+ if ((query_str = strstr(req_uri, Z_STRVAL_P(delimer))) != NULL
+ && *(query_str - 1) == '/') {
+ tmp = req_uri;
+ rest = query_str + Z_STRLEN_P(delimer);
+ if (*rest == '\0') {
+ req_uri = estrndup(req_uri, query_str - req_uri);
+ query_str = NULL;
+ efree(tmp);
+ } else if (*rest == '/') {
+ req_uri = estrndup(req_uri, query_str - req_uri);
+ query_str = estrdup(rest);
+ efree(tmp);
+ } else {
+ query_str = NULL;
+ }
+ }
+ }
+
+ seg = php_strtok_r(req_uri, YAF_ROUTER_URL_DELIMIETER, &ptrptr);
+ while (seg) {
+ seg_len = strlen(seg);
+ if (seg_len) {
+ smart_str_appendl(&route_result, seg, seg_len);
+ }
+ smart_str_appendc(&route_result, '_');
+ seg = php_strtok_r(NULL, YAF_ROUTER_URL_DELIMIETER, &ptrptr);
+ }
+
+ if (route_result.len) {
+ if (Z_BVAL_P(ctl_prefer)) {
+ zend_update_property_stringl(yaf_request_ce, request, YAF_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), route_result.c, route_result.len - 1 TSRMLS_CC);
+ } else {
+ zend_update_property_stringl(yaf_request_ce, request, YAF_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), route_result.c, route_result.len - 1 TSRMLS_CC);
+ }
+ efree(route_result.c);
+ }
+
+ if (query_str) {
+ params = yaf_router_parse_parameters(query_str TSRMLS_CC);
+ (void)yaf_request_set_params_multi(request, params TSRMLS_CC);
+ zval_ptr_dtor(&params);
+ efree(query_str);
+ }
+
+ efree(req_uri);
+
+ return 1;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Route_Simple::route(Yaf_Request $req)
+*/
+PHP_METHOD(yaf_route_map, route) {
+ yaf_request_t *request;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &request) == FAILURE) {
+ return;
+ } else {
+ RETURN_BOOL(yaf_route_map_route(getThis(), request TSRMLS_CC));
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Route_Simple::__construct(int $controller_prefer=0, string $delimer = '#!')
+*/
+PHP_METHOD(yaf_route_map, __construct) {
+ long controller_prefer = 0;
+ char *delim = NULL;
+ uint delim_len = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ls",
+ &controller_prefer, &delim, &delim_len) == FAILURE) {
+ return;
+ }
+
+ if (controller_prefer) {
+ zend_update_property_bool(yaf_route_map_ce, getThis(),
+ YAF_STRL(YAF_ROUTE_MAP_VAR_NAME_CTL_PREFER), 1 TSRMLS_CC);
+ }
+
+ if (delim && delim_len) {
+ zend_update_property_stringl(yaf_route_map_ce, getThis(),
+ YAF_STRL(YAF_ROUTE_MAP_VAR_NAME_DELIMETER), delim, delim_len TSRMLS_CC);
+ }
+}
+/* }}} */
+
+/** {{{ yaf_route_map_methods
+*/
+zend_function_entry yaf_route_map_methods[] = {
+ PHP_ME(yaf_route_map, __construct, yaf_route_map_construct_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(yaf_route_map, route, yaf_route_route_arginfo, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(route_map) {
+ zend_class_entry ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Route_Map", "Yaf\\Route\\Map", yaf_route_map_methods);
+ yaf_route_map_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+ zend_class_implements(yaf_route_map_ce TSRMLS_CC, 1, yaf_route_ce);
+
+ yaf_route_map_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+
+ zend_declare_property_bool(yaf_route_map_ce, YAF_STRL(YAF_ROUTE_MAP_VAR_NAME_CTL_PREFER), 0, ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_route_map_ce, YAF_STRL(YAF_ROUTE_MAP_VAR_NAME_DELIMETER), ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/routes/regex.c b/routes/regex.c
new file mode 100644
index 0000000000..52e09aa49a
--- /dev/null
+++ b/routes/regex.c
@@ -0,0 +1,270 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+zend_class_entry *yaf_route_regex_ce;
+
+/** {{{ ARG_INFO
+ */
+ZEND_BEGIN_ARG_INFO_EX(yaf_route_regex_construct_arginfo, 0, 0, 2)
+ ZEND_ARG_INFO(0, match)
+ ZEND_ARG_ARRAY_INFO(0, route, 0)
+ ZEND_ARG_ARRAY_INFO(0, map, 1)
+ ZEND_ARG_ARRAY_INFO(0, verify, 1)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/** {{{ yaf_route_t * yaf_route_regex_instance(yaf_route_t *this_ptr, zval *route, zval *def, zval *map, zval *verify TSRMLS_DC)
+ */
+yaf_route_t * yaf_route_regex_instance(yaf_route_t *this_ptr, zval *route, zval *def, zval *map, zval *verify TSRMLS_DC) {
+ yaf_route_t *instance;
+
+ if (this_ptr) {
+ instance = this_ptr;
+ } else {
+ MAKE_STD_ZVAL(instance);
+ object_init_ex(instance, yaf_route_regex_ce);
+ }
+
+ zend_update_property(yaf_route_regex_ce, instance, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_MATCH), route TSRMLS_CC);
+ zend_update_property(yaf_route_regex_ce, instance, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_ROUTE), def TSRMLS_CC);
+ zend_update_property(yaf_route_regex_ce, instance, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_MAP), map TSRMLS_CC);
+
+ if (!verify) {
+ zend_update_property_null(yaf_route_regex_ce, instance, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_VERIFY) TSRMLS_CC);
+ } else {
+ zend_update_property(yaf_route_regex_ce, instance, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_VERIFY), verify TSRMLS_CC);
+ }
+
+ return instance;
+}
+/* }}} */
+
+/** {{{ static zval * yaf_route_regex_match(yaf_route_t *router, char *uir, int len TSRMLS_DC)
+ */
+static zval * yaf_route_regex_match(yaf_route_t *route, char *uir, int len TSRMLS_DC) {
+ zval *match;
+ pcre_cache_entry *pce_regexp;
+
+ if (!len) {
+ return NULL;
+ }
+
+ match = zend_read_property(yaf_route_regex_ce, route, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_MATCH), 1 TSRMLS_CC);
+
+ if ((pce_regexp = pcre_get_compiled_regex_cache(Z_STRVAL_P(match), Z_STRLEN_P(match) TSRMLS_CC)) == NULL) {
+ return NULL;
+ } else {
+ zval *matches, *subparts, *map;
+
+ MAKE_STD_ZVAL(matches);
+ MAKE_STD_ZVAL(subparts);
+ ZVAL_NULL(subparts);
+
+ map = zend_read_property(yaf_route_regex_ce, route, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_MAP), 1 TSRMLS_CC);
+
+ php_pcre_match_impl(pce_regexp, uir, len, matches, subparts /* subpats */,
+ 0/* global */, 0/* ZEND_NUM_ARGS() >= 4 */, 0/*flags PREG_OFFSET_CAPTURE*/, 0/* start_offset */ TSRMLS_CC);
+
+ if (!Z_LVAL_P(matches)) {
+ zval_ptr_dtor(&matches);
+ zval_ptr_dtor(&subparts);
+ return NULL;
+ } else {
+ zval *ret, **name, **ppzval;
+ char *key = NULL;
+ int len = 0;
+ long idx = 0;
+ HashTable *ht;
+
+ MAKE_STD_ZVAL(ret);
+ array_init(ret);
+
+ ht = Z_ARRVAL_P(subparts);
+ for(zend_hash_internal_pointer_reset(ht);
+ zend_hash_has_more_elements(ht) == SUCCESS;
+ zend_hash_move_forward(ht)) {
+
+ if (zend_hash_get_current_data(ht, (void**)&ppzval) == FAILURE) {
+ continue;
+ }
+
+ if (zend_hash_get_current_key_ex(ht, &key, &len, &idx, 0, NULL) == HASH_KEY_IS_LONG) {
+ if (zend_hash_index_find(Z_ARRVAL_P(map), idx, (void **)&name) == SUCCESS) {
+ Z_ADDREF_P(*ppzval);
+ zend_hash_update(Z_ARRVAL_P(ret), Z_STRVAL_PP(name), Z_STRLEN_PP(name) + 1, (void **)ppzval, sizeof(zval *), NULL);
+ }
+ } else {
+ Z_ADDREF_P(*ppzval);
+ zend_hash_update(Z_ARRVAL_P(ret), key, len, (void **)ppzval, sizeof(zval *), NULL);
+ }
+ }
+
+ zval_ptr_dtor(&matches);
+ zval_ptr_dtor(&subparts);
+ return ret;
+ }
+ }
+
+ return NULL;
+}
+/* }}} */
+
+/** {{{ int yaf_route_regex_route(yaf_route_t *router, yaf_request_t *request TSRMLS_DC)
+ */
+int yaf_route_regex_route(yaf_route_t *router, yaf_request_t *request TSRMLS_DC) {
+ char *request_uri;
+ zval *args, *base_uri, *zuri;
+
+ zuri = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_URI), 1 TSRMLS_CC);
+ base_uri = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_BASE), 1 TSRMLS_CC);
+
+ if (base_uri && IS_STRING == Z_TYPE_P(base_uri)
+ && strstr(Z_STRVAL_P(zuri), Z_STRVAL_P(base_uri)) == Z_STRVAL_P(zuri)) {
+ request_uri = estrdup(Z_STRVAL_P(zuri) + Z_STRLEN_P(base_uri));
+ } else {
+ request_uri = estrdup(Z_STRVAL_P(zuri));
+ }
+
+ if (!(args = yaf_route_regex_match(router, request_uri, strlen(request_uri) TSRMLS_CC))) {
+ efree(request_uri);
+ return 0;
+ } else {
+ zval **module, **controller, **action, *routes;
+
+ routes = zend_read_property(yaf_route_regex_ce, router, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_ROUTE), 1 TSRMLS_CC);
+ if (zend_hash_find(Z_ARRVAL_P(routes), ZEND_STRS("module"), (void **)&module) == SUCCESS) {
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), *module TSRMLS_CC);
+ }
+
+ if (zend_hash_find(Z_ARRVAL_P(routes), ZEND_STRS("controller"), (void **)&controller) == SUCCESS) {
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), *controller TSRMLS_CC);
+ }
+
+ if (zend_hash_find(Z_ARRVAL_P(routes), ZEND_STRS("action"), (void **)&action) == SUCCESS) {
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), *action TSRMLS_CC);
+ }
+
+ (void)yaf_request_set_params_multi(request, args TSRMLS_CC);
+ zval_ptr_dtor(&args);
+ efree(request_uri);
+ }
+
+ return 1;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Route_Regex::route(string $uri)
+ */
+PHP_METHOD(yaf_route_regex, route) {
+ yaf_route_t *route;
+ yaf_request_t *request;
+
+ route = getThis();
+
+ RETVAL_FALSE;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &request) == FAILURE) {
+ return;
+ }
+
+ if (!request || IS_OBJECT != Z_TYPE_P(request)
+ || !instanceof_function(Z_OBJCE_P(request), yaf_request_ce TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expects a %s instance", yaf_request_ce->name);
+ RETURN_FALSE;
+ }
+
+ RETURN_BOOL(yaf_route_regex_route(route, request TSRMLS_CC));
+}
+/** }}} */
+
+/** {{{ proto public Yaf_Route_Regex::__construct(string $match, array $route, array $map = NULL, array $verify = NULL)
+ */
+PHP_METHOD(yaf_route_regex, __construct) {
+ zval *match, *route, *map, *verify = NULL;
+ yaf_route_t *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zaa|a", &match, &route, &map, &verify) == FAILURE) {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "Expects an array as third paramter", yaf_route_regex_ce->name);
+ WRONG_PARAM_COUNT;
+ }
+
+ if (IS_STRING != Z_TYPE_P(match) || !Z_STRLEN_P(match)) {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "Expects a string as the first parameter", yaf_route_regex_ce->name);
+ RETURN_FALSE;
+ }
+
+ if (Z_TYPE_P(route) != IS_ARRAY) {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "Expects a array as the second parameter", yaf_route_regex_ce->name);
+ RETURN_FALSE;
+ }
+
+ if (IS_ARRAY != Z_TYPE_P(map)) {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "Expects an array as third parameter", yaf_route_regex_ce->name);
+ RETURN_FALSE;
+ }
+
+ if (verify && IS_ARRAY != Z_TYPE_P(verify)) {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "Expects an array as verify parmater", yaf_route_regex_ce->name);
+ RETURN_FALSE;
+ }
+
+ (void)yaf_route_regex_instance(self, match, route, map, verify TSRMLS_CC);
+
+ if (self) {
+ RETURN_ZVAL(self, 1, 0);
+ }
+
+ RETURN_FALSE;
+}
+/** }}} */
+
+/** {{{ yaf_route_regex_methods
+ */
+zend_function_entry yaf_route_regex_methods[] = {
+ PHP_ME(yaf_route_regex, __construct, yaf_route_regex_construct_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(yaf_route_regex, route, yaf_route_route_arginfo, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+ */
+YAF_STARTUP_FUNCTION(route_regex) {
+ zend_class_entry ce;
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Route_Regex", "Yaf\\Route\\Regex", yaf_route_regex_methods);
+ yaf_route_regex_ce = zend_register_internal_class_ex(&ce, yaf_route_ce, NULL TSRMLS_CC);
+ zend_class_implements(yaf_route_regex_ce TSRMLS_CC, 1, yaf_route_ce);
+ yaf_route_regex_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+
+ zend_declare_property_null(yaf_route_regex_ce, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_MATCH), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_route_regex_ce, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_ROUTE), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_route_regex_ce, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_MAP), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_route_regex_ce, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_VERIFY), ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
+
diff --git a/routes/rewrite.c b/routes/rewrite.c
new file mode 100644
index 0000000000..8c38fb9338
--- /dev/null
+++ b/routes/rewrite.c
@@ -0,0 +1,324 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+zend_class_entry *yaf_route_rewrite_ce;
+
+/** {{{ ARG_INFO
+ */
+ZEND_BEGIN_ARG_INFO_EX(yaf_route_rewrite_construct_arginfo, 0, 0, 2)
+ ZEND_ARG_INFO(0, match)
+ ZEND_ARG_ARRAY_INFO(0, route, 0)
+ ZEND_ARG_ARRAY_INFO(0, verify, 1)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/** {{{ yaf_route_t * yaf_route_rewrite_instance(yaf_route_t *this_ptr, zval *match, zval *router, zval *verify TSRMLS_DC)
+ */
+yaf_route_t * yaf_route_rewrite_instance(yaf_route_t *this_ptr, zval *match, zval *route, zval *verify TSRMLS_DC) {
+ yaf_route_t *instance;
+
+ if (this_ptr) {
+ instance = this_ptr;
+ } else {
+ MAKE_STD_ZVAL(instance);
+ object_init_ex(instance, yaf_route_rewrite_ce);
+ }
+
+ zend_update_property(yaf_route_rewrite_ce, instance, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_MATCH), match TSRMLS_CC);
+ zend_update_property(yaf_route_rewrite_ce, instance, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_ROUTE), route TSRMLS_CC);
+
+ if (!verify) {
+ zend_update_property_null(yaf_route_rewrite_ce, instance, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_VERIFY) TSRMLS_CC);
+ } else {
+ zend_update_property(yaf_route_rewrite_ce, instance, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_VERIFY), verify TSRMLS_CC);
+ }
+
+ return instance;
+}
+/* }}} */
+
+/** {{{ static zval * yaf_route_rewrite_match(yaf_route_t *router, char *uir, int len TSRMLS_DC)
+ */
+static zval * yaf_route_rewrite_match(yaf_route_t *router, char *uir, int len TSRMLS_DC) {
+ char *seg, *pmatch, *ptrptr;
+ int seg_len;
+ zval *match;
+ pcre_cache_entry *pce_regexp;
+ smart_str pattern = {0};
+
+ if (!len) {
+ return NULL;
+ }
+
+ match = zend_read_property(yaf_route_rewrite_ce, router, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_MATCH), 1 TSRMLS_CC);
+ pmatch = estrndup(Z_STRVAL_P(match), Z_STRLEN_P(match));
+
+ smart_str_appendc(&pattern, YAF_ROUTE_REGEX_DILIMITER);
+ smart_str_appendc(&pattern, '^');
+
+ seg = php_strtok_r(pmatch, YAF_ROUTER_URL_DELIMIETER, &ptrptr);
+ while (seg) {
+ seg_len = strlen(seg);
+ if (seg_len) {
+ smart_str_appendl(&pattern, YAF_ROUTER_URL_DELIMIETER, 1);
+
+ if(*(seg) == '*') {
+ smart_str_appendl(&pattern, "(?P<__yaf_route_rest>.*)", sizeof("(?P<__yaf_route_rest>.*)") -1);
+ break;
+ }
+
+ if(*(seg) == ':') {
+ smart_str_appendl(&pattern, "(?P<", sizeof("(?P<") -1 );
+ smart_str_appendl(&pattern, seg + 1, seg_len - 1);
+ smart_str_appendl(&pattern, ">[^"YAF_ROUTER_URL_DELIMIETER"]+)", sizeof(">[^"YAF_ROUTER_URL_DELIMIETER"]+)") - 1);
+ } else {
+ smart_str_appendl(&pattern, seg, seg_len);
+ }
+
+ }
+ seg = php_strtok_r(NULL, YAF_ROUTER_URL_DELIMIETER, &ptrptr);
+ }
+
+ efree(pmatch);
+ smart_str_appendc(&pattern, YAF_ROUTE_REGEX_DILIMITER);
+ smart_str_appendc(&pattern, 'i');
+ smart_str_0(&pattern);
+
+ if ((pce_regexp = pcre_get_compiled_regex_cache(pattern.c, pattern.len TSRMLS_CC)) == NULL) {
+ smart_str_free(&pattern);
+ return NULL;
+ } else {
+ zval *matches, *subparts;
+
+ smart_str_free(&pattern);
+
+ MAKE_STD_ZVAL(matches);
+ MAKE_STD_ZVAL(subparts);
+ ZVAL_LONG(matches, 0);
+ ZVAL_NULL(subparts);
+
+ php_pcre_match_impl(pce_regexp, uir, len, matches, subparts /* subpats */,
+ 0/* global */, 0/* ZEND_NUM_ARGS() >= 4 */, 0/*flags PREG_OFFSET_CAPTURE*/, 0/* start_offset */ TSRMLS_CC);
+
+ if (!Z_LVAL_P(matches)) {
+ zval_ptr_dtor(&matches);
+ zval_ptr_dtor(&subparts);
+ return NULL;
+ } else {
+ zval *ret, **ppzval;
+ char *key;
+ int len = 0;
+ long idx = 0;
+ HashTable *ht;
+
+ MAKE_STD_ZVAL(ret);
+ array_init(ret);
+
+ ht = Z_ARRVAL_P(subparts);
+ for(zend_hash_internal_pointer_reset(ht);
+ zend_hash_has_more_elements(ht) == SUCCESS;
+ zend_hash_move_forward(ht)) {
+
+ if (zend_hash_get_current_key_type(ht) != HASH_KEY_IS_STRING) {
+ continue;
+ }
+
+ zend_hash_get_current_key_ex(ht, &key, &len, &idx, 0, NULL);
+ if (zend_hash_get_current_data(ht, (void**)&ppzval) == FAILURE) {
+ continue;
+ }
+
+ if (!strncmp(key, "__yaf_route_rest", len)) {
+ zval *args = yaf_router_parse_parameters(Z_STRVAL_PP(ppzval) TSRMLS_CC);
+ if (args) {
+ zend_hash_copy(Z_ARRVAL_P(ret), Z_ARRVAL_P(args), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
+ zval_ptr_dtor(&args);
+ }
+ } else {
+ Z_ADDREF_P(*ppzval);
+ zend_hash_update(Z_ARRVAL_P(ret), key, len, (void **)ppzval, sizeof(zval *), NULL);
+ }
+ }
+
+ zval_ptr_dtor(&matches);
+ zval_ptr_dtor(&subparts);
+ return ret;
+ }
+ }
+
+ return NULL;
+}
+/* }}} */
+
+/** {{{ int yaf_route_rewrite_route(yaf_route_t *router, yaf_request_t *request TSRMLS_DC)
+ */
+int yaf_route_rewrite_route(yaf_route_t *router, yaf_request_t *request TSRMLS_DC) {
+ char *request_uri;
+ zval *args, *base_uri, *zuri;
+
+ zuri = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_URI), 1 TSRMLS_CC);
+ base_uri = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_BASE), 1 TSRMLS_CC);
+
+ if (base_uri && IS_STRING == Z_TYPE_P(base_uri)
+ && strstr(Z_STRVAL_P(zuri), Z_STRVAL_P(base_uri)) == Z_STRVAL_P(zuri)) {
+ request_uri = estrdup(Z_STRVAL_P(zuri) + Z_STRLEN_P(base_uri));
+ } else {
+ request_uri = estrdup(Z_STRVAL_P(zuri));
+ }
+
+ if (!(args = yaf_route_rewrite_match(router, request_uri, strlen(request_uri) TSRMLS_CC))) {
+ efree(request_uri);
+ return 0;
+ } else {
+ zval **module, **controller, **action, *routes;
+
+ routes = zend_read_property(yaf_route_rewrite_ce, router, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_ROUTE), 1 TSRMLS_CC);
+ if (zend_hash_find(Z_ARRVAL_P(routes), ZEND_STRS("module"), (void **)&module) == SUCCESS) {
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), *module TSRMLS_CC);
+ }
+
+ if (zend_hash_find(Z_ARRVAL_P(routes), ZEND_STRS("controller"), (void **)&controller) == SUCCESS) {
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), *controller TSRMLS_CC);
+ }
+
+ if (zend_hash_find(Z_ARRVAL_P(routes), ZEND_STRS("action"), (void **)&action) == SUCCESS) {
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), *action TSRMLS_CC);
+ }
+
+ (void)yaf_request_set_params_multi(request, args TSRMLS_CC);
+ zval_ptr_dtor(&args);
+ efree(request_uri);
+ return 1;
+ }
+
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Route_Rewrite::route(Yaf_Request_Abstarct $request)
+ */
+PHP_METHOD(yaf_route_rewrite, route) {
+ yaf_route_t *route;
+ yaf_request_t *request;
+
+ route = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &request) == FAILURE) {
+ return;
+ }
+
+ if (!request || IS_OBJECT != Z_TYPE_P(request)
+ || !instanceof_function(Z_OBJCE_P(request), yaf_request_ce TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expect a %s instance", yaf_request_ce->name);
+ RETURN_FALSE;
+ }
+
+ RETURN_BOOL(yaf_route_rewrite_route(route, request TSRMLS_CC));
+}
+/** }}} */
+
+/** {{{ proto public Yaf_Route_Rewrite::match(string $uri)
+ */
+PHP_METHOD(yaf_route_rewrite, match) {
+ char *uri;
+ uint len;
+ zval *matches;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &uri, &len) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ if (!len) RETURN_FALSE;
+
+ if ((matches = yaf_route_rewrite_match(getThis(), uri, len TSRMLS_CC))) {
+ RETURN_ZVAL(matches, 0, 0);
+ }
+
+ RETURN_FALSE;
+}
+/** }}} */
+
+/** {{{ proto public Yaf_Route_Rewrite::__construct(string $match, array $route, array $verify = NULL)
+ */
+PHP_METHOD(yaf_route_rewrite, __construct) {
+ zval *match, *route, *verify = NULL;
+ yaf_route_t *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "za|a", &match, &route, &verify) == FAILURE) {
+ return;
+ }
+
+ if (IS_STRING != Z_TYPE_P(match) || !Z_STRLEN_P(match)) {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "Expects a string as the first parameter", yaf_route_rewrite_ce->name);
+ RETURN_FALSE;
+ }
+
+ if (IS_ARRAY != Z_TYPE_P(route)) {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "Expects an array as the second parameter", yaf_route_rewrite_ce->name);
+ RETURN_FALSE;
+ }
+
+ if (verify && IS_ARRAY != Z_TYPE_P(verify)) {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "Expects an array as third parameter", yaf_route_rewrite_ce->name);
+ RETURN_FALSE;
+ }
+
+ (void)yaf_route_rewrite_instance(self, match, route, verify TSRMLS_CC);
+
+ if (self) {
+ RETURN_ZVAL(self, 1, 0);
+ }
+
+ RETURN_FALSE;
+}
+/** }}} */
+
+/** {{{ yaf_route_rewrite_methods
+ */
+zend_function_entry yaf_route_rewrite_methods[] = {
+ PHP_ME(yaf_route_rewrite, __construct, yaf_route_rewrite_construct_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(yaf_route_rewrite, route, yaf_route_route_arginfo, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+ */
+YAF_STARTUP_FUNCTION(route_rewrite) {
+ zend_class_entry ce;
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Route_Rewrite", "Yaf\\Route\\Rewrite", yaf_route_rewrite_methods);
+ yaf_route_rewrite_ce = zend_register_internal_class_ex(&ce, yaf_route_ce, NULL TSRMLS_CC);
+ zend_class_implements(yaf_route_rewrite_ce TSRMLS_CC, 1, yaf_route_ce);
+ yaf_route_rewrite_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+
+ zend_declare_property_null(yaf_route_rewrite_ce, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_MATCH), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_route_rewrite_ce, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_ROUTE), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_route_rewrite_ce, ZEND_STRL(YAF_ROUTE_PROPETY_NAME_VERIFY), ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
+
diff --git a/routes/simple.c b/routes/simple.c
new file mode 100644
index 0000000000..0392210169
--- /dev/null
+++ b/routes/simple.c
@@ -0,0 +1,149 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+zend_class_entry *yaf_route_simple_ce;
+
+#define YAF_ROUTE_SIMPLE_VAR_NAME_MODULE "module"
+#define YAF_ROUTE_SIMPLE_VAR_NAME_CONTROLLER "controller"
+#define YAF_ROUTE_SIMPLE_VAR_NAME_ACTION "action"
+
+/** {{{ ARG_INFO
+ */
+ZEND_BEGIN_ARG_INFO_EX(yaf_route_simple_construct_arginfo, 0, 0, 3)
+ ZEND_ARG_INFO(0, module_name)
+ ZEND_ARG_INFO(0, controller_name)
+ ZEND_ARG_INFO(0, action_name)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/** {{{ int yaf_route_simple_route(yaf_route_t *route, yaf_request_t *request TSRMLS_DC)
+ */
+int yaf_route_simple_route(yaf_route_t *route, yaf_request_t *request TSRMLS_DC) {
+ zval *module, *controller, *action;
+ zval *nmodule, *ncontroller, *naction;
+
+ nmodule = zend_read_property(yaf_route_simple_ce, route, ZEND_STRL(YAF_ROUTE_SIMPLE_VAR_NAME_MODULE), 1 TSRMLS_CC);
+ ncontroller = zend_read_property(yaf_route_simple_ce, route, ZEND_STRL(YAF_ROUTE_SIMPLE_VAR_NAME_CONTROLLER), 1 TSRMLS_CC);
+ naction = zend_read_property(yaf_route_simple_ce, route, ZEND_STRL(YAF_ROUTE_SIMPLE_VAR_NAME_ACTION), 1 TSRMLS_CC);
+
+ /* if there is no expect parameter in supervars, then null will be return */
+ module = yaf_request_query(YAF_GLOBAL_VARS_GET, Z_STRVAL_P(nmodule), Z_STRLEN_P(nmodule) TSRMLS_CC);
+ controller = yaf_request_query(YAF_GLOBAL_VARS_GET, Z_STRVAL_P(ncontroller), Z_STRLEN_P(ncontroller) TSRMLS_CC);
+ action = yaf_request_query(YAF_GLOBAL_VARS_GET, Z_STRVAL_P(naction), Z_STRLEN_P(naction) TSRMLS_CC);
+
+ if (ZVAL_IS_NULL(module) && ZVAL_IS_NULL(controller) && ZVAL_IS_NULL(action)) {
+ return 0;
+ }
+
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), module TSRMLS_CC);
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), controller TSRMLS_CC);
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), action TSRMLS_CC);
+
+ return 1;
+}
+/* }}} */
+
+/** {{{ yaf_route_t * yaf_route_simple_instance(yaf_route_t *this_ptr, zval *module, zval *controller, zval *action TSRMLS_DC)
+ */
+yaf_route_t * yaf_route_simple_instance(yaf_route_t *this_ptr, zval *module, zval *controller, zval *action TSRMLS_DC) {
+ yaf_route_t *instance;
+
+ if (this_ptr) {
+ instance = this_ptr;
+ } else {
+ MAKE_STD_ZVAL(instance);
+ object_init_ex(instance, yaf_route_simple_ce);
+ }
+
+ zend_update_property(yaf_route_simple_ce, instance, ZEND_STRL(YAF_ROUTE_SIMPLE_VAR_NAME_MODULE), module TSRMLS_CC);
+ zend_update_property(yaf_route_simple_ce, instance, ZEND_STRL(YAF_ROUTE_SIMPLE_VAR_NAME_CONTROLLER), controller TSRMLS_CC);
+ zend_update_property(yaf_route_simple_ce, instance, ZEND_STRL(YAF_ROUTE_SIMPLE_VAR_NAME_ACTION), action TSRMLS_CC);
+
+ return instance;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Route_Simple::route(Yaf_Request $req)
+*/
+PHP_METHOD(yaf_route_simple, route) {
+ yaf_request_t *request;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &request) == FAILURE) {
+ return;
+ } else {
+ RETURN_BOOL(yaf_route_simple_route(getThis(), request TSRMLS_CC));
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Route_Simple::__construct(string $module, string $controller, string $action)
+ */
+PHP_METHOD(yaf_route_simple, __construct) {
+ zval *module, *controller, *action;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz", &module, &controller, &action) == FAILURE) {
+ return;
+ }
+
+ if (IS_STRING != Z_TYPE_P(module)
+ || IS_STRING != Z_TYPE_P(controller)
+ || IS_STRING != Z_TYPE_P(action)) {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "Expect 3 string paramsters", yaf_route_simple_ce->name);
+ RETURN_FALSE;
+ } else {
+ (void)yaf_route_simple_instance(getThis(), module, controller, action TSRMLS_CC);
+ }
+}
+/* }}} */
+
+/** {{{ yaf_route_simple_methods
+ */
+zend_function_entry yaf_route_simple_methods[] = {
+ PHP_ME(yaf_route_simple, __construct, yaf_route_simple_construct_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(yaf_route_simple, route, yaf_route_route_arginfo, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+ */
+YAF_STARTUP_FUNCTION(route_simple) {
+ zend_class_entry ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Route_Simple", "Yaf\\Route\\Simple", yaf_route_simple_methods);
+ yaf_route_simple_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+ zend_class_implements(yaf_route_simple_ce TSRMLS_CC, 1, yaf_route_ce);
+
+ yaf_route_simple_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+
+ zend_declare_property_null(yaf_route_simple_ce, YAF_STRL(YAF_ROUTE_SIMPLE_VAR_NAME_CONTROLLER), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_route_simple_ce, YAF_STRL(YAF_ROUTE_SIMPLE_VAR_NAME_MODULE), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_route_simple_ce, YAF_STRL(YAF_ROUTE_SIMPLE_VAR_NAME_ACTION), ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/routes/static.c b/routes/static.c
new file mode 100644
index 0000000000..f6e2c86d9d
--- /dev/null
+++ b/routes/static.c
@@ -0,0 +1,206 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+zend_class_entry * yaf_route_static_ce;
+
+/** {{{ ARG_INFO
+ */
+ZEND_BEGIN_ARG_INFO_EX(yaf_route_static_match_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, uri)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/** {{{ int yaf_route_static_route(yaf_route_t *route, yaf_request_t *request TSRMLS_DC)
+ */
+int yaf_route_static_route(yaf_route_t *route, yaf_request_t *request TSRMLS_DC) {
+ zval *zuri, *base_uri, *params;
+ char *req_uri, *module = NULL, *controller = NULL, *action = NULL, *rest = NULL;
+
+ zuri = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_URI), 1 TSRMLS_CC);
+ base_uri = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_BASE), 1 TSRMLS_CC);
+
+ if (base_uri && IS_STRING == Z_TYPE_P(base_uri)
+ && strstr(Z_STRVAL_P(zuri), Z_STRVAL_P(base_uri)) == Z_STRVAL_P(zuri)) {
+ req_uri = estrdup(Z_STRVAL_P(zuri) + Z_STRLEN_P(base_uri));
+ } else {
+ req_uri = estrdup(Z_STRVAL_P(zuri));
+ }
+
+ do {
+ char *s, *p;
+ char *uri;
+ int request_uri_len = Z_STRLEN_P(zuri);
+
+ if (request_uri_len == 0
+ || (request_uri_len == 1 && *req_uri == '/')) {
+ break;
+ }
+
+ uri = req_uri;
+ s = p = uri;
+
+ while(*p == ' ' || *p == '/') {
+ ++p;
+ }
+
+ if ((s = strstr(p, "/")) != NULL) {
+ if (yaf_application_is_module_name(p, s-p TSRMLS_CC)) {
+ module = estrndup(p, s - p);
+ p = s + 1;
+ }
+ }
+
+ if ((s = strstr(p, "/")) != NULL) {
+ controller = estrndup(p, s - p);
+ p = s + 1;
+ }
+
+ if ((s = strstr(p, "/")) != NULL) {
+ action = estrndup(p, s - p);
+ p = s + 1;
+ }
+
+ if (*p != '\0') {
+ rest = estrdup(p);
+ }
+
+ if (module == NULL
+ && controller == NULL
+ && action == NULL ) {
+ /* /one */
+ if (YAF_G(action_prefer)) {
+ action = rest;
+ } else {
+ controller = rest;
+ }
+ rest = NULL;
+ } else if (module == NULL
+ && action == NULL
+ && rest == NULL) {
+ /* /one/ */
+ if (YAF_G(action_prefer)) {
+ action = controller;
+ controller = NULL;
+ }
+ } else if (controller == NULL
+ && action == NULL
+ && rest != NULL) {
+ /* /controller/action */
+ controller = module;
+ action = rest;
+ module = NULL;
+ rest = NULL;
+ } else if (action == NULL
+ && rest == NULL) {
+ /* /module/controller/ */
+ action = controller;
+ controller = module;
+ module = NULL;
+ } else if (controller == NULL
+ && action == NULL) {
+ /* /module/rest */
+ controller = module;
+ action = rest;
+ module = NULL;
+ rest = NULL;
+ } else if (action == NULL) {
+ /* /module/controller/action */
+ action = rest;
+ rest = NULL;
+ }
+
+ } while (0);
+
+ efree(req_uri);
+
+ if (module != NULL) {
+ zend_update_property_string(yaf_request_ce, request, YAF_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), module TSRMLS_CC);
+ efree(module);
+ }
+ if (controller != NULL) {
+ zend_update_property_string(yaf_request_ce, request, YAF_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), controller TSRMLS_CC);
+ efree(controller);
+ }
+
+ if (action != NULL) {
+ zend_update_property_string(yaf_request_ce, request, YAF_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), action TSRMLS_CC);
+ efree(action);
+ }
+
+ if (rest) {
+ params = yaf_router_parse_parameters(rest TSRMLS_CC);
+ (void)yaf_request_set_params_multi(request, params TSRMLS_CC);
+ zval_ptr_dtor(&params);
+ efree(rest);
+ }
+
+ return 1;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Router_Classical::route(Yaf_Request $req)
+*/
+PHP_METHOD(yaf_route_static, route) {
+ yaf_request_t *request;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &request) == FAILURE) {
+ return;
+ } else {
+ RETURN_BOOL(yaf_route_static_route(getThis(), request TSRMLS_CC));
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Router_Classical::match(string $uri)
+*/
+PHP_METHOD(yaf_route_static, match) {
+ RETURN_TRUE;
+}
+/* }}} */
+
+/** {{{ yaf_route_static_methods
+ */
+zend_function_entry yaf_route_static_methods[] = {
+ PHP_ME(yaf_route_static, match, yaf_route_static_match_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_route_static, route, yaf_route_route_arginfo, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+ */
+YAF_STARTUP_FUNCTION(route_static) {
+ zend_class_entry ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Route_Static", "Yaf\\Route\\Static", yaf_route_static_methods);
+ yaf_route_static_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+ zend_class_implements(yaf_route_static_ce TSRMLS_CC, 1, yaf_router_ce);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
+
diff --git a/routes/supervar.c b/routes/supervar.c
new file mode 100644
index 0000000000..1b6b353263
--- /dev/null
+++ b/routes/supervar.c
@@ -0,0 +1,241 @@
+ /*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#define YAF_ROUTE_SUPERVAR_PROPETY_NAME_VAR "_var_name"
+
+zend_class_entry *yaf_route_supervar_ce;
+
+/** {{{ ARG_INFO
+ */
+ZEND_BEGIN_ARG_INFO_EX(yaf_route_supervar_construct_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, supervar_name)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/** {{{ int yaf_route_supervar_route(yaf_route_t *route, yaf_request_t *request TSRMLS_DC)
+ */
+int yaf_route_supervar_route(yaf_route_t *route, yaf_request_t *request TSRMLS_DC) {
+ zval *varname, *zuir, *params;
+ char *req_uri, *module = NULL, *controller = NULL, *action = NULL, *rest = NULL;
+
+ varname = zend_read_property(yaf_route_supervar_ce, route, ZEND_STRL(YAF_ROUTE_SUPERVAR_PROPETY_NAME_VAR), 1 TSRMLS_CC);
+
+ zuir = yaf_request_query(YAF_GLOBAL_VARS_GET, Z_STRVAL_P(varname), Z_STRLEN_P(varname) TSRMLS_CC);
+
+ if (!zuir || ZVAL_IS_NULL(zuir)) {
+ return 0;
+ }
+
+ req_uri = estrndup(Z_STRVAL_P(zuir), Z_STRLEN_P(zuir));
+ do {
+ char *s, *p;
+ char *uri;
+ int request_uri_len = Z_STRLEN_P(zuir);
+
+ if (request_uri_len == 0
+ || (request_uri_len == 1 && *req_uri == '/')) {
+ break;
+ }
+
+ uri = req_uri;
+ s = p = uri;
+
+ while(*p == ' ' || *p == '/') {
+ ++p;
+ }
+
+ if ((s = strstr(p, "/")) != NULL) {
+ if (yaf_application_is_module_name(p, s-p TSRMLS_CC)) {
+ module = estrndup(p, s - p);
+ p = s + 1;
+ }
+ }
+
+ if ((s = strstr(p, "/")) != NULL) {
+ controller = estrndup(p, s - p);
+ p = s + 1;
+ }
+
+ if ((s = strstr(p, "/")) != NULL) {
+ action = estrndup(p, s - p);
+ p = s + 1;
+ }
+
+ if (*p != '\0') {
+ rest = estrdup(p);
+ }
+
+ if (module == NULL
+ && controller == NULL
+ && action == NULL ) {
+ /* /one */
+ if (YAF_G(action_prefer)) {
+ action = rest;
+ } else {
+ controller = rest;
+ }
+ rest = NULL;
+ } else if (module == NULL
+ && action == NULL
+ && rest == NULL) {
+ /* /one/ */
+ if (YAF_G(action_prefer)) {
+ action = controller;
+ controller = NULL;
+ }
+ } else if (controller == NULL
+ && action == NULL
+ && rest != NULL) {
+ /* /controller/action */
+ controller = module;
+ action = rest;
+ module = NULL;
+ rest = NULL;
+ } else if (action == NULL
+ && rest == NULL) {
+ /* /module/controller/ */
+ action = controller;
+ controller = module;
+ module = NULL;
+ } else if (controller == NULL
+ && action == NULL) {
+ /* /module/rest */
+ controller = module;
+ action = rest;
+ module = NULL;
+ rest = NULL;
+ } else if (action == NULL) {
+ /* /module/controller/action */
+ action = rest;
+ rest = NULL;
+ }
+
+ } while (0);
+
+ efree(req_uri);
+
+ if (module != NULL) {
+ zend_update_property_string(yaf_request_ce, request, YAF_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), module TSRMLS_CC);
+ efree(module);
+ }
+ if (controller != NULL) {
+ zend_update_property_string(yaf_request_ce, request, YAF_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), controller TSRMLS_CC);
+ efree(controller);
+ }
+ if (action != NULL) {
+ zend_update_property_string(yaf_request_ce, request, YAF_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), action TSRMLS_CC);
+ efree(action);
+ }
+
+ if (rest) {
+ params = yaf_router_parse_parameters(rest TSRMLS_CC);
+ (void)yaf_request_set_params_multi(request, params TSRMLS_CC);
+ zval_ptr_dtor(&params);
+ efree(rest);
+ }
+
+ return 1;
+}
+/* }}} */
+
+/** {{{ yaf_route_t * yaf_route_supervar_instance(yaf_route_t *this_ptr, zval *name TSRMLS_DC)
+ */
+yaf_route_t * yaf_route_supervar_instance(yaf_route_t *this_ptr, zval *name TSRMLS_DC) {
+ yaf_route_t *instance;
+
+ if (!name || IS_STRING != Z_TYPE_P(name) || !Z_STRLEN_P(name)) {
+ return NULL;
+ }
+
+ if (this_ptr) {
+ instance = this_ptr;
+ } else {
+ MAKE_STD_ZVAL(instance);
+ object_init_ex(instance, yaf_route_supervar_ce);
+ }
+
+ zend_update_property(yaf_route_supervar_ce, instance, ZEND_STRL(YAF_ROUTE_SUPERVAR_PROPETY_NAME_VAR), name TSRMLS_CC);
+
+ return instance;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Route_Supervar::route(string $uri)
+ */
+PHP_METHOD(yaf_route_supervar, route) {
+ yaf_request_t *request;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &request) == FAILURE) {
+ return;
+ } else {
+ RETURN_BOOL(yaf_route_supervar_route(getThis(), request TSRMLS_CC));
+ }
+}
+/** }}} */
+
+/** {{{ proto public Yaf_Route_Supervar::__construct(string $varname)
+ */
+PHP_METHOD(yaf_route_supervar, __construct) {
+ zval *var;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &var) == FAILURE) {
+ return;
+ }
+
+ if (Z_TYPE_P(var) != IS_STRING || !Z_STRLEN_P(var)) {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "Expects a string super var name", yaf_route_supervar_ce->name);
+ RETURN_FALSE;
+ }
+
+ zend_update_property(yaf_route_supervar_ce, getThis(), ZEND_STRL(YAF_ROUTE_SUPERVAR_PROPETY_NAME_VAR), var TSRMLS_CC);
+}
+/** }}} */
+
+/** {{{ yaf_route_supervar_methods
+ */
+zend_function_entry yaf_route_supervar_methods[] = {
+ PHP_ME(yaf_route_supervar, __construct, yaf_route_supervar_construct_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(yaf_route_supervar, route, yaf_route_route_arginfo, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+ */
+YAF_STARTUP_FUNCTION(route_supervar) {
+ zend_class_entry ce;
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Route_Supervar", "Yaf\\Route\\Supervar", yaf_route_supervar_methods);
+ yaf_route_supervar_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+ zend_class_implements(yaf_route_supervar_ce TSRMLS_CC, 1, yaf_route_ce);
+ yaf_route_supervar_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+
+ zend_declare_property_null(yaf_route_supervar_ce, YAF_STRL(YAF_ROUTE_SUPERVAR_PROPETY_NAME_VAR), ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
+
diff --git a/tests/001.phpt b/tests/001.phpt
new file mode 100644
index 0000000000..0c3687d61c
--- /dev/null
+++ b/tests/001.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Check for yaf presence
+--SKIPIF--
+<?php if (!extension_loaded("yaf")) print "skip"; ?>
+--FILE--
+<?php
+echo "yaf extension is available";
+/*
+ you can add regression tests for your extension here
+
+ the output of your test code has to be equal to the
+ text in the --EXPECT-- section below for the tests
+ to pass, differences between the output and the
+ expected text are interpreted as failure
+
+ see php5/README.TESTING for further information on
+ writing regression tests
+*/
+?>
+--EXPECT--
+yaf extension is available
diff --git a/tests/002.phpt b/tests/002.phpt
new file mode 100644
index 0000000000..7aa4f19366
--- /dev/null
+++ b/tests/002.phpt
@@ -0,0 +1,53 @@
+--TEST--
+Check for Yaf_Request_Simple
+--SKIPIF--
+<?php if (!extension_loaded("yaf")) print "skip"; ?>
+--FILE--
+<?php
+$request = new Yaf_Request_Simple("CLI", "index", "index", "index");
+print_r($request);
+print_r($request->setParam("name", "Laruence"));
+var_dump($request->isCli());
+var_dump($request->getParam("name"));
+var_dump($request->getParam("notexists"));
+
+?>
+--EXPECTF--
+Yaf_Request_Simple Object
+(
+ [module] => index
+ [controller] => index
+ [action] => index
+ [method] => CLI
+ [params:protected] => Array
+ (
+ )
+
+ [language:protected] =>
+ [_exception:protected] =>
+ [_base_uri:protected] =>
+ [uri:protected] =>
+ [dispatched:protected] =>
+ [routed:protected] => 1
+)
+Yaf_Request_Simple Object
+(
+ [module] => index
+ [controller] => index
+ [action] => index
+ [method] => CLI
+ [params:protected] => Array
+ (
+ [name] => Laruence
+ )
+
+ [language:protected] =>
+ [_exception:protected] =>
+ [_base_uri:protected] =>
+ [uri:protected] =>
+ [dispatched:protected] =>
+ [routed:protected] => 1
+)
+bool(true)
+string(8) "Laruence"
+NULL
diff --git a/tests/003.phpt b/tests/003.phpt
new file mode 100644
index 0000000000..02b53a6cd3
--- /dev/null
+++ b/tests/003.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Check for Yaf_Loader
+--SKIPIF--
+<?php if (!extension_loaded("yaf")) print "skip"; ?>
+--FILE--
+<?php
+ini_set("ap.lowcase_path", FALSE);
+$loader = Yaf_Loader::getInstance(dirname(__FILE__), dirname(__FILE__) . "/global");
+$loader->registerLocalNamespace("Baidu");
+var_dump($loader->isLocalName("Baidu_Name"));
+
+try {
+ var_dump($loader->autoload("Baidu_Name"));
+} catch (Yaf_Exception_LoadFailed $e) {
+ var_dump($e->getMessage());
+}
+try {
+ var_dump($loader->autoload("Global_Name"));
+} catch (Yaf_Exception_LoadFailed $e) {
+ var_dump($e->getMessage());
+}
+
+?>
+--EXPECTF--
+bool(true)
+
+Warning: Yaf_Loader::autoload(): Could not find script %s/Baidu/Name.php in %s
+bool(true)
+
+Warning: Yaf_Loader::autoload(): Could not find script %s/global/Global/Name.php in %s
+bool(true)
diff --git a/tests/004.phpt b/tests/004.phpt
new file mode 100644
index 0000000000..908cac5faa
--- /dev/null
+++ b/tests/004.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Check for Yaf_Registry
+--SKIPIF--
+<?php if (!extension_loaded("yaf")) print "skip"; ?>
+--FILE--
+<?php
+$str = "Ageli Platform";
+
+Yaf_Registry::set("name", $str);
+unset($str);
+
+var_dump(Yaf_Registry::get("name"));
+var_dump(Yaf_Registry::has("name"));
+
+$name = "name";
+
+Yaf_Registry::del($name);
+
+var_dump(Yaf_Registry::get($name));
+
+var_dump(Yaf_Registry::has($name));
+
+?>
+--EXPECT--
+string(14) "Ageli Platform"
+bool(true)
+NULL
+bool(false)
diff --git a/tests/005.phpt b/tests/005.phpt
new file mode 100644
index 0000000000..420b762193
--- /dev/null
+++ b/tests/005.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Check for Yaf_Response
+--SKIPIF--
+<?php if (!extension_loaded("yaf")) print "skip"; ?>
+--FILE--
+<?php
+$response = new Yaf_Response_Http();
+
+
+$body = <<<HTML
+ifjakdsljfklasdjfkljasdkljfkljadsf
+HTML;
+
+$string = "laruence";
+
+$response->appendBody($body);
+$response->prependBody($string);
+$response->appendBody("kfjdaksljfklajdsfkljasdkljfkjasdf");
+
+$body = $response->getBody();
+unset($body);
+
+debug_zval_dump($response->getBody());
+unset($string);
+debug_zval_dump($response->getBody());
+echo $response;
+debug_zval_dump($response->getBody());
+$response->response();
+debug_zval_dump($response->getBody());
+?>
+--EXPECTF--
+string(75) "laruenceifjakdsljfklasdjfkljasdkljfkljadsfkfjdaksljfklajdsfkljasdkljfkjasdf" refcount(1)
+string(75) "laruenceifjakdsljfklasdjfkljasdkljfkljadsfkfjdaksljfklajdsfkljasdkljfkjasdf" refcount(1)
+laruenceifjakdsljfklasdjfkljasdkljfkljadsfkfjdaksljfklajdsfkljasdkljfkjasdfstring(75) "laruenceifjakdsljfklasdjfkljasdkljfkljadsfkfjdaksljfklajdsfkljasdkljfkjasdf" refcount(1)
+laruenceifjakdsljfklasdjfkljasdkljfkljadsfkfjdaksljfklajdsfkljasdkljfkjasdfstring(75) "laruenceifjakdsljfklasdjfkljasdkljfkljadsfkfjdaksljfklajdsfkljasdkljfkjasdf" refcount(1)
diff --git a/tests/006.phpt b/tests/006.phpt
new file mode 100644
index 0000000000..f6b8e00aff
--- /dev/null
+++ b/tests/006.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Check for Yaf_Route_Static
+--SKIPIF--
+<?php if (!extension_loaded("yaf")) print "skip"; ?>
+--FILE--
+<?php
+$request_uri = "/prefix/controller/action/name/laruence/age/28";
+$base_uri = "/prefix/";
+
+$request = new Yaf_Request_Http($request_uri, $base_uri);
+
+unset($base_uri);
+unset($request_uri);
+
+$route = new Yaf_Route_Static();
+
+var_dump($route->route($request));
+
+print_r($request);
+?>
+--EXPECTF--
+bool(true)
+Yaf_Request_Http Object
+(
+ [module] =>
+ [controller] => controller
+ [action] => action
+ [method] => Cli
+ [params:protected] => Array
+ (
+ [name] => laruence
+ [age] => 28
+ )
+
+ [language:protected] =>
+ [_exception:protected] =>
+ [_base_uri:protected] => /prefix/
+ [uri:protected] => /prefix/controller/action/name/laruence/age/28
+ [dispatched:protected] =>
+ [routed:protected] =>
+)
diff --git a/tests/007.phpt b/tests/007.phpt
new file mode 100644
index 0000000000..0e4914345d
--- /dev/null
+++ b/tests/007.phpt
@@ -0,0 +1,94 @@
+--TEST--
+Check for Yaf_Config_Simple
+--SKIPIF--
+<?php if (!extension_loaded("yaf")) print "skip"; ?>
+--FILE--
+<?php
+$config = array(
+ 'section1' => array(
+ 'name' => 'value',
+ 'dummy' => 'foo',
+ ),
+ 'section2' => "laruence",
+);
+
+$config1 = new Yaf_Config_Simple($config, 'section2');
+print_r($config1);
+$config2 = new Yaf_Config_Simple($config, 'section1');
+var_dump($config2->readonly());
+$config2->new = "value";
+var_dump(isset($config->new));
+$config3 = new Yaf_Config_Simple($config);
+unset($config);
+
+echo "Isset config3 section:";
+var_dump(isset($config3["section2"]));
+$config3->new = "value";
+echo "Config3 readonly:";
+var_dump($config3->readonly());
+
+foreach($config3 as $key => $val) {
+ print_r($key);
+ print_r("=>");
+ print_r($val);
+ print_r("\n");
+}
+
+print_r($config3->toArray());
+
+$sick = @new Yaf_Config_Simple();
+
+var_dump($sick->__isset(1));
+var_dump($sick->__get(2));
+$sick->total = 1;
+var_dump(count($sick));
+var_dump($sick->total);
+?>
+--EXPECTF--
+Yaf_Config_Simple Object
+(
+ [_config:protected] => Array
+ (
+ [section1] => Array
+ (
+ [name] => value
+ [dummy] => foo
+ )
+
+ [section2] => laruence
+ )
+
+ [_readonly:protected] => 1
+)
+bool(true)
+bool(false)
+Isset config3 section:bool(true)
+Config3 readonly:bool(false)
+section1=>Yaf_Config_Simple Object
+(
+ [_config:protected] => Array
+ (
+ [name] => value
+ [dummy] => foo
+ )
+
+ [_readonly:protected] =>
+)
+
+section2=>laruence
+new=>value
+Array
+(
+ [section1] => Array
+ (
+ [name] => value
+ [dummy] => foo
+ )
+
+ [section2] => laruence
+ [new] => value
+)
+bool(false)
+bool(false)
+int(1)
+int(1)
diff --git a/tests/008.phpt b/tests/008.phpt
new file mode 100644
index 0000000000..dac855a13e
--- /dev/null
+++ b/tests/008.phpt
@@ -0,0 +1,70 @@
+--TEST--
+Check for Yaf_Router
+--SKIPIF--
+<?php if (!extension_loaded("yaf")) print "skip"; ?>
+--FILE--
+<?php
+
+$router = new Yaf_Router();
+
+$route = new Yaf_Route_Simple('m', 'c', 'a');
+$sroute = new Yaf_Route_Supervar('r');
+
+$router->addRoute("simple", $route)->addRoute("super", $sroute);
+print_r($router);
+var_dump($router->getCurrentRoute());
+print_r($router->getRoutes());
+print_r($router->getRoute("simple"));
+var_dump($router->getRoute("noexists"));
+--EXPECTF--
+Yaf_Router Object
+(
+ [_routes:protected] => Array
+ (
+ [_default] => Yaf_Route_Static Object
+ (
+ )
+
+ [simple] => Yaf_Route_Simple Object
+ (
+ [controller:protected] => c
+ [module:protected] => m
+ [action:protected] => a
+ )
+
+ [super] => Yaf_Route_Supervar Object
+ (
+ [_var_name:protected] => r
+ )
+
+ )
+
+ [_current:protected] =>
+)
+NULL
+Array
+(
+ [_default] => Yaf_Route_Static Object
+ (
+ )
+
+ [simple] => Yaf_Route_Simple Object
+ (
+ [controller:protected] => c
+ [module:protected] => m
+ [action:protected] => a
+ )
+
+ [super] => Yaf_Route_Supervar Object
+ (
+ [_var_name:protected] => r
+ )
+
+)
+Yaf_Route_Simple Object
+(
+ [controller:protected] => c
+ [module:protected] => m
+ [action:protected] => a
+)
+NULL
diff --git a/tests/009.phpt b/tests/009.phpt
new file mode 100644
index 0000000000..8f7f408dde
--- /dev/null
+++ b/tests/009.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Check for Yaf_View_Simple
+--SKIPIF--
+<?php if (!extension_loaded("yaf")) print "skip"; ?>
+--FILE--
+<?php
+$view = new Yaf_View_Simple(dirname(__FILE__));
+$value = "laruence";
+$view->assign("name", $value);
+unset($value);
+print_r($view);
+var_dump(strlen($view->render(dirname(__FILE__) . "/002.phpt")));
+var_dump($view->name);
+var_dump($view->noexists);
+print_r($view);
+--EXPECTF--
+Yaf_View_Simple Object
+(
+ [_tpl_vars:protected] => Array
+ (
+ [name] => laruence
+ )
+
+ [_tpl_dir:protected] => %s
+)
+int(1590)
+string(8) "laruence"
+NULL
+Yaf_View_Simple Object
+(
+ [_tpl_vars:protected] => Array
+ (
+ [name] => laruence
+ )
+
+ [_tpl_dir:protected] => %s
+)
diff --git a/tests/010.phpt b/tests/010.phpt
new file mode 100644
index 0000000000..8ffc168aa0
--- /dev/null
+++ b/tests/010.phpt
@@ -0,0 +1,315 @@
+--TEST--
+Check for Yaf_Config_Ini
+--SKIPIF--
+<?php if (!extension_loaded("yaf")) print "skip"; ?>
+--FILE--
+<?php
+$file = dirname(__FILE__) . "/simple.ini";
+
+$config = new Yaf_Config_Ini($file);
+print_r($config);
+$config = new Yaf_Config_Ini($file, "extra");
+print_r($config);
+$config = new Yaf_Config_Ini($file);
+$config->longtime = 23424234324;
+var_dump($config->readonly());
+
+foreach($config as $key => $value) {
+ print_r($key);
+}
+
+$sick = @new Yaf_Config_Ini();
+
+var_dump($sick->__isset(1));
+var_dump($sick->__get(1));
+$sick->total = 1;
+
+var_dump(count($sick));
+?>
+--EXPECTF--
+Yaf_Config_Ini Object
+(
+ [_config:protected] => Array
+ (
+ [base] => Array
+ (
+ [application] => Array
+ (
+ [directory] => APPLICATION_PATCH/applcation
+ )
+
+ [name] => base
+ [array] => Array
+ (
+ [1] => 1
+ [name] => name
+ )
+
+ [5] => 5
+ [routes] => Array
+ (
+ [regex] => Array
+ (
+ [type] => regex
+ [match] => ^/ap/(.*)
+ [route] => Array
+ (
+ [controller] => Index
+ [action] => action
+ )
+
+ [map] => Array
+ (
+ [0] => name
+ [1] => name
+ [2] => value
+ )
+
+ )
+
+ [simple] => Array
+ (
+ [type] => simple
+ [controller] => c
+ [module] => m
+ [action] => a
+ )
+
+ [supervar] => Array
+ (
+ [type] => supervar
+ [varname] => c
+ )
+
+ [rewrite] => Array
+ (
+ [type] => rewrite
+ [match] => /ap/:name/:value
+ [route] => Array
+ (
+ [controller] => Index
+ [action] => action
+ )
+
+ )
+
+ )
+
+ )
+
+ [extra] => Array
+ (
+ [application] => Array
+ (
+ [directory] => APPLICATION_PATCH/applcation
+ )
+
+ [name] => extra
+ [array] => Array
+ (
+ [1] => 1
+ [name] => new_name
+ [2] => test
+ )
+
+ [5] => 5
+ [routes] => Array
+ (
+ [regex] => Array
+ (
+ [type] => regex
+ [match] => ^/ap/(.*)
+ [route] => Array
+ (
+ [controller] => Index
+ [action] => action
+ )
+
+ [map] => Array
+ (
+ [0] => name
+ [1] => name
+ [2] => value
+ )
+
+ )
+
+ [simple] => Array
+ (
+ [type] => simple
+ [controller] => c
+ [module] => m
+ [action] => a
+ )
+
+ [supervar] => Array
+ (
+ [type] => supervar
+ [varname] => c
+ )
+
+ [rewrite] => Array
+ (
+ [type] => rewrite
+ [match] => /ap/:name/:value
+ [route] => Array
+ (
+ [controller] => Index
+ [action] => action
+ )
+
+ )
+
+ )
+
+ [value] => 2
+ )
+
+ [product] => Array
+ (
+ [application] => Array
+ (
+ [directory] => APPLICATION_PATCH/applcation
+ )
+
+ [name] => extra
+ [array] => Array
+ (
+ [1] => 1
+ [name] => new_name
+ [2] => test
+ )
+
+ [5] => 5
+ [routes] => Array
+ (
+ [regex] => Array
+ (
+ [type] => regex
+ [match] => ^/ap/(.*)
+ [route] => Array
+ (
+ [controller] => Index
+ [action] => action
+ )
+
+ [map] => Array
+ (
+ [0] => name
+ [1] => name
+ [2] => value
+ )
+
+ )
+
+ [simple] => Array
+ (
+ [type] => simple
+ [controller] => c
+ [module] => m
+ [action] => a
+ )
+
+ [supervar] => Array
+ (
+ [type] => supervar
+ [varname] => c
+ )
+
+ [rewrite] => Array
+ (
+ [type] => rewrite
+ [match] => /ap/:name/:value
+ [route] => Array
+ (
+ [controller] => Index
+ [action] => action
+ )
+
+ )
+
+ )
+
+ [value] => 2
+ )
+
+ )
+
+ [_readonly:protected] => 1
+)
+Yaf_Config_Ini Object
+(
+ [_config:protected] => Array
+ (
+ [application] => Array
+ (
+ [directory] => APPLICATION_PATCH/applcation
+ )
+
+ [name] => extra
+ [array] => Array
+ (
+ [1] => 1
+ [name] => new_name
+ [2] => test
+ )
+
+ [5] => 5
+ [routes] => Array
+ (
+ [regex] => Array
+ (
+ [type] => regex
+ [match] => ^/ap/(.*)
+ [route] => Array
+ (
+ [controller] => Index
+ [action] => action
+ )
+
+ [map] => Array
+ (
+ [0] => name
+ [1] => name
+ [2] => value
+ )
+
+ )
+
+ [simple] => Array
+ (
+ [type] => simple
+ [controller] => c
+ [module] => m
+ [action] => a
+ )
+
+ [supervar] => Array
+ (
+ [type] => supervar
+ [varname] => c
+ )
+
+ [rewrite] => Array
+ (
+ [type] => rewrite
+ [match] => /ap/:name/:value
+ [route] => Array
+ (
+ [controller] => Index
+ [action] => action
+ )
+
+ )
+
+ )
+
+ [value] => 2
+ )
+
+ [_readonly:protected] => 1
+)
+bool(true)
+baseextraproductbool(false)
+NULL
+int(0)
diff --git a/tests/011.phpt b/tests/011.phpt
new file mode 100644
index 0000000000..8a6c640ada
--- /dev/null
+++ b/tests/011.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Check for Yaf_Route_Rewrite
+--SKIPIF--
+<?php if (!extension_loaded("yaf")) print "skip"; ?>
+--FILE--
+<?php
+$request = new Yaf_Request_Http("/subdir/ap/1.2/name/value", "/subdir");
+
+$router = new Yaf_Router();
+
+$route = new Yaf_Route_Rewrite(
+ "/subdir/:name/:version",
+ array(
+ "action" => "version",
+ )
+);
+
+$router->addRoute("subdir", $route)->addRoute("ap", new Yaf_Route_Rewrite(
+ "/ap/:version/*",
+ array(
+ "action" => 'ap',
+ )
+))->route($request);
+
+var_dump($router->getCurrentRoute());
+var_dump($request->getParam('version'));
+var_dump($request->getActionName());
+var_dump($request->getControllerName());
+var_dump($request->getParam('name'));
+
+?>
+--EXPECTF--
+string(2) "ap"
+string(3) "1.2"
+string(2) "ap"
+NULL
+string(5) "value"
diff --git a/tests/012.phpt b/tests/012.phpt
new file mode 100644
index 0000000000..8eb9639367
--- /dev/null
+++ b/tests/012.phpt
@@ -0,0 +1,42 @@
+--TEST--
+Check for Yaf_Route_Regex
+--SKIPIF--
+<?php if (!extension_loaded("yaf")) print "skip"; ?>
+--FILE--
+<?php
+$request = new Yaf_Request_Http("/subdir/ap/1.2/name/value", "/subdir");
+
+$router = new Yaf_Router();
+
+$route = new Yaf_Route_regex(
+ "#/subdir/(.*)#",
+ array(
+ "action" => "version",
+ ),
+ array(
+ )
+);
+
+$router->addRoute("subdir", $route)->addRoute("ap", new Yaf_Route_Regex(
+ "#^/ap/([^/]*)/*#i",
+ array(
+ "action" => 'ap',
+ ),
+ array(
+ 1 => 'version',
+ )
+))->route($request);
+
+var_dump($router->getCurrentRoute());
+var_dump($request->getParam('version'));
+var_dump($request->getActionName());
+var_dump($request->getControllerName());
+var_dump($request->getParam('name'));
+
+?>
+--EXPECTF--
+string(2) "ap"
+string(3) "1.2"
+string(2) "ap"
+NULL
+NULL
diff --git a/tests/013.phpt b/tests/013.phpt
new file mode 100644
index 0000000000..a34f9e4d0a
--- /dev/null
+++ b/tests/013.phpt
@@ -0,0 +1,122 @@
+--TEST--
+Check for Yaf_Router and Config Routes
+--SKIPIF--
+<?php if (!extension_loaded("yaf")) print "skip"; ?>
+--FILE--
+<?php
+$file = dirname(__FILE__) . "/simple.ini";
+
+$config = new Yaf_Config_Ini($file, 'extra');
+
+$routes = $config->routes;
+print_r($routes);
+
+$router = new Yaf_Router();
+$router->addConfig($routes);
+
+print_r($router->getRoutes());
+?>
+--EXPECTF--
+Yaf_Config_Ini Object
+(
+ [_config:protected] => Array
+ (
+ [regex] => Array
+ (
+ [type] => regex
+ [match] => ^/ap/(.*)
+ [route] => Array
+ (
+ [controller] => Index
+ [action] => action
+ )
+
+ [map] => Array
+ (
+ [0] => name
+ [1] => name
+ [2] => value
+ )
+
+ )
+
+ [simple] => Array
+ (
+ [type] => simple
+ [controller] => c
+ [module] => m
+ [action] => a
+ )
+
+ [supervar] => Array
+ (
+ [type] => supervar
+ [varname] => c
+ )
+
+ [rewrite] => Array
+ (
+ [type] => rewrite
+ [match] => /ap/:name/:value
+ [route] => Array
+ (
+ [controller] => Index
+ [action] => action
+ )
+
+ )
+
+ )
+
+ [_readonly:protected] => 1
+)
+Array
+(
+ [_default] => Yaf_Route_Static Object
+ (
+ )
+
+ [regex] => Yaf_Route_Regex Object
+ (
+ [_route:protected] => ^/ap/(.*)
+ [_default:protected] => Array
+ (
+ [controller] => Index
+ [action] => action
+ )
+
+ [_maps:protected] => Array
+ (
+ [0] => name
+ [1] => name
+ [2] => value
+ )
+
+ [_verify:protected] =>
+ )
+
+ [simple] => Yaf_Route_Simple Object
+ (
+ [controller:protected] => c
+ [module:protected] => m
+ [action:protected] => a
+ )
+
+ [supervar] => Yaf_Route_Supervar Object
+ (
+ [_var_name:protected] => c
+ )
+
+ [rewrite] => Yaf_Route_Rewrite Object
+ (
+ [_route:protected] => /ap/:name/:value
+ [_default:protected] => Array
+ (
+ [controller] => Index
+ [action] => action
+ )
+
+ [_verify:protected] =>
+ )
+
+)
diff --git a/tests/014.phpt b/tests/014.phpt
new file mode 100644
index 0000000000..0864d2d198
--- /dev/null
+++ b/tests/014.phpt
@@ -0,0 +1,142 @@
+--TEST--
+Check for Yaf_Application
+--SKIPIF--
+<?php if (!extension_loaded("yaf")) print "skip"; ?>
+--FILE--
+<?php
+define("APPLICATION_PATH", dirname(__FILE__));
+$app = new Yaf_Application(
+ dirname(__FILE__) . "/simple.ini",
+ 'product');
+print_r($app);
+?>
+--EXPECTF--
+Yaf_Application Object
+(
+ [config:protected] => Yaf_Config_Ini Object
+ (
+ [_config:protected] => Array
+ (
+ [application] => Array
+ (
+ [directory] => APPLICATION_PATCH/applcation
+ )
+
+ [name] => extra
+ [array] => Array
+ (
+ [1] => 1
+ [name] => new_name
+ [2] => test
+ )
+
+ [5] => 5
+ [routes] => Array
+ (
+ [regex] => Array
+ (
+ [type] => regex
+ [match] => ^/ap/(.*)
+ [route] => Array
+ (
+ [controller] => Index
+ [action] => action
+ )
+
+ [map] => Array
+ (
+ [0] => name
+ [1] => name
+ [2] => value
+ )
+
+ )
+
+ [simple] => Array
+ (
+ [type] => simple
+ [controller] => c
+ [module] => m
+ [action] => a
+ )
+
+ [supervar] => Array
+ (
+ [type] => supervar
+ [varname] => c
+ )
+
+ [rewrite] => Array
+ (
+ [type] => rewrite
+ [match] => /ap/:name/:value
+ [route] => Array
+ (
+ [controller] => Index
+ [action] => action
+ )
+
+ )
+
+ )
+
+ [value] => 2
+ )
+
+ [_readonly:protected] => 1
+ )
+
+ [dispatcher:protected] => Yaf_Dispatcher Object
+ (
+ [_router:protected] => Yaf_Router Object
+ (
+ [_routes:protected] => Array
+ (
+ [_default] => Yaf_Route_Static Object
+ (
+ )
+
+ )
+
+ [_current:protected] =>
+ )
+
+ [_view:protected] =>
+ [_request:protected] => Yaf_Request_Http Object
+ (
+ [module] =>
+ [controller] =>
+ [action] =>
+ [method] => Cli
+ [params:protected] => Array
+ (
+ )
+
+ [language:protected] =>
+ [_exception:protected] =>
+ [_base_uri:protected] =>
+ [uri:protected] =>
+ [dispatched:protected] =>
+ [routed:protected] =>
+ )
+
+ [_plugins:protected] => Array
+ (
+ )
+
+ [_auto_render:protected] => 1
+ [_return_response:protected] =>
+ [_instantly_flush:protected] =>
+ [_default_module:protected] => Index
+ [_default_controller:protected] => Index
+ [_default_action:protected] => index
+ )
+
+ [_modules:protected] => Array
+ (
+ [0] => Index
+ )
+
+ [_running:protected] =>
+ [_environ:protected] => product
+)
diff --git a/tests/015.phpt b/tests/015.phpt
new file mode 100644
index 0000000000..f12b3b43e5
--- /dev/null
+++ b/tests/015.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Check for Yaf_Exception
+--SKIPIF--
+<?php if (!extension_loaded("yaf")) print "skip"; ?>
+--FILE--
+<?php
+$previous = new Yaf_Exception("Previous", 100);
+$exception = new Yaf_Exception("Exception", 200, $previous);
+
+var_dump($previous === $exception->getPrevious());
+var_dump($exception->getMessage());
+var_dump($exception->getPrevious()->getCode());
+?>
+--EXPECTF--
+bool(true)
+string(9) "Exception"
+int(100)
diff --git a/tests/016.phpt b/tests/016.phpt
new file mode 100644
index 0000000000..f2e5a4f180
--- /dev/null
+++ b/tests/016.phpt
@@ -0,0 +1,42 @@
+--TEST--
+Check for Yaf_Session
+--SKIPIF--
+<?php if (!extension_loaded("yaf")) print "skip"; ?>
+--FILE--
+<?php
+$session = Yaf_Session::getInstance();
+
+$_SESSION["name"] = "Laruence";
+
+$age = 28;
+$session->age = $age;
+unset($age);
+
+unset($session);
+$session2 = Yaf_Session::getInstance();
+$session2["company"] = "Baidu";
+
+var_dump(isset($session2->age));
+var_dump($session2->has("name"));
+var_dump(count($session2));
+foreach ($session2 as $key => $value) {
+ echo $key , "=>", $value, "\n";
+}
+
+unset($session2);
+$session3 = Yaf_Session::getInstance();
+
+$session3->del("name");
+unset($session3["company"]);
+unset($session3->age);
+
+var_dump(count($session3));
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+int(3)
+name=>Laruence
+age=>28
+company=>Baidu
+int(0)
diff --git a/tests/simple.ini b/tests/simple.ini
new file mode 100644
index 0000000000..cf8cdb7f28
--- /dev/null
+++ b/tests/simple.ini
@@ -0,0 +1,31 @@
+[base]
+application.directory=APPLICATION_PATCH "/applcation"
+name = base
+array.1 = 1
+5=5
+array.name = name
+routes.regex.type="regex"
+routes.regex.match="^/ap/(.*)"
+routes.regex.route.controller=Index
+routes.regex.route.action=action
+routes.regex.map.0=name
+routes.regex.map.1=name
+routes.regex.map.2=value
+routes.simple.type="simple"
+routes.simple.controller=c
+routes.simple.module=m
+routes.simple.action=a
+routes.supervar.type="supervar"
+routes.supervar.varname=c
+routes.rewrite.type="rewrite"
+routes.rewrite.match="/ap/:name/:value"
+routes.rewrite.route.controller=Index
+routes.rewrite.route.action=action
+
+[extra : base]
+value = 2
+name = extra
+array.name = new_name
+array.2 = test
+
+[product : extra]
diff --git a/views/interface.c b/views/interface.c
new file mode 100644
index 0000000000..6598244e11
--- /dev/null
+++ b/views/interface.c
@@ -0,0 +1,77 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+zend_class_entry *yaf_view_interface_ce;
+
+/* {{{ ARG_INFO
+ */
+ZEND_BEGIN_ARG_INFO_EX(yaf_view_assign_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_view_display_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, tpl)
+ ZEND_ARG_INFO(0, tpl_vars)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_view_render_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, tpl)
+ ZEND_ARG_INFO(0, tpl_vars)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_view_setpath_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, template_dir)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_view_getpath_arginfo, 0, 0, 0)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/** {{{ yaf_view_interface_methods
+ */
+zend_function_entry yaf_view_interface_methods[] = {
+ ZEND_ABSTRACT_ME(yaf_view, assign, yaf_view_assign_arginfo)
+ ZEND_ABSTRACT_ME(yaf_view, display, yaf_view_display_arginfo)
+ ZEND_ABSTRACT_ME(yaf_view, render, yaf_view_render_arginfo)
+ ZEND_ABSTRACT_ME(yaf_view, setScriptPath, yaf_view_setpath_arginfo)
+ ZEND_ABSTRACT_ME(yaf_view, getScriptPath, yaf_view_getpath_arginfo)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+ */
+YAF_STARTUP_FUNCTION(view_interface) {
+ zend_class_entry ce;
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_View_Interface", "Yaf\\View_Interface", yaf_view_interface_methods);
+ yaf_view_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
+
diff --git a/views/simple.c b/views/simple.c
new file mode 100644
index 0000000000..9034475e29
--- /dev/null
+++ b/views/simple.c
@@ -0,0 +1,687 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#include "main/php_output.h"
+
+#define VIEW_BUFFER_BLOCK_SIZE 4096
+#define VIEW_BUFFER_SIZE_MASK 4095
+
+zend_class_entry *yaf_view_simple_ce;
+
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4))
+struct _yaf_view_simple_buffer {
+ char *buffer;
+ unsigned long size;
+ unsigned long len;
+ struct _yaf_view_simple_buffer *prev;
+};
+
+typedef struct _yaf_view_simple_buffer yaf_view_simple_buffer;
+
+typedef int(*yaf_body_write_func)(const char *str, uint str_length TSRMLS_DC);
+
+/** {{{ MACROS
+ */
+#define YAF_REDIRECT_OUTPUT_BUFFER(seg) \
+ do { \
+ if (!YAF_G(owrite_handler)) { \
+ YAF_G(owrite_handler) = OG(php_body_write); \
+ } \
+ OG(php_body_write) = yaf_view_simple_render_write; \
+ old_scope = EG(scope); \
+ EG(scope) = yaf_view_simple_ce; \
+ seg = (yaf_view_simple_buffer *)emalloc(sizeof(yaf_view_simple_buffer)); \
+ memset(seg, 0, sizeof(yaf_view_simple_buffer)); \
+ seg->prev = YAF_G(buffer);\
+ YAF_G(buffer) = seg; \
+ YAF_G(buf_nesting)++;\
+ } while (0)
+
+#define YAF_RESTORE_OUTPUT_BUFFER(seg) \
+ do { \
+ OG(php_body_write) = (yaf_body_write_func)YAF_G(owrite_handler); \
+ EG(scope) = old_scope; \
+ YAF_G(buffer) = seg->prev; \
+ if (!(--YAF_G(buf_nesting))) { \
+ if (YAF_G(buffer)) { \
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Yaf output buffer collapsed"); \
+ } else { \
+ YAF_G(owrite_handler) = NULL; \
+ } \
+ } \
+ if (seg->size) { \
+ efree(seg->buffer); \
+ } \
+ efree(seg); \
+ } while (0)
+/* }}} */
+#endif
+
+/** {{{ ARG_INFO */
+ZEND_BEGIN_ARG_INFO_EX(yaf_view_simple_construct_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, tempalte_dir)
+ ZEND_ARG_ARRAY_INFO(0, options, 1)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_view_simple_get_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_view_simple_isset_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_view_simple_assign_by_ref_arginfo, 0, 0, 2)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(1, value)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4))
+/** {{{ static int yaf_view_simple_render_write(const char *str, uint str_length TSRMLS_DC)
+*/
+static int yaf_view_simple_render_write(const char *str, uint str_length TSRMLS_DC) {
+ char *target;
+ yaf_view_simple_buffer *buffer = YAF_G(buffer);
+
+ if (!buffer->size) {
+ buffer->size = (str_length | VIEW_BUFFER_SIZE_MASK) + 1;
+ buffer->len = str_length;
+ buffer->buffer = emalloc(buffer->size);
+ target = buffer->buffer;
+ } else {
+ size_t len = buffer->len + str_length;
+
+ if (buffer->size < len + 1) {
+ buffer->size = (len | VIEW_BUFFER_SIZE_MASK) + 1;
+ buffer->buffer = erealloc(buffer->buffer, buffer->size);
+ if (!buffer->buffer) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Yaf output buffer collapsed");
+ }
+ }
+
+ target = buffer->buffer + buffer->len;
+ buffer->len = len;
+ }
+
+ memcpy(target, str, str_length);
+ target[str_length] = '\0';
+
+ return str_length;
+}
+/* }}} */
+#endif
+
+static int yaf_view_simple_valid_var_name(char *var_name, int len) /* {{{ */
+{
+ int i, ch;
+
+ if (!var_name)
+ return 0;
+
+ /* These are allowed as first char: [a-zA-Z_\x7f-\xff] */
+ ch = (int)((unsigned char *)var_name)[0];
+ if (var_name[0] != '_' &&
+ (ch < 65 /* A */ || /* Z */ ch > 90) &&
+ (ch < 97 /* a */ || /* z */ ch > 122) &&
+ (ch < 127 /* 0x7f */ || /* 0xff */ ch > 255)
+ ) {
+ return 0;
+ }
+
+ /* And these as the rest: [a-zA-Z0-9_\x7f-\xff] */
+ if (len > 1) {
+ for (i = 1; i < len; i++) {
+ ch = (int)((unsigned char *)var_name)[i];
+ if (var_name[i] != '_' &&
+ (ch < 48 /* 0 */ || /* 9 */ ch > 57) &&
+ (ch < 65 /* A */ || /* Z */ ch > 90) &&
+ (ch < 97 /* a */ || /* z */ ch > 122) &&
+ (ch < 127 /* 0x7f */ || /* 0xff */ ch > 255)
+ ) {
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+/* }}} */
+
+/** {{{ static int yaf_view_simple_extract(zval *tpl_vars, zval *vars TSRMLS_DC)
+*/
+static int yaf_view_simple_extract(zval *tpl_vars, zval *vars TSRMLS_DC) {
+ zval **entry;
+ char *var_name;
+ long num_key;
+ uint var_name_len;
+ HashPosition pos;
+
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION > 2)) || (PHP_MAJOR_VERSION > 5)
+ if (!EG(active_symbol_table)) {
+ /*zend_rebuild_symbol_table(TSRMLS_C);*/
+ return 1;
+ }
+#endif
+
+ if (tpl_vars && Z_TYPE_P(tpl_vars) == IS_ARRAY) {
+ for(zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(tpl_vars), &pos);
+ zend_hash_get_current_data_ex(Z_ARRVAL_P(tpl_vars), (void **)&entry, &pos) == SUCCESS;
+ zend_hash_move_forward_ex(Z_ARRVAL_P(tpl_vars), &pos)) {
+ if (zend_hash_get_current_key_ex(Z_ARRVAL_P(tpl_vars), &var_name, &var_name_len, &num_key, 0, &pos) != HASH_KEY_IS_STRING) {
+ continue;
+ }
+
+ /* GLOBALS protection */
+ if (var_name_len == sizeof("GLOBALS") && !strcmp(var_name, "GLOBALS")) {
+ continue;
+ }
+
+ if (var_name_len == sizeof("this") && !strcmp(var_name, "this") && EG(scope) && EG(scope)->name_length != 0) {
+ continue;
+ }
+
+
+ if (yaf_view_simple_valid_var_name(var_name, var_name_len - 1)) {
+ ZEND_SET_SYMBOL_WITH_LENGTH(EG(active_symbol_table), var_name, var_name_len,
+ *entry, Z_REFCOUNT_P(*entry) + 1, 0 /**PZVAL_IS_REF(*entry)*/);
+ }
+ }
+ }
+
+ if (vars && Z_TYPE_P(vars) == IS_ARRAY) {
+ for(zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(vars), &pos);
+ zend_hash_get_current_data_ex(Z_ARRVAL_P(vars), (void **)&entry, &pos) == SUCCESS;
+ zend_hash_move_forward_ex(Z_ARRVAL_P(vars), &pos)) {
+ if (zend_hash_get_current_key_ex(Z_ARRVAL_P(vars), &var_name, &var_name_len, &num_key, 0, &pos) != HASH_KEY_IS_STRING) {
+ continue;
+ }
+
+ /* GLOBALS protection */
+ if (var_name_len == sizeof("GLOBALS") && !strcmp(var_name, "GLOBALS")) {
+ continue;
+ }
+
+ if (var_name_len == sizeof("this") && !strcmp(var_name, "this") && EG(scope) && EG(scope)->name_length != 0) {
+ continue;
+ }
+
+ if (yaf_view_simple_valid_var_name(var_name, var_name_len - 1)) {
+ ZEND_SET_SYMBOL_WITH_LENGTH(EG(active_symbol_table), var_name, var_name_len,
+ *entry, Z_REFCOUNT_P(*entry) + 1, 0 /**PZVAL_IS_REF(*entry)*/);
+ }
+ }
+ }
+
+ return 1;
+}
+/* }}} */
+
+/** {{{ yaf_view_t * yaf_view_simple_instance(yaf_view_t *view, zval *tpl_dir, zval *options TSRMLS_DC)
+*/
+yaf_view_t * yaf_view_simple_instance(yaf_view_t *view, zval *tpl_dir, zval *options TSRMLS_DC) {
+ zval *instance, *tpl_vars;
+
+ instance = view;
+ if (!instance) {
+ MAKE_STD_ZVAL(instance);
+ object_init_ex(instance, yaf_view_simple_ce);
+ }
+
+ MAKE_STD_ZVAL(tpl_vars);
+ array_init(tpl_vars);
+ zend_update_property(yaf_view_simple_ce, instance, ZEND_STRL(YAF_VIEW_PROPERTY_NAME_TPLVARS), tpl_vars TSRMLS_CC);
+ zval_ptr_dtor(&tpl_vars);
+
+ if (tpl_dir && Z_TYPE_P(tpl_dir) == IS_STRING && IS_ABSOLUTE_PATH(Z_STRVAL_P(tpl_dir), Z_STRLEN_P(tpl_dir))) {
+ zend_update_property(yaf_view_simple_ce, instance, ZEND_STRL(YAF_VIEW_PROPERTY_NAME_TPLDIR), tpl_dir TSRMLS_CC);
+ }
+
+ return instance;
+}
+/* }}} */
+
+/** {{{ int yaf_view_simple_render(yaf_view_t *view, zval *tpl, zval * vars, zval *ret TSRMLS_DC)
+*/
+int yaf_view_simple_render(yaf_view_t *view, zval *tpl, zval * vars, zval *ret TSRMLS_DC) {
+ zval *tpl_vars;
+ char *script;
+ uint len;
+
+ HashTable *calling_symbol_table;
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4))
+ zend_class_entry *old_scope;
+ yaf_view_simple_buffer *buffer;
+#endif
+
+ ZVAL_NULL(ret);
+
+ tpl_vars = zend_read_property(yaf_view_simple_ce, view, ZEND_STRL(YAF_VIEW_PROPERTY_NAME_TPLVARS), 1 TSRMLS_CC);
+ if (EG(active_symbol_table)) {
+ calling_symbol_table = EG(active_symbol_table);
+ } else {
+ calling_symbol_table = NULL;
+ }
+
+ ALLOC_HASHTABLE(EG(active_symbol_table));
+ zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0);
+
+ (void)yaf_view_simple_extract(tpl_vars, vars TSRMLS_CC);
+
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4))
+ YAF_REDIRECT_OUTPUT_BUFFER(buffer);
+#else
+ if (php_output_start_user(NULL, 0, PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC) == FAILURE) {
+ php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "failed to create buffer");
+ return 0;
+ }
+#endif
+
+ if (IS_ABSOLUTE_PATH(Z_STRVAL_P(tpl), Z_STRLEN_P(tpl))) {
+ script = Z_STRVAL_P(tpl);
+ len = Z_STRLEN_P(tpl);
+ if (yaf_loader_compose(script, len + 1, 0 TSRMLS_CC) == 0) {
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4))
+ YAF_RESTORE_OUTPUT_BUFFER(buffer);
+#else
+ php_output_end(TSRMLS_C);
+#endif
+ if (calling_symbol_table) {
+ zend_hash_destroy(EG(active_symbol_table));
+ FREE_HASHTABLE(EG(active_symbol_table));
+ EG(active_symbol_table) = calling_symbol_table;
+ }
+
+ yaf_trigger_error(YAF_ERR_NOTFOUND_VIEW TSRMLS_CC, "Unable to find template %s", script);
+ return 0;
+ }
+ } else {
+ zval *tpl_dir = zend_read_property(yaf_view_simple_ce, view, ZEND_STRL(YAF_VIEW_PROPERTY_NAME_TPLDIR), 1 TSRMLS_CC);
+
+ if (ZVAL_IS_NULL(tpl_dir)) {
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4))
+ YAF_RESTORE_OUTPUT_BUFFER(buffer);
+#else
+ php_output_end(TSRMLS_C);
+#endif
+
+ if (calling_symbol_table) {
+ zend_hash_destroy(EG(active_symbol_table));
+ FREE_HASHTABLE(EG(active_symbol_table));
+ EG(active_symbol_table) = calling_symbol_table;
+ }
+
+ yaf_trigger_error(YAF_ERR_NOTFOUND_VIEW TSRMLS_CC,
+ "Could not determine the view script path, you should call %s::setScriptPath to specific it",
+ yaf_view_simple_ce->name);
+ return 0;
+ }
+
+ len = spprintf(&script, 0, "%s%c%s", Z_STRVAL_P(tpl_dir), DEFAULT_SLASH, Z_STRVAL_P(tpl));
+
+ if (yaf_loader_compose(script, len + 1, 0 TSRMLS_CC) == 0) {
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4))
+ YAF_RESTORE_OUTPUT_BUFFER(buffer);
+#else
+ php_output_end(TSRMLS_C);
+#endif
+ if (calling_symbol_table) {
+ zend_hash_destroy(EG(active_symbol_table));
+ FREE_HASHTABLE(EG(active_symbol_table));
+ EG(active_symbol_table) = calling_symbol_table;
+ }
+
+ yaf_trigger_error(YAF_ERR_NOTFOUND_VIEW TSRMLS_CC, "Unable to find template %s" , script);
+ efree(script);
+ return 0;
+ }
+ efree(script);
+ }
+
+ if (calling_symbol_table) {
+ zend_hash_destroy(EG(active_symbol_table));
+ FREE_HASHTABLE(EG(active_symbol_table));
+ EG(active_symbol_table) = calling_symbol_table;
+ }
+
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4))
+ if (buffer->len) {
+ ZVAL_STRINGL(ret, buffer->buffer, buffer->len, 1);
+ }
+#else
+ if (php_output_get_contents(ret TSRMLS_CC) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to fetch ob content");
+ }
+#endif
+
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4))
+ YAF_RESTORE_OUTPUT_BUFFER(buffer);
+#else
+ php_output_end(TSRMLS_C);
+#endif
+ return 1;
+}
+/* }}} */
+
+/** {{{ int yaf_view_simple_display(yaf_view_t *view, zval *tpl, zval * vars, zval *ret TSRMLS_DC)
+*/
+int yaf_view_simple_display(yaf_view_t *view, zval *tpl, zval *vars, zval *ret TSRMLS_DC) {
+ zval *tpl_vars;
+ char *script;
+ uint len;
+
+ zend_class_entry *old_scope;
+ HashTable *calling_symbol_table;
+
+ ZVAL_NULL(ret);
+
+ tpl_vars = zend_read_property(yaf_view_simple_ce, view, ZEND_STRL(YAF_VIEW_PROPERTY_NAME_TPLVARS), 1 TSRMLS_CC);
+ if (EG(active_symbol_table)) {
+ calling_symbol_table = EG(active_symbol_table);
+ } else {
+ calling_symbol_table = NULL;
+ }
+
+ ALLOC_HASHTABLE(EG(active_symbol_table));
+ zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0);
+
+ (void)yaf_view_simple_extract(tpl_vars, vars TSRMLS_CC);
+
+ old_scope = EG(scope);
+ EG(scope) = yaf_view_simple_ce;
+
+ if (IS_ABSOLUTE_PATH(Z_STRVAL_P(tpl), Z_STRLEN_P(tpl))) {
+ script = Z_STRVAL_P(tpl);
+ len = Z_STRLEN_P(tpl);
+ if (yaf_loader_compose(script, len + 1, 0 TSRMLS_CC) == 0) {
+ yaf_trigger_error(YAF_ERR_NOTFOUND_VIEW TSRMLS_CC, "Unable to find template %s" , script);
+ EG(scope) = old_scope;
+ if (calling_symbol_table) {
+ zend_hash_destroy(EG(active_symbol_table));
+ FREE_HASHTABLE(EG(active_symbol_table));
+ EG(active_symbol_table) = calling_symbol_table;
+ }
+ return 0;
+ }
+ } else {
+ zval *tpl_dir = zend_read_property(yaf_view_simple_ce, view, ZEND_STRL(YAF_VIEW_PROPERTY_NAME_TPLDIR), 1 TSRMLS_CC);
+
+ if (ZVAL_IS_NULL(tpl_dir)) {
+ yaf_trigger_error(YAF_ERR_NOTFOUND_VIEW TSRMLS_CC,
+ "Could not determine the view script path, you should call %s::setScriptPath to specific it", yaf_view_simple_ce->name);
+ EG(scope) = old_scope;
+ if (calling_symbol_table) {
+ zend_hash_destroy(EG(active_symbol_table));
+ FREE_HASHTABLE(EG(active_symbol_table));
+ EG(active_symbol_table) = calling_symbol_table;
+ }
+ return 0;
+ }
+
+ len = spprintf(&script, 0, "%s%c%s", Z_STRVAL_P(tpl_dir), DEFAULT_SLASH, Z_STRVAL_P(tpl));
+ if (yaf_loader_compose(script, len + 1, 0 TSRMLS_CC) == 0) {
+ yaf_trigger_error(YAF_ERR_NOTFOUND_VIEW TSRMLS_CC, "Unable to find template %s", script);
+ efree(script);
+ EG(scope) = old_scope;
+ if (calling_symbol_table) {
+ zend_hash_destroy(EG(active_symbol_table));
+ FREE_HASHTABLE(EG(active_symbol_table));
+ EG(active_symbol_table) = calling_symbol_table;
+ }
+ return 0;
+ }
+ efree(script);
+ }
+
+ EG(scope) = old_scope;
+ if (calling_symbol_table) {
+ zend_hash_destroy(EG(active_symbol_table));
+ FREE_HASHTABLE(EG(active_symbol_table));
+ EG(active_symbol_table) = calling_symbol_table;
+ }
+
+ return 1;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_View_Simple::__construct(string $tpl_dir, array $options = NULL)
+*/
+PHP_METHOD(yaf_view_simple, __construct) {
+ zval *tpl_dir, *options = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &tpl_dir, &options) == FAILURE) {
+ return;
+ }
+
+ yaf_view_simple_instance(getThis(), tpl_dir, options TSRMLS_CC);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_View_Simple::__isset($name)
+*/
+PHP_METHOD(yaf_view_simple, __isset) {
+ char *name;
+ uint len;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &len) == FAILURE) {
+ return;
+ } else {
+ zval *tpl_vars = zend_read_property(yaf_view_simple_ce, getThis(), ZEND_STRL(YAF_VIEW_PROPERTY_NAME_TPLVARS), 1 TSRMLS_CC);
+ RETURN_BOOL(zend_hash_exists(Z_ARRVAL_P(tpl_vars), name, len + 1));
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_View_Simple::setScriptPath(string $tpl_dir)
+*/
+PHP_METHOD(yaf_view_simple, setScriptPath) {
+ zval *tpl_dir;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &tpl_dir) == FAILURE) {
+ return;
+ }
+
+ if (Z_TYPE_P(tpl_dir) == IS_STRING && IS_ABSOLUTE_PATH(Z_STRVAL_P(tpl_dir), Z_STRLEN_P(tpl_dir))) {
+ zend_update_property(yaf_view_simple_ce, getThis(), ZEND_STRL(YAF_VIEW_PROPERTY_NAME_TPLDIR), tpl_dir TSRMLS_CC);
+ RETURN_ZVAL(getThis(), 1, 0);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_View_Simple::getScriptPath(void)
+*/
+PHP_METHOD(yaf_view_simple, getScriptPath) {
+ zval *tpl_dir = zend_read_property(yaf_view_simple_ce, getThis(), ZEND_STRL(YAF_VIEW_PROPERTY_NAME_TPLDIR), 1 TSRMLS_CC);
+ RETURN_ZVAL(tpl_dir, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_View_Simple::compose(string $script, zval *args)
+*/
+PHP_METHOD(yaf_view_simple, compose) {
+ char *script;
+ uint len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &script, &len) == FAILURE) {
+ return;
+ }
+
+ if (!len) {
+ RETURN_FALSE;
+ }
+
+}
+/* }}} */
+
+/** {{{ proto public Yaf_View_Simple::assign(mixed $value, mixed $value = null)
+*/
+PHP_METHOD(yaf_view_simple, assign) {
+ uint argc = ZEND_NUM_ARGS();
+ zval *tpl_vars = zend_read_property(yaf_view_simple_ce, getThis(), ZEND_STRL(YAF_VIEW_PROPERTY_NAME_TPLVARS), 1 TSRMLS_CC);
+ if (argc == 1) {
+ zval *value;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) {
+ return;
+ }
+
+ if (Z_TYPE_P(value) == IS_ARRAY) {
+ zend_hash_copy(Z_ARRVAL_P(tpl_vars), Z_ARRVAL_P(value), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+ } else if (argc == 2) {
+ zval *value;
+ char *name;
+ uint len;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name, &len, &value) == FAILURE) {
+ return;
+ }
+
+ Z_ADDREF_P(value);
+ if (zend_hash_update(Z_ARRVAL_P(tpl_vars), name, len + 1, &value, sizeof(zval *), NULL) == SUCCESS) {
+ RETURN_TRUE;
+ }
+ } else {
+ WRONG_PARAM_COUNT;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_View_Simple::assignRef(mixed $value, mixed $value)
+*/
+PHP_METHOD(yaf_view_simple, assignRef) {
+ char * name; int len;
+ zval * value, * tpl_vars;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name, &len, &value) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ tpl_vars = zend_read_property(yaf_view_simple_ce, getThis(), ZEND_STRL(YAF_VIEW_PROPERTY_NAME_TPLVARS), 1 TSRMLS_CC);
+
+ Z_ADDREF_P(value);
+ if (zend_hash_update(Z_ARRVAL_P(tpl_vars), name, len + 1, &value, sizeof(zval *), NULL) == SUCCESS) {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_View_Simple::get($name)
+*/
+PHP_METHOD(yaf_view_simple, get) {
+ char *name;
+ uint len;
+ zval *tpl_vars, **ret;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &len) == FAILURE) {
+ return;
+ }
+
+ tpl_vars = zend_read_property(yaf_view_simple_ce, getThis(), ZEND_STRL(YAF_VIEW_PROPERTY_NAME_TPLVARS), 1 TSRMLS_CC);
+
+ if (tpl_vars && Z_TYPE_P(tpl_vars) == IS_ARRAY) {
+ if (zend_hash_find(Z_ARRVAL_P(tpl_vars), name, len + 1, (void **) &ret) == SUCCESS) {
+ RETURN_ZVAL(*ret, 1, 0);
+ }
+ }
+
+ RETURN_NULL();
+}
+/* }}} */
+
+/** {{{ proto public Yaf_View_Simple::render(string $tpl, array $vars = NULL)
+*/
+PHP_METHOD(yaf_view_simple, render) {
+ zval *tpl, *vars = NULL, *tpl_vars;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &tpl, &vars) == FAILURE) {
+ return;
+ }
+
+ tpl_vars = zend_read_property(yaf_view_simple_ce, getThis(), ZEND_STRL(YAF_VIEW_PROPERTY_NAME_TPLVARS), 1 TSRMLS_CC);
+ if (!yaf_view_simple_render(getThis(), tpl, vars, return_value TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_View_Simple::display(string $tpl, array $vars = NULL)
+*/
+PHP_METHOD(yaf_view_simple, display) {
+ zval *tpl, *tpl_vars, *vars = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &tpl, &vars) == FAILURE) {
+ return;
+ }
+
+ tpl_vars = zend_read_property(yaf_view_simple_ce, getThis(), ZEND_STRL(YAF_VIEW_PROPERTY_NAME_TPLVARS), 1 TSRMLS_CC);
+ if (!yaf_view_simple_display(getThis(), tpl, vars, return_value TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+/** {{{ yaf_view_simple_methods
+*/
+zend_function_entry yaf_view_simple_methods[] = {
+ PHP_ME(yaf_view_simple, __construct, yaf_view_simple_construct_arginfo, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_view_simple, __isset, yaf_view_simple_isset_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_view_simple, get, yaf_view_simple_get_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_view_simple, assign, yaf_view_assign_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_view_simple, render, yaf_view_render_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_view_simple, display, yaf_view_display_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_view_simple, assignRef, yaf_view_simple_assign_by_ref_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_view_simple, setScriptPath, yaf_view_setpath_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_view_simple, getScriptPath, yaf_view_getpath_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_view_simple, __get, get, yaf_view_simple_get_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_view_simple, __set, assign, yaf_view_assign_arginfo, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(view_simple) {
+ zend_class_entry ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_View_Simple", "Yaf\\View\\Simple", yaf_view_simple_methods);
+ yaf_view_simple_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+
+ zend_declare_property_null(yaf_view_simple_ce, YAF_STRL(YAF_VIEW_PROPERTY_NAME_TPLVARS), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_view_simple_ce, YAF_STRL(YAF_VIEW_PROPERTY_NAME_TPLDIR), ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ yaf_view_simple_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+ zend_class_implements(yaf_view_simple_ce TSRMLS_CC, 1, yaf_view_interface_ce);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
+
diff --git a/yaf.c b/yaf.c
new file mode 100644
index 0000000000..4cc69d0097
--- /dev/null
+++ b/yaf.c
@@ -0,0 +1,275 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "main/SAPI.h"
+#include "Zend/zend_alloc.h"
+#include "ext/standard/info.h"
+#include "ext/standard/php_string.h"
+
+#include "php_yaf.h"
+#include "yaf_logo.h"
+#include "yaf_loader.h"
+#include "yaf_exception.h"
+#include "yaf_application.h"
+#include "yaf_dispatcher.h"
+#include "yaf_config.h"
+#include "yaf_view.h"
+#include "yaf_controller.h"
+#include "yaf_action.h"
+#include "yaf_request.h"
+#include "yaf_response.h"
+#include "yaf_router.h"
+#include "yaf_bootstrap.h"
+#include "yaf_plugin.h"
+#include "yaf_registry.h"
+#include "yaf_session.h"
+
+ZEND_DECLARE_MODULE_GLOBALS(yaf);
+
+/* {{{ yaf_functions[]
+*/
+zend_function_entry yaf_functions[] = {
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ PHP_INI
+ */
+PHP_INI_BEGIN()
+ STD_PHP_INI_ENTRY("yaf.library", "", PHP_INI_ALL, OnUpdateString, global_library, zend_yaf_globals, yaf_globals)
+ STD_PHP_INI_BOOLEAN("yaf.action_prefer", "0", PHP_INI_ALL, OnUpdateBool, action_prefer, zend_yaf_globals, yaf_globals)
+ STD_PHP_INI_BOOLEAN("yaf.lowcase_path", "0", PHP_INI_ALL, OnUpdateBool, lowcase_path, zend_yaf_globals, yaf_globals)
+ STD_PHP_INI_BOOLEAN("yaf.use_spl_autoload", "0", PHP_INI_ALL, OnUpdateBool, use_spl_autoload, zend_yaf_globals, yaf_globals)
+ STD_PHP_INI_ENTRY("yaf.forward_limit", "5", PHP_INI_ALL, OnUpdateLongGEZero, forward_limit, zend_yaf_globals, yaf_globals)
+ STD_PHP_INI_BOOLEAN("yaf.name_suffix", "1", PHP_INI_ALL, OnUpdateBool, name_suffix, zend_yaf_globals, yaf_globals)
+ STD_PHP_INI_ENTRY("yaf.name_separator", "", PHP_INI_ALL, OnUpdateString, name_separator, zend_yaf_globals, yaf_globals)
+ STD_PHP_INI_BOOLEAN("yaf.cache_config", "0", PHP_INI_SYSTEM, OnUpdateBool, cache_config, zend_yaf_globals, yaf_globals)
+/* {{{ This only effects internally */
+ STD_PHP_INI_BOOLEAN("yaf.st_compatible", "0", PHP_INI_ALL, OnUpdateBool, st_compatible, zend_yaf_globals, yaf_globals)
+/* }}} */
+ STD_PHP_INI_ENTRY("yaf.environ", "product", PHP_INI_SYSTEM, OnUpdateString, environ, zend_yaf_globals, yaf_globals)
+#ifdef YAF_HAVE_NAMESPACE
+ STD_PHP_INI_BOOLEAN("yaf.use_namespace", "0", PHP_INI_SYSTEM, OnUpdateBool, use_namespace, zend_yaf_globals, yaf_globals)
+#endif
+PHP_INI_END();
+/* }}} */
+
+/** {{{ PHP_GINIT_FUNCTION
+*/
+PHP_GINIT_FUNCTION(yaf)
+{
+ yaf_globals->autoload_started = 0;
+ yaf_globals->configs = NULL;
+ yaf_globals->directory = NULL;
+ yaf_globals->library_directory = NULL;
+ yaf_globals->ext = YAF_DEFAULT_EXT;
+ yaf_globals->view_ext = YAF_DEFAULT_VIEW_EXT;
+ yaf_globals->default_module = YAF_ROUTER_DEFAULT_MODULE;
+ yaf_globals->default_controller = YAF_ROUTER_DEFAULT_CONTROLLER;
+ yaf_globals->default_action = YAF_ROUTER_DEFAULT_ACTION;
+ yaf_globals->bootstrap = YAF_DEFAULT_BOOTSTRAP;
+ yaf_globals->modules = NULL;
+}
+/* }}} */
+
+/** {{{ PHP_MINIT_FUNCTION
+*/
+PHP_MINIT_FUNCTION(yaf)
+{
+ REGISTER_INI_ENTRIES();
+
+ php_register_info_logo(YAF_LOGO_GUID, YAF_LOGO_MIME_TYPE, yaf_logo, sizeof(yaf_logo));
+
+#ifdef YAF_HAVE_NAMESPACE
+ if(YAF_G(use_namespace)) {
+
+ REGISTER_STRINGL_CONSTANT("YAF\\VERSION", YAF_VERSION, sizeof(YAF_VERSION), CONST_PERSISTENT | CONST_CS);
+ REGISTER_STRINGL_CONSTANT("YAF\\ENVIRON", YAF_G(environ), strlen(YAF_G(environ)), CONST_PERSISTENT | CONST_CS);
+
+ REGISTER_LONG_CONSTANT("YAF\\ERR\\STARTUP_FAILED", YAF_ERR_STARTUP_FAILED, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF\\ERR\\ROUTE_FAILED", YAF_ERR_ROUTE_FAILED, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF\\ERR\\DISPATCH_FAILED", YAF_ERR_DISPATCH_FAILED, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF\\ERR\\AUTOLOAD_FAILED", YAF_ERR_AUTOLOAD_FAILED, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF\\ERR\\NOTFOUND\\MODULE", YAF_ERR_NOTFOUND_MODULE, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF\\ERR\\NOTFOUND\\CONTROLLER", YAF_ERR_NOTFOUND_CONTROLLER, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF\\ERR\\NOTFOUND\\ACTION", YAF_ERR_NOTFOUND_ACTION, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF\\ERR\\NOTFOUND\\VIEW", YAF_ERR_NOTFOUND_VIEW, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF\\ERR\\CALL_FAILED", YAF_ERR_CALL_FAILED, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF\\ERR\\TYPE_ERROR", YAF_ERR_TYPE_ERROR, CONST_PERSISTENT | CONST_CS);
+
+ } else {
+#endif
+ REGISTER_STRINGL_CONSTANT("YAF_VERSION", YAF_VERSION, sizeof(YAF_VERSION), CONST_PERSISTENT | CONST_CS);
+ REGISTER_STRINGL_CONSTANT("YAF_ENVIRON", YAF_G(environ), strlen(YAF_G(environ)), CONST_PERSISTENT | CONST_CS);
+
+ REGISTER_LONG_CONSTANT("YAF_ERR_STARTUP_FAILED", YAF_ERR_STARTUP_FAILED, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF_ERR_ROUTE_FAILED", YAF_ERR_ROUTE_FAILED, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF_ERR_DISPATCH_FAILED", YAF_ERR_DISPATCH_FAILED, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF_ERR_AUTOLOAD_FAILED", YAF_ERR_AUTOLOAD_FAILED, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF_ERR_NOTFOUND_MODULE", YAF_ERR_NOTFOUND_MODULE, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF_ERR_NOTFOUND_CONTROLLER", YAF_ERR_NOTFOUND_CONTROLLER, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF_ERR_NOTFOUND_ACTION", YAF_ERR_NOTFOUND_ACTION, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF_ERR_NOTFOUND_VIEW", YAF_ERR_NOTFOUND_VIEW, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF_ERR_CALL_FAILED", YAF_ERR_CALL_FAILED, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("YAF_ERR_TYPE_ERROR", YAF_ERR_TYPE_ERROR, CONST_PERSISTENT | CONST_CS);
+#ifdef YAF_HAVE_NAMESPACE
+ }
+#endif
+
+ /* startup components */
+ YAF_STARTUP(application);
+ YAF_STARTUP(bootstrap);
+ YAF_STARTUP(dispatcher);
+ YAF_STARTUP(loader);
+ YAF_STARTUP(request);
+ YAF_STARTUP(response);
+ YAF_STARTUP(controller);
+ YAF_STARTUP(action);
+ YAF_STARTUP(config);
+ YAF_STARTUP(view);
+ YAF_STARTUP(router);
+ YAF_STARTUP(plugin);
+ YAF_STARTUP(registry);
+ YAF_STARTUP(session);
+ YAF_STARTUP(exception);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/** {{{ PHP_MSHUTDOWN_FUNCTION
+*/
+PHP_MSHUTDOWN_FUNCTION(yaf)
+{
+ UNREGISTER_INI_ENTRIES();
+
+ if (YAF_G(configs)) {
+ zend_hash_destroy(YAF_G(configs));
+ pefree(YAF_G(configs), 1);
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
+/** {{{ PHP_RINIT_FUNCTION
+*/
+PHP_RINIT_FUNCTION(yaf)
+{
+ YAF_G(running) = 0;
+ YAF_G(in_exception) = 0;
+ YAF_G(throw_exception) = 1;
+ YAF_G(catch_exception) = 0;
+ YAF_G(directory) = NULL;
+ YAF_G(bootstrap) = NULL;
+ YAF_G(library_directory) = NULL;
+ YAF_G(modules) = NULL;
+ YAF_G(base_uri) = NULL;
+ YAF_G(buffer) = NULL;
+ YAF_G(owrite_handler) = NULL;
+ YAF_G(buf_nesting) = 0;
+
+ return SUCCESS;
+}
+/* }}} */
+
+/** {{{ PHP_RSHUTDOWN_FUNCTION
+*/
+PHP_RSHUTDOWN_FUNCTION(yaf)
+{
+ if (YAF_G(directory)) {
+ efree(YAF_G(directory));
+ YAF_G(directory) = NULL;
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
+/** {{{ PHP_MINFO_FUNCTION
+*/
+PHP_MINFO_FUNCTION(yaf)
+{
+ php_info_print_table_start();
+ if (PG(expose_php)) {
+ php_info_print_table_header(2, "yaf support", YAF_LOGO_IMG"enabled");
+ } else {
+ php_info_print_table_header(2, "yaf support", "enabled");
+ }
+
+ php_info_print_table_row(2, "Version", YAF_VERSION);
+ php_info_print_table_row(2, "Supports", YAF_SUPPORT_URL);
+ php_info_print_table_end();
+
+ DISPLAY_INI_ENTRIES();
+}
+/* }}} */
+
+/** {{{ DL support
+ */
+#ifdef COMPILE_DL_YAF
+ZEND_GET_MODULE(yaf)
+#endif
+/* }}} */
+
+/** {{{ module depends
+ */
+zend_module_dep yaf_deps[] = {
+ ZEND_MOD_REQUIRED("spl")
+ ZEND_MOD_REQUIRED("pcre")
+ ZEND_MOD_OPTIONAL("session")
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ yaf_module_entry
+*/
+zend_module_entry yaf_module_entry = {
+ STANDARD_MODULE_HEADER_EX,
+ NULL,
+ yaf_deps,
+ "yaf",
+ yaf_functions,
+ PHP_MINIT(yaf),
+ PHP_MSHUTDOWN(yaf),
+ PHP_RINIT(yaf),
+ PHP_RSHUTDOWN(yaf),
+ PHP_MINFO(yaf),
+ YAF_VERSION,
+ PHP_MODULE_GLOBALS(yaf),
+ PHP_GINIT(yaf),
+ NULL,
+ NULL,
+ STANDARD_MODULE_PROPERTIES_EX
+};
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf.dsp b/yaf.dsp
new file mode 100644
index 0000000000..c97a840db1
--- /dev/null
+++ b/yaf.dsp
@@ -0,0 +1,276 @@
+# Microsoft Developer Studio Project File - Name="yaf" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=yaf - Win32 Release_TS
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "yaf.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "yaf.mak" CFG="yaf - Win32 Release_TS"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "yaf - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "yaf - Win32 Release_NTS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "yaf - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "yaf - Win32 Debug_NTS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "yaf - Win32 Release_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release_TS"
+# PROP BASE Intermediate_Dir "Release_TS"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_TS"
+# PROP Intermediate_Dir "Release_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\..\TSRM" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_YAF" /D ZTS=1 /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D ZEND_DEBUG=0 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "YAF_EXPORTS" /D "COMPILE_DL_YAF" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_YAF=1 /D "LIBZEND_EXPORTS" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x406 /d "NDEBUG"
+# ADD RSC /l 0x406 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_yaf.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline"
+
+!ELSEIF "$(CFG)" == "yaf - Win32 Debug_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Debug_TS"
+# PROP BASE Intermediate_Dir "Debug_TS"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Debug_TS"
+# PROP Intermediate_Dir "Debug_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_YAF" /D ZTS=1 /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "YAF_EXPORTS" /D "COMPILE_DL_YAF" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_YAF=1 /D "LIBZEND_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x406 /d "NDEBUG"
+# ADD RSC /l 0x406 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts_debug.lib /nologo /dll /machine:I386 /out:"..\..\Debug_TS/php_yaf.dll" /libpath:"..\..\Debug_TS"
+
+!ELSEIF "$(CFG)" == "yaf - Win32 Release_NTS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release_NTS"
+# PROP BASE Intermediate_Dir "Release_NTS"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_NTS"
+# PROP Intermediate_Dir "Release_NTS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_YAF" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D ZEND_DEBUG=0 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "YAF_EXPORTS" /D "COMPILE_DL_YAF" /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_YAF=1 /D "LIBZEND_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x406 /d "NDEBUG"
+# ADD RSC /l 0x406 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5.lib /nologo /dll /machine:I386 /out:"..\..\Release_NTS/php_yaf.dll" /libpath:"..\..\Release_NTS"
+
+!ELSEIF "$(CFG)" == "yaf - Win32 Debug_NTS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Debug_NTS"
+# PROP BASE Intermediate_Dir "Debug_NTS"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Debug_NTS"
+# PROP Intermediate_Dir "Debug_NTS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_YAF" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "YAF_EXPORTS" /D "COMPILE_DL_YAF" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_YAF=1 /D "LIBZEND_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x406 /d "NDEBUG"
+# ADD RSC /l 0x406 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5_debug.lib /nologo /dll /machine:I386 /out:"..\..\Debug_NTS/php_yaf.dll" /libpath:"..\..\Debug_NTS"
+
+!ENDIF
+
+# Begin Target
+
+# Name "yaf - Win32 Release_TS"
+# Name "yaf - Win32 Debug_TS"
+# Name "yaf - Win32 Release_NTS"
+# Name "yaf - Win32 Debug_NTS"
+# Begin Group "Yaf Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\yaf.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_application.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_loader.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_dispatcher.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_bootstrap.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_config.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_registry.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_controller.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_action.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_view.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_request.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_response.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_router.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_exception.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_plugin.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_session.c
+# End Source File
+
+# End Group
+# Begin Group "Yaf Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\php_yaf.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_application.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_bootstrap.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_loader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_config.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_registry.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_controller.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_view.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\php_request.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_router.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_exception.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_plugin.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\yaf_session.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/yaf.php b/yaf.php
new file mode 100644
index 0000000000..348268e6cf
--- /dev/null
+++ b/yaf.php
@@ -0,0 +1,21 @@
+<?php
+$br = (php_sapi_name() == "cli")? "":"<br>";
+
+if(!extension_loaded('ap')) {
+ dl('ap.' . PHP_SHLIB_SUFFIX);
+}
+$module = 'ap';
+$functions = get_extension_funcs($module);
+echo "Functions available in the test extension:$br\n";
+foreach($functions as $func) {
+ echo $func."$br\n";
+}
+echo "$br\n";
+$function = 'confirm_' . $module . '_compiled';
+if (extension_loaded($module)) {
+ $str = $function($module);
+} else {
+ $str = "Module $module is not compiled into PHP";
+}
+echo "$str\n";
+?>
diff --git a/yaf_action.c b/yaf_action.c
new file mode 100644
index 0000000000..655358d913
--- /dev/null
+++ b/yaf_action.c
@@ -0,0 +1,81 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "main/SAPI.h"
+
+#include "php_yaf.h"
+#include "yaf_namespace.h"
+#include "yaf_request.h"
+#include "yaf_response.h"
+#include "yaf_view.h"
+#include "yaf_exception.h"
+#include "yaf_controller.h"
+#include "yaf_action.h"
+
+zend_class_entry *yaf_action_ce;
+
+/** {{{ ARG_INFO
+ */
+
+/* }}} */
+
+/** {{{ proto public Yaf_Action_Abstract::getController(void)
+*/
+PHP_METHOD(yaf_action, getController) {
+ yaf_controller_t *controller = zend_read_property(yaf_action_ce, getThis(), ZEND_STRL(YAF_ACTION_PROPERTY_NAME_CTRL), 1 TSRMLS_CC);
+ RETURN_ZVAL(controller, 1, 0);
+}
+/* }}} */
+
+/** {{{ yaf_controller_methods
+*/
+zend_function_entry yaf_action_methods[] = {
+ PHP_ABSTRACT_ME(yaf_action_controller, execute, NULL)
+ PHP_ME(yaf_action, getController, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(action) {
+ zend_class_entry ce;
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Action_Abstract", "Yaf\\Action_Abstract", yaf_action_methods);
+ yaf_action_ce = zend_register_internal_class_ex(&ce, yaf_controller_ce, NULL TSRMLS_CC);
+ yaf_action_ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
+
+ zend_declare_property_null(yaf_action_ce, YAF_STRL(YAF_ACTION_PROPERTY_NAME_CTRL), ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_action.h b/yaf_action.h
new file mode 100644
index 0000000000..d0c37fa5c8
--- /dev/null
+++ b/yaf_action.h
@@ -0,0 +1,37 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef YAF_ACTION_H
+#define YAF_ACTION_H
+
+#define YAF_ACTION_EXECUTOR_NAME "execute"
+#define YAF_ACTION_PROPERTY_NAME_CTRL "_controller"
+
+extern zend_class_entry * yaf_action_ce;
+
+YAF_STARTUP_FUNCTION(action);
+#endif
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
+
diff --git a/yaf_application.c b/yaf_application.c
new file mode 100644
index 0000000000..2c3d894b9e
--- /dev/null
+++ b/yaf_application.c
@@ -0,0 +1,650 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "main/SAPI.h"
+#include "Zend/zend_interfaces.h"
+#include "ext/standard/php_var.h"
+#include "ext/standard/basic_functions.h"
+
+#include "php_yaf.h"
+#include "yaf_namespace.h"
+#include "yaf_application.h"
+#include "yaf_dispatcher.h"
+#include "yaf_router.h"
+#include "yaf_config.h"
+#include "yaf_loader.h"
+#include "yaf_request.h"
+#include "yaf_bootstrap.h"
+#include "yaf_exception.h"
+
+zend_class_entry * yaf_application_ce;
+
+/** {{{ ARG_INFO
+ * */
+ZEND_BEGIN_ARG_INFO_EX(yaf_application_construct_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, config)
+ ZEND_ARG_INFO(0, envrion)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_application_app_arginfo, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_application_execute_arginfo, 0, 0, 2)
+ ZEND_ARG_INFO(0, entry)
+ ZEND_ARG_INFO(0, ...)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_application_getconfig_arginfo, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_application_getmodule_arginfo, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_application_getdispatch_arginfo, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_application_bootstrap_arginfo, 0, 0, 0)
+ ZEND_ARG_INFO(0, bootstrap)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_application_environ_arginfo, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_application_run_arginfo, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+/* }}} */
+
+/** {{{ int yaf_application_is_module_name(char *name, int len TSRMLS_DC)
+*/
+int yaf_application_is_module_name(char *name, int len TSRMLS_DC) {
+ zval *modules, **ppzval;
+ HashTable *ht;
+ yaf_application_t *app;
+
+ app = zend_read_static_property(yaf_application_ce, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_APP), 1 TSRMLS_CC);
+ if (!app || Z_TYPE_P(app) != IS_OBJECT) {
+ return 0;
+ }
+
+ modules = zend_read_property(yaf_application_ce, app, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_MODULES), 1 TSRMLS_CC);
+ if (!modules || Z_TYPE_P(modules) != IS_ARRAY) {
+ return 0;
+ }
+
+ ht = Z_ARRVAL_P(modules);
+ zend_hash_internal_pointer_reset(ht);
+ while (zend_hash_get_current_data(ht, (void **)&ppzval) == SUCCESS) {
+ if (Z_TYPE_PP(ppzval) == IS_STRING
+ && strncasecmp(Z_STRVAL_PP(ppzval), name, len) == 0) {
+ return 1;
+ }
+ zend_hash_move_forward(ht);
+ }
+ return 0;
+}
+/* }}} */
+
+/** {{{ static int yaf_application_parse_option(zval *options TSRMLS_DC)
+*/
+static int yaf_application_parse_option(zval *options TSRMLS_DC) {
+ HashTable *conf;
+ zval **ppzval, **ppsval, *app;
+
+ conf = HASH_OF(options);
+ if (zend_hash_find(conf, YAF_STRS("application"), (void **)&ppzval) == FAILURE) {
+ /* For back compatibilty */
+ if (zend_hash_find(conf, YAF_STRS("yaf"), (void **)&ppzval) == FAILURE) {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "%s", "Expected an array of application configure");
+ return FAILURE;
+ }
+ }
+
+ app = *ppzval;
+ if (Z_TYPE_P(app) != IS_ARRAY) {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "%s", "Expected an array of application configure");
+ return FAILURE;
+ }
+
+ if (zend_hash_find(Z_ARRVAL_P(app), YAF_STRS("directory"), (void **)&ppzval) == FAILURE
+ || Z_TYPE_PP(ppzval) != IS_STRING) {
+ yaf_trigger_error(YAF_ERR_STARTUP_FAILED TSRMLS_CC, "%s", "Expected a directory entry in application configures");
+ return FAILURE;
+ }
+
+ if (*(Z_STRVAL_PP(ppzval) + Z_STRLEN_PP(ppzval) - 1) == DEFAULT_SLASH) {
+ YAF_G(directory) = estrndup(Z_STRVAL_PP(ppzval), Z_STRLEN_PP(ppzval) - 1);
+ } else {
+ YAF_G(directory) = estrndup(Z_STRVAL_PP(ppzval), Z_STRLEN_PP(ppzval));
+ }
+
+ if (zend_hash_find(Z_ARRVAL_P(app), YAF_STRS("ext"), (void **)&ppzval) == SUCCESS
+ && Z_TYPE_PP(ppzval) == IS_STRING) {
+ YAF_G(ext) = estrndup(Z_STRVAL_PP(ppzval), Z_STRLEN_PP(ppzval));
+ } else {
+ YAF_G(ext) = YAF_DEFAULT_EXT;
+ }
+
+ if (zend_hash_find(Z_ARRVAL_P(app), YAF_STRS("bootstrap"), (void **)&ppzval) == SUCCESS
+ && Z_TYPE_PP(ppzval) == IS_STRING) {
+ YAF_G(bootstrap) = estrndup(Z_STRVAL_PP(ppzval), Z_STRLEN_PP(ppzval));
+ }
+
+ if (zend_hash_find(Z_ARRVAL_P(app), YAF_STRS("library"), (void **)&ppzval) == SUCCESS
+ && Z_TYPE_PP(ppzval) == IS_STRING) {
+ YAF_G(library_directory) = estrndup(Z_STRVAL_PP(ppzval), Z_STRLEN_PP(ppzval));
+ }
+
+ if (zend_hash_find(Z_ARRVAL_P(app), YAF_STRS("view"), (void **)&ppzval) == FAILURE
+ || Z_TYPE_PP(ppzval) != IS_ARRAY) {
+ YAF_G(view_ext) = YAF_DEFAULT_VIEW_EXT;
+ } else {
+ if (zend_hash_find(Z_ARRVAL_PP(ppzval), YAF_STRS("ext"), (void **)&ppsval) == FAILURE
+ || Z_TYPE_PP(ppsval) != IS_STRING) {
+ YAF_G(view_ext) = YAF_DEFAULT_VIEW_EXT;
+ } else {
+ YAF_G(view_ext) = estrndup(Z_STRVAL_PP(ppsval), Z_STRLEN_PP(ppsval));
+ }
+ }
+
+ if (zend_hash_find(Z_ARRVAL_P(app), YAF_STRS("baseUri"), (void **)&ppzval) == SUCCESS
+ && Z_TYPE_PP(ppzval) == IS_STRING) {
+ YAF_G(base_uri) = estrndup(Z_STRVAL_PP(ppzval), Z_STRLEN_PP(ppzval));
+ }
+
+ if (zend_hash_find(Z_ARRVAL_P(app), YAF_STRS("dispatcher"), (void **)&ppzval) == FAILURE
+ || Z_TYPE_PP(ppzval) != IS_ARRAY) {
+ YAF_G(default_module) = YAF_ROUTER_DEFAULT_MODULE;
+ YAF_G(default_controller) = YAF_ROUTER_DEFAULT_CONTROLLER;
+ YAF_G(default_action) = YAF_ROUTER_DEFAULT_ACTION;
+ } else {
+ if (zend_hash_find(Z_ARRVAL_PP(ppzval), YAF_STRS("defaultModule"), (void **)&ppsval) == FAILURE
+ || Z_TYPE_PP(ppsval) != IS_STRING) {
+ YAF_G(default_module) = YAF_ROUTER_DEFAULT_MODULE;
+ } else {
+ YAF_G(default_module) = zend_str_tolower_dup(Z_STRVAL_PP(ppsval), Z_STRLEN_PP(ppsval));
+ *(YAF_G(default_module)) = toupper(*YAF_G(default_module));
+ }
+
+ if (zend_hash_find(Z_ARRVAL_PP(ppzval), YAF_STRS("defaultController"), (void **)&ppsval) == FAILURE
+ || Z_TYPE_PP(ppsval) != IS_STRING) {
+ YAF_G(default_controller) = YAF_ROUTER_DEFAULT_CONTROLLER;
+ } else {
+ YAF_G(default_controller) = zend_str_tolower_dup(Z_STRVAL_PP(ppsval), Z_STRLEN_PP(ppsval));
+ *(YAF_G(default_controller)) = toupper(*YAF_G(default_controller));
+ }
+
+ if (zend_hash_find(Z_ARRVAL_PP(ppzval), YAF_STRS("defaultAction"), (void **)&ppsval) == FAILURE
+ || Z_TYPE_PP(ppsval) != IS_STRING) {
+ YAF_G(default_action) = YAF_ROUTER_DEFAULT_ACTION;
+ } else {
+ YAF_G(default_action) = zend_str_tolower_dup(Z_STRVAL_PP(ppsval), Z_STRLEN_PP(ppsval));
+ }
+
+ if (zend_hash_find(Z_ARRVAL_PP(ppzval), YAF_STRS("throwException"), (void **)&ppsval) == SUCCESS) {
+ zval_add_ref(ppsval);
+ convert_to_boolean_ex(ppsval);
+ YAF_G(throw_exception) = Z_BVAL_PP(ppsval);
+ }
+
+ if (zend_hash_find(Z_ARRVAL_PP(ppzval), YAF_STRS("catchException"), (void **)&ppsval) == SUCCESS) {
+ zval_add_ref(ppsval);
+ convert_to_boolean_ex(ppsval);
+ YAF_G(catch_exception) = Z_BVAL_PP(ppsval);
+ }
+ }
+
+ do {
+ char *ptrptr;
+ zval *module, *zmodules;
+
+ MAKE_STD_ZVAL(zmodules);
+ array_init(zmodules);
+ if (zend_hash_find(Z_ARRVAL_P(app), YAF_STRS("modules"), (void **)&ppzval) == SUCCESS
+ && Z_TYPE_PP(ppzval) == IS_STRING && Z_STRLEN_PP(ppzval)) {
+ char *seg, *modules;
+ modules = estrndup(Z_STRVAL_PP(ppzval), Z_STRLEN_PP(ppzval));
+ seg = php_strtok_r(modules, ",", &ptrptr);
+ while(seg) {
+ if (seg && strlen(seg)) {
+ MAKE_STD_ZVAL(module);
+ ZVAL_STRINGL(module, seg, strlen(seg), 1);
+ zend_hash_next_index_insert(Z_ARRVAL_P(zmodules),
+ (void **)&module, sizeof(zval *), NULL);
+ }
+ seg = php_strtok_r(NULL, ",", &ptrptr);
+ }
+ efree(modules);
+ } else {
+ MAKE_STD_ZVAL(module);
+ ZVAL_STRING(module, YAF_G(default_module), 1);
+ zend_hash_next_index_insert(Z_ARRVAL_P(zmodules), (void **)&module, sizeof(zval *), NULL);
+ }
+ YAF_G(modules) = zmodules;
+ } while (0);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/** {{{ proto Yaf_Application::__construct(mixed $config, string $environ = YAF_G(environ))
+*/
+PHP_METHOD(yaf_application, __construct) {
+ yaf_config_t *zconfig;
+ yaf_request_t *request;
+ yaf_dispatcher_t *zdispatcher;
+ yaf_application_t *app, *self;
+ yaf_loader_t *loader;
+ zval *config;
+ zval *section = NULL;
+
+ app = zend_read_static_property(yaf_application_ce, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_APP), 1 TSRMLS_CC);
+
+#if PHP_YAF_DEBUG
+ php_error_docref(NULL, E_STRICT, "Yaf is running in debug mode");
+#endif
+
+ if (!ZVAL_IS_NULL(app)) {
+ yaf_trigger_error(YAF_ERR_STARTUP_FAILED TSRMLS_CC, "Only one application can be initialized");
+ RETURN_FALSE;
+ }
+
+ self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &config, &section) == FAILURE) {
+ yaf_trigger_error(YAF_ERR_STARTUP_FAILED TSRMLS_CC, "%s::__construct expects at least 1 parameter, 0 give", yaf_application_ce->name);
+ return;
+ }
+
+ if (!section || Z_TYPE_P(section) != IS_STRING || !Z_STRLEN_P(section)) {
+ MAKE_STD_ZVAL(section);
+ ZVAL_STRING(section, YAF_G(environ), 0);
+ zconfig = yaf_config_instance(NULL, config, section TSRMLS_CC);
+ efree(section);
+ } else {
+ zconfig = yaf_config_instance(NULL, config, section TSRMLS_CC);
+ }
+
+ if (zconfig == NULL
+ || Z_TYPE_P(zconfig) != IS_OBJECT
+ || !instanceof_function(Z_OBJCE_P(zconfig), yaf_config_ce TSRMLS_CC)
+ || yaf_application_parse_option(zend_read_property(yaf_config_ce,
+ zconfig, ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC) TSRMLS_CC) == FAILURE) {
+ yaf_trigger_error(YAF_ERR_STARTUP_FAILED TSRMLS_CC, "Initialization of application config failed");
+ RETURN_FALSE;
+ }
+
+ request = yaf_request_instance(NULL, YAF_G(base_uri) TSRMLS_CC);
+ if (YAF_G(base_uri)) {
+ efree(YAF_G(base_uri));
+ YAF_G(base_uri) = NULL;
+ }
+
+ if (!request) {
+ yaf_trigger_error(YAF_ERR_STARTUP_FAILED TSRMLS_CC, "Initialization of request failed");
+ RETURN_FALSE;
+ }
+
+ zdispatcher = yaf_dispatcher_instance(NULL TSRMLS_CC);
+ yaf_dispatcher_set_request(zdispatcher, request TSRMLS_CC);
+ if (NULL == zdispatcher
+ || Z_TYPE_P(zdispatcher) != IS_OBJECT
+ || !instanceof_function(Z_OBJCE_P(zdispatcher), yaf_dispatcher_ce TSRMLS_CC)) {
+ yaf_trigger_error(YAF_ERR_STARTUP_FAILED TSRMLS_CC, "Instantiation of application dispatcher failed");
+ RETURN_FALSE;
+ }
+
+ zend_update_property(yaf_application_ce, self, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_CONFIG), zconfig TSRMLS_CC);
+ zend_update_property(yaf_application_ce, self, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_DISPATCHER), zdispatcher TSRMLS_CC);
+
+ zval_ptr_dtor(&request);
+ zval_ptr_dtor(&zdispatcher);
+ zval_ptr_dtor(&zconfig);
+
+ if (YAF_G(library_directory)) {
+ loader = yaf_loader_instance(NULL, YAF_G(library_directory),
+ strlen(YAF_G(global_library))? YAF_G(global_library) : NULL TSRMLS_CC);
+ efree(YAF_G(library_directory));
+ YAF_G(library_directory) = NULL;
+ } else {
+ char *library_directory;
+ spprintf(&library_directory, 0, "%s%c%s", YAF_G(directory), DEFAULT_SLASH, YAF_LIBRARY_DIRECTORY_NAME);
+ loader = yaf_loader_instance(NULL, library_directory,
+ strlen(YAF_G(global_library))? YAF_G(global_library) : NULL TSRMLS_CC);
+ efree(library_directory);
+ }
+
+ if (!loader) {
+ yaf_trigger_error(YAF_ERR_STARTUP_FAILED TSRMLS_CC, "Initialization of application auto loader failed");
+ RETURN_FALSE;
+ }
+
+ zend_update_property_bool(yaf_application_ce, self, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_RUN), 0 TSRMLS_CC);
+ zend_update_property_string(yaf_application_ce, self, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_ENV), YAF_G(environ) TSRMLS_CC);
+
+ if (YAF_G(modules)) {
+ zend_update_property(yaf_application_ce, self, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_MODULES), YAF_G(modules) TSRMLS_CC);
+ Z_DELREF_P(YAF_G(modules));
+ YAF_G(modules) = NULL;
+ } else {
+ zend_update_property_null(yaf_application_ce, self, YAF_STRL(YAF_APPLICATION_PROPERTY_NAME_MODULES) TSRMLS_CC);
+ }
+
+ zend_update_static_property(yaf_application_ce, YAF_STRL(YAF_APPLICATION_PROPERTY_NAME_APP), self TSRMLS_CC);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Application::__desctruct(void)
+*/
+PHP_METHOD(yaf_application, __destruct) {
+ zend_update_static_property_null(yaf_application_ce, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_APP) TSRMLS_CC);
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Application::__sleep(void)
+*/
+PHP_METHOD(yaf_application, __sleep) {
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Application::__wakeup(void)
+*/
+PHP_METHOD(yaf_application, __wakeup) {
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Application::__clone(void)
+*/
+PHP_METHOD(yaf_application, __clone) {
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Application::run(void)
+*/
+PHP_METHOD(yaf_application, run) {
+ zval *running;
+ yaf_dispatcher_t *dispatcher;
+ yaf_response_t *response;
+ yaf_application_t *self = getThis();
+
+ running = zend_read_property(yaf_application_ce, self, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_RUN), 1 TSRMLS_CC);
+ if (IS_BOOL == Z_TYPE_P(running)
+ && Z_BVAL_P(running)) {
+ yaf_trigger_error(YAF_ERR_STARTUP_FAILED TSRMLS_CC, "An application instance already run");
+ RETURN_TRUE;
+ }
+
+ ZVAL_BOOL(running, 1);
+ zend_update_property(yaf_application_ce, self, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_RUN), running TSRMLS_CC);
+
+ dispatcher = zend_read_property(yaf_application_ce, self, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_DISPATCHER), 1 TSRMLS_CC);
+ if ((response = yaf_dispatcher_dispatch(dispatcher TSRMLS_CC))) {
+ RETURN_ZVAL(response, 1, 0);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Application::execute(callback $func)
+ * We can not call to zif_call_user_func on windows, since it was not declared with dllexport
+*/
+PHP_METHOD(yaf_application, execute) {
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION > 2)) || (PHP_MAJOR_VERSION > 5)
+ zval *retval_ptr;
+ zend_fcall_info fci;
+ zend_fcall_info_cache fci_cache;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f*", &fci, &fci_cache, &fci.params, &fci.param_count) == FAILURE) {
+ return;
+ }
+
+ fci.retval_ptr_ptr = &retval_ptr;
+
+ if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && fci.retval_ptr_ptr && *fci.retval_ptr_ptr) {
+ COPY_PZVAL_TO_ZVAL(*return_value, *fci.retval_ptr_ptr);
+ }
+
+ if (fci.params) {
+ efree(fci.params);
+ }
+#else
+ zval ***params;
+ zval *retval_ptr;
+ char *name;
+ int argc = ZEND_NUM_ARGS();
+
+ if (argc < 1) {
+ return;
+ }
+
+ params = safe_emalloc(sizeof(zval **), argc, 0);
+ if (zend_get_parameters_array_ex(1, params) == FAILURE) {
+ efree(params);
+ RETURN_FALSE;
+ }
+
+ if (Z_TYPE_PP(params[0]) != IS_STRING && Z_TYPE_PP(params[0]) != IS_ARRAY) {
+ SEPARATE_ZVAL(params[0]);
+ convert_to_string_ex(params[0]);
+ }
+
+ if (!zend_is_callable(*params[0], 0, &name)) {
+ php_error_docref1(NULL TSRMLS_CC, name, E_WARNING, "First argument is expected to be a valid callback");
+ efree(name);
+ efree(params);
+ RETURN_NULL();
+ }
+
+ if (zend_get_parameters_array_ex(argc, params) == FAILURE) {
+ efree(params);
+ RETURN_FALSE;
+ }
+
+ if (call_user_function_ex(EG(function_table), NULL, *params[0], &retval_ptr, argc - 1, params + 1, 0, NULL TSRMLS_CC) == SUCCESS) {
+ if (retval_ptr) {
+ COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
+ }
+ } else {
+ if (argc > 1) {
+ SEPARATE_ZVAL(params[1]);
+ convert_to_string_ex(params[1]);
+ if (argc > 2) {
+ SEPARATE_ZVAL(params[2]);
+ convert_to_string_ex(params[2]);
+ php_error_docref1(NULL TSRMLS_CC, name, E_WARNING, "Unable to call %s(%s,%s)", name, Z_STRVAL_PP(params[1]), Z_STRVAL_PP(params[2]));
+ } else {
+ php_error_docref1(NULL TSRMLS_CC, name, E_WARNING, "Unable to call %s(%s)", name, Z_STRVAL_PP(params[1]));
+ }
+ } else {
+ php_error_docref1(NULL TSRMLS_CC, name, E_WARNING, "Unable to call %s()", name);
+ }
+ }
+
+ efree(name);
+ efree(params);
+#endif
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Application::app(void)
+*/
+PHP_METHOD(yaf_application, app) {
+ yaf_application_t *app = zend_read_static_property(yaf_application_ce, YAF_STRL(YAF_APPLICATION_PROPERTY_NAME_APP), 1 TSRMLS_CC);
+ RETVAL_ZVAL(app, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Application::getConfig(void)
+*/
+PHP_METHOD(yaf_application, getConfig) {
+ yaf_config_t *config = zend_read_property(yaf_application_ce, getThis(), ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_CONFIG), 1 TSRMLS_CC);
+ RETVAL_ZVAL(config, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Application::getDispatcher(void)
+*/
+PHP_METHOD(yaf_application, getDispatcher) {
+ yaf_dispatcher_t *dispatcher = zend_read_property(yaf_application_ce, getThis(), ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_DISPATCHER), 1 TSRMLS_CC);
+ RETVAL_ZVAL(dispatcher, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Application::getModules(void)
+*/
+PHP_METHOD(yaf_application, getModules) {
+ zval *modules = zend_read_property(yaf_application_ce, getThis(), ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_MODULES), 1 TSRMLS_CC);
+ RETVAL_ZVAL(modules, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Application::environ(void)
+*/
+PHP_METHOD(yaf_application, environ) {
+ zval *env = zend_read_property(yaf_application_ce, getThis(), ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_ENV), 1 TSRMLS_CC);
+ RETURN_STRINGL(Z_STRVAL_P(env), Z_STRLEN_P(env), 1);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Application::bootstrap(void)
+*/
+PHP_METHOD(yaf_application, bootstrap) {
+ char *bootstrap_path;
+ uint len, retval = 1;
+ zend_class_entry **ce;
+ yaf_application_t *self = getThis();
+
+ if (zend_hash_find(EG(class_table), YAF_DEFAULT_BOOTSTRAP_LOWER, YAF_DEFAULT_BOOTSTRAP_LEN, (void **) &ce) != SUCCESS) {
+ if (YAF_G(bootstrap)) {
+ bootstrap_path = estrdup(YAF_G(bootstrap));
+ len = strlen(YAF_G(bootstrap));
+ } else {
+ len = spprintf(&bootstrap_path, 0, "%s%c%s.%s", YAF_G(directory), DEFAULT_SLASH, YAF_DEFAULT_BOOTSTRAP, YAF_G(ext));
+ }
+
+ if (!yaf_loader_import(bootstrap_path, len + 1, 0 TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't find bootstrap file %s", bootstrap_path);
+ retval = 0;
+ } else if (zend_hash_find(EG(class_table), YAF_DEFAULT_BOOTSTRAP_LOWER, YAF_DEFAULT_BOOTSTRAP_LEN, (void **) &ce) != SUCCESS) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't find class %s in %s", YAF_DEFAULT_BOOTSTRAP, bootstrap_path);
+ retval = 0;
+ } else if (!instanceof_function(*ce, yaf_bootstrap_ce TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expect a %s instance, %s give", yaf_bootstrap_ce->name, (*ce)->name);
+ retval = 0;
+ }
+
+ efree(bootstrap_path);
+ }
+
+ if (!retval) {
+ RETURN_FALSE;
+ } else {
+ zval *bootstrap;
+ HashTable *methods;
+ yaf_dispatcher_t *dispatcher;
+
+ MAKE_STD_ZVAL(bootstrap);
+ object_init_ex(bootstrap, *ce);
+ dispatcher = zend_read_property(yaf_application_ce, self, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_DISPATCHER), 1 TSRMLS_CC);
+
+ methods = &((*ce)->function_table);
+ for(zend_hash_internal_pointer_reset(methods);
+ zend_hash_has_more_elements(methods) == SUCCESS;
+ zend_hash_move_forward(methods)) {
+ uint len;
+ long idx;
+ char *func;
+ zend_hash_get_current_key_ex(methods, &func, &len, &idx, 0, NULL);
+ /* cann't use ZEND_STRL in strncasecmp, it cause a compile failed in VS2009 */
+ if (strncasecmp(func, YAF_BOOTSTRAP_INITFUNC_PREFIX, sizeof(YAF_BOOTSTRAP_INITFUNC_PREFIX)-1)) {
+ continue;
+ }
+
+ zend_call_method(&bootstrap, *ce, NULL, func, len - 1, NULL, 1, dispatcher, NULL TSRMLS_CC);
+ /** an uncaught exception threw in function call */
+ if (EG(exception)) {
+ zval_dtor(bootstrap);
+ efree(bootstrap);
+ RETURN_FALSE;
+ }
+ }
+
+ zval_dtor(bootstrap);
+ efree(bootstrap);
+ }
+
+ RETVAL_ZVAL(self, 1, 0);
+}
+/* }}} */
+
+/** {{{ yaf_application_methods
+*/
+zend_function_entry yaf_application_methods[] = {
+ PHP_ME(yaf_application, __construct, yaf_application_construct_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(yaf_application, run, yaf_application_run_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_application, execute, yaf_application_execute_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_application, app, yaf_application_app_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ PHP_ME(yaf_application, environ, yaf_application_environ_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_application, bootstrap, yaf_application_bootstrap_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_application, getConfig, yaf_application_getconfig_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_application, getModules, yaf_application_getmodule_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_application, getDispatcher, yaf_application_getdispatch_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_application, __destruct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
+ PHP_ME(yaf_application, __clone, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CLONE)
+ PHP_ME(yaf_application, __sleep, NULL, ZEND_ACC_PRIVATE)
+ PHP_ME(yaf_application, __wakeup, NULL, ZEND_ACC_PRIVATE)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(application) {
+ zend_class_entry ce;
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Application", "Yaf\\Application", yaf_application_methods);
+
+ yaf_application_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+ yaf_application_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+
+ zend_declare_property_null(yaf_application_ce, YAF_STRL(YAF_APPLICATION_PROPERTY_NAME_CONFIG), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_application_ce, YAF_STRL(YAF_APPLICATION_PROPERTY_NAME_DISPATCHER), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_application_ce, YAF_STRL(YAF_APPLICATION_PROPERTY_NAME_APP), ZEND_ACC_STATIC|ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_application_ce, YAF_STRL(YAF_APPLICATION_PROPERTY_NAME_MODULES), ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ zend_declare_property_bool(yaf_application_ce, YAF_STRL(YAF_APPLICATION_PROPERTY_NAME_RUN), 0, ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_string(yaf_application_ce, YAF_STRL(YAF_APPLICATION_PROPERTY_NAME_ENV), YAF_G(environ), ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_application.h b/yaf_application.h
new file mode 100644
index 0000000000..30c6f673ed
--- /dev/null
+++ b/yaf_application.h
@@ -0,0 +1,34 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef PHP_YAF_APPLICATION_H
+#define PHP_YAF_APPLICATION_H
+
+#define YAF_APPLICATION_PROPERTY_NAME_CONFIG "config"
+#define YAF_APPLICATION_PROPERTY_NAME_DISPATCHER "dispatcher"
+#define YAF_APPLICATION_PROPERTY_NAME_RUN "_running"
+#define YAF_APPLICATION_PROPERTY_NAME_APP "_app"
+#define YAF_APPLICATION_PROPERTY_NAME_ENV "_environ"
+#define YAF_APPLICATION_PROPERTY_NAME_MODULES "_modules"
+
+extern zend_class_entry *yaf_application_ce;
+
+int yaf_application_is_module_name(char *name, int len TSRMLS_DC);
+
+YAF_STARTUP_FUNCTION(application);
+#endif
diff --git a/yaf_bootstrap.c b/yaf_bootstrap.c
new file mode 100644
index 0000000000..32e5acbf18
--- /dev/null
+++ b/yaf_bootstrap.c
@@ -0,0 +1,59 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "main/SAPI.h"
+
+#include "php_yaf.h"
+#include "yaf_namespace.h"
+#include "yaf_bootstrap.h"
+
+zend_class_entry *yaf_bootstrap_ce;
+
+/** {{{ yaf_bootstrap_methods
+*/
+zend_function_entry yaf_bootstrap_methods[] = {
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(bootstrap) {
+ zend_class_entry ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Bootstrap_Abstract", "Yaf\\Bootstrap\\Abstract", yaf_bootstrap_methods);
+ yaf_bootstrap_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+ yaf_bootstrap_ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_bootstrap.h b/yaf_bootstrap.h
new file mode 100644
index 0000000000..d5a153fe4f
--- /dev/null
+++ b/yaf_bootstrap.h
@@ -0,0 +1,38 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef YAF_BOOTSTRAP_H
+#define YAF_BOOTSTRAP_H
+
+#define YAF_DEFAULT_BOOTSTRAP "Bootstrap"
+#define YAF_DEFAULT_BOOTSTRAP_LOWER "bootstrap"
+#define YAF_DEFAULT_BOOTSTRAP_LEN 10
+#define YAF_BOOTSTRAP_INITFUNC_PREFIX "_init"
+
+extern zend_class_entry *yaf_bootstrap_ce;
+
+YAF_STARTUP_FUNCTION(bootstrap);
+#endif
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_config.c b/yaf_config.c
new file mode 100644
index 0000000000..36cff9bb8f
--- /dev/null
+++ b/yaf_config.c
@@ -0,0 +1,401 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "main/SAPI.h"
+#include "Zend/zend_interfaces.h"
+#include "Zend/zend_exceptions.h"
+#include "Zend/zend_alloc.h"
+#include "ext/standard/php_string.h"
+#include "ext/standard/php_filestat.h"
+
+#include "php_yaf.h"
+#include "yaf_namespace.h"
+#include "yaf_exception.h"
+#include "yaf_config.h"
+
+zend_class_entry *yaf_config_ce;
+#ifdef HAVE_SPL
+extern PHPAPI zend_class_entry *spl_ce_Countable;
+#endif
+
+/* {{{ ARG_INFO
+ */
+ZEND_BEGIN_ARG_INFO_EX(yaf_config_void_arginfo, 0, 0, 0)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+#include "configs/ini.c"
+#include "configs/simple.c"
+
+static zval * yaf_config_ini_zval_persistent(zval *zvalue TSRMLS_DC);
+static zval * yaf_config_ini_zval_losable(zval *zvalue TSRMLS_DC);
+
+/** {{{ yaf_config_ini_modified
+*/
+static int yaf_config_ini_modified(zval * file, long ctime TSRMLS_DC) {
+ zval n_ctime;
+ php_stat(Z_STRVAL_P(file), Z_STRLEN_P(file) + 1, 7 /*YAF_FS_CTIME*/ , &n_ctime TSRMLS_CC);
+ if (Z_TYPE(n_ctime) != IS_BOOL && ctime != Z_LVAL(n_ctime)) {
+ return Z_LVAL(n_ctime);
+ }
+ return 0;
+}
+/* }}} */
+
+/** {{{ static void yaf_config_cache_dtor(yaf_config_cache **cache)
+ */
+static void yaf_config_cache_dtor(yaf_config_cache **cache) {
+ if (*cache) {
+ zend_hash_destroy((*cache)->data);
+ pefree((*cache)->data, 1);
+ pefree(*cache, 1);
+ }
+}
+/* }}} */
+
+/** {{{ static void yaf_config_zval_dtor(zval **value)
+ */
+static void yaf_config_zval_dtor(zval **value) {
+ if (*value) {
+ switch(Z_TYPE_PP(value)) {
+ case IS_STRING:
+ case IS_CONSTANT:
+ CHECK_ZVAL_STRING(*value);
+ pefree((*value)->value.str.val, 1);
+ pefree(*value, 1);
+ break;
+ case IS_ARRAY:
+ case IS_CONSTANT_ARRAY: {
+ zend_hash_destroy((*value)->value.ht);
+ pefree((*value)->value.ht, 1);
+ pefree(*value, 1);
+ }
+ break;
+ }
+ }
+}
+/* }}} */
+
+/** {{{ static void yaf_config_copy_persistent(HashTable *pdst, HashTable *src TSRMLS_DC)
+ */
+static void yaf_config_copy_persistent(HashTable *pdst, HashTable *src TSRMLS_DC) {
+ zval **ppzval;
+ char *key;
+ uint keylen;
+ long idx;
+
+ for(zend_hash_internal_pointer_reset(src);
+ zend_hash_has_more_elements(src) == SUCCESS;
+ zend_hash_move_forward(src)) {
+
+ if (zend_hash_get_current_key_ex(src, &key, &keylen, &idx, 0, NULL) == HASH_KEY_IS_LONG) {
+ zval *tmp;
+ if (zend_hash_get_current_data(src, (void**)&ppzval) == FAILURE) {
+ continue;
+ }
+
+ tmp = yaf_config_ini_zval_persistent(*ppzval TSRMLS_CC);
+ if (tmp)
+ zend_hash_index_update(pdst, idx, (void **)&tmp, sizeof(zval *), NULL);
+
+ } else {
+ zval *tmp;
+ if (zend_hash_get_current_data(src, (void**)&ppzval) == FAILURE) {
+ continue;
+ }
+
+ tmp = yaf_config_ini_zval_persistent(*ppzval TSRMLS_CC);
+ if (tmp)
+ zend_hash_update(pdst, key, keylen, (void **)&tmp, sizeof(zval *), NULL);
+ }
+ }
+}
+/* }}} */
+
+/** {{{ static void yaf_config_copy_losable(HashTable *ldst, HashTable *src TSRMLS_DC)
+ */
+static void yaf_config_copy_losable(HashTable *ldst, HashTable *src TSRMLS_DC) {
+ zval **ppzval, *tmp;
+ char *key;
+ long idx;
+ uint keylen;
+
+ for(zend_hash_internal_pointer_reset(src);
+ zend_hash_has_more_elements(src) == SUCCESS;
+ zend_hash_move_forward(src)) {
+
+ if (zend_hash_get_current_key_ex(src, &key, &keylen, &idx, 0, NULL) == HASH_KEY_IS_LONG) {
+ if (zend_hash_get_current_data(src, (void**)&ppzval) == FAILURE) {
+ continue;
+ }
+
+ tmp = yaf_config_ini_zval_losable(*ppzval TSRMLS_CC);
+ zend_hash_index_update(ldst, idx, (void **)&tmp, sizeof(zval *), NULL);
+
+ } else {
+ if (zend_hash_get_current_data(src, (void**)&ppzval) == FAILURE) {
+ continue;
+ }
+
+ tmp = yaf_config_ini_zval_losable(*ppzval TSRMLS_CC);
+ zend_hash_update(ldst, key, keylen, (void **)&tmp, sizeof(zval *), NULL);
+ }
+ }
+}
+/* }}} */
+
+/** {{{ static zval * yaf_config_ini_zval_persistent(zval *zvalue TSRMLS_DC)
+ */
+static zval * yaf_config_ini_zval_persistent(zval *zvalue TSRMLS_DC) {
+ zval *ret = (zval *)pemalloc(sizeof(zval), 1);
+ INIT_PZVAL(ret);
+ switch (zvalue->type) {
+ case IS_RESOURCE:
+ case IS_OBJECT:
+ break;
+ case IS_BOOL:
+ case IS_LONG:
+ case IS_NULL:
+ break;
+ case IS_CONSTANT:
+ case IS_STRING:
+ CHECK_ZVAL_STRING(zvalue);
+ Z_TYPE_P(ret) = IS_STRING;
+ ret->value.str.val = pestrndup(zvalue->value.str.val, zvalue->value.str.len, 1);
+ ret->value.str.len = zvalue->value.str.len;
+ break;
+ case IS_ARRAY:
+ case IS_CONSTANT_ARRAY: {
+ HashTable *tmp_ht, *original_ht = zvalue->value.ht;
+ tmp_ht = (HashTable *)pemalloc(sizeof(HashTable), 1);
+ if (!tmp_ht) {
+ return NULL;
+ }
+
+ zend_hash_init(tmp_ht, zend_hash_num_elements(original_ht), NULL, (dtor_func_t)yaf_config_zval_dtor, 1);
+ yaf_config_copy_persistent(tmp_ht, original_ht TSRMLS_CC);
+ Z_TYPE_P(ret) = IS_ARRAY;
+ ret->value.ht = tmp_ht;
+ }
+ break;
+ }
+
+ return ret;
+}
+/* }}} */
+
+/** {{{ static zval * yaf_config_ini_zval_losable(zval *zvalue TSRMLS_DC)
+ */
+static zval * yaf_config_ini_zval_losable(zval *zvalue TSRMLS_DC) {
+ zval *ret;
+ MAKE_STD_ZVAL(ret);
+ switch (zvalue->type) {
+ case IS_RESOURCE:
+ case IS_OBJECT:
+ break;
+ case IS_BOOL:
+ case IS_LONG:
+ case IS_NULL:
+ break;
+ case IS_CONSTANT:
+ case IS_STRING:
+ CHECK_ZVAL_STRING(zvalue);
+ ZVAL_STRINGL(ret, zvalue->value.str.val, zvalue->value.str.len, 1);
+ break;
+ case IS_ARRAY:
+ case IS_CONSTANT_ARRAY: {
+ HashTable *original_ht = zvalue->value.ht;
+ array_init(ret);
+ yaf_config_copy_losable(Z_ARRVAL_P(ret), original_ht TSRMLS_CC);
+ }
+ break;
+ }
+
+ return ret;
+}
+/* }}} */
+
+/** {{{ static yaf_config_t * yaf_config_ini_unserialize(yaf_config_t *this_ptr, zval *filename, zval *section TSRMLS_DC)
+ */
+static yaf_config_t * yaf_config_ini_unserialize(yaf_config_t *this_ptr, zval *filename, zval *section TSRMLS_DC) {
+ char *key;
+ uint len;
+ yaf_config_cache **ppval;
+
+ if (!YAF_G(configs)) {
+ return NULL;
+ }
+
+ len = spprintf(&key, 0, "%s#%s", Z_STRVAL_P(filename), Z_STRVAL_P(section));
+
+ if (zend_hash_find(YAF_G(configs), key, len + 1, (void **)&ppval) == SUCCESS) {
+ if (yaf_config_ini_modified(filename, (*ppval)->ctime TSRMLS_CC)) {
+ efree(key);
+ return NULL;
+ } else {
+ zval *props;
+
+ MAKE_STD_ZVAL(props);
+ array_init(props);
+ yaf_config_copy_losable(Z_ARRVAL_P(props), (*ppval)->data TSRMLS_CC);
+ efree(key);
+ return yaf_config_ini_instance(this_ptr, props, section TSRMLS_CC);
+ }
+ efree(key);
+ }
+
+ return NULL;
+}
+/* }}} */
+
+/** {{{ static void yaf_config_ini_serialize(yaf_config_t *this_ptr, zval *filename, zval *section TSRMLS_DC)
+ */
+static void yaf_config_ini_serialize(yaf_config_t *this_ptr, zval *filename, zval *section TSRMLS_DC) {
+ char *key;
+ uint len;
+ long ctime;
+ zval *configs;
+ HashTable *persistent;
+ yaf_config_cache *cache;
+
+ if (!YAF_G(configs)) {
+ YAF_G(configs) = (HashTable *)pemalloc(sizeof(HashTable), 1);
+ if (!YAF_G(configs)) {
+ return;
+ }
+ zend_hash_init(YAF_G(configs), 8, NULL, (dtor_func_t) yaf_config_cache_dtor, 1);
+ }
+
+ cache = (yaf_config_cache *)pemalloc(sizeof(yaf_config_cache), 1);
+
+ if (!cache) {
+ return;
+ }
+
+ persistent = (HashTable *)pemalloc(sizeof(HashTable), 1);
+ if (!persistent) {
+ return;
+ }
+
+ configs = zend_read_property(yaf_config_ini_ce, this_ptr, ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+
+ zend_hash_init(persistent, zend_hash_num_elements(Z_ARRVAL_P(configs)), NULL, (dtor_func_t) yaf_config_zval_dtor, 1);
+
+ yaf_config_copy_persistent(persistent, Z_ARRVAL_P(configs) TSRMLS_CC);
+
+ ctime = yaf_config_ini_modified(filename, 0 TSRMLS_CC);
+ cache->ctime = ctime;
+ cache->data = persistent;
+ len = spprintf(&key, 0, "%s#%s", Z_STRVAL_P(filename), Z_STRVAL_P(section));
+
+ zend_hash_update(YAF_G(configs), key, len + 1, (void **)&cache, sizeof(yaf_config_cache *), NULL);
+
+ efree(key);
+}
+/* }}} */
+
+/** {{{ yaf_config_t * yaf_config_instance(yaf_config_t *this_ptr, zval *arg1, zval *arg2 TSRMLS_DC)
+ */
+yaf_config_t * yaf_config_instance(yaf_config_t *this_ptr, zval *arg1, zval *arg2 TSRMLS_DC) {
+ yaf_config_t *instance;
+
+ if (!arg1) {
+ return NULL;
+ }
+
+ if (Z_TYPE_P(arg1) == IS_STRING) {
+ if (strncasecmp(Z_STRVAL_P(arg1) + Z_STRLEN_P(arg1) - 3, "ini", 3) == 0) {
+ if (YAF_G(cache_config)) {
+ if ((instance = yaf_config_ini_unserialize(this_ptr, arg1, arg2 TSRMLS_CC))) {
+ return instance;
+ }
+ }
+
+ instance = yaf_config_ini_instance(this_ptr, arg1, arg2 TSRMLS_CC);
+
+ if (!instance) {
+ return NULL;
+ }
+
+ if (YAF_G(cache_config)) {
+ yaf_config_ini_serialize(instance, arg1, arg2 TSRMLS_CC);
+ }
+
+ return instance;
+ }
+ }
+
+ if (Z_TYPE_P(arg1) == IS_ARRAY) {
+ zval *readonly;
+
+ MAKE_STD_ZVAL(readonly);
+ ZVAL_BOOL(readonly, 1);
+ instance = yaf_config_simple_instance(this_ptr, arg1, readonly TSRMLS_CC);
+ efree(readonly);
+ return instance;
+ }
+
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "Expects a string or an array as parameter");
+ return NULL;
+}
+/* }}} */
+
+/** {{{ yaf_config_methods
+*/
+zend_function_entry yaf_config_methods[] = {
+ PHP_ABSTRACT_ME(yaf_config, get, NULL)
+ PHP_ABSTRACT_ME(yaf_config, set, NULL)
+ PHP_ABSTRACT_ME(yaf_config, readonly, NULL)
+ PHP_ABSTRACT_ME(yaf_config, toArray, NULL)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(config) {
+ zend_class_entry ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Config_Abstract", "Yaf\\Config_Abstract", yaf_config_methods);
+ yaf_config_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+ yaf_config_ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
+
+ zend_declare_property_null(yaf_config_ce, YAF_STRL(YAF_CONFIG_PROPERT_NAME), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_bool(yaf_config_ce, YAF_STRL(YAF_CONFIG_PROPERT_NAME_READONLY), 1, ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ YAF_STARTUP(config_ini);
+ YAF_STARTUP(config_simple);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_config.h b/yaf_config.h
new file mode 100644
index 0000000000..c65be8ca24
--- /dev/null
+++ b/yaf_config.h
@@ -0,0 +1,52 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef YAF_CONFIG_H
+#define YAF_CONFIG_H
+
+#define YAF_EXTRACT_FUNC_NAME "extract"
+#define YAF_CONFIG_PROPERT_NAME "_config"
+#define YAF_CONFIG_PROPERT_NAME_READONLY "_readonly"
+
+struct _yaf_config_cache {
+ long ctime;
+ HashTable *data;
+};
+
+typedef struct _yaf_config_cache yaf_config_cache;
+
+extern zend_class_entry *yaf_config_ce;
+
+yaf_config_t * yaf_config_instance(yaf_config_t *this_ptr, zval *arg1, zval *arg2 TSRMLS_DC);
+void yaf_config_unserialize(yaf_config_t *self, HashTable *data TSRMLS_DC);
+
+#ifndef pestrndup
+/* before php-5.2.4, pestrndup is not defined */
+#define pestrndup(s, length, persistent) ((persistent)?zend_strndup((s),(length)):estrndup((s),(length)))
+#endif
+
+YAF_STARTUP_FUNCTION(config);
+#endif
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_controller.c b/yaf_controller.c
new file mode 100644
index 0000000000..815562e8af
--- /dev/null
+++ b/yaf_controller.c
@@ -0,0 +1,542 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "main/SAPI.h"
+#include "Zend/zend_API.h"
+#include "Zend/zend_interfaces.h"
+
+#include "php_yaf.h"
+#include "yaf_namespace.h"
+#include "yaf_request.h"
+#include "yaf_response.h"
+#include "yaf_dispatcher.h"
+#include "yaf_view.h"
+#include "yaf_exception.h"
+#include "yaf_action.h"
+#include "yaf_controller.h"
+
+zend_class_entry * yaf_controller_ce;
+
+/** {{{ ARG_INFO
+ */
+ZEND_BEGIN_ARG_INFO_EX(yaf_controller_void_arginfo, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_controller_initview_arginfo, 0, 0, 0)
+ ZEND_ARG_ARRAY_INFO(0, options, 1)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_controller_getiarg_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_controller_setvdir_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, view_directory)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_controller_forward_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, module)
+ ZEND_ARG_INFO(0, controller)
+ ZEND_ARG_INFO(0, action)
+ ZEND_ARG_ARRAY_INFO(0, paramters, 1)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_controller_redirect_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, url)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_controller_render_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, tpl)
+ ZEND_ARG_ARRAY_INFO(0, parameters, 1)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_controller_display_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, tpl)
+ ZEND_ARG_ARRAY_INFO(0, parameters, 1)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/** {{{ zval * yaf_controller_render(yaf_controller_t *instance, char *action_name, int len, zval *var_array TSRMLS_DC)
+ */
+static zval * yaf_controller_render(yaf_controller_t *instance, char *action_name, int len, zval *var_array TSRMLS_DC) {
+ char *path, *view_ext, *self_name, *tmp;
+ zval *name, *param, *ret = NULL;
+ int path_len;
+ yaf_view_t *view;
+
+ view = zend_read_property(yaf_controller_ce, instance, ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_VIEW), 1 TSRMLS_CC);
+ name = zend_read_property(yaf_controller_ce, instance, ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_NAME), 1 TSRMLS_CC);
+ view_ext = YAF_G(view_ext);
+
+ self_name = zend_str_tolower_dup(Z_STRVAL_P(name), Z_STRLEN_P(name));
+
+ tmp = self_name;
+ while (*tmp != '\0') {
+ if (*tmp == '_') {
+ *tmp = DEFAULT_SLASH;
+ }
+ tmp++;
+ }
+
+ action_name = estrndup(action_name, len);
+
+ tmp = action_name;
+ while (*tmp != '\0') {
+ if (*tmp == '_') {
+ *tmp = DEFAULT_SLASH;
+ }
+ tmp++;
+ }
+
+ path_len = spprintf(&path, 0, "%s%c%s.%s", self_name, DEFAULT_SLASH, action_name, view_ext);
+
+ efree(self_name);
+ efree(action_name);
+
+ MAKE_STD_ZVAL(param);
+ ZVAL_STRING(param, path, 0);
+
+ if (var_array) {
+ zend_call_method_with_2_params(&view, yaf_view_ce, NULL, "render", &ret, param, var_array);
+ } else {
+ zend_call_method_with_1_params(&view, yaf_view_ce, NULL, "render", &ret, param);
+ }
+
+ zval_dtor(param);
+ efree(param);
+
+ if (!ret || (Z_TYPE_P(ret) == IS_BOOL && !Z_BVAL_P(ret))) {
+ return NULL;
+ }
+
+ return ret;
+}
+/* }}} */
+
+/** {{{ static int yaf_controller_display(zend_class_entry *ce, yaf_controller_t *instance, char *action_name, int len, zval *var_array TSRMLS_DC)
+ */
+static int yaf_controller_display(zend_class_entry *ce, yaf_controller_t *instance, char *action_name, int len, zval *var_array TSRMLS_DC) {
+ char *path, *view_ext, *self_name;
+ zval *name, *param, *ret = NULL;
+ int path_len;
+
+ yaf_view_t *view;
+
+ view = zend_read_property(ce, instance, ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_VIEW), 1 TSRMLS_CC);
+ name = zend_read_property(ce, instance, ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_NAME), 1 TSRMLS_CC);
+ view_ext = YAF_G(view_ext);
+
+ self_name = zend_str_tolower_dup(Z_STRVAL_P(name), Z_STRLEN_P(name));
+
+ path_len = spprintf(&path, 0, "%s%c%s.%s", self_name, DEFAULT_SLASH, action_name, view_ext);
+
+ MAKE_STD_ZVAL(param);
+ ZVAL_STRING(param, path, 0);
+
+ if (var_array) {
+ zend_call_method_with_2_params(&view, yaf_view_ce, NULL, "display", &ret, param, var_array);
+ } else {
+ zend_call_method_with_1_params(&view, yaf_view_ce, NULL, "display", &ret, param);
+ }
+
+ zval_dtor(param);
+ efree(param);
+
+ if (!ret) {
+ return 0;
+ }
+
+ if ((Z_TYPE_P(ret) == IS_BOOL && !Z_BVAL_P(ret))) {
+ zval_ptr_dtor(&ret);
+ return 0;
+ }
+
+ return 1;
+}
+/* }}} */
+
+/** {{{ int yaf_controller_construct(zend_class_entry *ce, yaf_controller_t *self, yaf_request_t *request, yaf_response_t *responseew_t *view, zval *args TSRMLS_DC)
+ */
+int yaf_controller_construct(zend_class_entry *ce, yaf_controller_t *self, yaf_request_t *request, yaf_response_t *response, yaf_view_t *view, zval *args TSRMLS_DC) {
+ zval *module;
+
+ if (args) {
+ zend_update_property(ce, self, ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_ARGS), args TSRMLS_CC);
+ }
+
+ module = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), 1 TSRMLS_CC);
+
+ zend_update_property(ce, self, ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_REQUEST), request TSRMLS_CC);
+ zend_update_property(ce, self, ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_RESPONSE), response TSRMLS_CC);
+ zend_update_property(ce, self, ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_MODULE), module TSRMLS_CC);
+ zend_update_property(ce, self, ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_VIEW), view TSRMLS_CC);
+
+ if (!instanceof_function(ce, yaf_action_ce TSRMLS_CC)
+ && zend_hash_exists(&(ce->function_table), ZEND_STRS("init"))) {
+ zend_call_method_with_0_params(&self, ce, NULL, "init", NULL);
+ }
+
+ return 1;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Controller_Abstract::init()
+*/
+PHP_METHOD(yaf_controller, init) {
+}
+
+/* }}} */
+
+/** {{{ proto protected Yaf_Controller_Abstract::__construct(Yaf_Request_Abstract $request, Yaf_Response_abstrct $response, Yaf_View_Interface $view, array $invokeArgs = NULL)
+*/
+PHP_METHOD(yaf_controller, __construct) {
+ yaf_request_t *request;
+ yaf_response_t *response;
+ yaf_view_t *view;
+ zval *invoke_arg = NULL;
+ yaf_controller_t *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ooo|z",
+ &request, yaf_request_ce, &response, yaf_response_ce, &view, yaf_view_interface_ce, &invoke_arg) == FAILURE) {
+ return;
+ } else {
+ if(!yaf_controller_construct(yaf_controller_ce, self, request, response, view, invoke_arg TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Controller_Abstract::getView(void)
+*/
+PHP_METHOD(yaf_controller, getView) {
+ yaf_view_t *view = zend_read_property(yaf_controller_ce, getThis(), ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_VIEW), 1 TSRMLS_CC);
+ RETURN_ZVAL(view, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Controller_Abstract::getRequest(void)
+*/
+PHP_METHOD(yaf_controller, getRequest) {
+ yaf_request_t *request = zend_read_property(yaf_controller_ce, getThis(), ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_REQUEST), 1 TSRMLS_CC);
+ RETURN_ZVAL(request, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Controller_Abstract::getResponse(void)
+*/
+PHP_METHOD(yaf_controller, getResponse) {
+ yaf_view_t *response = zend_read_property(yaf_controller_ce, getThis(), ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_RESPONSE), 1 TSRMLS_CC);
+ RETURN_ZVAL(response, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Controller_Abstract::initView(array $options = NULL)
+*/
+PHP_METHOD(yaf_controller, initView) {
+ RETURN_ZVAL(getThis(), 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Controller_Abstract::getInvokeArg(string $name)
+ */
+PHP_METHOD(yaf_controller, getInvokeArg) {
+ char *name;
+ uint len = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &len) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ if (len) {
+ zval **ppzval, *args;
+ args = zend_read_property(yaf_controller_ce, getThis(), ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_ARGS), 1 TSRMLS_CC);
+
+ if (ZVAL_IS_NULL(args)) {
+ RETURN_NULL();
+ }
+
+ if (zend_hash_find(Z_ARRVAL_P(args), name, len + 1, (void **)&ppzval) == SUCCESS) {
+ RETURN_ZVAL(*ppzval, 1, 0);
+ }
+ }
+ RETURN_NULL();
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Controller_Abstract::getInvokeArgs(void)
+ */
+PHP_METHOD(yaf_controller, getInvokeArgs) {
+ zval *args = zend_read_property(yaf_controller_ce, getThis(), ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_ARGS), 1 TSRMLS_CC);
+ RETURN_ZVAL(args, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Controller_Abstract::getModuleName(void)
+ */
+PHP_METHOD(yaf_controller, getModuleName) {
+ zval *module = zend_read_property(yaf_controller_ce, getThis(), ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_MODULE), 1 TSRMLS_CC);
+ RETURN_ZVAL(module, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Controller_Abstract::setViewpath(string $view_directory)
+*/
+PHP_METHOD(yaf_controller, setViewpath) {
+ zval *path;
+ yaf_view_t *view;
+ zend_class_entry *view_ce;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &path) == FAILURE) {
+ return;
+ }
+
+ if (Z_TYPE_P(path) != IS_STRING) {
+ RETURN_FALSE;
+ }
+
+ view = zend_read_property(yaf_controller_ce, getThis(), ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_VIEW), 1 TSRMLS_CC);
+ if ((view_ce = yaf_view_ce) == yaf_view_simple_ce) {
+ zend_update_property(view_ce, view, ZEND_STRL(YAF_VIEW_PROPERTY_NAME_TPLDIR), path TSRMLS_CC);
+ } else {
+ zend_call_method_with_1_params(&view, view_ce, NULL, "setscriptpath", NULL, path);
+ }
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Controller_Abstract::getViewpath(void)
+*/
+PHP_METHOD(yaf_controller, getViewpath) {
+ zend_class_entry *view_ce;
+ zval *view = zend_read_property(yaf_controller_ce, getThis(), ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_VIEW), 1 TSRMLS_CC);
+ if ((view_ce = yaf_view_ce) == yaf_view_simple_ce) {
+ zval *tpl_dir = zend_read_property(view_ce, view, ZEND_STRL(YAF_VIEW_PROPERTY_NAME_TPLDIR), 1 TSRMLS_CC);
+ RETURN_ZVAL(tpl_dir, 1, 0);
+ } else {
+ zval *ret;
+ zend_call_method_with_0_params(&view, view_ce, NULL, "getscriptpath", &ret);
+ RETURN_ZVAL(ret, 1, 1);
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Controller_Abstract::forward($module, $controller, $action, $args = NULL)
+*/
+PHP_METHOD(yaf_controller, forward) {
+ zval *controller, *module, *action, *args, *parameters;
+ yaf_request_t *request;
+ zend_class_entry *request_ce;
+
+ yaf_controller_t *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|zzz", &module, &controller, &action, &args) == FAILURE) {
+ return;
+ }
+
+ request = zend_read_property(yaf_controller_ce, self, ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_REQUEST), 1 TSRMLS_CC);
+ parameters = zend_read_property(yaf_controller_ce, self, ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_ARGS), 1 TSRMLS_CC);
+
+ if (ZVAL_IS_NULL(parameters)) {
+ MAKE_STD_ZVAL(parameters);
+ array_init(parameters);
+ }
+
+ if (Z_TYPE_P(request) != IS_OBJECT
+ || !instanceof_function((request_ce = Z_OBJCE_P(request)), yaf_request_ce TSRMLS_CC)) {
+ RETURN_FALSE
+ }
+
+ switch (ZEND_NUM_ARGS()) {
+ case 1:
+ if (Z_TYPE_P(module) != IS_STRING) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expect a string action name");
+ zval_dtor(parameters);
+ efree(parameters);
+ RETURN_FALSE;
+ }
+ zend_update_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), module TSRMLS_CC);
+ break;
+ case 2:
+ if (Z_TYPE_P(controller) == IS_STRING) {
+ zend_update_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), module TSRMLS_CC);
+ zend_update_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), controller TSRMLS_CC);
+ } else if (Z_TYPE_P(controller) == IS_ARRAY) {
+ zend_hash_copy(Z_ARRVAL_P(parameters), Z_ARRVAL_P(controller), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
+ zend_update_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), module TSRMLS_CC);
+ zend_update_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_PARAMS), parameters TSRMLS_CC);
+ } else {
+ zval_dtor(parameters);
+ efree(parameters);
+ RETURN_FALSE;
+ }
+ break;
+ case 3:
+ if (Z_TYPE_P(action) == IS_STRING) {
+ zend_update_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), module TSRMLS_CC);
+ zend_update_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), controller TSRMLS_CC);
+ zend_update_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), action TSRMLS_CC);
+ } else if (Z_TYPE_P(action) == IS_ARRAY) {
+ zend_hash_copy(Z_ARRVAL_P(parameters), Z_ARRVAL_P(action), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
+ zend_update_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), module TSRMLS_CC);
+ zend_update_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), controller TSRMLS_CC);
+ zend_update_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_PARAMS), parameters TSRMLS_CC);
+ } else {
+ zval_dtor(parameters);
+ efree(parameters);
+ RETURN_FALSE;
+ }
+ break;
+ case 4:
+ if (Z_TYPE_P(args) != IS_ARRAY) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameters must be an array");
+ zval_dtor(parameters);
+ efree(parameters);
+ RETURN_FALSE;
+ }
+ zend_hash_copy(Z_ARRVAL_P(parameters), Z_ARRVAL_P(args), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
+ zend_update_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), module TSRMLS_CC);
+ zend_update_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), controller TSRMLS_CC);
+ zend_update_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), action TSRMLS_CC);
+ zend_update_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_PARAMS), parameters TSRMLS_CC);
+ break;
+ }
+
+ (void)yaf_request_set_dispatched(request, 0 TSRMLS_CC);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Controller_Abstract::redirect(string $url)
+*/
+PHP_METHOD(yaf_controller, redirect) {
+ char *location;
+ uint location_len;
+ yaf_response_t *response;
+ yaf_controller_t *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &location, &location_len) == FAILURE) {
+ return;
+ }
+
+ response = zend_read_property(yaf_controller_ce, self, ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_RESPONSE), 1 TSRMLS_CC);
+
+ (void)yaf_response_set_redirect(response, location, location_len TSRMLS_CC);
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+/** {{{ proto protected Yaf_Controller_Abstract::render(string $action, array $var_array = NULL)
+*/
+PHP_METHOD(yaf_controller, render) {
+ char *action_name;
+ uint action_name_len;
+ zval *var_array = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &action_name, &action_name_len, &var_array) == FAILURE) {
+ return;
+ } else {
+ zval *output = yaf_controller_render(getThis(), action_name, action_name_len, var_array TSRMLS_CC);
+ if (output) {
+ RETURN_ZVAL(output, 1, 0);
+ } else {
+ RETURN_FALSE;
+ }
+ }
+}
+/* }}} */
+
+/** {{{ proto protected Yaf_Controller_Abstract::display(string $action, array $var_array = NULL)
+*/
+PHP_METHOD(yaf_controller, display) {
+ char *action_name;
+ uint action_name_len;
+ zval *var_array = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &action_name, &action_name_len, &var_array) == FAILURE) {
+ return;
+ } else {
+ RETURN_BOOL(yaf_controller_display(yaf_controller_ce, getThis(), action_name, action_name_len, var_array TSRMLS_CC));
+ }
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Controller_Abstract::__clone()
+*/
+PHP_METHOD(yaf_controller, __clone) {
+}
+/* }}} */
+
+/** {{{ yaf_controller_methods
+*/
+zend_function_entry yaf_controller_methods[] = {
+ PHP_ME(yaf_controller, render, yaf_controller_render_arginfo, ZEND_ACC_PROTECTED|ZEND_ACC_FINAL)
+ PHP_ME(yaf_controller, display, yaf_controller_display_arginfo, ZEND_ACC_PROTECTED|ZEND_ACC_FINAL)
+ PHP_ME(yaf_controller, getRequest, yaf_controller_void_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
+ PHP_ME(yaf_controller, getResponse, yaf_controller_void_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
+ PHP_ME(yaf_controller, getModuleName,yaf_controller_void_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
+ PHP_ME(yaf_controller, getView, yaf_controller_void_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
+ PHP_ME(yaf_controller, initView, yaf_controller_initview_arginfo,ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
+ PHP_ME(yaf_controller, setViewpath, yaf_controller_setvdir_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
+ PHP_ME(yaf_controller, getViewpath, yaf_controller_void_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
+ PHP_ME(yaf_controller, forward, yaf_controller_forward_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
+ PHP_ME(yaf_controller, redirect, yaf_controller_redirect_arginfo,ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
+ PHP_ME(yaf_controller, getInvokeArgs,yaf_controller_void_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
+ PHP_ME(yaf_controller, getInvokeArg, yaf_controller_getiarg_arginfo,ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
+ PHP_ME(yaf_controller, __construct, NULL, ZEND_ACC_CTOR|ZEND_ACC_FINAL|ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_controller, __clone, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(controller) {
+ zend_class_entry ce;
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Controller_Abstract", "Yaf\\Controller_Abstract", yaf_controller_methods);
+ yaf_controller_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+ yaf_controller_ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
+
+ zend_declare_property_null(yaf_controller_ce, YAF_STRL(YAF_CONTROLLER_PROPERTY_NAME_ACTIONS), ZEND_ACC_PUBLIC TSRMLS_CC);
+ zend_declare_property_null(yaf_controller_ce, YAF_STRL(YAF_CONTROLLER_PROPERTY_NAME_MODULE), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_controller_ce, YAF_STRL(YAF_CONTROLLER_PROPERTY_NAME_NAME), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_controller_ce, YAF_STRL(YAF_CONTROLLER_PROPERTY_NAME_REQUEST), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_controller_ce, YAF_STRL(YAF_CONTROLLER_PROPERTY_NAME_RESPONSE), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_controller_ce, YAF_STRL(YAF_CONTROLLER_PROPERTY_NAME_ARGS), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_controller_ce, YAF_STRL(YAF_CONTROLLER_PROPERTY_NAME_VIEW), ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_controller.h b/yaf_controller.h
new file mode 100644
index 0000000000..5b7a11fcab
--- /dev/null
+++ b/yaf_controller.h
@@ -0,0 +1,44 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef YAF_CONTROLLER_H
+#define YAF_CONTROLLER_H
+
+#define YAF_CONTROLLER_PROPERTY_NAME_MODULE "_module"
+#define YAF_CONTROLLER_PROPERTY_NAME_NAME "_name"
+#define YAF_CONTROLLER_PROPERTY_NAME_SCRIPT "_script_path"
+#define YAF_CONTROLLER_PROPERTY_NAME_RESPONSE "_response"
+#define YAF_CONTROLLER_PROPERTY_NAME_REQUEST "_request"
+#define YAF_CONTROLLER_PROPERTY_NAME_ARGS "_invoke_args"
+#define YAF_CONTROLLER_PROPERTY_NAME_ACTIONS "actions"
+#define YAF_CONTROLLER_PROPERTY_NAME_VIEW "_view"
+
+extern zend_class_entry *yaf_controller_ce;
+int yaf_controller_construct(zend_class_entry *ce, yaf_controller_t *self,
+ yaf_request_t *request, yaf_response_t *response, yaf_view_t *view, zval *args TSRMLS_DC);
+YAF_STARTUP_FUNCTION(controller);
+#endif
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
+
diff --git a/yaf_dispatcher.c b/yaf_dispatcher.c
new file mode 100644
index 0000000000..80484749e4
--- /dev/null
+++ b/yaf_dispatcher.c
@@ -0,0 +1,1359 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "main/SAPI.h"
+#include "Zend/zend_API.h"
+#include "Zend/zend_interfaces.h"
+
+#include "php_yaf.h"
+#include "yaf_namespace.h"
+#include "yaf_dispatcher.h"
+#include "yaf_controller.h"
+#include "yaf_action.h"
+#include "yaf_application.h"
+#include "yaf_view.h"
+#include "yaf_response.h"
+#include "yaf_loader.h"
+#include "yaf_router.h"
+#include "yaf_request.h"
+#include "yaf_config.h"
+#include "yaf_plugin.h"
+#include "yaf_exception.h"
+
+zend_class_entry * yaf_dispatcher_ce;
+
+/** {{{ ARG_INFO
+ */
+ZEND_BEGIN_ARG_INFO_EX(yaf_dispatcher_void_arginfo, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_dispatcher_dispatch_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, request)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_dispatcher_seterrhdler_arginfo, 0, 0, 2)
+ ZEND_ARG_INFO(0, callback)
+ ZEND_ARG_INFO(0, error_types)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_dispatcher_flush_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, flag)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_dispatcher_regplugin_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, plugin)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_dispatcher_setrequest_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, plugin)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_dispatcher_throwex_arginfo, 0, 0, 0)
+ ZEND_ARG_INFO(0, flag)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_dispatcher_catchex_arginfo, 0, 0, 0)
+ ZEND_ARG_INFO(0, flag)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_dispatcher_autorender_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, flag)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_dispatcher_returnresp_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, flag)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_dispatcher_initview_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, templates_dir)
+ ZEND_ARG_ARRAY_INFO(0, options, 1)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_dispatcher_setview_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, view)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_dispatcher_setappdir_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, directory)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_dispatcher_setctrl_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, controller)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_dispatcher_setmodule_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, module)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_dispatcher_setaction_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, action)
+ZEND_END_ARG_INFO()
+
+/* }}} */
+
+/** {{{ yaf_dispatcher_t * yaf_dispatcher_instance(zval *this_ptr TSRMLS_DC)
+*/
+yaf_dispatcher_t * yaf_dispatcher_instance(yaf_dispatcher_t *this_ptr TSRMLS_DC) {
+ zval *plugins;
+ yaf_router_t *router;
+ yaf_dispatcher_t *instance;
+
+ instance = zend_read_static_property(yaf_dispatcher_ce, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_INSTANCE), 1 TSRMLS_CC);
+
+ if (IS_OBJECT == Z_TYPE_P(instance)
+ && instanceof_function(Z_OBJCE_P(instance), yaf_dispatcher_ce TSRMLS_CC)) {
+ Z_ADDREF_P(instance);
+ return instance;
+ }
+
+ if (this_ptr) {
+ instance = this_ptr;
+ return this_ptr;
+ } else {
+ instance = NULL;
+ MAKE_STD_ZVAL(instance);
+ object_init_ex(instance, yaf_dispatcher_ce);
+ }
+
+ /** unecessary yet
+ MAKE_STD_ZVAL(args);
+ array_init(args);
+ yaf_update_property(instance, YAF_DISPATCHER_PROPERTY_NAME_ARGS, args);
+ */
+
+ MAKE_STD_ZVAL(plugins);
+ array_init(plugins);
+ zend_update_property(yaf_dispatcher_ce, instance, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_PLUGINS), plugins TSRMLS_CC);
+ zval_ptr_dtor(&plugins);
+
+ router = yaf_router_instance(NULL TSRMLS_CC);
+
+ zend_update_property(yaf_dispatcher_ce, instance, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_ROUTER), router TSRMLS_CC);
+ zend_update_property_string(yaf_dispatcher_ce, instance, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_MODULE), YAF_G(default_module) TSRMLS_CC);
+ zend_update_property_string(yaf_dispatcher_ce, instance, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_CONTROLLER), YAF_G(default_controller) TSRMLS_CC);
+ zend_update_property_string(yaf_dispatcher_ce, instance, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_ACTION), YAF_G(default_action) TSRMLS_CC);
+ zend_update_static_property(yaf_dispatcher_ce, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_INSTANCE), instance TSRMLS_CC);
+
+ zval_ptr_dtor(&router);
+
+ return instance;
+}
+/* }}} */
+
+/** {{{ static void yaf_dispatcher_get_call_parmaters(zend_class_entry *request_ce, yaf_request_t *request, zend_function *fptr, zval ****params, uint *count TSRMLS_DC)
+ */
+static void yaf_dispatcher_get_call_parmaters(zend_class_entry *request_ce, yaf_request_t *request, zend_function *fptr, zval ****params, uint *count TSRMLS_DC) {
+ zval *args, **arg;
+ zend_arg_info *arg_info;
+ uint current;
+ HashTable *params_ht;
+
+ args = zend_read_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_PARAMS), 1 TSRMLS_CC);
+
+ params_ht = Z_ARRVAL_P(args);
+
+ arg_info = fptr->common.arg_info;
+ *params = safe_emalloc(sizeof(zval **), fptr->common.num_args, 0);
+ for (current = 0;current < fptr->common.num_args; current++, arg_info++) {
+ if (zend_hash_find(params_ht, arg_info->name, arg_info->name_len + 1, (void **)&arg) == SUCCESS) {
+ (*params)[current] = arg;
+ (*count)++;
+ } else {
+ char *key;
+ uint keylen;
+ long idx, llen;
+
+ arg = NULL;
+ llen = arg_info->name_len + 1;
+ /* since we need search ignoring case, can't use zend_hash_find */
+ for(zend_hash_internal_pointer_reset(params_ht);
+ zend_hash_has_more_elements(params_ht) == SUCCESS;
+ zend_hash_move_forward(params_ht)) {
+
+ if (zend_hash_get_current_key_ex(params_ht, &key, &keylen, &idx, 0, NULL) == HASH_KEY_IS_STRING) {
+ if (keylen == llen && !strncasecmp(key, arg_info->name, keylen)) {
+ if (zend_hash_get_current_data(params_ht, (void**)&arg) == SUCCESS) {
+ /* return when we find first match, there is a trap
+ * when multi different parameters in different case presenting in params_ht
+ * only the first take affect
+ */
+ (*params)[current] = arg;
+ (*count)++;
+ break;
+ }
+ }
+ }
+ }
+
+ if (NULL == arg) {
+ break;
+ }
+ }
+ }
+}
+/* }}} */
+
+/** {{{ static yaf_view_t * yaf_dispatcher_init_view(yaf_dispatcher_t *dispatcher, zval *tpl_dir, zval *options TSRMLS_DC)
+*/
+ yaf_view_t * yaf_dispatcher_init_view(yaf_dispatcher_t *dispatcher, zval *tpl_dir, zval *options TSRMLS_DC) {
+ yaf_view_t *view = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_VIEW), 1 TSRMLS_CC);
+ if (view && IS_OBJECT == Z_TYPE_P(view)
+ && instanceof_function(Z_OBJCE_P(view), yaf_view_interface_ce TSRMLS_CC)) {
+ return view;
+ }
+
+ view = yaf_view_instance(NULL, tpl_dir, options TSRMLS_CC);
+ zend_update_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_VIEW), view TSRMLS_CC);
+
+ return view;
+}
+/* }}} */
+
+/** {{{ static inline void yaf_dispatcher_fix_default(yaf_dispatcher_t *dispatcher, yaf_request_t *request TSRMLS_DC)
+*/
+static inline void yaf_dispatcher_fix_default(yaf_dispatcher_t *dispatcher, yaf_request_t *request TSRMLS_DC) {
+ zval *module, *controller, *action;
+
+ module = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), 1 TSRMLS_CC);
+ action = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), 1 TSRMLS_CC);
+ controller = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), 1 TSRMLS_CC);
+
+ if (!module || Z_TYPE_P(module) != IS_STRING || !Z_STRLEN_P(module)) {
+ zval *default_module = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_MODULE), 1 TSRMLS_CC);
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), default_module TSRMLS_CC);
+ } else {
+ ZVAL_STRINGL(module, zend_str_tolower_dup(Z_STRVAL_P(module), Z_STRLEN_P(module)), Z_STRLEN_P(module), 0);
+ *(Z_STRVAL_P(module)) = toupper(*(Z_STRVAL_P(module)));
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), module TSRMLS_CC);
+ }
+
+ if (!controller || Z_TYPE_P(controller) != IS_STRING || !Z_STRLEN_P(controller)) {
+ zval *default_controller = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_CONTROLLER), 1 TSRMLS_CC);
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), default_controller TSRMLS_CC);
+ } else {
+ char *p;
+ ZVAL_STRINGL(controller, zend_str_tolower_dup(Z_STRVAL_P(controller), Z_STRLEN_P(controller)), Z_STRLEN_P(controller), 0);
+ p = Z_STRVAL_P(controller);
+
+ /**
+ * upper contolerr name
+ * eg: Index_sub -> Index_Sub
+ */
+ *p = toupper(*p);
+ while (*p != '\0') {
+ if (*p == '_'
+#ifdef YAF_HAVE_NAMESPACE
+ || *p == '\\'
+#endif
+ ) {
+ if (*(p+1) != '\0') {
+ *(p+1) = toupper(*(p+1));
+ p++;
+ }
+ }
+ p++;
+ }
+
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), controller TSRMLS_CC);
+ }
+
+
+ if (!action || Z_TYPE_P(action) != IS_STRING || !Z_STRLEN_P(action)) {
+ zval *default_action = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_ACTION), 1 TSRMLS_CC);
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), default_action TSRMLS_CC);
+ } else {
+ ZVAL_STRINGL(action, zend_str_tolower_dup(Z_STRVAL_P(action), Z_STRLEN_P(action)), Z_STRLEN_P(action), 0);
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), action TSRMLS_CC);
+ }
+}
+/* }}} */
+
+/** {{{int yaf_dispatcher_set_request(yaf_dispatcher_t *dispatcher, yaf_request_t *request TSRMLS_DC)
+*/
+int yaf_dispatcher_set_request(yaf_dispatcher_t *dispatcher, yaf_request_t *request TSRMLS_DC) {
+ if (request) {
+ zend_update_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_REQUEST), request TSRMLS_CC);
+ return 1;
+ }
+ return 0;
+}
+/* }}} */
+
+/** {{{ zend_class_entry * yaf_dispatcher_get_controller(char *app_dir, char *module, char *controller, int len, int def_module TSRMLS_DC)
+ */
+zend_class_entry * yaf_dispatcher_get_controller(char *app_dir, char *module, char *controller, int len, int def_module TSRMLS_DC) {
+ char *directory = NULL;
+ int directory_len = 0;
+
+ if (def_module) {
+ directory_len = spprintf(&directory, 0, "%s%c%s", app_dir, DEFAULT_SLASH, "controllers");
+ } else {
+ directory_len = spprintf(&directory, 0, "%s%c%s%c%s%c%s", app_dir, DEFAULT_SLASH,
+ "modules", DEFAULT_SLASH, module, DEFAULT_SLASH, "controllers");
+ }
+
+ if (directory_len) {
+ char *class = NULL;
+ char *class_lowercase = NULL;
+ int class_len = 0;
+ zend_class_entry **ce = NULL;
+
+ if (YAF_G(name_suffix)) {
+ class_len = spprintf(&class, 0, "%s%s%s", controller, YAF_G(name_separator), "Controller");
+ } else {
+ class_len = spprintf(&class, 0, "%s%s%s", "Controller", YAF_G(name_separator), controller);
+ }
+
+ class_lowercase = zend_str_tolower_dup(class, class_len);
+
+ if (zend_hash_find(EG(class_table), class_lowercase, class_len + 1, (void *)&ce) != SUCCESS) {
+
+ if (!yaf_internal_autoload(controller, len, &directory TSRMLS_CC)) {
+ yaf_trigger_error(YAF_ERR_NOTFOUND_CONTROLLER TSRMLS_CC, "Could not find controller script %s", directory);
+ efree(class);
+ efree(class_lowercase);
+ efree(directory);
+ return NULL;
+ } else if (zend_hash_find(EG(class_table), class_lowercase, class_len + 1, (void **) &ce) != SUCCESS) {
+ yaf_trigger_error(YAF_ERR_AUTOLOAD_FAILED TSRMLS_CC, "Could not find class %s in controller script %s", class, directory);
+ efree(class);
+ efree(class_lowercase);
+ efree(directory);
+ return 0;
+ } else if (!instanceof_function(*ce, yaf_controller_ce TSRMLS_CC)) {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "Controller must be an instance of %s", yaf_controller_ce->name);
+ efree(class);
+ efree(class_lowercase);
+ efree(directory);
+ return 0;
+ }
+ }
+
+ efree(class);
+ efree(class_lowercase);
+ efree(directory);
+
+ return *ce;
+ }
+
+ return NULL;
+}
+/* }}} */
+
+/** {{{ zend_class_entry * yaf_dispatcher_get_action(char *app_dir, yaf_controller_t *controller, char *module, int def_module, char *action, int len TSRMLS_DC)
+ */
+zend_class_entry * yaf_dispatcher_get_action(char *app_dir, yaf_controller_t *controller, char *module, int def_module, char *action, int len TSRMLS_DC) {
+ zval **ppaction, *actions_map;
+
+ actions_map = zend_read_property(Z_OBJCE_P(controller), controller, ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_ACTIONS), 1 TSRMLS_CC);
+ if (IS_ARRAY == Z_TYPE_P(actions_map)) {
+ if (zend_hash_find(Z_ARRVAL_P(actions_map), action, len + 1, (void **)&ppaction) == SUCCESS) {
+ char *action_path;
+ uint action_path_len;
+
+ action_path_len = spprintf(&action_path, 0, "%s%c%s", app_dir, DEFAULT_SLASH, Z_STRVAL_PP(ppaction));
+ if (yaf_loader_import(action_path, action_path_len, 0 TSRMLS_CC)) {
+ zend_class_entry **ce;
+ char *class, *class_lowercase;
+ uint class_len;
+ char *action_upper = estrndup(action, len);
+
+ *(action_upper) = toupper(*action_upper);
+
+ if (YAF_G(name_suffix)) {
+ class_len = spprintf(&class, 0, "%s%s%s", action_upper, YAF_G(name_separator), "Action");
+ } else {
+ class_len = spprintf(&class, 0, "%s%s%s", "Action", YAF_G(name_separator), action_upper);
+ }
+
+ class_lowercase = zend_str_tolower_dup(class, class_len);
+
+ if (zend_hash_find(EG(class_table), class_lowercase, class_len + 1, (void **) &ce) == SUCCESS) {
+ efree(action_path);
+ efree(action_upper);
+ efree(class_lowercase);
+
+ if (instanceof_function(*ce, yaf_action_ce TSRMLS_CC)) {
+ efree(class);
+ return *ce;
+ } else {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "Action %s must extends from %s", class, yaf_action_ce->name);
+ efree(class);
+ }
+
+ } else {
+ yaf_trigger_error(YAF_ERR_NOTFOUND_ACTION TSRMLS_CC, "Could not find action %s in %s", class, action_path);
+ }
+
+ efree(action_path);
+ efree(action_upper);
+ efree(class);
+ efree(class_lowercase);
+
+ } else {
+ yaf_trigger_error(YAF_ERR_NOTFOUND_ACTION TSRMLS_CC, "Could not find action script %s", action_path);
+ efree(action_path);
+ }
+ } else {
+ yaf_trigger_error(YAF_ERR_NOTFOUND_ACTION TSRMLS_CC, "There is no method %s%s in %s::$%s",
+ action, "Action", Z_OBJCE_P(controller)->name, YAF_CONTROLLER_PROPERTY_NAME_ACTIONS);
+ }
+ } else
+/* {{{ This only effects internally */
+ if (YAF_G(st_compatible)) {
+ char *directory, *class, *class_lowercase, *p;
+ uint directory_len, class_len;
+ zend_class_entry **ce;
+ char *action_upper = estrndup(action, len);
+
+ /**
+ * upper Action Name
+ * eg: Index_sub -> Index_Sub
+ */
+ p = action_upper;
+ *(p) = toupper(*p);
+ while (*p != '\0') {
+ if (*p == '_'
+#ifdef YAF_HAVE_NAMESPACE
+ || *p == '\\'
+#endif
+ ) {
+ if (*(p+1) != '\0') {
+ *(p+1) = toupper(*(p+1));
+ p++;
+ }
+ }
+ p++;
+ }
+
+ if (def_module) {
+ directory_len = spprintf(&directory, 0, "%s%c%s", app_dir, DEFAULT_SLASH, "actions");
+ } else {
+ directory_len = spprintf(&directory, 0, "%s%c%s%c%s%c%s", app_dir, DEFAULT_SLASH,
+ "modules", DEFAULT_SLASH, module, DEFAULT_SLASH, "actions");
+ }
+
+ if (YAF_G(name_suffix)) {
+ class_len = spprintf(&class, 0, "%s%s%s", action_upper, YAF_G(name_separator), "Action");
+ } else {
+ class_len = spprintf(&class, 0, "%s%s%s", "Action", YAF_G(name_separator), action_upper);
+ }
+
+ class_lowercase = zend_str_tolower_dup(class, class_len);
+
+ if (zend_hash_find(EG(class_table), class_lowercase, class_len + 1, (void *)&ce) != SUCCESS) {
+ if (!yaf_internal_autoload(action_upper, len, &directory TSRMLS_CC)) {
+ yaf_trigger_error(YAF_ERR_NOTFOUND_ACTION TSRMLS_CC, "Could not find action script %s", directory);
+
+ efree(class);
+ efree(action_upper);
+ efree(class_lowercase);
+ efree(directory);
+ return NULL;
+ } else if (zend_hash_find(EG(class_table), class_lowercase, class_len + 1, (void **) &ce) != SUCCESS) {
+ yaf_trigger_error(YAF_ERR_AUTOLOAD_FAILED TSRMLS_CC, "Could find class %s in action script %s", class, directory);
+
+ efree(class);
+ efree(action_upper);
+ efree(class_lowercase);
+ efree(directory);
+ return NULL;
+ } else if (!instanceof_function(*ce, yaf_action_ce TSRMLS_CC)) {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "Action must be an instance of %s", yaf_action_ce->name);
+
+ efree(class);
+ efree(action_upper);
+ efree(class_lowercase);
+ efree(directory);
+ return NULL;
+ }
+ }
+
+ efree(class);
+ efree(action_upper);
+ efree(class_lowercase);
+ efree(directory);
+
+ return *ce;
+ } else
+/* }}} */
+ {
+ yaf_trigger_error(YAF_ERR_NOTFOUND_ACTION TSRMLS_CC, "There is no method %s%s in %s", action, "Action", Z_OBJCE_P(controller)->name);
+ }
+
+ return NULL;
+}
+/* }}} */
+
+/** {{{ int yaf_dispatcher_handle(yaf_dispatcher_t *dispatcher, yaf_request_t *request, yaf_response_t *response, yaf_view_t *view TSRMLS_DC)
+*/
+int yaf_dispatcher_handle(yaf_dispatcher_t *dispatcher, yaf_request_t *request, yaf_response_t *response, yaf_view_t *view TSRMLS_DC) {
+ zend_class_entry *request_ce;
+ char *app_dir = YAF_G(directory);
+
+ request_ce = Z_OBJCE_P(request);
+
+ yaf_request_set_dispatched(request, 1 TSRMLS_CC);
+ if (!app_dir) {
+ yaf_trigger_error(YAF_ERR_STARTUP_FAILED TSRMLS_CC, "%s requires %s(which set the application.directory) to be initialized first",
+ yaf_dispatcher_ce->name, yaf_application_ce->name);
+ return 0;
+ } else {
+ int is_def_module = 0;
+ int is_def_ctr = 0;
+ zval *module, *controller, *dmodule, *dcontroller, *return_response, *instantly_flush;
+ zend_class_entry *ce;
+ yaf_controller_t *executor;
+ zend_function *fptr;
+
+ module = zend_read_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), 1 TSRMLS_CC);
+ controller = zend_read_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), 1 TSRMLS_CC);
+
+ dmodule = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_MODULE), 1 TSRMLS_CC);
+ dcontroller = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_CONTROLLER), 1 TSRMLS_CC);
+
+ if (Z_TYPE_P(module) != IS_STRING
+ || !Z_STRLEN_P(module)) {
+ yaf_trigger_error(YAF_ERR_DISPATCH_FAILED TSRMLS_CC, "Unexcepted a empty module name");
+ return 0;
+ } else if (!yaf_application_is_module_name(Z_STRVAL_P(module), Z_STRLEN_P(module) TSRMLS_CC)) {
+ yaf_trigger_error(YAF_ERR_NOTFOUND_MODULE TSRMLS_CC, "There is no module %s", Z_STRVAL_P(module));
+ return 0;
+ }
+
+ if (Z_TYPE_P(controller) != IS_STRING
+ || !Z_STRLEN_P(controller)) {
+ yaf_trigger_error(YAF_ERR_DISPATCH_FAILED TSRMLS_CC, "Unexcepted a empty controller name");
+ return 0;
+ }
+
+ if(strncasecmp(Z_STRVAL_P(dmodule), Z_STRVAL_P(module), Z_STRLEN_P(module)) == 0) {
+ is_def_module = 1;
+ }
+
+ if (strncasecmp(Z_STRVAL_P(dcontroller), Z_STRVAL_P(controller), Z_STRLEN_P(controller)) == 0) {
+ is_def_ctr = 1;
+ }
+
+ ce = yaf_dispatcher_get_controller(app_dir, Z_STRVAL_P(module), Z_STRVAL_P(controller), Z_STRLEN_P(controller), is_def_module TSRMLS_CC);
+ if (!ce) {
+ return 0;
+ } else {
+ zval *action, *view_dir, *render, *ret = NULL;
+ char *action_lower, *func_name;
+ uint func_name_len;
+ zend_class_entry *view_ce;
+
+ yaf_controller_t *icontroller;
+
+ MAKE_STD_ZVAL(icontroller);
+ object_init_ex(icontroller, ce);
+
+ /* cause controller's constructor is a final method, so it must be a internal function
+ do {
+ zend_function *constructor = NULL;
+ constructor = Z_OBJ_HT_P(exec_ctr)->get_constructor(exec_ctr TSRMLS_CC);
+ if (constructor != NULL) {
+ if (zend_call_method_with_2_params(&exec_ctr, *ce
+ , &constructor, NULL, &ret, request, response) == NULL) {
+ yaf_trigger_error(YAF_ERR_CALL_FAILED, "function call for %s::__construct failed", (*ce)->name);
+ return 0;
+ }
+ }
+ } while(0);
+ */
+ yaf_controller_construct(ce, icontroller, request, response, view, NULL TSRMLS_CC);
+
+ MAKE_STD_ZVAL(view_dir);
+ Z_TYPE_P(view_dir) = IS_STRING;
+
+ if (is_def_module) {
+ Z_STRLEN_P(view_dir) = spprintf(&(Z_STRVAL_P(view_dir)), 0, "%s/%s", app_dir ,"views");
+ } else {
+ Z_STRLEN_P(view_dir) = spprintf(&(Z_STRVAL_P(view_dir)), 0, "%s/%s/%s/%s", app_dir,
+ "modules", Z_STRVAL_P(module), "views");
+ }
+
+ /** tell the view engine where to find templates */
+ if ((view_ce = Z_OBJCE_P(view)) == yaf_view_simple_ce) {
+ zend_update_property(view_ce, view, ZEND_STRL(YAF_VIEW_PROPERTY_NAME_TPLDIR), view_dir TSRMLS_CC);
+ } else {
+ zend_call_method_with_1_params(&view, view_ce, NULL, "setscriptpath", NULL, view_dir);
+ }
+
+ zval_ptr_dtor(&view_dir);
+
+ zend_update_property(ce, icontroller, ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_NAME), controller TSRMLS_CC);
+
+ action = zend_read_property(request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), 1 TSRMLS_CC);
+ action_lower = zend_str_tolower_dup(Z_STRVAL_P(action), Z_STRLEN_P(action));
+
+ /* cause the action might call the forward to override the old action */
+ Z_ADDREF_P(action);
+
+ func_name_len = spprintf(&func_name, 0, "%s%s", action_lower, "action");
+ efree(action_lower);
+
+ if (zend_hash_find(&((ce)->function_table), func_name, func_name_len + 1, (void **)&fptr) == SUCCESS) {
+ uint count = 0;
+ zval ***call_args = NULL;
+
+ ret = NULL;
+
+ executor = icontroller;
+ if (fptr->common.num_args) {
+ zval *method_name;
+
+ yaf_dispatcher_get_call_parmaters(request_ce, request, fptr, &call_args, &count TSRMLS_CC);
+ MAKE_STD_ZVAL(method_name);
+ ZVAL_STRINGL(method_name, func_name, func_name_len, 0);
+
+ call_user_function_ex(&(ce)->function_table, &icontroller, method_name, &ret, count, call_args, 1, NULL TSRMLS_CC);
+
+ efree(method_name);
+ efree(call_args);
+ } else {
+ zend_call_method(&icontroller, ce, NULL, func_name, func_name_len, &ret, 0, NULL, NULL TSRMLS_CC);
+ }
+
+ efree(func_name);
+
+ if (!ret) {
+ Z_DELREF_P(action);
+ zval_dtor(icontroller);
+ efree(icontroller);
+ return 0;
+ }
+
+ if ((Z_TYPE_P(ret) == IS_BOOL
+ && !Z_BVAL_P(ret))) {
+ zval_ptr_dtor(&ret);
+ Z_DELREF_P(action);
+ zval_dtor(icontroller);
+ efree(icontroller);
+ return 0;
+ }
+ } else if ((ce = yaf_dispatcher_get_action(app_dir, icontroller,
+ Z_STRVAL_P(module), is_def_module, Z_STRVAL_P(action), Z_STRLEN_P(action) TSRMLS_CC))
+ && (zend_hash_find(&(ce)->function_table, YAF_ACTION_EXECUTOR_NAME,
+ sizeof(YAF_ACTION_EXECUTOR_NAME), (void **)&fptr) == SUCCESS)) {
+ zval ***call_args;
+ yaf_action_t *iaction;
+ uint count = 0;
+
+ MAKE_STD_ZVAL(iaction);
+ object_init_ex(iaction, ce);
+
+ yaf_controller_construct(ce, iaction, request, response, view, NULL TSRMLS_CC);
+ executor = iaction;
+
+ zend_update_property(ce, iaction, ZEND_STRL(YAF_CONTROLLER_PROPERTY_NAME_NAME), controller TSRMLS_CC);
+ zend_update_property(ce, iaction, ZEND_STRL(YAF_ACTION_PROPERTY_NAME_CTRL), icontroller TSRMLS_CC);
+
+ if (fptr->common.num_args) {
+ zval *method_name = NULL;
+
+ yaf_dispatcher_get_call_parmaters(request_ce, request, fptr, &call_args, &count TSRMLS_CC);
+ MAKE_STD_ZVAL(method_name);
+ ZVAL_STRINGL(method_name, YAF_ACTION_EXECUTOR_NAME, sizeof(YAF_ACTION_EXECUTOR_NAME) - 1, 0);
+
+ call_user_function_ex(&(ce)->function_table, &iaction, method_name, &ret, count, call_args, 1, NULL TSRMLS_CC);
+
+ efree(method_name);
+ efree(call_args);
+ } else {
+ zend_call_method_with_0_params(&iaction, ce, NULL, "execute", &ret);
+ }
+
+ if (!ret) {
+ Z_DELREF_P(action);
+ zval_dtor(iaction);
+ efree(iaction);
+ zval_dtor(icontroller);
+ efree(icontroller);
+ return 0;
+ }
+
+ if (( Z_TYPE_P(ret) == IS_BOOL
+ && !Z_BVAL_P(ret))) {
+ zval_ptr_dtor(&ret);
+ Z_DELREF_P(action);
+ zval_dtor(iaction);
+ efree(iaction);
+ zval_dtor(icontroller);
+ efree(icontroller);
+ return 0;
+ }
+ } else {
+ Z_DELREF_P(action);
+ zval_dtor(icontroller);
+ efree(icontroller);
+ return 0;
+ }
+
+ render = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_RENDER), 1 TSRMLS_CC);
+ return_response = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_RETURN), 1 TSRMLS_CC);
+ instantly_flush = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_FLUSH), 1 TSRMLS_CC);
+
+ if (executor && Z_BVAL_P(render)) {
+ ret = NULL;
+ if (!Z_BVAL_P(instantly_flush)) {
+ zend_call_method_with_1_params(&executor, ce, NULL, "render", &ret, action);
+ zval_dtor(executor);
+ efree(executor);
+
+ if (ret && Z_TYPE_P(ret) == IS_STRING && Z_STRLEN_P(ret)) {
+ yaf_response_alter_body(response, NULL, 0, Z_STRVAL_P(ret), Z_STRLEN_P(ret), 0 TSRMLS_CC);
+ zval_ptr_dtor(&ret);
+ } else if (ret) {
+ zval_ptr_dtor(&ret);
+ Z_DELREF_P(action);
+ return 0;
+ }
+ } else {
+ zend_call_method_with_1_params(&executor, ce, NULL, "display", &ret, action);
+ zval_dtor(executor);
+ efree(executor);
+
+ if (!ret) {
+ Z_DELREF_P(action);
+ return 0;
+ }
+
+ if ((Z_TYPE_P(ret) == IS_BOOL && !Z_BVAL_P(ret))) {
+ zval_ptr_dtor(&ret);
+ Z_DELREF_P(action);
+ return 0;
+ }
+ }
+
+ }
+ Z_DELREF_P(action);
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+/* }}} */
+
+/** {{{ void yaf_dispatcher_exception_handler(yaf_dispatcher_t *dispatcher, yaf_request_t *request, yaf_response_t *response TSRMLS_DC)
+*/
+void yaf_dispatcher_exception_handler(yaf_dispatcher_t *dispatcher, yaf_request_t *request, yaf_response_t *response TSRMLS_DC) {
+ zval *module, *controller, *action, *exception;
+ yaf_view_t *view;
+
+ if (YAF_G(in_exception) || !EG(exception)) {
+ return;
+ }
+
+ YAF_G(in_exception) = 1;
+
+ MAKE_STD_ZVAL(controller);
+ MAKE_STD_ZVAL(action);
+
+ module = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), 1 TSRMLS_CC);
+
+ if (!module || Z_TYPE_P(module) != IS_STRING || !Z_STRLEN_P(module)) {
+ module = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_MODULE), 1 TSRMLS_CC);
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), module TSRMLS_CC);
+ }
+
+ ZVAL_STRING(controller, YAF_ERROR_CONTROLLER, 1);
+ ZVAL_STRING(action, YAF_ERROR_ACTION, 1);
+
+ exception = EG(exception);
+ EG(exception) = NULL;
+
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), controller TSRMLS_CC);
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), action TSRMLS_CC);
+ zend_update_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_EXCEPTION), exception TSRMLS_CC);
+
+ Z_DELREF_P(controller);
+ Z_DELREF_P(action);
+
+ /** use $request->getException() instand of */
+ yaf_request_set_params_single(request, YAF_STRL("exception"), exception TSRMLS_CC);
+ yaf_request_set_dispatched(request, 0 TSRMLS_CC);
+
+ view = yaf_dispatcher_init_view(dispatcher, NULL, NULL TSRMLS_CC);
+
+ if (!yaf_dispatcher_handle(dispatcher, request, response, view TSRMLS_CC)) {
+ return;
+ }
+
+ (void)yaf_response_send(response TSRMLS_CC);
+
+ YAF_EXCEPTION_ERASE_EXCEPTION();
+}
+/* }}} */
+
+/** {{{ int yaf_dispatcher_route(yaf_dispatcher_t *dispatcher, yaf_request_t *request TSRMLS_DC)
+ */
+int yaf_dispatcher_route(yaf_dispatcher_t *dispatcher, yaf_request_t *request TSRMLS_DC) {
+ zend_class_entry *router_ce;
+ yaf_router_t *router = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_ROUTER), 1 TSRMLS_CC);
+ if (IS_OBJECT == Z_TYPE_P(router)) {
+ if ((router_ce = Z_OBJCE_P(router)) == yaf_router_ce) {
+ /* use buildin router */
+ if (!yaf_router_route(router, request TSRMLS_CC)) {
+ return 0;
+ }
+ } else {
+ /* user custom router */
+ zval *ret = zend_call_method_with_1_params(&router, router_ce, NULL, "route", &ret, request);
+ if (Z_TYPE_P(ret) == IS_BOOL && Z_BVAL_P(ret) == 0) {
+ yaf_trigger_error(YAF_ERR_ROUTE_FAILED TSRMLS_CC, "Routing request faild");
+ return 0;
+ }
+ }
+ return 1;
+ }
+ return 0;
+}
+/* }}} */
+
+/** {{{ yaf_response_t * yaf_dispatcher_dispatch(yaf_dispatcher_t *dispatcher TSRMLS_DC)
+*/
+yaf_response_t * yaf_dispatcher_dispatch(yaf_dispatcher_t *dispatcher TSRMLS_DC) {
+ zval *return_response, *plugins, *view;
+ uint nesting = YAF_G(forward_limit);
+
+ yaf_response_t *response;
+ yaf_request_t *request;
+
+ response = yaf_response_instance(NULL, sapi_module.name TSRMLS_CC);
+ request = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_REQUEST), 1 TSRMLS_CC);
+ plugins = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_PLUGINS), 1 TSRMLS_CC);
+
+ if (!request || IS_OBJECT != Z_TYPE_P(request)) {
+ yaf_trigger_error(YAF_ERR_TYPE_ERROR TSRMLS_CC, "Expect a %s instance", yaf_request_ce->name);
+ return NULL;
+ }
+
+ /* route request */
+ if (!yaf_request_is_routed(request TSRMLS_CC)) {
+ YAF_PLUGIN_HANDLE(plugins, YAF_PLUGIN_HOOK_ROUTESTARTUP, request, response);
+ YAF_EXCEPTION_HANDLE(dispatcher, request, response);
+ if (!yaf_dispatcher_route(dispatcher, request TSRMLS_CC)) {
+ yaf_trigger_error(YAF_ERR_ROUTE_FAILED TSRMLS_CC, "Routing request failed");
+ YAF_EXCEPTION_HANDLE_NORET(dispatcher, request, response);
+ return NULL;
+ }
+ YAF_PLUGIN_HANDLE(plugins, YAF_PLUGIN_HOOK_ROUTESHUTDOWN, request, response);
+ YAF_EXCEPTION_HANDLE(dispatcher, request, response);
+ (void)yaf_request_set_routed(request, 1 TSRMLS_CC);
+ }
+
+ yaf_dispatcher_fix_default(dispatcher, request TSRMLS_CC);
+
+ YAF_PLUGIN_HANDLE(plugins, YAF_PLUGIN_HOOK_LOOPSTARTUP, request, response);
+ YAF_EXCEPTION_HANDLE(dispatcher, request, response);
+
+ view = yaf_dispatcher_init_view(dispatcher, NULL, NULL TSRMLS_CC);
+
+ do {
+ YAF_PLUGIN_HANDLE(plugins, YAF_PLUGIN_HOOK_PREDISPATCH, request, response);
+ if (!yaf_dispatcher_handle(dispatcher, request, response, view TSRMLS_CC)) {
+ YAF_EXCEPTION_HANDLE(dispatcher, request, response);
+ return NULL;
+ }
+ yaf_dispatcher_fix_default(dispatcher, request TSRMLS_CC);
+ YAF_PLUGIN_HANDLE(plugins, YAF_PLUGIN_HOOK_POSTDISPATCH, request, response);
+ YAF_EXCEPTION_HANDLE(dispatcher, request, response);
+ } while (--nesting > 0 && !yaf_request_is_dispatched(request TSRMLS_CC));
+
+ YAF_PLUGIN_HANDLE(plugins, YAF_PLUGIN_HOOK_LOOPSHUTDOWN, request, response);
+ YAF_EXCEPTION_HANDLE(dispatcher, request, response);
+
+ if (0 == nesting && !yaf_request_is_dispatched(request TSRMLS_CC)) {
+ yaf_trigger_error(YAF_ERR_DISPATCH_FAILED TSRMLS_CC, "The max dispatch nesting %ld was reached", YAF_G(forward_limit));
+ YAF_EXCEPTION_HANDLE_NORET(dispatcher, request, response);
+ return NULL;
+ }
+
+ return_response = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_RETURN), 1 TSRMLS_CC);
+
+ if (!Z_BVAL_P(return_response)) {
+ (void)yaf_response_send(response TSRMLS_CC);
+ yaf_response_clear_body(response TSRMLS_CC);
+ }
+
+ return response;
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Dispatcher::__construct(void)
+*/
+PHP_METHOD(yaf_dispatcher, __construct) {
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Dispatcher::__sleep(void)
+*/
+PHP_METHOD(yaf_dispatcher, __sleep) {
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Dispatcher::__wakeup(void)
+*/
+PHP_METHOD(yaf_dispatcher, __wakeup) {
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::setErrorHandler(string $callbacak[, int $error_types = E_ALL | E_STRICT ] )
+*/
+PHP_METHOD(yaf_dispatcher, setErrorHandler) {
+ zval *callback, *error_type = NULL;
+ zval *params[2] = {0};
+ zval function = {{0}, 0};
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &callback, &error_type) == FAILURE) {
+ return;
+ }
+
+ params[0] = callback;
+ if (error_type) {
+ params[1] = error_type;
+ }
+
+ ZVAL_STRING(&function, "set_error_handler", 0);
+ if (call_user_function(EG(function_table), NULL, &function, return_value, ZEND_NUM_ARGS(), params TSRMLS_CC) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Call to set_error_handler failed");
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::disableView()
+*/
+PHP_METHOD(yaf_dispatcher, disableView) {
+ yaf_dispatcher_t *self = getThis();
+ zend_update_property_bool(yaf_dispatcher_ce, self, YAF_STRL(YAF_DISPATCHER_PROPERTY_NAME_RENDER), 0 TSRMLS_CC);
+ RETURN_ZVAL(self, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::enableView()
+*/
+PHP_METHOD(yaf_dispatcher, enableView) {
+ yaf_dispatcher_t *self = getThis();
+ zend_update_property_bool(yaf_dispatcher_ce, self, YAF_STRL(YAF_DISPATCHER_PROPERTY_NAME_RENDER), 1 TSRMLS_CC);
+ RETURN_ZVAL(self, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::returnResponse()
+*/
+PHP_METHOD(yaf_dispatcher, returnResponse) {
+ long auto_response;
+ yaf_dispatcher_t *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &auto_response) == FAILURE) {
+ return;
+ }
+
+ zend_update_property_bool(yaf_dispatcher_ce, self, YAF_STRL(YAF_DISPATCHER_PROPERTY_NAME_RETURN), (auto_response)? 1:0 TSRMLS_CC);
+
+ RETURN_ZVAL(self, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::flushInstantly(bool $flag)
+*/
+PHP_METHOD(yaf_dispatcher, flushInstantly) {
+ long instantly_flush;
+ yaf_dispatcher_t *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &instantly_flush) == FAILURE) {
+ return;
+ }
+
+ zend_update_property_bool(yaf_dispatcher_ce, self, YAF_STRL(YAF_DISPATCHER_PROPERTY_NAME_FLUSH), (instantly_flush)? 1:0 TSRMLS_CC);
+
+ RETURN_ZVAL(self, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::registerPlugin(Yaf_Plugin_Abstract $plugin)
+*/
+PHP_METHOD(yaf_dispatcher, registerPlugin) {
+ zval *plugin, *plugins;
+ yaf_dispatcher_t *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &plugin) == FAILURE) {
+ return;
+ }
+
+ if (Z_TYPE_P(plugin) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(plugin), yaf_plugin_ce TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expect a %s instance", yaf_plugin_ce->name);
+ RETURN_FALSE;
+ }
+
+ plugins = zend_read_property(yaf_dispatcher_ce, self, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_PLUGINS), 1 TSRMLS_CC);
+
+ Z_ADDREF_P(plugin);
+ add_next_index_zval(plugins, plugin);
+
+ RETVAL_ZVAL(self, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::setRequest(Yaf_Request_Abstract $request)
+*/
+PHP_METHOD(yaf_dispatcher, setRequest) {
+ yaf_request_t *request;
+ yaf_dispatcher_t *self;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &request) == FAILURE) {
+ return;
+ }
+
+ if (IS_OBJECT != Z_TYPE_P(request)
+ || !instanceof_function(Z_OBJCE_P(request), yaf_request_ce TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expects a %s instance", yaf_request_ce->name);
+ RETURN_FALSE;
+ }
+
+ self = getThis();
+ if (yaf_dispatcher_set_request(self, request TSRMLS_CC)) {
+ RETURN_ZVAL(self, 1, 0);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::getInstance(void)
+*/
+PHP_METHOD(yaf_dispatcher, getInstance) {
+ yaf_dispatcher_t *dispatcher = yaf_dispatcher_instance(NULL TSRMLS_CC);
+ RETURN_ZVAL(dispatcher, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::getRouter(void)
+*/
+PHP_METHOD(yaf_dispatcher, getRouter) {
+ yaf_router_t *router = zend_read_property(yaf_dispatcher_ce, getThis(), ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_ROUTER), 1 TSRMLS_CC);
+ RETURN_ZVAL(router, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::getRequest(void)
+*/
+PHP_METHOD(yaf_dispatcher, getRequest) {
+ yaf_request_t *request = zend_read_property(yaf_dispatcher_ce, getThis(), ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_REQUEST), 1 TSRMLS_CC);
+ RETURN_ZVAL(request, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::getApplication(void)
+*/
+PHP_METHOD(yaf_dispatcher, getApplication) {
+ PHP_MN(yaf_application_app)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::dispatch(yaf_request_t $request)
+*/
+PHP_METHOD(yaf_dispatcher, dispatch) {
+ yaf_request_t *request;
+ yaf_response_t *response;
+ yaf_dispatcher_t *self;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &request) == FAILURE) {
+ return;
+ }
+
+ self = getThis();
+ zend_update_property(yaf_dispatcher_ce, self, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_REQUEST), request TSRMLS_CC);
+ if ((response = yaf_dispatcher_dispatch(self TSRMLS_CC))) {
+ RETURN_ZVAL(response, 1, 1);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::throwException(bool $flag=0)
+*/
+PHP_METHOD(yaf_dispatcher, throwException) {
+ int flag;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &flag) == FAILURE) {
+ return;
+ }
+
+ YAF_G(throw_exception) = flag? 1: 0;
+ RETURN_ZVAL(getThis(), 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::catchException(bool $flag=0)
+*/
+PHP_METHOD(yaf_dispatcher, catchException) {
+ int flag;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &flag) == FAILURE) {
+ return;
+ }
+
+ YAF_G(catch_exception) = flag? 1: 0;
+ RETURN_ZVAL(getThis(), 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::autoRender(int $flag)
+ */
+PHP_METHOD(yaf_dispatcher, autoRender) {
+ long flag;
+ yaf_dispatcher_t *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &flag) == FAILURE) {
+ return;
+ }
+
+ zend_update_property_bool(yaf_dispatcher_ce, self, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_RENDER), flag? 1 : 0 TSRMLS_CC);
+
+ RETURN_ZVAL(self, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::initView(string $tpl_dir, array $options = NULL)
+*/
+PHP_METHOD(yaf_dispatcher, initView) {
+ yaf_view_t *view = NULL;
+ zval *tpl_dir = NULL;
+ zval *options = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &tpl_dir, &options) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ view = yaf_dispatcher_init_view(getThis(), tpl_dir, options TSRMLS_CC);
+ if (view) {
+ RETURN_ZVAL(view, 1, 0);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::setView(Yaf_View_Interface $view)
+*/
+PHP_METHOD(yaf_dispatcher, setView) {
+ yaf_view_t *view;
+ yaf_dispatcher_t *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &view) == FAILURE) {
+ return;
+ }
+
+ if (view && IS_OBJECT == Z_TYPE_P(view)
+ && instanceof_function(Z_OBJCE_P(view), yaf_view_interface_ce TSRMLS_CC)) {
+ zend_update_property(yaf_dispatcher_ce, self, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_VIEW), view TSRMLS_CC);
+ RETURN_ZVAL(self, 1, 0);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::setAppDirectory(string $directory)
+*/
+PHP_METHOD(yaf_dispatcher, setAppDirectory) {
+ int len;
+ char *directory;
+ yaf_dispatcher_t *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &directory, &len) == FAILURE) {
+ return;
+ }
+
+ if (!len || !IS_ABSOLUTE_PATH(directory, len)) {
+ RETURN_FALSE;
+ }
+
+ efree(YAF_G(directory));
+
+ YAF_G(directory) = estrndup(directory, len);
+
+ RETURN_ZVAL(self, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::setDefaultModule(string $name)
+*/
+PHP_METHOD(yaf_dispatcher, setDefaultModule) {
+ zval *module;
+ zval *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &module) == FAILURE) {
+ return;
+ }
+
+ if (IS_STRING == Z_TYPE_P(module) && Z_STRLEN_P(module)
+ && yaf_application_is_module_name(Z_STRVAL_P(module), Z_STRLEN_P(module) TSRMLS_CC)) {
+ zval *module_std;
+ MAKE_STD_ZVAL(module_std);
+ ZVAL_STRING(module_std, zend_str_tolower_dup(Z_STRVAL_P(module), Z_STRLEN_P(module)), 0);
+ *Z_STRVAL_P(module_std) = toupper(*Z_STRVAL_P(module_std));
+ zend_update_property(yaf_dispatcher_ce, self, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_MODULE), module_std TSRMLS_CC);
+
+ RETURN_ZVAL(self, 1, 0);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::setDefaultController(string $name)
+*/
+PHP_METHOD(yaf_dispatcher, setDefaultController) {
+ zval *controller;
+ zval *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &controller) == FAILURE) {
+ return;
+ }
+
+ if (IS_STRING == Z_TYPE_P(controller) && Z_STRLEN_P(controller)) {
+ zval *controller_std;
+ MAKE_STD_ZVAL(controller_std);
+ ZVAL_STRING(controller_std, zend_str_tolower_dup(Z_STRVAL_P(controller), Z_STRLEN_P(controller)), 0);
+ *Z_STRVAL_P(controller_std) = toupper(*Z_STRVAL_P(controller_std));
+ zend_update_property(yaf_dispatcher_ce, self, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_CONTROLLER), controller_std TSRMLS_CC);
+
+ RETURN_ZVAL(self, 1, 0);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::setDefaultAction(string $name)
+*/
+PHP_METHOD(yaf_dispatcher, setDefaultAction) {
+ zval *action;
+ zval *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &action) == FAILURE) {
+ return;
+ }
+
+ if (action && IS_STRING == Z_TYPE_P(action) && Z_STRLEN_P(action)) {
+ zval *action_lower;
+ MAKE_STD_ZVAL(action_lower);
+ ZVAL_STRING(action_lower, zend_str_tolower_dup(Z_STRVAL_P(action), Z_STRLEN_P(action)), 0);
+ zend_update_property(yaf_dispatcher_ce, self, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_ACTION), action_lower TSRMLS_CC);
+
+ RETURN_ZVAL(self, 1, 0);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Dispatcher::__desctruct(void)
+*/
+PHP_METHOD(yaf_dispatcher, __destruct) {
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Dispatcher::__clone(void)
+*/
+PHP_METHOD(yaf_dispatcher, __clone) {
+}
+/* }}} */
+
+/** {{{ yaf_dispatcher_methods
+*/
+zend_function_entry yaf_dispatcher_methods[] = {
+ PHP_ME(yaf_dispatcher, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
+ PHP_ME(yaf_dispatcher, __clone, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CLONE)
+ PHP_ME(yaf_dispatcher, __sleep, NULL, ZEND_ACC_PRIVATE)
+ PHP_ME(yaf_dispatcher, __wakeup, NULL, ZEND_ACC_PRIVATE)
+ PHP_ME(yaf_dispatcher, enableView, yaf_dispatcher_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, disableView, yaf_dispatcher_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, initView, yaf_dispatcher_initview_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, setView, yaf_dispatcher_setview_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, setRequest, yaf_dispatcher_setrequest_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, getApplication, yaf_dispatcher_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, getRouter, yaf_dispatcher_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, getRequest, yaf_dispatcher_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, setErrorHandler, yaf_dispatcher_seterrhdler_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, setAppDirectory, yaf_dispatcher_setappdir_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, setDefaultModule, yaf_dispatcher_setmodule_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, setDefaultController,yaf_dispatcher_setctrl_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, setDefaultAction, yaf_dispatcher_setaction_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, returnResponse, yaf_dispatcher_returnresp_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, autoRender, yaf_dispatcher_autorender_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, flushInstantly, yaf_dispatcher_flush_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, getInstance, yaf_dispatcher_void_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ PHP_ME(yaf_dispatcher, dispatch, yaf_dispatcher_dispatch_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, throwException, yaf_dispatcher_throwex_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, catchException, yaf_dispatcher_catchex_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_dispatcher, registerPlugin, yaf_dispatcher_regplugin_arginfo, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(dispatcher) {
+ zend_class_entry ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Dispatcher", "Yaf\\Dispatcher", yaf_dispatcher_methods);
+
+ yaf_dispatcher_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+ yaf_dispatcher_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+
+ zend_declare_property_null(yaf_dispatcher_ce, YAF_STRL(YAF_DISPATCHER_PROPERTY_NAME_ROUTER), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_dispatcher_ce, YAF_STRL(YAF_DISPATCHER_PROPERTY_NAME_VIEW), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_dispatcher_ce, YAF_STRL(YAF_DISPATCHER_PROPERTY_NAME_REQUEST), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_dispatcher_ce, YAF_STRL(YAF_DISPATCHER_PROPERTY_NAME_PLUGINS), ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ zend_declare_property_null(yaf_dispatcher_ce, YAF_STRL(YAF_DISPATCHER_PROPERTY_NAME_INSTANCE), ZEND_ACC_PROTECTED|ZEND_ACC_STATIC TSRMLS_CC);
+
+ zend_declare_property_bool(yaf_dispatcher_ce, YAF_STRL(YAF_DISPATCHER_PROPERTY_NAME_RENDER), 1, ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_bool(yaf_dispatcher_ce, YAF_STRL(YAF_DISPATCHER_PROPERTY_NAME_RETURN), 0, ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_bool(yaf_dispatcher_ce, YAF_STRL(YAF_DISPATCHER_PROPERTY_NAME_FLUSH), 0, ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ zend_declare_property_null(yaf_dispatcher_ce, YAF_STRL(YAF_DISPATCHER_PROPERTY_NAME_MODULE), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_dispatcher_ce, YAF_STRL(YAF_DISPATCHER_PROPERTY_NAME_CONTROLLER), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_dispatcher_ce, YAF_STRL(YAF_DISPATCHER_PROPERTY_NAME_ACTION), ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ /*zend_declare_property_null(yaf_dispatcher_ce, YAF_STRL(YAF_DISPATCHER_PROPERTY_NAME_ARGS), ZEND_ACC_PROTECTED TSRMLS_CC);*/
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_dispatcher.h b/yaf_dispatcher.h
new file mode 100644
index 0000000000..b64dbce7b0
--- /dev/null
+++ b/yaf_dispatcher.h
@@ -0,0 +1,73 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#ifndef PHP_YAF_DISPATCHER_H
+#define PHP_YAF_DISPATCHER_H
+
+#define YAF_DISPATCHER_PROPERTY_NAME_REQUEST "_request"
+#define YAF_DISPATCHER_PROPERTY_NAME_VIEW "_view"
+#define YAF_DISPATCHER_PROPERTY_NAME_ROUTER "_router"
+#define YAF_DISPATCHER_PROPERTY_NAME_INSTANCE "_instance"
+#define YAF_DISPATCHER_PROPERTY_NAME_RENDER "_auto_render"
+#define YAF_DISPATCHER_PROPERTY_NAME_RETURN "_return_response"
+#define YAF_DISPATCHER_PROPERTY_NAME_FLUSH "_instantly_flush"
+#define YAF_DISPATCHER_PROPERTY_NAME_ARGS "_invoke_args"
+
+#define YAF_DISPATCHER_PROPERTY_NAME_MODULE "_default_module"
+#define YAF_DISPATCHER_PROPERTY_NAME_CONTROLLER "_default_controller"
+#define YAF_DISPATCHER_PROPERTY_NAME_ACTION "_default_action"
+
+#define YAF_ERROR_CONTROLLER "Error"
+#define YAF_ERROR_ACTION "error"
+
+#define YAF_DISPATCHER_PROPERTY_NAME_PLUGINS "_plugins"
+
+#define YAF_PLUGIN_HOOK_ROUTESTARTUP "routerstartup"
+#define YAF_PLUGIN_HOOK_ROUTESHUTDOWN "routershutdown"
+#define YAF_PLUGIN_HOOK_LOOPSTARTUP "dispatchloopstartup"
+#define YAF_PLUGIN_HOOK_PREDISPATCH "predispatch"
+#define YAF_PLUGIN_HOOK_POSTDISPATCH "postdispatch"
+#define YAF_PLUGIN_HOOK_LOOPSHUTDOWN "dispatchloopshutdown"
+#define YAF_PLUGIN_HOOK_PRERESPONSE "preresponse"
+
+#define YAF_PLUGIN_HANDLE(p, n, request, response) \
+ do { \
+ if (!ZVAL_IS_NULL(p)) { \
+ zval **_t_plugin;\
+ for(zend_hash_internal_pointer_reset(Z_ARRVAL_P(p));\
+ zend_hash_has_more_elements(Z_ARRVAL_P(p)) == SUCCESS;\
+ zend_hash_move_forward(Z_ARRVAL_P(p))) {\
+ if (zend_hash_get_current_data(Z_ARRVAL_P(p), (void**)&_t_plugin) == SUCCESS) {\
+ if (zend_hash_exists(&(Z_OBJCE_PP(_t_plugin)->function_table), n, sizeof(n))) {\
+ zend_call_method_with_2_params(_t_plugin, Z_OBJCE_PP(_t_plugin), NULL, n, NULL, request, response);\
+ }\
+ }\
+ }\
+ }\
+ } while(0)
+
+extern zend_class_entry *yaf_dispatcher_ce;
+
+yaf_dispatcher_t * yaf_dispatcher_instance(yaf_dispatcher_t *this_ptr TSRMLS_DC);
+yaf_response_t * yaf_dispatcher_dispatch(yaf_dispatcher_t *dispatcher TSRMLS_DC);
+int yaf_dispatcher_set_request(yaf_dispatcher_t *dispatcher, yaf_request_t *request TSRMLS_DC);
+
+PHP_METHOD(yaf_application, app);
+PHP_FUNCTION(set_error_handler);
+YAF_STARTUP_FUNCTION(dispatcher);
+#endif
diff --git a/yaf_exception.c b/yaf_exception.c
new file mode 100644
index 0000000000..315d8e4f7f
--- /dev/null
+++ b/yaf_exception.c
@@ -0,0 +1,209 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "main/SAPI.h"
+#include "Zend/zend_interfaces.h"
+#include "Zend/zend_exceptions.h"
+#include "Zend/zend_alloc.h"
+#include "ext/standard/info.h"
+#include "ext/standard/php_string.h"
+#include "zend_objects.h"
+
+#include "php_yaf.h"
+#include "yaf_namespace.h"
+#include "yaf_exception.h"
+
+zend_class_entry *yaf_ce_RuntimeException;
+zend_class_entry *yaf_exception_ce;
+
+static zend_class_entry * yaf_buildin_exceptions[YAF_MAX_BUILDIN_EXCEPTION];
+
+/** {{{void yaf_trigger_error(int type TSRMLS_DC, char *format, ...)
+ */
+void yaf_trigger_error(int type TSRMLS_DC, char *format, ...) {
+ va_list args;
+
+ if (YAF_G(throw_exception)) {
+ char *message;
+ va_start(args, format);
+ vspprintf(&message, 0, format, args);
+ va_end(args);
+ yaf_throw_exception(type, message TSRMLS_CC);
+ efree(message);
+ } else {
+ va_start(args, format);
+ php_verror(NULL, "", E_ERROR, format, args TSRMLS_CC);
+ va_end(args);
+ }
+}
+/* }}} */
+
+/** {{{ zend_class_entry * yaf_get_exception_base(int root TSRMLS_DC)
+*/
+zend_class_entry * yaf_get_exception_base(int root TSRMLS_DC) {
+#if can_handle_soft_dependency_on_SPL && defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
+ if (!root) {
+ if (!yaf_ce_RuntimeException) {
+ zend_class_entry **pce;
+
+ if (zend_hash_find(CG(class_table), "runtimeexception", sizeof("RuntimeException"), (void **) &pce) == SUCCESS) {
+ yaf_ce_RuntimeException = *pce;
+ return *pce;
+ }
+ } else {
+ return yaf_ce_RuntimeException;
+ }
+ }
+#endif
+
+#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 2)
+ return zend_exception_get_default();
+#else
+ return zend_exception_get_default(TSRMLS_C);
+#endif
+}
+/* }}} */
+
+/** {{{ void yaf_throw_exception(long code, char *message TSRMLS_DC)
+*/
+void yaf_throw_exception(long code, char *message TSRMLS_DC) {
+ zend_class_entry *base_exception = yaf_exception_ce;
+
+ if ((code & YAF_ERR_BASE) == YAF_ERR_BASE
+ && yaf_buildin_exceptions[YAF_EXCEPTION_OFFSET(code)]) {
+ base_exception = yaf_buildin_exceptions[YAF_EXCEPTION_OFFSET(code)];
+ }
+
+ zend_throw_exception(base_exception, message, code TSRMLS_CC);
+}
+/* }}} */
+
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 3)) || (PHP_MAJOR_VERSION < 5)
+/** {{{ proto Yaf_Exception::__construct($mesg = 0, $code = 0, Exception $previous = NULL)
+*/
+PHP_METHOD(yaf_exception, __construct) {
+ char *message = NULL;
+ zval *object, *previous = NULL;
+ int message_len, code = 0;
+ int argc = ZEND_NUM_ARGS();
+
+ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "|slO!", &message, &message_len, &code, &previous, yaf_get_exception_base(0 TSRMLS_CC)) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong parameters for Exception([string $exception [, long $code [, Exception $previous = NULL]]])");
+ }
+
+ object = getThis();
+
+ if (message) {
+ zend_update_property_string(Z_OBJCE_P(object), object, "message", sizeof("message")-1, message TSRMLS_CC);
+ }
+
+ if (code) {
+ zend_update_property_long(Z_OBJCE_P(object), object, "code", sizeof("code")-1, code TSRMLS_CC);
+ }
+
+ if (previous) {
+ zend_update_property(Z_OBJCE_P(object), object, ZEND_STRL("previous"), previous TSRMLS_CC);
+ }
+}
+/* }}} */
+
+/** {{{ proto Yaf_Exception::getPrevious(void)
+*/
+PHP_METHOD(yaf_exception, getPrevious) {
+ zval *prev = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("previous"), 1 TSRMLS_CC);
+ RETURN_ZVAL(prev, 1, 0);
+}
+/* }}} */
+#endif
+
+/** {{{ yaf_exception_methods
+*/
+zend_function_entry yaf_exception_methods[] = {
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 3)) || (PHP_MAJOR_VERSION < 5)
+ PHP_ME(yaf_exception, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(yaf_exception, getPrevious, NULL, ZEND_ACC_PUBLIC)
+#endif
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(exception) {
+ zend_class_entry ce;
+ zend_class_entry startup_ce;
+ zend_class_entry route_ce;
+ zend_class_entry dispatch_ce;
+ zend_class_entry loader_ce;
+ zend_class_entry module_notfound_ce;
+ zend_class_entry controller_notfound_ce;
+ zend_class_entry action_notfound_ce;
+ zend_class_entry view_notfound_ce;
+ zend_class_entry type_ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Exception", "Yaf\\Exception", yaf_exception_methods);
+ yaf_exception_ce = zend_register_internal_class_ex(&ce, yaf_get_exception_base(0 TSRMLS_CC), NULL TSRMLS_CC);
+ zend_declare_property_null(yaf_exception_ce, YAF_STRL("message"), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_long(yaf_exception_ce, YAF_STRL("code"), 0, ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_exception_ce, YAF_STRL("previous"), ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ YAF_INIT_CLASS_ENTRY(startup_ce, "Yaf_Exception_StartupError", "Yaf\\Exception\\StartupError", NULL);
+ yaf_buildin_exceptions[YAF_EXCEPTION_OFFSET(YAF_ERR_STARTUP_FAILED)] = zend_register_internal_class_ex(&startup_ce, yaf_exception_ce, NULL TSRMLS_CC);
+
+ YAF_INIT_CLASS_ENTRY(route_ce, "Yaf_Exception_RouterFailed", "Yaf\\Exception\\RouterFailed", NULL);
+ yaf_buildin_exceptions[YAF_EXCEPTION_OFFSET(YAF_ERR_ROUTE_FAILED)] = zend_register_internal_class_ex(&route_ce, yaf_exception_ce, NULL TSRMLS_CC);
+
+ YAF_INIT_CLASS_ENTRY(dispatch_ce, "Yaf_Exception_DispatchFailed", "Yaf\\Exception\\DispatchFailed", NULL);
+ yaf_buildin_exceptions[YAF_EXCEPTION_OFFSET(YAF_ERR_DISPATCH_FAILED)] = zend_register_internal_class_ex(&dispatch_ce, yaf_exception_ce, NULL TSRMLS_CC);
+
+ YAF_INIT_CLASS_ENTRY(loader_ce, "Yaf_Exception_LoadFailed", "Yaf\\Exception\\LoadFailed", NULL);
+ yaf_buildin_exceptions[YAF_EXCEPTION_OFFSET(YAF_ERR_AUTOLOAD_FAILED)] = zend_register_internal_class_ex(&loader_ce, yaf_exception_ce, NULL TSRMLS_CC);
+
+ YAF_INIT_CLASS_ENTRY(module_notfound_ce, "Yaf_Exception_LoadFailed_Module", "Yaf\\Exception\\LoadFailed\\Module", NULL);
+ yaf_buildin_exceptions[YAF_EXCEPTION_OFFSET(YAF_ERR_NOTFOUND_MODULE)] = zend_register_internal_class_ex(&module_notfound_ce, yaf_buildin_exceptions[YAF_EXCEPTION_OFFSET(YAF_ERR_AUTOLOAD_FAILED)], NULL TSRMLS_CC);
+
+ YAF_INIT_CLASS_ENTRY(controller_notfound_ce, "Yaf_Exception_LoadFailed_Controller", "Yaf\\Exception\\LoadFailed\\Controller", NULL);
+ yaf_buildin_exceptions[YAF_EXCEPTION_OFFSET(YAF_ERR_NOTFOUND_CONTROLLER)] = zend_register_internal_class_ex(&controller_notfound_ce, yaf_buildin_exceptions[YAF_EXCEPTION_OFFSET(YAF_ERR_AUTOLOAD_FAILED)], NULL TSRMLS_CC);
+
+ YAF_INIT_CLASS_ENTRY(action_notfound_ce, "Yaf_Exception_LoadFailed_Action", "Yaf\\Exception\\LoadFailed\\Action", NULL);
+ yaf_buildin_exceptions[YAF_EXCEPTION_OFFSET(YAF_ERR_NOTFOUND_ACTION)] = zend_register_internal_class_ex(&action_notfound_ce, yaf_buildin_exceptions[YAF_EXCEPTION_OFFSET(YAF_ERR_AUTOLOAD_FAILED)], NULL TSRMLS_CC);
+
+ YAF_INIT_CLASS_ENTRY(view_notfound_ce, "Yaf_Exception_LoadFailed_View", "Yaf\\Exception\\LoadFailed\\View", NULL);
+ yaf_buildin_exceptions[YAF_EXCEPTION_OFFSET(YAF_ERR_NOTFOUND_VIEW)] = zend_register_internal_class_ex(&view_notfound_ce, yaf_buildin_exceptions[YAF_EXCEPTION_OFFSET(YAF_ERR_AUTOLOAD_FAILED)], NULL TSRMLS_CC);
+
+ YAF_INIT_CLASS_ENTRY(type_ce, "Yaf_Exception_TypeError", "Yaf\\Exception\\TypeError", NULL);
+ yaf_buildin_exceptions[YAF_EXCEPTION_OFFSET(YAF_ERR_TYPE_ERROR)] = zend_register_internal_class_ex(&type_ce, yaf_exception_ce, NULL TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_exception.h b/yaf_exception.h
new file mode 100644
index 0000000000..9d82b3161c
--- /dev/null
+++ b/yaf_exception.h
@@ -0,0 +1,79 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef YAF_EXCEPTION_H
+#define YAF_EXCEPTION_H
+
+#define YAF_MAX_BUILDIN_EXCEPTION 10
+
+#define YAF_ERR_BASE 512
+#define YAF_UERR_BASE 1024
+#define YAF_ERR_MASK 127
+
+#define YAF_ERR_STARTUP_FAILED 512
+#define YAF_ERR_ROUTE_FAILED 513
+#define YAF_ERR_DISPATCH_FAILED 514
+#define YAF_ERR_NOTFOUND_MODULE 515
+#define YAF_ERR_NOTFOUND_CONTROLLER 516
+#define YAF_ERR_NOTFOUND_ACTION 517
+#define YAF_ERR_NOTFOUND_VIEW 518
+#define YAF_ERR_CALL_FAILED 519
+#define YAF_ERR_AUTOLOAD_FAILED 520
+#define YAF_ERR_TYPE_ERROR 521
+
+#define YAF_EXCEPTION_OFFSET(x) (x & YAF_ERR_MASK)
+
+#define YAF_CORRESPOND_ERROR(x) (x>>9L)
+
+#define YAF_EXCEPTION_HANDLE(dispatcher, request, response) \
+ if (EG(exception)) { \
+ if (YAF_G(catch_exception)) { \
+ yaf_dispatcher_exception_handler(dispatcher, request, response TSRMLS_CC); \
+ } \
+ return NULL; \
+ }
+
+#define YAF_EXCEPTION_HANDLE_NORET(dispatcher, request, response) \
+ if (EG(exception)) { \
+ if (YAF_G(catch_exception)) { \
+ yaf_dispatcher_exception_handler(dispatcher, request, response TSRMLS_CC); \
+ } \
+ }
+
+#define YAF_EXCEPTION_ERASE_EXCEPTION() \
+ do { \
+ EG(current_execute_data)->opline = EG(opline_before_exception); \
+ } while(0)
+
+
+extern zend_class_entry *yaf_ce_RuntimeException;
+extern zend_class_entry *yaf_exception_ce;
+void yaf_trigger_error(int type TSRMLS_DC, char *format, ...);
+void yaf_throw_exception(long code, char *message TSRMLS_DC);
+
+YAF_STARTUP_FUNCTION(exception);
+
+#endif
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_loader.c b/yaf_loader.c
new file mode 100644
index 0000000000..742e559afb
--- /dev/null
+++ b/yaf_loader.c
@@ -0,0 +1,882 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "main/SAPI.h"
+#include "Zend/zend_alloc.h"
+#include "ext/standard/php_smart_str.h"
+#include "TSRM/tsrm_virtual_cwd.h"
+
+#include "php_yaf.h"
+#include "yaf_application.h"
+#include "yaf_namespace.h"
+#include "yaf_request.h"
+#include "yaf_loader.h"
+#include "yaf_exception.h"
+
+zend_class_entry *yaf_loader_ce;
+
+/** {{{ int yaf_loader_register(TSRMLS_D)
+*/
+int yaf_loader_register(yaf_loader_t *loader TSRMLS_DC) {
+ zval *autoload, *method, *function, *ret = NULL;
+ zval **params[1] = {&autoload};
+
+ MAKE_STD_ZVAL(autoload);
+ array_init(autoload);
+
+ MAKE_STD_ZVAL(method);
+ ZVAL_STRING(method, YAF_AUTOLOAD_FUNC_NAME, 1);
+
+ zend_hash_next_index_insert(Z_ARRVAL_P(autoload), &loader, sizeof(yaf_loader_t *), NULL);
+ zend_hash_next_index_insert(Z_ARRVAL_P(autoload), &method, sizeof(zval *), NULL);
+
+ MAKE_STD_ZVAL(function);
+ ZVAL_STRING(function, YAF_SPL_AUTOLOAD_REGISTER_NAME, 0);
+
+ do {
+ zend_fcall_info fci = {
+ sizeof(fci),
+ EG(function_table),
+ function,
+ NULL,
+ &ret,
+ 1,
+ (zval ***)params,
+ NULL,
+ 1
+ };
+
+ if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE) {
+ if (ret) {
+ zval_ptr_dtor(&ret);
+ }
+ efree(function);
+ zval_ptr_dtor(&autoload);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to register autoload function %s", YAF_AUTOLOAD_FUNC_NAME);
+ return 0;
+ }
+
+ /*{{{ no use anymore
+ if (0 && !YAF_G(use_spl_autoload)) {
+ zend_function *reg_function;
+ zend_internal_function override_function = {
+ ZEND_INTERNAL_FUNCTION,
+ YAF_AUTOLOAD_FUNC_NAME,
+ NULL,
+ ZEND_ACC_PUBLIC,
+ NULL,
+ 1,
+ 0,
+ NULL,
+ 0,
+ 0,
+ ZEND_FN(yaf_override_spl_autoload),
+ NULL
+ };
+ zend_internal_function *internal_function = (zend_internal_function *)&override_function;
+ internal_function->type = ZEND_INTERNAL_FUNCTION;
+ internal_function->module = NULL;
+ internal_function->handler = ZEND_FN(yaf_override_spl_autoload);
+ internal_function->function_name = YAF_AUTOLOAD_FUNC_NAME;
+ internal_function->scope = NULL;
+ internal_function->prototype = NULL;
+ internal_function->arg_info = NULL;
+ internal_function->num_args = 1;
+ internal_function->required_num_args = 0;
+ internal_function->pass_rest_by_reference = 0;
+ internal_function->return_reference = 0;
+ internal_function->fn_flags = ZEND_ACC_PUBLIC;
+ function_add_ref((zend_function*)&override_function);
+ //zend_register_functions
+ if (zend_hash_update(EG(function_table), YAF_SPL_AUTOLOAD_REGISTER_NAME,
+ sizeof(YAF_SPL_AUTOLOAD_REGISTER_NAME), &override_function, sizeof(zend_function), (void **)&reg_function) == FAILURE) {
+ YAF_DEBUG("register autoload failed");
+ //no big deal
+ }
+ }
+ }}} */
+
+ if (ret) {
+ zval_ptr_dtor(&ret);
+ }
+ efree(function);
+ zval_ptr_dtor(&autoload);
+ } while (0);
+ return 1;
+}
+/* }}} */
+
+/** {{{ inline int yaf_loader_is_category(char *class, uint class_len, char *category, uint category_len TSRMLS_DC)
+ */
+inline int yaf_loader_is_category(char *class, uint class_len, char *category, uint category_len TSRMLS_DC) {
+ uint separator_len = strlen(YAF_G(name_separator));
+
+ if (YAF_G(name_suffix)) {
+ if (strncmp(class + class_len - category_len, category, category_len) == 0) {
+ if (!separator_len || strncmp(class + class_len - category_len - separator_len, YAF_G(name_separator), separator_len) == 0) {
+ return 1;
+ }
+ }
+ } else {
+ if (strncmp(class, category, category_len) == 0) {
+ if (!separator_len || strncmp(class + category_len, YAF_G(name_separator), separator_len) == 0) {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+/* }}} */
+
+/** {{{ int yaf_loader_is_local_namespace(yaf_loader_t *loader, char *class_name, int len TSRMLS_DC)
+ */
+int yaf_loader_is_local_namespace(yaf_loader_t *loader, char *class_name, int len TSRMLS_DC) {
+ char *pos, *ns, *prefix = NULL;
+ uint prefix_len = 0;
+ zval *namespaces = zend_read_property(yaf_loader_ce, loader, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_NAMESPACE), 1 TSRMLS_CC);
+
+ if (ZVAL_IS_NULL(namespaces)) {
+ return 0;
+ }
+
+ pos = Z_STRVAL_P(namespaces);
+ ns = Z_STRVAL_P(namespaces);
+
+ pos = strstr(class_name, "_");
+ if (pos) {
+ prefix_len = pos - class_name;
+ prefix = estrndup(class_name, prefix_len);
+ }
+#ifdef YAF_HAVE_NAMESPACE
+ else if ((pos = strstr(class_name, "\\"))) {
+ prefix_len = pos - class_name;
+ prefix = estrndup(class_name, prefix_len);
+ }
+#endif
+
+ if (!prefix_len) {
+ efree(prefix);
+ return 0;
+ }
+
+ while ((pos = strstr(ns, prefix))) {
+ if ((pos == ns) && *(pos + prefix_len) == DEFAULT_DIR_SEPARATOR) {
+ efree(prefix);
+ return 1;
+ } else if (*(pos - 1) == DEFAULT_DIR_SEPARATOR && *(pos + prefix_len) == DEFAULT_DIR_SEPARATOR) {
+ efree(prefix);
+ return 1;
+ }
+ ns = pos + prefix_len;
+ }
+ efree(prefix);
+ return 0;
+}
+/* }}} */
+
+/** {{{ yaf_loader_t * yaf_loader_instance(yaf_loader_t *this_ptr, char *library_path, char *global_path TSRMLS_DC)
+ */
+yaf_loader_t * yaf_loader_instance(yaf_loader_t *this_ptr, char *library_path, char *global_path TSRMLS_DC) {
+ yaf_loader_t *instance;
+ zval *glibrary, *library;
+
+ instance = zend_read_static_property(yaf_loader_ce, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_INSTANCE), 1 TSRMLS_CC);
+
+ if (IS_OBJECT == Z_TYPE_P(instance)
+ && instanceof_function(Z_OBJCE_P(instance), yaf_loader_ce TSRMLS_CC)) {
+ return instance;
+ }
+
+ if (!global_path && !library_path) {
+ return NULL;
+ }
+
+ if (this_ptr) {
+ instance = this_ptr;
+ } else {
+ MAKE_STD_ZVAL(instance);
+ object_init_ex(instance, yaf_loader_ce);
+ }
+
+ zend_update_property_null(yaf_loader_ce, instance, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_NAMESPACE) TSRMLS_CC);
+
+ if (library_path && global_path) {
+ MAKE_STD_ZVAL(glibrary);
+ MAKE_STD_ZVAL(library);
+ ZVAL_STRING(glibrary, global_path, 1);
+ ZVAL_STRING(library, library_path, 1);
+ zend_update_property(yaf_loader_ce, instance, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_LIBRARY), library TSRMLS_CC);
+ zend_update_property(yaf_loader_ce, instance, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_GLOBAL_LIB), glibrary TSRMLS_CC);
+ zval_ptr_dtor(&library);
+ zval_ptr_dtor(&glibrary);
+ } else if (!global_path) {
+ MAKE_STD_ZVAL(library);
+ ZVAL_STRING(library, library_path, 1);
+ zend_update_property(yaf_loader_ce, instance, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_LIBRARY), library TSRMLS_CC);
+ zend_update_property(yaf_loader_ce, instance, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_GLOBAL_LIB), library TSRMLS_CC);
+ zval_ptr_dtor(&library);
+ } else {
+ MAKE_STD_ZVAL(glibrary);
+ ZVAL_STRING(glibrary, global_path, 1);
+ zend_update_property(yaf_loader_ce, instance, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_LIBRARY), glibrary TSRMLS_CC);
+ zend_update_property(yaf_loader_ce, instance, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_GLOBAL_LIB), glibrary TSRMLS_CC);
+ zval_ptr_dtor(&glibrary);
+ }
+
+ if (!yaf_loader_register(instance TSRMLS_CC)) {
+ return NULL;
+ }
+
+ zend_update_static_property(yaf_loader_ce, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_INSTANCE), instance TSRMLS_CC);
+
+ return instance;
+}
+/* }}} */
+
+/** {{{ int yaf_loader_compose(char *path, int lenA, int use_path TSRMLS_DC)
+*/
+int yaf_loader_compose(char *path, int len, int use_path TSRMLS_DC) {
+ zend_file_handle file_handle;
+
+ if (php_stream_open_for_zend_ex(path, &file_handle, ENFORCE_SAFE_MODE|IGNORE_URL_WIN|STREAM_OPEN_FOR_INCLUDE TSRMLS_CC) == SUCCESS) {
+ /* if (zend_stream_open(file_path, &file_handle TSRMLS_CC) == SUCCESS) { */
+ zend_op_array *new_op_array;
+ uint dummy = 1;
+
+ if (!file_handle.opened_path) {
+ file_handle.opened_path = estrndup(path, len);
+ }
+
+ if (zend_hash_update(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path) + 1, (void *)&dummy, sizeof(int), NULL) == SUCCESS) {
+ new_op_array = zend_compile_file(&file_handle, ZEND_REQUIRE TSRMLS_CC);
+ zend_destroy_file_handle(&file_handle TSRMLS_CC);
+ } else {
+ new_op_array = NULL;
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION > 2)) || (PHP_MAJOR_VERSION > 5)
+ zend_file_handle_dtor(&file_handle TSRMLS_CC);
+#else
+ zend_file_handle_dtor(&file_handle);
+#endif
+ }
+
+ if (new_op_array) {
+ zval *result;
+
+ YAF_STORE_EG_ENVIRON();
+
+ EG(return_value_ptr_ptr) = &result;
+ EG(active_op_array) = new_op_array;
+
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION > 2)) || (PHP_MAJOR_VERSION > 5)
+ if (!EG(active_symbol_table)) {
+ zend_rebuild_symbol_table(TSRMLS_C);
+ }
+#endif
+ zend_execute(new_op_array TSRMLS_CC);
+
+ destroy_op_array(new_op_array TSRMLS_CC);
+ efree(new_op_array);
+
+ if (!EG(exception)) {
+ if (EG(return_value_ptr_ptr)) {
+ zval_ptr_dtor(EG(return_value_ptr_ptr));
+ }
+ }
+
+ YAF_RESTORE_EG_ENVIRON();
+ }
+ } else {
+ return 0;
+ }
+
+ return 1;
+}
+/* }}} */
+
+/** {{{ int yaf_loader_import(char *path, int len, int use_path TSRMLS_DC)
+*/
+int yaf_loader_import(char *path, int len, int use_path TSRMLS_DC) {
+ zend_file_handle file_handle;
+
+ if (php_stream_open_for_zend_ex(path, &file_handle, ENFORCE_SAFE_MODE|IGNORE_URL_WIN|STREAM_OPEN_FOR_INCLUDE TSRMLS_CC) == SUCCESS) {
+ /* if (zend_stream_open(file_path, &file_handle TSRMLS_CC) == SUCCESS) { */
+ zend_op_array *new_op_array;
+ uint dummy = 1;
+
+ if (!file_handle.opened_path) {
+ file_handle.opened_path = estrndup(path, len);
+ }
+
+ if (zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path) + 1, (void *)&dummy, sizeof(int), NULL) == SUCCESS) {
+ new_op_array = zend_compile_file(&file_handle, ZEND_REQUIRE TSRMLS_CC);
+ zend_destroy_file_handle(&file_handle TSRMLS_CC);
+ } else {
+ new_op_array = NULL;
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION > 2)) || (PHP_MAJOR_VERSION > 5)
+ zend_file_handle_dtor(&file_handle TSRMLS_CC);
+#else
+ zend_file_handle_dtor(&file_handle);
+#endif
+ }
+
+ if (new_op_array) {
+ zval *result;
+
+ YAF_STORE_EG_ENVIRON();
+
+ EG(return_value_ptr_ptr) = &result;
+ EG(active_op_array) = new_op_array;
+
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION > 2)) || (PHP_MAJOR_VERSION > 5)
+ if (!EG(active_symbol_table)) {
+ zend_rebuild_symbol_table(TSRMLS_C);
+ }
+#endif
+ zend_execute(new_op_array TSRMLS_CC);
+
+ destroy_op_array(new_op_array TSRMLS_CC);
+ efree(new_op_array);
+ if (!EG(exception)) {
+ if (EG(return_value_ptr_ptr)) {
+ zval_ptr_dtor(EG(return_value_ptr_ptr));
+ }
+ }
+ YAF_RESTORE_EG_ENVIRON();
+ }
+ } else {
+ return 0;
+ }
+
+ return 1;
+}
+/* }}} */
+
+/** {{{ int yaf_internal_autoload(char * file_name, uint name_len, char **directory TSRMLS_DC)
+ */
+int yaf_internal_autoload(char *file_name, uint name_len, char **directory TSRMLS_DC) {
+ zval *library_dir, *global_dir;
+ char *q, *p, *seg;
+ uint seg_len, directory_len, status;
+ char *ext = YAF_G(ext);
+ smart_str buf = {0};
+
+ if (NULL == *directory) {
+ char *library_path;
+ uint library_path_len;
+ yaf_loader_t *loader;
+
+ loader = yaf_loader_instance(NULL, NULL, NULL TSRMLS_CC);
+
+ if (!loader) {
+ /* since only call from userspace can cause loader is NULL, exception throw will works well */
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s need to be initialize first", yaf_loader_ce->name);
+ return 0;
+ } else {
+ library_dir = zend_read_property(yaf_loader_ce, loader, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_LIBRARY), 1 TSRMLS_CC);
+ global_dir = zend_read_property(yaf_loader_ce, loader, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_GLOBAL_LIB), 1 TSRMLS_CC);
+
+ if (yaf_loader_is_local_namespace(loader, file_name, name_len TSRMLS_CC)) {
+ library_path = Z_STRVAL_P(library_dir);
+ library_path_len = Z_STRLEN_P(library_dir);
+ } else {
+ library_path = Z_STRVAL_P(global_dir);
+ library_path_len = Z_STRLEN_P(global_dir);
+ }
+ }
+
+ if (NULL == library_path) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s requires %s(which set the library_directory) to be initialized first", yaf_loader_ce->name, yaf_application_ce->name);
+ return 0;
+ }
+
+ smart_str_appendl(&buf, library_path, library_path_len);
+ } else {
+ smart_str_appendl(&buf, *directory, strlen(*directory));
+ efree(*directory);
+ }
+
+ directory_len = buf.len;
+
+ /* aussume all the path is not end in slash */
+ smart_str_appendc(&buf, DEFAULT_SLASH);
+
+ p = file_name;
+ q = p;
+
+ while (1) {
+ while(++q && *q != '_' && *q != '\0');
+
+ if (*q != '\0') {
+ seg_len = q - p;
+ seg = estrndup(p, seg_len);
+ smart_str_appendl(&buf, seg, seg_len);
+ efree(seg);
+ smart_str_appendc(&buf, DEFAULT_SLASH);
+ p = q + 1;
+ } else {
+ break;
+ }
+ }
+
+ if (YAF_G(lowcase_path)) {
+ /* all path of library is lowercase */
+ zend_str_tolower(buf.c + directory_len, buf.len - directory_len);
+ }
+
+ smart_str_appendl(&buf, p, strlen(p));
+ smart_str_appendc(&buf, '.');
+ smart_str_appendl(&buf, ext, strlen(ext));
+
+ smart_str_0(&buf);
+
+ if (directory) {
+ *(directory) = estrndup(buf.c, buf.len);
+ }
+
+ status = yaf_loader_import(buf.c, buf.len, 0 TSRMLS_CC);
+ smart_str_free(&buf);
+
+ if (!status)
+ return 0;
+
+ return 1;
+}
+/* }}} */
+
+/** {{{ int yaf_loader_register_namespace_single(yaf_loader_t *loader, zval *prefix TSRMLS_DC)
+ */
+int yaf_loader_register_namespace_single(yaf_loader_t *loader, zval *prefix TSRMLS_DC) {
+ zval *namespaces;
+ smart_str buf = {NULL, 0, 0};
+
+ namespaces = zend_read_property(yaf_loader_ce, loader, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_NAMESPACE), 1 TSRMLS_CC);
+
+ if (Z_TYPE_P(namespaces) == IS_NULL) {
+ smart_str_appendc(&buf, DEFAULT_DIR_SEPARATOR);
+ } else {
+ smart_str_appendl(&buf, Z_STRVAL_P(namespaces), Z_STRLEN_P(namespaces));
+ }
+
+ smart_str_appendl(&buf, Z_STRVAL_P(prefix), Z_STRLEN_P(prefix));
+ smart_str_appendc(&buf, DEFAULT_DIR_SEPARATOR);
+
+ ZVAL_STRINGL(namespaces, buf.c, buf.len, 1);
+
+ smart_str_free(&buf);
+
+ return 1;
+}
+/* }}} */
+
+/** {{{ int yaf_loader_register_namespace_multi(yaf_loader_t *loader, zval *prefixes TSRMLS_DC)
+ */
+int yaf_loader_register_namespace_multi(yaf_loader_t *loader, zval *prefixes TSRMLS_DC) {
+ zval *namespaces, **ppzval;
+ HashTable *ht;
+ smart_str buf = {0};
+
+ namespaces = zend_read_property(yaf_loader_ce, loader, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_NAMESPACE), 1 TSRMLS_CC);
+
+ if (Z_TYPE_P(namespaces) == IS_NULL) {
+ smart_str_appendc(&buf, DEFAULT_DIR_SEPARATOR);
+ } else {
+ smart_str_appendl(&buf, Z_STRVAL_P(namespaces), Z_STRLEN_P(namespaces));
+ }
+
+ ht = Z_ARRVAL_P(prefixes);
+ for(zend_hash_internal_pointer_reset(ht);
+ zend_hash_has_more_elements(ht) == SUCCESS;
+ zend_hash_move_forward(ht)) {
+
+ if (zend_hash_get_current_data(ht, (void**)&ppzval) == FAILURE) {
+ continue;
+ } else {
+ smart_str_appendl(&buf, Z_STRVAL_PP(ppzval), Z_STRLEN_PP(ppzval));
+ smart_str_appendc(&buf, DEFAULT_DIR_SEPARATOR);
+ }
+ }
+
+ ZVAL_STRINGL(namespaces, buf.c, buf.len, 1);
+
+ smart_str_free(&buf);
+
+ return 1;
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Loader::__construct(void)
+*/
+PHP_METHOD(yaf_loader, __construct) {
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Loader::__sleep(void)
+*/
+PHP_METHOD(yaf_loader, __sleep) {
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Loader::__wakeup(void)
+*/
+PHP_METHOD(yaf_loader, __wakeup) {
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Loader::__clone(void)
+*/
+PHP_METHOD(yaf_loader, __clone) {
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Loader::registerLocalNamespace(mixed $namespace)
+*/
+PHP_METHOD(yaf_loader, registerLocalNamespace) {
+ zval *namespaces;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &namespaces) == FAILURE) {
+ return;
+ }
+
+ if (IS_STRING == Z_TYPE_P(namespaces)) {
+ if (yaf_loader_register_namespace_single(getThis(), namespaces TSRMLS_CC)) {
+ RETURN_ZVAL(getThis(), 1, 0);
+ }
+ } else if (IS_ARRAY == Z_TYPE_P(namespaces)) {
+ if(yaf_loader_register_namespace_multi(getThis(), namespaces TSRMLS_CC)) {
+ RETURN_ZVAL(getThis(), 1, 0);
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameters provided, must be a string, or an array");
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Loader::getLocalNamespace(void)
+*/
+PHP_METHOD(yaf_loader, getLocalNamespace) {
+ zval *namespaces = zend_read_property(yaf_loader_ce, getThis(), ZEND_STRL(YAF_LOADER_PROPERTY_NAME_NAMESPACE), 1 TSRMLS_CC);
+ RETURN_ZVAL(namespaces, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Loader::clearLocalNamespace(void)
+*/
+PHP_METHOD(yaf_loader, clearLocalNamespace) {
+ zend_update_property_null(yaf_loader_ce, getThis(), ZEND_STRL(YAF_LOADER_PROPERTY_NAME_NAMESPACE) TSRMLS_CC);
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Loader::isLocalName(string $class_name)
+*/
+PHP_METHOD(yaf_loader, isLocalName) {
+ zval *name;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &name) == FAILURE) {
+ return;
+ }
+
+ if (Z_TYPE_P(name) != IS_STRING) {
+ RETURN_FALSE;
+ }
+
+ RETURN_BOOL(yaf_loader_is_local_namespace(getThis(), Z_STRVAL_P(name), Z_STRLEN_P(name) TSRMLS_CC));
+}
+/* }}} */
+
+/** {{{ proto public static Yaf_Loader::import($file)
+*/
+PHP_METHOD(yaf_loader, import) {
+ char *file;
+ uint len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s" ,&file, &len) == FAILURE) {
+ return;
+ }
+
+ if (!len) {
+ RETURN_FALSE;
+ } else {
+ int retval = 0;
+
+ if (!IS_ABSOLUTE_PATH(file, len)) {
+ yaf_loader_t *loader = yaf_loader_instance(NULL, NULL, NULL TSRMLS_CC);
+ if (!loader) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s need to be initialize first", yaf_loader_ce->name);
+ RETURN_FALSE;
+ } else {
+ zval *library = zend_read_property(yaf_loader_ce, loader, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_LIBRARY), 1 TSRMLS_CC);
+ len = spprintf(&file, 0, "%s%c%s", Z_STRVAL_P(library), DEFAULT_SLASH, file);
+ }
+ }
+
+ retval = (zend_hash_exists(&EG(included_files), file, len + 1));
+
+ if (retval) {
+ RETURN_TRUE;
+ }
+
+ RETURN_BOOL(yaf_loader_import(file, len, 0 TSRMLS_CC));
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Loader::autoload($class_name)
+*/
+PHP_METHOD(yaf_loader, autoload) {
+ char *class_name, *app_directory, *directory = NULL, *file_name = NULL;
+#ifdef YAF_HAVE_NAMESPACE
+ char *origin_lcname = NULL;
+#endif
+ uint separator_len, class_name_len, file_name_len = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &class_name, &class_name_len) == FAILURE) {
+ return;
+ }
+
+ separator_len = strlen(YAF_G(name_separator));
+ app_directory = YAF_G(directory);
+
+ do {
+ if (!class_name_len) {
+ break;
+ }
+#ifdef YAF_HAVE_NAMESPACE
+ {
+ int pos = 0;
+ origin_lcname = estrndup(class_name, class_name_len);
+ class_name = origin_lcname;
+ while (pos < class_name_len) {
+ if (*(class_name + pos) == '\\') {
+ *(class_name + pos) = '_';
+ }
+ pos += 1;
+ }
+ }
+#endif
+
+ if (strncmp(class_name, YAF_LOADER_RESERVERD, YAF_LOADER_LEN_RESERVERD) == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "You should not use '%s' as class name prefix", YAF_LOADER_RESERVERD);
+ }
+
+ if (yaf_loader_is_category(class_name, class_name_len, YAF_LOADER_MODEL, YAF_LOADER_LEN_MODEL TSRMLS_CC)) {
+ /* this is a model class */
+ spprintf(&directory, 0, "%s/%s", app_directory, YAF_MODEL_DIRECTORY_NAME);
+ file_name_len = class_name_len - separator_len - YAF_LOADER_LEN_MODEL;
+
+ if (YAF_G(name_suffix)) {
+ file_name = estrndup(class_name, file_name_len);
+ } else {
+ file_name = estrdup(class_name + YAF_LOADER_LEN_MODEL + separator_len);
+ }
+
+ break;
+ }
+
+ if (yaf_loader_is_category(class_name, class_name_len, YAF_LOADER_PLUGIN, YAF_LOADER_LEN_PLUGIN TSRMLS_CC)) {
+ /* this is a plugin class */
+ spprintf(&directory, 0, "%s/%s", app_directory, YAF_PLUGIN_DIRECTORY_NAME);
+ file_name_len = class_name_len - separator_len - YAF_LOADER_LEN_PLUGIN;
+
+ if (YAF_G(name_suffix)) {
+ file_name = estrndup(class_name, file_name_len);
+ } else {
+ file_name = estrdup(class_name + YAF_LOADER_LEN_PLUGIN + separator_len);
+ }
+
+ break;
+ }
+
+/* {{{ This only effects internally */
+ if (YAF_G(st_compatible) && (strncmp(class_name, YAF_LOADER_DAO, YAF_LOADER_LEN_DAO) == 0
+ || strncmp(class_name, YAF_LOADER_SERVICE, YAF_LOADER_LEN_SERVICE) == 0)) {
+ /* this is a model class */
+ spprintf(&directory, 0, "%s/%s", app_directory, YAF_MODEL_DIRECTORY_NAME);
+ }
+/* }}} */
+
+ file_name_len = class_name_len;
+ file_name = class_name;
+
+ } while(0);
+
+ if (!app_directory && directory) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Couldn't load a framework MVC class without an %s initializing", yaf_application_ce->name);
+ RETURN_FALSE;
+ }
+
+ if (!YAF_G(use_spl_autoload)) {
+ /** directory might be NULL since we passed a NULL */
+ if (yaf_internal_autoload(file_name, file_name_len, &directory TSRMLS_CC)) {
+ if (zend_hash_exists(EG(class_table), zend_str_tolower_dup(class_name, class_name_len), class_name_len + 1)) {
+#ifdef YAF_HAVE_NAMESPACE
+ if (origin_lcname) {
+ efree(origin_lcname);
+ }
+#endif
+ if (directory) {
+ efree(directory);
+ }
+
+ if (file_name != class_name) {
+ efree(file_name);
+ }
+
+ RETURN_TRUE;
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_STRICT, "Could not find class %s in %s", class_name, directory);
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find script %s", directory);
+ }
+
+#ifdef YAF_HAVE_NAMESPACE
+ if (origin_lcname) {
+ efree(origin_lcname);
+ }
+#endif
+ if (directory) {
+ efree(directory);
+ }
+ if (file_name != class_name) {
+ efree(file_name);
+ }
+ RETURN_TRUE;
+ } else {
+ if (yaf_internal_autoload(file_name, file_name_len, &directory TSRMLS_CC) &&
+ zend_hash_exists(EG(class_table), zend_str_tolower_dup(class_name, class_name_len), class_name_len + 1)) {
+#ifdef YAF_HAVE_NAMESPACE
+ if (origin_lcname) {
+ efree(origin_lcname);
+ }
+#endif
+ if (directory) {
+ efree(directory);
+ }
+ if (file_name != class_name) {
+ efree(file_name);
+ }
+ RETURN_TRUE;
+ }
+#ifdef YAF_HAVE_NAMESPACE
+ if (origin_lcname) {
+ efree(origin_lcname);
+ }
+#endif
+ if (directory) {
+ efree(directory);
+ }
+ if (file_name != class_name) {
+ efree(file_name);
+ }
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Loader::getInstance($library = NULL, $global_library = NULL)
+*/
+PHP_METHOD(yaf_loader, getInstance) {
+ char *library = NULL;
+ char *global = NULL;
+ int library_len = 0;
+ int global_len = 0;
+ yaf_loader_t *loader;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &library, &library_len, &global, &global_len) == FAILURE) {
+ loader = yaf_loader_instance(NULL, NULL, NULL TSRMLS_CC);
+ } else {
+ loader = yaf_loader_instance(NULL, library, global TSRMLS_CC);
+ }
+
+ if (loader)
+ RETURN_ZVAL(loader, 1, 0);
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Loader::__desctruct(void)
+*/
+PHP_METHOD(yaf_loader, __destruct) {
+}
+/* }}} */
+
+/** {{{ proto yaf_override_spl_autoload($class_name)
+*/
+PHP_FUNCTION(yaf_override_spl_autoload) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is disabled by ap.use_spl_autoload", YAF_SPL_AUTOLOAD_REGISTER_NAME);
+ RETURN_BOOL(0);
+}
+/* }}} */
+
+/** {{{ yaf_loader_methods
+*/
+zend_function_entry yaf_loader_methods[] = {
+ PHP_ME(yaf_loader, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
+ PHP_ME(yaf_loader, __clone, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CLONE)
+ PHP_ME(yaf_loader, __sleep, NULL, ZEND_ACC_PRIVATE)
+ PHP_ME(yaf_loader, __wakeup, NULL, ZEND_ACC_PRIVATE)
+ PHP_ME(yaf_loader, autoload, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_loader, getInstance, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ PHP_ME(yaf_loader, registerLocalNamespace, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_loader, getLocalNamespace, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_loader, clearLocalNamespace, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_loader, isLocalName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_loader, import, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(loader) {
+ zend_class_entry ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Loader", "Yaf\\Loader", yaf_loader_methods);
+ yaf_loader_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+ yaf_loader_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+
+ zend_declare_property_null(yaf_loader_ce, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_NAMESPACE), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_loader_ce, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_LIBRARY), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_loader_ce, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_GLOBAL_LIB), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_loader_ce, ZEND_STRL(YAF_LOADER_PROPERTY_NAME_INSTANCE), ZEND_ACC_PROTECTED|ZEND_ACC_STATIC TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_loader.h b/yaf_loader.h
new file mode 100644
index 0000000000..736ab352d0
--- /dev/null
+++ b/yaf_loader.h
@@ -0,0 +1,107 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef YAF_LOADER_H
+#define YAF_LOADER_H
+
+#define YAF_DEFAULT_VIEW_EXT "phtml"
+#define YAF_DEFAULT_LIBRARY_EXT YAF_DEFAULT_CONTROLLER_EXT
+
+#define YAF_LIBRARY_DIRECTORY_NAME "library"
+#define YAF_CONTROLLER_DIRECTORY_NAME "controller"
+#define YAF_PLUGIN_DIRECTORY_NAME "plugins"
+#define YAF_MODULE_DIRECTORY_NAME "modules"
+#define YAF_VIEW_DIRECTORY_NAME "views"
+#define YAF_MODEL_DIRECTORY_NAME "models"
+
+#define YAF_SPL_AUTOLOAD_REGISTER_NAME "spl_autoload_register"
+#define YAF_AUTOLOAD_FUNC_NAME "autoload"
+#define YAF_LOADER_PROPERTY_NAME_INSTANCE "_instance"
+#define YAF_LOADER_PROPERTY_NAME_NAMESPACE "_local_ns"
+
+#define YAF_LOADER_CONTROLLER "Controller"
+#define YAF_LOADER_LEN_CONTROLLER 10
+#define YAF_LOADER_MODEL "Model"
+#define YAF_LOADER_LEN_MODEL 5
+#define YAF_LOADER_PLUGIN "Plugin"
+#define YAF_LOADER_LEN_PLUGIN 6
+#define YAF_LOADER_RESERVERD "Yaf_"
+#define YAF_LOADER_LEN_RESERVERD 3
+
+/* {{{ This only effects internally */
+#define YAF_LOADER_DAO "Dao_"
+#define YAF_LOADER_LEN_DAO 4
+#define YAF_LOADER_SERVICE "Service_"
+#define YAF_LOADER_LEN_SERVICE 8
+/* }}} */
+
+#define YAF_LOADER_PROPERTY_NAME_LIBRARY "_library"
+#define YAF_LOADER_PROPERTY_NAME_GLOBAL_LIB "_global_library"
+
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION > 2)) || (PHP_MAJOR_VERSION > 5)
+#define YAF_STORE_EG_ENVIRON() \
+ { \
+ zval ** __old_return_value_pp = EG(return_value_ptr_ptr); \
+ zend_op ** __old_opline_ptr = EG(opline_ptr); \
+ zend_op_array * __old_op_array = EG(active_op_array);
+
+#define YAF_RESTORE_EG_ENVIRON() \
+ EG(return_value_ptr_ptr) = __old_return_value_pp;\
+ EG(opline_ptr) = __old_opline_ptr; \
+ EG(active_op_array) = __old_op_array; \
+ }
+
+#else
+
+#define YAF_STORE_EG_ENVIRON() \
+ { \
+ zval ** __old_return_value_pp = EG(return_value_ptr_ptr); \
+ zend_op ** __old_opline_ptr = EG(opline_ptr); \
+ zend_op_array * __old_op_array = EG(active_op_array); \
+ zend_function_state * __old_func_state = EG(function_state_ptr);
+
+#define YAF_RESTORE_EG_ENVIRON() \
+ EG(return_value_ptr_ptr) = __old_return_value_pp;\
+ EG(opline_ptr) = __old_opline_ptr; \
+ EG(active_op_array) = __old_op_array; \
+ EG(function_state_ptr) = __old_func_state; \
+ }
+
+#endif
+
+extern zend_class_entry *yaf_loader_ce;
+
+int yaf_internal_autoload(char *file_name, uint name_len, char **directory TSRMLS_DC);
+int yaf_loader_import(char *path, int len, int use_path TSRMLS_DC);
+int yaf_loader_compose(char *path, int len, int use_path TSRMLS_DC);
+int yaf_register_autoloader(yaf_loader_t *loader TSRMLS_DC);
+yaf_loader_t * yaf_loader_instance(yaf_loader_t *this_ptr, char *library_path, char *global_path TSRMLS_DC);
+
+extern PHPAPI int php_stream_open_for_zend_ex(const char *filename, zend_file_handle *handle, int mode TSRMLS_DC);
+
+YAF_STARTUP_FUNCTION(loader);
+
+#endif
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_logo.h b/yaf_logo.h
new file mode 100644
index 0000000000..a20dfec667
--- /dev/null
+++ b/yaf_logo.h
@@ -0,0 +1,182 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef YAF_LOGO_H
+#define YAF_LOGO_H
+
+#define YAF_LOGO_MIME_TYPE "image/png"
+#define YAF_LOGO_GUID "YAF-LOGO-LARUNECE-COM"
+#define YAF_SUPPORT_URL "http://pecl.php.net/package/yaf"
+#define YAF_LOGO_IMG "<a href=" YAF_SUPPORT_URL "> \
+ <img src=\"?="YAF_LOGO_GUID"\" alt=\"Yaf logo\" /></a>\n"
+
+static const unsigned char yaf_logo[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
+ 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x15,
+ 0x08, 0x06, 0x00, 0x00, 0x00, 0xbe, 0x35, 0x35, 0x5f, 0x00, 0x00, 0x00,
+ 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61,
+ 0x05, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b,
+ 0x10, 0x00, 0x00, 0x0b, 0x10, 0x01, 0xad, 0x23, 0xbd, 0x75, 0x00, 0x00,
+ 0x00, 0x1f, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61,
+ 0x72, 0x65, 0x00, 0x4d, 0x61, 0x63, 0x72, 0x6f, 0x6d, 0x65, 0x64, 0x69,
+ 0x61, 0x20, 0x46, 0x69, 0x72, 0x65, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x20,
+ 0x38, 0xb5, 0x68, 0xd2, 0x78, 0x00, 0x00, 0x06, 0x1a, 0x49, 0x44, 0x41,
+ 0x54, 0x48, 0x4b, 0x95, 0x55, 0x09, 0x4c, 0x94, 0x47, 0x14, 0x46, 0x04,
+ 0x85, 0x72, 0x28, 0x42, 0x6d, 0x04, 0x43, 0x22, 0xa4, 0x96, 0x43, 0x0e,
+ 0x39, 0x2c, 0x6a, 0x23, 0x56, 0xb0, 0x50, 0x35, 0x1c, 0x86, 0x88, 0x06,
+ 0x10, 0x31, 0x20, 0xa0, 0xc2, 0x7a, 0x21, 0xa8, 0xa0, 0x20, 0xc8, 0x2d,
+ 0x0d, 0x97, 0x18, 0x56, 0x10, 0xb1, 0x40, 0x11, 0x2c, 0xe5, 0x58, 0xb1,
+ 0x88, 0xda, 0x02, 0x0a, 0x04, 0x13, 0xb9, 0x94, 0x86, 0xd6, 0xc6, 0xb6,
+ 0x11, 0x49, 0x4b, 0x8b, 0x42, 0xbd, 0x5d, 0x5e, 0xbf, 0x37, 0x89, 0x84,
+ 0x15, 0xb4, 0xba, 0xc9, 0x66, 0x7f, 0xf8, 0x67, 0xe6, 0x7d, 0xd7, 0x7b,
+ 0xa3, 0xa4, 0xf4, 0x8e, 0x1f, 0x22, 0x52, 0xee, 0xeb, 0xeb, 0xd3, 0xba,
+ 0x7a, 0xf5, 0xaa, 0xda, 0x54, 0x5b, 0xf8, 0x7d, 0x77, 0x77, 0x77, 0x69,
+ 0x57, 0x57, 0xd7, 0xa3, 0xea, 0xea, 0x6a, 0x73, 0x33, 0x33, 0xb3, 0x19,
+ 0xef, 0x78, 0xf4, 0xd4, 0xcb, 0xce, 0x9d, 0x3b, 0x37, 0xfd, 0xc8, 0x91,
+ 0x23, 0x2a, 0x07, 0x0e, 0x1c, 0x30, 0x09, 0x0d, 0x0d, 0x75, 0x44, 0xe1,
+ 0x92, 0xf6, 0xf6, 0xf6, 0xf0, 0x0b, 0x17, 0x2e, 0xcc, 0x7c, 0x7d, 0xc7,
+ 0xc8, 0xc8, 0xc8, 0x87, 0x32, 0x99, 0x2c, 0xf0, 0xe4, 0xc9, 0x93, 0x7d,
+ 0x31, 0x31, 0x31, 0xff, 0x38, 0x38, 0x38, 0xf8, 0xf0, 0x5e, 0x80, 0x9a,
+ 0xf6, 0xde, 0x20, 0xda, 0xda, 0xda, 0xe6, 0xe7, 0xe4, 0xe4, 0xb8, 0xfa,
+ 0xf8, 0xf8, 0x78, 0x6d, 0xd9, 0xb2, 0xe5, 0x2f, 0x6f, 0x6f, 0x6f, 0x3a,
+ 0x7e, 0xfc, 0x38, 0xa1, 0x40, 0x4f, 0x5d, 0x5d, 0x9d, 0xf5, 0x9b, 0x0e,
+ 0x2c, 0x2c, 0x2c, 0xb4, 0xc8, 0xcb, 0xcb, 0x7b, 0xea, 0xe6, 0xe6, 0xf6,
+ 0xcb, 0x9e, 0x3d, 0x7b, 0x3c, 0x00, 0xdc, 0xec, 0xbd, 0x8a, 0xdf, 0xb9,
+ 0x73, 0x67, 0x56, 0x53, 0x53, 0x53, 0x52, 0x78, 0x78, 0xf8, 0xf0, 0xca,
+ 0x95, 0x2b, 0xc9, 0xd4, 0xd4, 0x94, 0x0e, 0x1e, 0x3c, 0x48, 0x49, 0x49,
+ 0x49, 0xcf, 0xc1, 0xac, 0xa1, 0xb6, 0xb6, 0xd6, 0xea, 0xd5, 0x81, 0xcc,
+ 0xac, 0xb3, 0xb3, 0xf3, 0xb3, 0xa2, 0xa2, 0xa2, 0x4d, 0xd7, 0xae, 0x5d,
+ 0xdb, 0xd4, 0xd3, 0xd3, 0xe3, 0x57, 0x5f, 0x5f, 0x3f, 0xbc, 0x71, 0xe3,
+ 0x46, 0xf2, 0xf5, 0xf5, 0x7d, 0x0e, 0xd0, 0x32, 0xec, 0xb3, 0x7a, 0x67,
+ 0x05, 0x6e, 0xdc, 0xb8, 0xe1, 0x91, 0x91, 0x91, 0xf1, 0x93, 0x95, 0x95,
+ 0x15, 0xe9, 0xea, 0xea, 0x12, 0xfc, 0x23, 0x0b, 0x0b, 0x8b, 0x17, 0x1b,
+ 0x36, 0x6c, 0xa8, 0x38, 0x73, 0xe6, 0x8c, 0xf3, 0x44, 0x26, 0xec, 0x75,
+ 0x47, 0x47, 0x47, 0xe8, 0xa9, 0x53, 0xa7, 0xbe, 0xc1, 0xbb, 0xd1, 0x9a,
+ 0x9a, 0x1a, 0xaa, 0xa8, 0xa8, 0xa0, 0x7d, 0xfb, 0xf6, 0x11, 0x14, 0x23,
+ 0xc8, 0x2f, 0xdf, 0xbe, 0x7d, 0xfb, 0xf7, 0x00, 0x6d, 0xf3, 0xbf, 0x0a,
+ 0xc0, 0xe7, 0x59, 0xd8, 0x9c, 0xeb, 0xee, 0xee, 0x3e, 0xa6, 0xa5, 0xa5,
+ 0x45, 0x6a, 0x6a, 0x6a, 0xa4, 0xa7, 0xa7, 0xc7, 0x07, 0x3d, 0x28, 0x2d,
+ 0x2d, 0xfd, 0x74, 0xaa, 0x03, 0x38, 0x84, 0xf0, 0x57, 0x7f, 0xf7, 0xee,
+ 0xdd, 0xc5, 0xc1, 0xc1, 0xc1, 0x2f, 0x5c, 0x5c, 0x5c, 0x28, 0x24, 0x24,
+ 0x84, 0xb2, 0xb2, 0xb2, 0x68, 0xf9, 0xf2, 0xe5, 0xe4, 0xe8, 0xe8, 0x28,
+ 0x0f, 0x08, 0x08, 0x88, 0x6f, 0x69, 0x69, 0xd1, 0x7a, 0x2b, 0x80, 0xa8,
+ 0xa8, 0x28, 0xe7, 0xcd, 0x9b, 0x37, 0xdf, 0x34, 0x36, 0x36, 0x26, 0x65,
+ 0x65, 0x65, 0x52, 0x55, 0x55, 0x25, 0x3f, 0x3f, 0x3f, 0x2a, 0x28, 0x28,
+ 0x08, 0xe0, 0xb4, 0x5f, 0xba, 0x74, 0xc9, 0xb0, 0xa4, 0xa4, 0x24, 0x19,
+ 0x52, 0xe6, 0x55, 0x56, 0x56, 0xe6, 0xc1, 0xff, 0x3c, 0x04, 0x30, 0xbf,
+ 0xa1, 0xa1, 0xe1, 0x63, 0x0e, 0xe6, 0x8e, 0x1d, 0x3b, 0x52, 0x9d, 0x9d,
+ 0x9d, 0x89, 0xbf, 0xfe, 0xfe, 0xfe, 0x04, 0xef, 0xc9, 0xdc, 0xdc, 0x9c,
+ 0x56, 0xac, 0x58, 0xd1, 0x1e, 0x18, 0x18, 0xe8, 0xf0, 0xc6, 0xe2, 0xbd,
+ 0xbd, 0xbd, 0x9a, 0x90, 0x27, 0x26, 0x22, 0x22, 0xe2, 0x19, 0x4b, 0xad,
+ 0xae, 0xae, 0x4e, 0xfa, 0xfa, 0xfa, 0x32, 0xc8, 0x19, 0xd1, 0xdf, 0xdf,
+ 0x3f, 0x13, 0xc8, 0xdd, 0x21, 0xeb, 0x8f, 0x50, 0xe0, 0xb1, 0x54, 0x2a,
+ 0x95, 0xf3, 0x17, 0x4a, 0xc9, 0xa1, 0xd4, 0x18, 0x3c, 0x6f, 0xc1, 0x73,
+ 0x14, 0xce, 0xf0, 0x39, 0x71, 0xe2, 0x44, 0xa1, 0xa5, 0xa5, 0x65, 0xf7,
+ 0xbc, 0x79, 0xf3, 0xc8, 0xce, 0xce, 0x8e, 0x4c, 0x4c, 0x4c, 0xc8, 0xc6,
+ 0xc6, 0xe6, 0xe9, 0xd6, 0xad, 0x5b, 0xc3, 0x60, 0xe9, 0x07, 0x53, 0x02,
+ 0x00, 0x23, 0x1d, 0x30, 0x4a, 0xe3, 0x54, 0xaf, 0x5b, 0xb7, 0x8e, 0xe0,
+ 0x15, 0x45, 0x46, 0x46, 0xba, 0x33, 0xe3, 0xc1, 0xc1, 0xc1, 0x66, 0x30,
+ 0xbc, 0xdb, 0xd8, 0xd8, 0x48, 0x17, 0x2f, 0x5e, 0x24, 0x14, 0x60, 0x35,
+ 0x08, 0x40, 0x44, 0x18, 0x13, 0x13, 0x13, 0x09, 0xec, 0xff, 0x3e, 0x7b,
+ 0xf6, 0x6c, 0xd5, 0xc0, 0xc0, 0x80, 0x29, 0x32, 0xf3, 0xd5, 0xb2, 0x65,
+ 0xcb, 0xc8, 0xc8, 0xc8, 0x88, 0x60, 0x85, 0x50, 0x60, 0xcd, 0x9a, 0x35,
+ 0xd1, 0x78, 0xaf, 0xad, 0x50, 0x1c, 0x7e, 0x29, 0x23, 0xd9, 0xb6, 0x41,
+ 0x41, 0x41, 0xe1, 0x87, 0x0f, 0x1f, 0x0e, 0x85, 0x74, 0xff, 0xf2, 0xe2,
+ 0xb0, 0xb0, 0x30, 0x02, 0xa3, 0x01, 0xa8, 0xf1, 0x2b, 0x06, 0xc7, 0xd8,
+ 0xf5, 0xeb, 0xd7, 0xe9, 0xf2, 0xe5, 0xcb, 0xc4, 0x00, 0xb8, 0xf0, 0xd1,
+ 0xa3, 0x47, 0x09, 0x36, 0xd1, 0xb1, 0x63, 0xc7, 0xa8, 0xb9, 0xb9, 0x99,
+ 0x60, 0x09, 0xa1, 0x45, 0x9f, 0x5c, 0xb9, 0x72, 0xa5, 0xbf, 0xac, 0xac,
+ 0xac, 0x0d, 0xca, 0x10, 0xbc, 0xa6, 0xf5, 0xeb, 0xd7, 0x93, 0xad, 0xad,
+ 0x2d, 0xed, 0xda, 0xb5, 0xab, 0x1d, 0x2a, 0xc6, 0x64, 0x67, 0x67, 0xeb,
+ 0x8e, 0x03, 0xe0, 0x61, 0xb2, 0x7f, 0xff, 0xfe, 0x2f, 0xc1, 0xf2, 0x8f,
+ 0xb4, 0xb4, 0xb4, 0xd8, 0xbd, 0x7b, 0xf7, 0xe6, 0x78, 0x7a, 0x7a, 0x92,
+ 0x81, 0x81, 0x01, 0xa3, 0x15, 0xc8, 0xab, 0xaa, 0xaa, 0x08, 0xad, 0x44,
+ 0xd8, 0xcc, 0x80, 0x08, 0x33, 0x80, 0x00, 0x5a, 0xbc, 0x03, 0x68, 0xd1,
+ 0x11, 0xcc, 0x92, 0xdf, 0xa1, 0xbf, 0x29, 0x3f, 0x3f, 0x5f, 0x0e, 0x89,
+ 0x45, 0x5e, 0x34, 0x35, 0x35, 0x69, 0xd5, 0xaa, 0x55, 0xb4, 0x6d, 0xdb,
+ 0xb6, 0xa7, 0x00, 0x50, 0x09, 0x5b, 0xf5, 0x15, 0xd8, 0xa3, 0x65, 0xa6,
+ 0xdf, 0xba, 0x75, 0xcb, 0x1b, 0x03, 0x62, 0x00, 0x8c, 0x1f, 0xc1, 0xdb,
+ 0x97, 0x7c, 0x10, 0x42, 0x24, 0x14, 0x00, 0x13, 0x02, 0x23, 0x82, 0xef,
+ 0x04, 0xe4, 0x04, 0x75, 0xd8, 0x47, 0x82, 0xb7, 0x02, 0x24, 0x07, 0x93,
+ 0x8b, 0x60, 0x28, 0x89, 0x16, 0xe3, 0xc0, 0xb9, 0xba, 0xba, 0xd2, 0x82,
+ 0x05, 0x0b, 0x68, 0xf1, 0xe2, 0xc5, 0x2f, 0x3d, 0x3c, 0x3c, 0xfe, 0x4c,
+ 0x48, 0x48, 0x88, 0x83, 0x82, 0x1f, 0xc1, 0x56, 0x75, 0x10, 0x9e, 0xa1,
+ 0xc4, 0xac, 0x21, 0xa7, 0xc1, 0x2b, 0x24, 0x98, 0xcd, 0x36, 0x60, 0x97,
+ 0x12, 0x17, 0x17, 0x57, 0x0f, 0xdf, 0x86, 0x59, 0xde, 0xd4, 0xd4, 0x54,
+ 0xd1, 0xb7, 0xe5, 0xe5, 0xe5, 0x82, 0x19, 0x17, 0x5e, 0xb2, 0x64, 0x09,
+ 0xcd, 0x99, 0x33, 0x47, 0xcc, 0x01, 0x6d, 0x6d, 0x6d, 0xd2, 0xd0, 0xd0,
+ 0x10, 0x00, 0xac, 0xad, 0xad, 0x89, 0x55, 0x43, 0x41, 0x32, 0x34, 0x34,
+ 0xa4, 0xd5, 0xab, 0x57, 0x13, 0xc6, 0xed, 0x10, 0x14, 0x8d, 0x46, 0x36,
+ 0xec, 0xc0, 0xfa, 0x73, 0xe4, 0x2a, 0x2c, 0x3e, 0x3e, 0xde, 0x4f, 0x09,
+ 0x52, 0xda, 0x7f, 0x8d, 0x0f, 0x24, 0x74, 0x83, 0x87, 0x6e, 0x38, 0xd8,
+ 0xed, 0xd5, 0x33, 0xa4, 0xee, 0x60, 0x99, 0x99, 0x3d, 0x7b, 0x9b, 0x99,
+ 0x99, 0x49, 0x00, 0x25, 0x24, 0xe4, 0x24, 0xcf, 0x9d, 0x3b, 0x97, 0x66,
+ 0xcf, 0x9e, 0x2d, 0x66, 0x81, 0x8a, 0x8a, 0x0a, 0xe9, 0xe8, 0xe8, 0x88,
+ 0x77, 0xac, 0x86, 0xbd, 0xbd, 0x3d, 0x71, 0xbf, 0xa3, 0x6d, 0x59, 0xb9,
+ 0x61, 0xdc, 0x0d, 0xbd, 0xb0, 0xf6, 0xa6, 0x44, 0x22, 0xe9, 0x00, 0x18,
+ 0x19, 0xac, 0xf9, 0x4e, 0xa9, 0xb5, 0xb5, 0xd5, 0xfb, 0xd0, 0xa1, 0x43,
+ 0xd2, 0xd8, 0xd8, 0x58, 0x29, 0x82, 0x23, 0xdd, 0xb9, 0x73, 0xa7, 0x14,
+ 0xa8, 0x2a, 0x51, 0xe8, 0x1e, 0x16, 0x8b, 0xc0, 0xa0, 0x45, 0xc4, 0x2f,
+ 0xa7, 0x1f, 0xb3, 0x5b, 0xf4, 0x2f, 0x26, 0x17, 0x2d, 0x5c, 0xb8, 0x50,
+ 0x48, 0xcd, 0xc3, 0x88, 0x41, 0x70, 0x51, 0x96, 0x1b, 0x43, 0x85, 0x25,
+ 0x1f, 0x43, 0x16, 0xe4, 0x00, 0xce, 0xdf, 0x7b, 0x08, 0x72, 0x0d, 0x3a,
+ 0x22, 0x1c, 0x1d, 0xe1, 0x84, 0x71, 0xac, 0x31, 0xa9, 0xdd, 0x92, 0x93,
+ 0x93, 0xe7, 0xc3, 0x33, 0x7f, 0x6c, 0x4a, 0xc7, 0x74, 0xaa, 0x4e, 0x4f,
+ 0x4f, 0x97, 0x01, 0x58, 0x1d, 0xd0, 0x3e, 0x5e, 0xba, 0x74, 0xa9, 0x38,
+ 0x9c, 0x81, 0x70, 0xa0, 0x78, 0x82, 0x61, 0x76, 0x0b, 0x76, 0x5e, 0x5e,
+ 0x5e, 0xa2, 0x35, 0xd7, 0xae, 0x5d, 0x2b, 0x7c, 0x86, 0xd4, 0xcf, 0x20,
+ 0xfd, 0x0f, 0x58, 0x17, 0x8f, 0x73, 0x12, 0xc0, 0x3e, 0x1f, 0xcf, 0x5d,
+ 0xe8, 0xa8, 0x62, 0x9c, 0xf7, 0x05, 0xec, 0x53, 0x1f, 0x2f, 0xce, 0xf3,
+ 0x39, 0x37, 0x37, 0xd7, 0x12, 0x8c, 0xca, 0x31, 0x56, 0xef, 0x62, 0x51,
+ 0x05, 0x0a, 0xba, 0x40, 0x89, 0x45, 0xe8, 0xe7, 0x45, 0x28, 0x38, 0x00,
+ 0x46, 0x2f, 0x51, 0x6c, 0x10, 0xde, 0x37, 0x22, 0xe1, 0x12, 0x58, 0x24,
+ 0x49, 0x49, 0x49, 0x11, 0xbf, 0x00, 0x29, 0x01, 0x3b, 0x09, 0x2e, 0x11,
+ 0x09, 0x0e, 0x7f, 0x82, 0xc0, 0x8d, 0x46, 0x47, 0x47, 0xc7, 0x70, 0x01,
+ 0xbe, 0x50, 0x50, 0x58, 0x0f, 0x7b, 0xdc, 0x61, 0xdd, 0xb7, 0xf8, 0x7f,
+ 0x33, 0x3a, 0xc5, 0x7c, 0xfc, 0xa2, 0xe1, 0xa4, 0x23, 0x54, 0x9e, 0x90,
+ 0xbc, 0x03, 0x28, 0x03, 0x50, 0xf0, 0x93, 0x09, 0xb7, 0x96, 0x32, 0x2c,
+ 0xf9, 0x0d, 0xbd, 0x3a, 0x82, 0xdf, 0x20, 0x0c, 0x98, 0xf1, 0x1b, 0x6d,
+ 0xaa, 0x49, 0x85, 0x71, 0xfb, 0x00, 0xa9, 0x1e, 0x45, 0x58, 0x45, 0xf1,
+ 0x89, 0x1f, 0x0c, 0xab, 0x30, 0xd4, 0xe9, 0x54, 0xb8, 0xe5, 0x18, 0x05,
+ 0x52, 0x68, 0x03, 0xb6, 0x11, 0x78, 0x56, 0x7d, 0xed, 0xd6, 0x9a, 0x86,
+ 0xff, 0xf7, 0x39, 0x39, 0x39, 0xbd, 0x80, 0x67, 0xad, 0x00, 0xd6, 0x88,
+ 0x36, 0x4c, 0xc4, 0x10, 0x52, 0xb8, 0x24, 0xb0, 0x4f, 0x05, 0xcc, 0x8c,
+ 0xd0, 0x0d, 0x23, 0x48, 0xf6, 0xe8, 0xe9, 0xd3, 0xa7, 0x27, 0x15, 0x1f,
+ 0x1a, 0x1a, 0x9a, 0x8f, 0x80, 0x27, 0x62, 0x20, 0x19, 0x2a, 0xa0, 0x42,
+ 0x22, 0x67, 0x22, 0x91, 0x3a, 0x53, 0xb1, 0x41, 0xea, 0xb3, 0x39, 0x3c,
+ 0xec, 0x2f, 0xae, 0x55, 0x1e, 0x2a, 0x3f, 0x63, 0xd4, 0x7a, 0x4d, 0x5c,
+ 0x8b, 0xf9, 0x50, 0x00, 0x46, 0xfd, 0x90, 0x5d, 0x8e, 0x0b, 0x64, 0xf4,
+ 0xf6, 0xed, 0xdb, 0x93, 0x8a, 0xf3, 0xfa, 0x87, 0x0f, 0x1f, 0xea, 0x62,
+ 0xf8, 0x28, 0x10, 0x7c, 0xeb, 0x4d, 0x87, 0x2b, 0x53, 0x13, 0x6c, 0xcb,
+ 0x90, 0xf6, 0xdf, 0x11, 0xb4, 0xc2, 0xe2, 0xe2, 0xe2, 0x48, 0x85, 0xd0,
+ 0x60, 0x37, 0xfe, 0x6e, 0x3a, 0x7f, 0xfe, 0x3c, 0xcf, 0x01, 0x39, 0xde,
+ 0x17, 0xdd, 0xbf, 0x7f, 0x7f, 0x72, 0xa2, 0x5f, 0xab, 0xf2, 0x1f, 0xf3,
+ 0xb5, 0xec, 0x46, 0x1d, 0x87, 0x54, 0xda, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_namespace.h b/yaf_namespace.h
new file mode 100644
index 0000000000..0395b39df0
--- /dev/null
+++ b/yaf_namespace.h
@@ -0,0 +1,62 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef YAF_NAMESPACE_H
+#define YAF_NAMESPACE_H
+
+#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION > 2)) || (PHP_MAJOR_VERSION > 5)
+#define YAF_BEGIN_ARG_INFO ZEND_BEGIN_ARG_INFO
+#define YAF_BEGIN_ARG_INFO_EX ZEND_BEGIN_ARG_INFO_EX
+
+#define namespace_switch(n) \
+ (YAF_G(use_namespace)? n##_ns : n)
+
+#define YAF_INIT_CLASS_ENTRY(ce, name, name_ns, methods) \
+ if(YAF_G(use_namespace)) { \
+ INIT_CLASS_ENTRY(ce, name_ns, methods); \
+ } else { \
+ INIT_CLASS_ENTRY(ce, name, methods); \
+ }
+#else
+
+#ifdef YAF_HAVE_NAMESPACE
+#undef YAF_HAVE_NAMESPACE
+#endif
+
+#define namespace_switch(n) (n)
+#define YAF_INIT_CLASS_ENTRY(ce, name, name_ns, methods) INIT_CLASS_ENTRY(ce, name, methods)
+#define YAF_BEGIN_ARG_INFO static ZEND_BEGIN_ARG_INFO
+#define YAF_BEGIN_ARG_INFO_EX static ZEND_BEGIN_ARG_INFO_EX
+
+#endif
+
+#define YAF_END_ARG_INFO ZEND_END_ARG_INFO
+#define YAF_ARG_INFO ZEND_ARG_INFO
+#define YAF_ARG_OBJ_INFO ZEND_ARG_OBJ_INFO
+#define YAF_ARG_ARRAY_INFO ZEND_ARG_ARRAY_INFO
+
+#endif /* PHP_YAF_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_plugin.c b/yaf_plugin.c
new file mode 100644
index 0000000000..7d91af7acb
--- /dev/null
+++ b/yaf_plugin.c
@@ -0,0 +1,149 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "main/SAPI.h"
+#include "Zend/zend_interfaces.h"
+#include "Zend/zend_exceptions.h"
+#include "Zend/zend_alloc.h"
+#include "ext/standard/info.h"
+#include "ext/standard/php_string.h"
+#include "zend_objects.h"
+
+#include "php_yaf.h"
+#include "yaf_namespace.h"
+#include "yaf_plugin.h"
+
+zend_class_entry * yaf_plugin_ce;
+
+/** {{{ ARG_INFO
+ */
+ZEND_BEGIN_ARG_INFO_EX(plugin_arg, 0, 0, 2)
+ ZEND_ARG_OBJ_INFO(0, request, Yaf_Request_Abstract, 0)
+ ZEND_ARG_OBJ_INFO(0, response, Yaf_Response_Abstract, 0)
+ZEND_END_ARG_INFO()
+
+#ifdef YAF_HAVE_NAMESPACE
+ZEND_BEGIN_ARG_INFO_EX(plugin_arg_ns, 0, 0, 2)
+ ZEND_ARG_OBJ_INFO(0, request, Yaf\\Request_Abstract, 0)
+ ZEND_ARG_OBJ_INFO(0, response, Yaf\\Response_Abstract, 0)
+ZEND_END_ARG_INFO()
+#endif
+/* }}} */
+
+/** {{{ proto public Yaf_Plugin::routerStartup(Yaf_Request_Abstract $request, Yaf_Response_Abstarct $response)
+*/
+PHP_METHOD(yaf_plugin, routerStartup) {
+ RETURN_TRUE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Plugin::routerShutdown(Yaf_Request_Abstract $request, Yaf_Response_Abstarct $response)
+*/
+PHP_METHOD(yaf_plugin, routerShutdown) {
+ RETURN_TRUE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Plugin::dispatchLoopStartup(Yaf_Request_Abstract $request, Yaf_Response_Abstarct $response)
+*/
+PHP_METHOD(yaf_plugin, dispatchLoopStartup) {
+ RETURN_TRUE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Plugin::preDispatch(Yaf_Request_Abstract $request, Yaf_Response_Abstarct $response)
+*/
+PHP_METHOD(yaf_plugin, preDispatch) {
+ RETURN_TRUE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Plugin::postDispatch(Yaf_Request_Abstract $request, Yaf_Response_Abstarct $response)
+*/
+PHP_METHOD(yaf_plugin, postDispatch) {
+ RETURN_TRUE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Plugin::dispatchLoopShutdown(Yaf_Request_Abstract $request, Yaf_Response_Abstarct $response)
+*/
+PHP_METHOD(yaf_plugin, dispatchLoopShutdown) {
+ RETURN_TRUE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Plugin::preResponse(Yaf_Request_Abstract $request, Yaf_Response_Abstarct $response)
+*/
+PHP_METHOD(yaf_plugin, preResponse) {
+ RETURN_TRUE;
+}
+/* }}} */
+
+/** {{{ yaf_plugin_methods
+*/
+zend_function_entry yaf_plugin_methods[] = {
+ PHP_ME(yaf_plugin, routerStartup, plugin_arg, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_plugin, routerShutdown, plugin_arg, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_plugin, dispatchLoopStartup, plugin_arg, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_plugin, dispatchLoopShutdown, plugin_arg, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_plugin, preDispatch, plugin_arg, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_plugin, postDispatch, plugin_arg, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_plugin, preResponse, plugin_arg, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+#ifdef YAF_HAVE_NAMESPACE
+zend_function_entry yaf_plugin_methods_ns[] = {
+ PHP_ME(yaf_plugin, routerStartup, plugin_arg_ns, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_plugin, routerShutdown, plugin_arg_ns, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_plugin, dispatchLoopStartup, plugin_arg_ns, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_plugin, dispatchLoopShutdown, plugin_arg_ns, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_plugin, preDispatch, plugin_arg_ns, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_plugin, postDispatch, plugin_arg_ns, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_plugin, preResponse, plugin_arg_ns, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+#endif
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(plugin) {
+ zend_class_entry ce;
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Plugin_Abstract", "Yaf\\Plugin\\Abstract", namespace_switch(yaf_plugin_methods));
+ yaf_plugin_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+ yaf_plugin_ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_plugin.h b/yaf_plugin.h
new file mode 100644
index 0000000000..318df6b74d
--- /dev/null
+++ b/yaf_plugin.h
@@ -0,0 +1,33 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef YAF_PLUGIN_H
+#define YAF_PLUGIN_H
+
+extern zend_class_entry *yaf_plugin_ce;
+
+YAF_STARTUP_FUNCTION(plugin);
+#endif
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_registry.c b/yaf_registry.c
new file mode 100644
index 0000000000..b66acb6a40
--- /dev/null
+++ b/yaf_registry.c
@@ -0,0 +1,230 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "main/SAPI.h"
+
+#include "php_yaf.h"
+#include "yaf_namespace.h"
+#include "yaf_registry.h"
+
+zend_class_entry *yaf_registry_ce;
+
+/* {{{ ARG_INFO
+ */
+ZEND_BEGIN_ARG_INFO_EX(yaf_registry_get_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_registry_has_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_registry_del_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_registry_set_arginfo, 0, 0, 2)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/** {{{ yaf_registry_t *yaf_registry_instance(yaf_registry_t *this_ptr TSRMLS_DC)
+*/
+yaf_registry_t *yaf_registry_instance(yaf_registry_t *this_ptr TSRMLS_DC) {
+ yaf_registry_t *instance = zend_read_static_property(yaf_registry_ce, ZEND_STRL(YAF_REGISTRY_PROPERTY_NAME_INSTANCE), 1 TSRMLS_CC);
+
+ if (Z_TYPE_P(instance) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(instance), yaf_registry_ce TSRMLS_CC)) {
+ zval *regs;
+
+ MAKE_STD_ZVAL(instance);
+ object_init_ex(instance, yaf_registry_ce);
+
+ MAKE_STD_ZVAL(regs);
+ array_init(regs);
+ zend_update_property(yaf_registry_ce, instance, ZEND_STRL(YAF_REGISTRY_PROPERTY_NAME_ENTRYS), regs TSRMLS_CC);
+ zend_update_static_property(yaf_registry_ce, ZEND_STRL(YAF_REGISTRY_PROPERTY_NAME_INSTANCE), instance TSRMLS_CC);
+ zval_ptr_dtor(&regs);
+ zval_ptr_dtor(&instance);
+ }
+
+ return instance;
+}
+/* }}} */
+
+/** {{{ int yaf_registry_is_set(char *name, int len TSRMLS_DC)
+ */
+int yaf_registry_is_set(char *name, int len TSRMLS_DC) {
+ yaf_registry_t *registry;
+ zval *entrys;
+
+ registry = yaf_registry_instance(NULL TSRMLS_CC);
+ entrys = zend_read_property(yaf_registry_ce, registry, ZEND_STRL(YAF_REGISTRY_PROPERTY_NAME_ENTRYS), 1 TSRMLS_CC);
+ return zend_hash_exists(Z_ARRVAL_P(entrys), name, len + 1);
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Registry::__construct(void)
+*/
+PHP_METHOD(yaf_registry, __construct) {
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Registry::__clone(void)
+*/
+PHP_METHOD(yaf_registry, __clone) {
+}
+/* }}} */
+
+/** {{{ proto public static Yaf_Registry::get($name)
+*/
+PHP_METHOD(yaf_registry, get) {
+ char *name;
+ uint len;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &len) == FAILURE) {
+ return;
+ } else {
+ zval **ppzval, *entrys;
+ yaf_registry_t *registry;
+
+ registry = yaf_registry_instance(NULL TSRMLS_CC);
+ entrys = zend_read_property(yaf_registry_ce, registry, ZEND_STRL(YAF_REGISTRY_PROPERTY_NAME_ENTRYS), 1 TSRMLS_CC);
+
+ if (entrys && Z_TYPE_P(entrys) == IS_ARRAY) {
+ if (zend_hash_find(Z_ARRVAL_P(entrys), name, len + 1, (void **) &ppzval) == SUCCESS) {
+ RETURN_ZVAL(*ppzval, 1, 0);
+ }
+ }
+ }
+
+ RETURN_NULL();
+}
+/* }}} */
+
+/** {{{ proto public staitc Yaf_Registry::set($name, $value)
+*/
+PHP_METHOD(yaf_registry, set) {
+ zval *value;
+ char *name;
+ uint len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name, &len, &value) == FAILURE) {
+ return;
+ } else {
+ yaf_registry_t *registry;
+ zval *entrys;
+
+ registry = yaf_registry_instance(NULL TSRMLS_CC);
+ entrys = zend_read_property(yaf_registry_ce, registry, ZEND_STRL(YAF_REGISTRY_PROPERTY_NAME_ENTRYS), 1 TSRMLS_CC);
+
+ Z_ADDREF_P(value);
+ if (zend_hash_update(Z_ARRVAL_P(entrys), name, len + 1, &value, sizeof(zval *), NULL) == SUCCESS) {
+ RETURN_TRUE;
+ }
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public staitc Yaf_Registry::del($name)
+*/
+PHP_METHOD(yaf_registry, del) {
+ char *name;
+ uint len;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &len) == FAILURE) {
+ return;
+ } else {
+ yaf_registry_t *registry;
+ zval *entrys;
+
+ registry = yaf_registry_instance(NULL TSRMLS_CC);
+ entrys = zend_read_property(yaf_registry_ce, registry, ZEND_STRL(YAF_REGISTRY_PROPERTY_NAME_ENTRYS), 1 TSRMLS_CC);
+
+ zend_hash_del(Z_ARRVAL_P(entrys), name, len + 1);
+ }
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Registry::has($name)
+*/
+PHP_METHOD(yaf_registry, has) {
+ char *name;
+ uint len;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &len) == FAILURE) {
+ return;
+ } else {
+ RETURN_BOOL(yaf_registry_is_set(name, len TSRMLS_CC));
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Registry::getInstance(void)
+*/
+PHP_METHOD(yaf_registry, getInstance) {
+ yaf_registry_t *registry = yaf_registry_instance(NULL TSRMLS_CC);
+ RETURN_ZVAL(registry, 1, 0);
+}
+/* }}} */
+
+/** {{{ yaf_registry_methods
+*/
+zend_function_entry yaf_registry_methods[] = {
+ PHP_ME(yaf_registry, __construct, NULL, ZEND_ACC_CTOR|ZEND_ACC_PRIVATE)
+ PHP_ME(yaf_registry, __clone, NULL, ZEND_ACC_CLONE|ZEND_ACC_PRIVATE)
+ PHP_ME(yaf_registry, get, yaf_registry_get_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ PHP_ME(yaf_registry, has, yaf_registry_has_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ PHP_ME(yaf_registry, set, yaf_registry_set_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ PHP_ME(yaf_registry, del, yaf_registry_del_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(registry) {
+ zend_class_entry ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Registry", "Yaf\\Registry", yaf_registry_methods);
+
+ yaf_registry_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+ yaf_registry_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+
+ zend_declare_property_null(yaf_registry_ce, YAF_STRL(YAF_REGISTRY_PROPERTY_NAME_INSTANCE), ZEND_ACC_PROTECTED|ZEND_ACC_STATIC TSRMLS_CC);
+ zend_declare_property_null(yaf_registry_ce, YAF_STRL(YAF_REGISTRY_PROPERTY_NAME_ENTRYS), ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_registry.h b/yaf_registry.h
new file mode 100644
index 0000000000..833a045bde
--- /dev/null
+++ b/yaf_registry.h
@@ -0,0 +1,36 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef YAF_REGISTRY_H
+#define YAF_REGISTRY_H
+
+#define YAF_REGISTRY_PROPERTY_NAME_ENTRYS "_entries"
+#define YAF_REGISTRY_PROPERTY_NAME_INSTANCE "_instance"
+
+extern zend_class_entry *yaf_registry_ce;
+
+YAF_STARTUP_FUNCTION(registry);
+#endif
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_request.c b/yaf_request.c
new file mode 100644
index 0000000000..42b3541beb
--- /dev/null
+++ b/yaf_request.c
@@ -0,0 +1,835 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "main/SAPI.h"
+#include "Zend/zend_interfaces.h"
+#include "Zend/zend_exceptions.h"
+#include "Zend/zend_alloc.h"
+#include "ext/standard/php_string.h"
+
+#include "php_yaf.h"
+#include "yaf_request.h"
+#include "yaf_namespace.h"
+#include "yaf_exception.h"
+
+#include "requests/simple.c"
+#include "requests/http.c"
+
+zend_class_entry *yaf_request_ce;
+
+/** {{{ ARG_INFO
+ */
+ZEND_BEGIN_ARG_INFO_EX(yaf_request_void_arginfo, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_request_set_routed_arginfo, 0, 0, 0)
+ ZEND_ARG_INFO(0, flag)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_request_set_module_name_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, module)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_request_set_controller_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, controller)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_request_set_action_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, action)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_request_set_baseuir_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, uir)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_request_set_request_uri_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, uir)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_request_set_param_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_request_get_param_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, default)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_request_getserver_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, default)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_request_getenv_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, default)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/** {{{ yaf_request_t * yaf_request_instance(zval *this_ptr, char *other TSRMLS_DC)
+*/
+yaf_request_t * yaf_request_instance(yaf_request_t *this_ptr, char *other TSRMLS_DC) {
+ yaf_request_t *instance = yaf_request_http_instance(this_ptr, NULL, other TSRMLS_CC);
+ return instance;
+}
+/* }}} */
+
+/** {{{ int yaf_request_set_base_uri(yaf_request_t *request, char *base_uri, char *request_uri TSRMLS_DC)
+*/
+int yaf_request_set_base_uri(yaf_request_t *request, char *base_uri, char *request_uri TSRMLS_DC) {
+ char *basename = NULL;
+ uint basename_len = 0;
+
+ if (!base_uri) {
+ zval *script_filename;
+ char *file_name, *ext = YAF_G(ext);
+ size_t file_name_len;
+ uint ext_len;
+
+ ext_len = strlen(ext);
+
+ script_filename = yaf_request_query(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("SCRIPT_FILENAME") TSRMLS_CC);
+
+ do {
+ if (script_filename && IS_STRING == Z_TYPE_P(script_filename)) {
+ zval *script_name, *phpself_name, *orig_name;
+
+ script_name = yaf_request_query(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("SCRIPT_NAME") TSRMLS_CC);
+ php_basename(Z_STRVAL_P(script_filename), Z_STRLEN_P(script_filename), ext, ext_len, &file_name, &file_name_len TSRMLS_CC);
+ if (script_name && IS_STRING == Z_TYPE_P(script_name)) {
+ char *script;
+ size_t script_len;
+
+ php_basename(Z_STRVAL_P(script_name), Z_STRLEN_P(script_name),
+ NULL, 0, &script, &script_len TSRMLS_CC);
+
+ if (strncmp(file_name, script, file_name_len) == 0) {
+ basename = Z_STRVAL_P(script_name);
+ basename_len = Z_STRLEN_P(script_name);
+ efree(script);
+ break;
+ }
+ efree(script);
+ }
+
+ phpself_name = yaf_request_query(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("PHP_SELF") TSRMLS_CC);
+ if (phpself_name && IS_STRING == Z_TYPE_P(phpself_name)) {
+ char *phpself;
+ size_t phpself_len;
+
+ php_basename(Z_STRVAL_P(phpself_name), Z_STRLEN_P(phpself_name), NULL, 0, &phpself, &phpself_len TSRMLS_CC);
+ if (strncmp(file_name, phpself, file_name_len) == 0) {
+ basename = Z_STRVAL_P(phpself_name);
+ basename_len = Z_STRLEN_P(phpself_name);
+ efree(phpself);
+ break;
+ }
+ efree(phpself);
+ }
+
+ orig_name = yaf_request_query(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("PHP_SELF") TSRMLS_CC);
+ if (orig_name && IS_STRING == Z_TYPE_P(orig_name)) {
+ char *orig;
+ size_t orig_len;
+ php_basename(Z_STRVAL_P(orig_name), Z_STRLEN_P(orig_name), NULL, 0, &orig, &orig_len TSRMLS_CC);
+ if (strncmp(file_name, orig, file_name_len) == 0) {
+ basename = Z_STRVAL_P(orig_name);
+ basename_len = Z_STRLEN_P(orig_name);
+ efree(orig);
+ break;
+ }
+ efree(orig);
+ }
+ }
+ } while (0);
+
+ if (basename && strstr(request_uri, basename) == request_uri) {
+ if (*(basename + basename_len - 1) == '/') {
+ --basename_len;
+ }
+ zend_update_property_stringl(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_BASE), basename, basename_len TSRMLS_CC);
+ return 1;
+ } else if (basename) {
+ char *dir;
+ size_t dir_len;
+
+ dir_len = php_dirname(basename, basename_len);
+ if (*(basename + dir_len - 1) == '/') {
+ --dir_len;
+ }
+
+ if (dir_len) {
+ dir = estrndup(basename, dir_len);
+ if (strstr(request_uri, dir) == request_uri) {
+ zend_update_property_string(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_BASE), dir TSRMLS_CC);
+ efree(dir);
+ return 1;
+ }
+ efree(dir);
+ }
+ }
+ zend_update_property_string(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_BASE), "" TSRMLS_CC);
+ return 1;
+ } else {
+ zend_update_property_string(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_BASE), base_uri TSRMLS_CC);
+ return 1;
+ }
+}
+/* }}} */
+
+/** {{{ zval * yaf_request_query(uint type, char * name, uint len TSRMLS_DC)
+*/
+zval * yaf_request_query(uint type, char * name, uint len TSRMLS_DC) {
+ zval **carrier, **ret;
+
+#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4)
+ zend_bool jit_initialization = (PG(auto_globals_jit) && !PG(register_globals) && !PG(register_long_arrays));
+#else
+ zend_bool jit_initialization = PG(auto_globals_jit);
+#endif
+
+ /* for phpunit test requirements */
+#if PHP_YAF_DEBUG
+ switch (type) {
+ case YAF_GLOBAL_VARS_POST:
+ (void)zend_hash_find(&EG(symbol_table), YAF_STRS("_POST"), (void **)&carrier);
+ break;
+ case YAF_GLOBAL_VARS_GET:
+ (void)zend_hash_find(&EG(symbol_table), YAF_STRS("_GET"), (void **)&carrier);
+ break;
+ case YAF_GLOBAL_VARS_COOKIE:
+ (void)zend_hash_find(&EG(symbol_table), YAF_STRS("_COOKIE"), (void **)&carrier);
+ break;
+ case YAF_GLOBAL_VARS_SERVER:
+ if (jit_initialization) {
+ zend_is_auto_global(ZEND_STRL("_SERVER") TSRMLS_CC);
+ }
+ (void)zend_hash_find(&EG(symbol_table), YAF_STRS("_SERVER"), (void **)&carrier);
+ break;
+ case YAF_GLOBAL_VARS_ENV:
+ if (jit_initialization) {
+ zend_is_auto_global(ZEND_STRL("_ENV") TSRMLS_CC);
+ }
+ carrier = &PG(http_globals)[YAF_GLOBAL_VARS_ENV];
+ break;
+ case YAF_GLOBAL_VARS_FILES:
+ carrier = &PG(http_globals)[YAF_GLOBAL_VARS_FILES];
+ break;
+ case YAF_GLOBAL_VARS_REQUEST:
+ if (jit_initialization) {
+ zend_is_auto_global(ZEND_STRL("_REQUEST") TSRMLS_CC);
+ }
+ (void)zend_hash_find(&EG(symbol_table), YAF_STRS("_REQUEST"), (void **)&carrier);
+ break;
+ default:
+ break;
+ }
+#else
+ switch (type) {
+ case YAF_GLOBAL_VARS_POST:
+ case YAF_GLOBAL_VARS_GET:
+ case YAF_GLOBAL_VARS_FILES:
+ case YAF_GLOBAL_VARS_COOKIE:
+ carrier = &PG(http_globals)[type];
+ break;
+ case YAF_GLOBAL_VARS_ENV:
+ if (jit_initialization) {
+ zend_is_auto_global(ZEND_STRL("_ENV") TSRMLS_CC);
+ }
+ carrier = &PG(http_globals)[type];
+ break;
+ case YAF_GLOBAL_VARS_SERVER:
+ if (jit_initialization) {
+ zend_is_auto_global(ZEND_STRL("_SERVER") TSRMLS_CC);
+ }
+ carrier = &PG(http_globals)[type];
+ break;
+ case YAF_GLOBAL_VARS_REQUEST:
+ if (jit_initialization) {
+ zend_is_auto_global(ZEND_STRL("_REQUEST") TSRMLS_CC);
+ }
+ (void)zend_hash_find(&EG(symbol_table), YAF_STRS("_REQUEST"), (void **)&carrier);
+ break;
+ default:
+ break;
+ }
+#endif
+
+ if (!carrier || !(*carrier)) {
+ zval *empty;
+ MAKE_STD_ZVAL(empty);
+ ZVAL_NULL(empty);
+ return empty;
+ }
+
+ if (!len) {
+ Z_ADDREF_P(*carrier);
+ return *carrier;
+ }
+
+ if (zend_hash_find(Z_ARRVAL_PP(carrier), name, len + 1, (void **)&ret) == FAILURE) {
+ zval *empty;
+ MAKE_STD_ZVAL(empty);
+ ZVAL_NULL(empty);
+ return empty;
+ }
+
+ Z_ADDREF_P(*ret);
+ return *ret;
+}
+/* }}} */
+
+/** {{{inline yaf_request_t * yaf_request_get_method(yaf_request_t *request TSRMLS_DC)
+*/
+inline yaf_request_t * yaf_request_get_method(yaf_request_t *request TSRMLS_DC) {
+ yaf_request_t *method = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_METHOD), 1 TSRMLS_CC);
+ return method;
+}
+/* }}} */
+
+/** {{{ inline yaf_request_t * yaf_request_get_language(yaf_request_t *instance TSRMLS_DC)
+*/
+inline zval * yaf_request_get_language(yaf_request_t *instance TSRMLS_DC) {
+ zval *lang;
+
+ lang = zend_read_property(yaf_request_ce, instance, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_LANG), 1 TSRMLS_CC);
+
+ if (IS_STRING != Z_TYPE_P(lang)) {
+ zval * accept_langs = yaf_request_query(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("HTTP_ACCEPT_LANGUAGE") TSRMLS_CC);
+
+ if (IS_STRING != Z_TYPE_P(accept_langs) || !Z_STRLEN_P(accept_langs)) {
+ return lang;
+ } else {
+ char *ptrptr, *seg;
+ uint prefer_len = 0;
+ double max_qvlaue = 0;
+ char *prefer = NULL;
+ char *langs = estrndup(Z_STRVAL_P(accept_langs), Z_STRLEN_P(accept_langs));
+
+ seg = php_strtok_r(langs, ",", &ptrptr);
+ while(seg) {
+ char *qvalue;
+ while( *(seg) == ' ') seg++ ;
+ /* Accept-Language: da, en-gb;q=0.8, en;q=0.7 */
+ if ((qvalue = strstr(seg, "q="))) {
+ float qval = (float)zend_string_to_double(qvalue + 2, seg - qvalue + 2);
+ if (qval > max_qvlaue) {
+ max_qvlaue = qval;
+ if (prefer) {
+ efree(prefer);
+ }
+ prefer_len = qvalue - seg - 1;
+ prefer = estrndup(seg, prefer_len);
+ }
+ } else {
+ if (max_qvlaue < 1) {
+ max_qvlaue = 1;
+ prefer_len = strlen(seg);
+ prefer = estrndup(seg, prefer_len);
+ }
+ }
+
+ seg = php_strtok_r(NULL, ",", &ptrptr);
+ }
+
+ if (prefer) {
+ zval *accept_language;
+ MAKE_STD_ZVAL(accept_language);
+ ZVAL_STRINGL(accept_language, prefer, prefer_len, 1);
+ zend_update_property(yaf_request_ce, instance, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_LANG), accept_language TSRMLS_CC);
+ efree(prefer);
+ efree(langs);
+ return accept_language;
+ }
+ efree(langs);
+ }
+ }
+ return lang;
+}
+/* }}} */
+
+/** {{{ inline int yaf_request_is_routed(yaf_request_t *request TSRMLS_DC)
+*/
+inline int yaf_request_is_routed(yaf_request_t *request TSRMLS_DC) {
+ yaf_request_t *routed = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ROUTED), 1 TSRMLS_CC);
+ return Z_LVAL_P(routed);
+}
+/* }}} */
+
+/** {{{ inline int yaf_request_is_dispatched(yaf_request_t *request TSRMLS_DC)
+*/
+inline int yaf_request_is_dispatched(yaf_request_t *request TSRMLS_DC) {
+ zval *dispatched = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_STATE), 1 TSRMLS_CC);
+ return Z_LVAL_P(dispatched);
+}
+/* }}} */
+
+/** {{{ inline int yaf_request_set_dispatched(yaf_request_t *instance, int flag TSRMLS_DC)
+*/
+inline int yaf_request_set_dispatched(yaf_request_t *instance, int flag TSRMLS_DC) {
+ zend_update_property_bool(yaf_request_ce, instance, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_STATE), flag TSRMLS_CC);
+ return 1;
+}
+/* }}} */
+
+/** {{{ inline int yaf_request_set_routed(yaf_request_t *request, int flag TSRMLS_DC)
+*/
+inline int yaf_request_set_routed(yaf_request_t *request, int flag TSRMLS_DC) {
+ zend_update_property_bool(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ROUTED), flag TSRMLS_CC);
+ return 1;
+}
+/* }}} */
+
+/** {{{ inline int yaf_request_set_params_single(yaf_request_t *request, char *key, int len, zval *value TSRMLS_DC)
+*/
+inline int yaf_request_set_params_single(yaf_request_t *request, char *key, int len, zval *value TSRMLS_DC) {
+ zval *params = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_PARAMS), 1 TSRMLS_CC);
+
+ if (zend_hash_update(Z_ARRVAL_P(params), key, len+1, &value, sizeof(zval *), NULL) == SUCCESS) {
+ Z_ADDREF_P(value);
+ return 1;
+ }
+
+ return 0;
+}
+/* }}} */
+
+/** {{{ inline int yaf_request_set_params_multi(yaf_request_t *request, zval *values TSRMLS_DC)
+*/
+inline int yaf_request_set_params_multi(yaf_request_t *request, zval *values TSRMLS_DC) {
+ zval *params = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_PARAMS), 1 TSRMLS_CC);
+ if (values && Z_TYPE_P(values) == IS_ARRAY) {
+ zend_hash_copy(Z_ARRVAL_P(params), Z_ARRVAL_P(values), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
+ return 1;
+ }
+ return 0;
+}
+/* }}} */
+
+/** {{{ inline zval * yaf_request_get_param(yaf_request_t *request, char *key, int len TSRMLS_DC)
+*/
+inline zval * yaf_request_get_param(yaf_request_t *request, char *key, int len TSRMLS_DC) {
+ zval **ppzval;
+ zval *params = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_PARAMS), 1 TSRMLS_CC);
+ if (zend_hash_find(Z_ARRVAL_P(params), key, len + 1, (void **) &ppzval) == SUCCESS) {
+ return *ppzval;
+ }
+ return NULL;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::isGet(void)
+*/
+YAF_REQUEST_IS_METHOD(Get);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::isPost(void)
+*/
+YAF_REQUEST_IS_METHOD(Post);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::isPut(void)
+*/
+YAF_REQUEST_IS_METHOD(Put);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::isHead(void)
+*/
+YAF_REQUEST_IS_METHOD(Head);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::isOptions(void)
+*/
+YAF_REQUEST_IS_METHOD(Options);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::isCli(void)
+*/
+YAF_REQUEST_IS_METHOD(Cli);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::isXmlHttpRequest(void)
+*/
+PHP_METHOD(yaf_request, isXmlHttpRequest) {
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::getEnv(mixed $name, mixed $default = NULL)
+*/
+YAF_REQUEST_METHOD(yaf_request, Env, YAF_GLOBAL_VARS_ENV);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::getServer(mixed $name, mixed $default = NULL)
+*/
+YAF_REQUEST_METHOD(yaf_request, Server, YAF_GLOBAL_VARS_SERVER);
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::getModuleName(void)
+*/
+PHP_METHOD(yaf_request, getModuleName) {
+ zval *module = zend_read_property(yaf_request_ce, getThis(), ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), 1 TSRMLS_CC);
+ RETVAL_ZVAL(module, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::getControllerName(void)
+*/
+PHP_METHOD(yaf_request, getControllerName) {
+ zval *controller = zend_read_property(yaf_request_ce, getThis(), ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), 1 TSRMLS_CC);
+ RETVAL_ZVAL(controller, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::getActionName(void)
+*/
+PHP_METHOD(yaf_request, getActionName) {
+ zval *action = zend_read_property(yaf_request_ce, getThis(), ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), 1 TSRMLS_CC);
+ RETVAL_ZVAL(action, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::setModuleName(string $module)
+*/
+PHP_METHOD(yaf_request, setModuleName) {
+ zval *module;
+ yaf_request_t *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &module) == FAILURE) {
+ return;
+ }
+
+ if (Z_TYPE_P(module) != IS_STRING) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expect a string module name");
+ RETURN_FALSE;
+ }
+
+ zend_update_property(yaf_request_ce, self, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), module TSRMLS_CC);
+
+ RETURN_ZVAL(self, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::setControllerName(string $controller)
+*/
+PHP_METHOD(yaf_request, setControllerName) {
+ zval *controller;
+ yaf_request_t *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &controller) == FAILURE) {
+ return;
+ }
+
+ if (Z_TYPE_P(controller) != IS_STRING) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expect a string controller name");
+ RETURN_FALSE;
+ }
+
+ zend_update_property(yaf_request_ce, getThis(), ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), controller TSRMLS_CC);
+
+ RETURN_ZVAL(self, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::setActionName(string $action)
+*/
+PHP_METHOD(yaf_request, setActionName) {
+ zval *action;
+ zval *self = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &action) == FAILURE) {
+ return;
+ }
+
+ if (Z_TYPE_P(action) != IS_STRING) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expect a string action name");
+ RETURN_FALSE;
+ }
+
+ zend_update_property(yaf_request_ce, getThis(), ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), action TSRMLS_CC);
+
+ RETURN_ZVAL(self, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::setParam(mixed $value)
+*/
+PHP_METHOD(yaf_request, setParam) {
+ uint argc;
+ yaf_request_t *self = getThis();
+
+ argc = ZEND_NUM_ARGS();
+
+ if (1 == argc) {
+ zval *value ;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) {
+ return;
+ }
+ if (value && Z_TYPE_P(value) == IS_ARRAY) {
+ if (yaf_request_set_params_multi(self, value TSRMLS_CC)) {
+ RETURN_ZVAL(self, 1, 0);
+ }
+ }
+ } else if (2 == argc) {
+ zval *value;
+ char *name;
+ uint len;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name, &len, &value) == FAILURE) {
+ return;
+ }
+
+ if (yaf_request_set_params_single(getThis(), name, len, value TSRMLS_CC)) {
+ RETURN_ZVAL(self, 1, 0);
+ }
+ } else {
+ WRONG_PARAM_COUNT;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::getParam(string $name, $mixed $default = NULL)
+*/
+PHP_METHOD(yaf_request, getParam) {
+ char *name;
+ uint len;
+ zval *def = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &name, &len, &def) == FAILURE) {
+ return;
+ } else {
+ zval *value = yaf_request_get_param(getThis(), name, len TSRMLS_CC);
+ if (value) {
+ RETURN_ZVAL(value, 1, 0);
+ }
+ if (def) {
+ RETURN_ZVAL(def, 1, 0);
+ }
+ }
+
+ RETURN_NULL();
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::getException(void)
+*/
+PHP_METHOD(yaf_request, getException) {
+ zval *exception = zend_read_property(yaf_request_ce, getThis(), ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_EXCEPTION), 1 TSRMLS_CC);
+ if (IS_OBJECT == Z_TYPE_P(exception)
+ && instanceof_function(Z_OBJCE_P(exception),
+#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 2)
+ zend_exception_get_default()
+#else
+ zend_exception_get_default(TSRMLS_C)
+#endif
+ TSRMLS_CC)) {
+ RETURN_ZVAL(exception, 1, 0);
+ }
+
+ RETURN_NULL();
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::getParams(void)
+*/
+PHP_METHOD(yaf_request, getParams) {
+ zval *params = zend_read_property(yaf_request_ce, getThis(), ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_PARAMS), 1 TSRMLS_CC);
+ RETURN_ZVAL(params, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::getLanguage(void)
+*/
+PHP_METHOD(yaf_request, getLanguage) {
+ zval *lang = yaf_request_get_language(getThis() TSRMLS_CC);
+ RETURN_ZVAL(lang, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::getMethod(void)
+*/
+PHP_METHOD(yaf_request, getMethod) {
+ zval *method = yaf_request_get_method(getThis() TSRMLS_CC);
+ RETURN_ZVAL(method, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::isDispatched(void)
+*/
+PHP_METHOD(yaf_request, isDispatched) {
+ RETURN_BOOL(yaf_request_is_dispatched(getThis() TSRMLS_CC));
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::setDispatched(void)
+*/
+PHP_METHOD(yaf_request, setDispatched) {
+ RETURN_BOOL(yaf_request_set_dispatched(getThis(), 1 TSRMLS_CC));
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::setBaseUri(string $name)
+*/
+PHP_METHOD(yaf_request, setBaseUri) {
+ zval *uri;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &uri) == FAILURE) {
+ return;
+ }
+
+ if (Z_TYPE_P(uri) != IS_STRING || !Z_STRLEN_P(uri)) {
+ RETURN_FALSE;
+ }
+
+ if (yaf_request_set_base_uri(getThis(), Z_STRVAL_P(uri), NULL TSRMLS_CC)) {
+ RETURN_ZVAL(getThis(), 1, 0);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::getBaseUri(string $name)
+*/
+PHP_METHOD(yaf_request, getBaseUri) {
+ zval *uri = zend_read_property(yaf_request_ce, getThis(), ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_BASE), 1 TSRMLS_CC);
+ RETURN_ZVAL(uri, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::getRequestUri(string $name)
+*/
+PHP_METHOD(yaf_request, getRequestUri) {
+ zval *uri = zend_read_property(yaf_request_ce, getThis(), ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_URI), 1 TSRMLS_CC);
+ RETURN_ZVAL(uri, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::setRequestUri(string $name)
+*/
+PHP_METHOD(yaf_request, setRequestUri) {
+ char *uri;
+ uint len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &uri, &len) == FAILURE) {
+ return;
+ }
+
+ zend_update_property_stringl(yaf_request_ce, getThis(), ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_URI), uri, len TSRMLS_CC);
+ RETURN_ZVAL(getThis(), 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::isRouted(void)
+*/
+PHP_METHOD(yaf_request, isRouted) {
+ RETURN_BOOL(yaf_request_is_routed(getThis() TSRMLS_CC));
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Request_Abstract::setRouted(void)
+*/
+PHP_METHOD(yaf_request, setRouted) {
+ if (yaf_request_set_routed(getThis(), 1 TSRMLS_CC)) {
+ RETURN_ZVAL(getThis(), 1, 0);
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ yaf_request_methods
+*/
+zend_function_entry yaf_request_methods[] = {
+ PHP_ME(yaf_request, isGet, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, isPost, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, isPut, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, isHead, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, isOptions, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, isCli, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, isXmlHttpRequest, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, getServer, yaf_request_getserver_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, getEnv, yaf_request_getenv_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, setParam, yaf_request_set_param_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, getParam, yaf_request_get_param_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, getParams, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, getException, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, getModuleName, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, getControllerName, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, getActionName, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, setModuleName, yaf_request_set_module_name_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, setControllerName, yaf_request_set_controller_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, setActionName, yaf_request_set_action_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, getMethod, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, getLanguage, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, setBaseUri, yaf_request_set_baseuir_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, getBaseUri, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, getRequestUri, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, setRequestUri, yaf_request_set_request_uri_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, isDispatched, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, setDispatched, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, isRouted, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_request, setRouted, yaf_request_set_routed_arginfo, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(request){
+ zend_class_entry ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Request_Abstract", "Yaf\\Request_Abstract", yaf_request_methods);
+ yaf_request_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+ yaf_request_ce->ce_flags = ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
+
+ zend_declare_property_null(yaf_request_ce, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), ZEND_ACC_PUBLIC TSRMLS_CC);
+ zend_declare_property_null(yaf_request_ce, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), ZEND_ACC_PUBLIC TSRMLS_CC);
+ zend_declare_property_null(yaf_request_ce, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), ZEND_ACC_PUBLIC TSRMLS_CC);
+ zend_declare_property_null(yaf_request_ce, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_METHOD), ZEND_ACC_PUBLIC TSRMLS_CC);
+ zend_declare_property_null(yaf_request_ce, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_PARAMS), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_request_ce, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_LANG), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_request_ce, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_EXCEPTION), ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ zend_declare_property_string(yaf_request_ce, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_BASE), "", ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_string(yaf_request_ce, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_URI), "", ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_bool(yaf_request_ce, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_STATE), 0, ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_bool(yaf_request_ce, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ROUTED), 0, ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ YAF_STARTUP(request_http);
+ YAF_STARTUP(request_simple);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_request.h b/yaf_request.h
new file mode 100644
index 0000000000..04ea94410c
--- /dev/null
+++ b/yaf_request.h
@@ -0,0 +1,103 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef YAF_REQUEST_H
+#define YAF_REQUEST_H
+
+#define YAF_REQUEST_PROPERTY_NAME_MODULE "module"
+#define YAF_REQUEST_PROPERTY_NAME_CONTROLLER "controller"
+#define YAF_REQUEST_PROPERTY_NAME_ACTION "action"
+#define YAF_REQUEST_PROPERTY_NAME_METHOD "method"
+#define YAF_REQUEST_PROPERTY_NAME_PARAMS "params"
+#define YAF_REQUEST_PROPERTY_NAME_URI "uri"
+#define YAF_REQUEST_PROPERTY_NAME_STATE "dispatched"
+#define YAF_REQUEST_PROPERTY_NAME_LANG "language"
+#define YAF_REQUEST_PROPERTY_NAME_ROUTED "routed"
+#define YAF_REQUEST_PROPERTY_NAME_BASE "_base_uri"
+#define YAF_REQUEST_PROPERTY_NAME_EXCEPTION "_exception"
+
+#define YAF_REQUEST_SERVER_URI "request_uri="
+
+#define YAF_GLOBAL_VARS_TYPE unsigned int
+#define YAF_GLOBAL_VARS_POST TRACK_VARS_POST
+#define YAF_GLOBAL_VARS_GET TRACK_VARS_GET
+#define YAF_GLOBAL_VARS_ENV TRACK_VARS_ENV
+#define YAF_GLOBAL_VARS_FILES TRACK_VARS_FILES
+#define YAF_GLOBAL_VARS_SERVER TRACK_VARS_SERVER
+#define YAF_GLOBAL_VARS_REQUEST TRACK_VARS_REQUEST
+#define YAF_GLOBAL_VARS_COOKIE TRACK_VARS_COOKIE
+
+#define YAF_REQUEST_IS_METHOD(x) \
+PHP_METHOD(yaf_request, is##x) {\
+ zval * method = zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_METHOD), 1 TSRMLS_CC);\
+ if (strncasecmp(#x, Z_STRVAL_P(method), Z_STRLEN_P(method)) == 0) { \
+ RETURN_TRUE; \
+ } \
+ RETURN_FALSE; \
+}
+
+#define YAF_REQUEST_METHOD(ce, x, type) \
+PHP_METHOD(ce, get##x) { \
+ char *name; \
+ int len; \
+ zval *ret; \
+ zval *def = NULL; \
+ if (ZEND_NUM_ARGS() == 0) {\
+ ret = yaf_request_query(type, NULL, 0 TSRMLS_CC);\
+ }else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &name, &len, &def) == FAILURE) {\
+ WRONG_PARAM_COUNT;\
+ } else { \
+ ret = yaf_request_query(type, name, len TSRMLS_CC); \
+ if (ZVAL_IS_NULL(ret)) {\
+ if (def != NULL) {\
+ RETURN_ZVAL(def, 1, 0); \
+ }\
+ }\
+ }\
+ RETURN_ZVAL(ret, 1, 0);\
+}
+
+extern zend_class_entry * yaf_request_ce;
+
+zval * yaf_request_query(uint type, char * name, uint len TSRMLS_DC);
+yaf_request_t * yaf_request_instance(yaf_request_t *this_ptr, char *info TSRMLS_DC);
+int yaf_request_set_base_uri(yaf_request_t *request, char *base_uri, char *request_uri TSRMLS_DC);
+PHPAPI void php_session_start(TSRMLS_D);
+
+inline zval * yaf_request_get_method(yaf_request_t *instance TSRMLS_DC);
+inline zval * yaf_request_get_param(yaf_request_t *instance, char *key, int len TSRMLS_DC);
+inline zval * yaf_request_get_language(yaf_request_t *instance TSRMLS_DC);
+
+inline int yaf_request_is_routed(yaf_request_t *request TSRMLS_DC);
+inline int yaf_request_is_dispatched(yaf_request_t *request TSRMLS_DC);
+inline int yaf_request_set_dispatched(yaf_request_t *request, int flag TSRMLS_DC);
+inline int yaf_request_set_routed(yaf_request_t *request, int flag TSRMLS_DC);
+inline int yaf_request_set_params_single(yaf_request_t *instance, char *key, int len, zval *value TSRMLS_DC);
+inline int yaf_request_set_params_multi(yaf_request_t *instance, zval *values TSRMLS_DC);
+
+YAF_STARTUP_FUNCTION(request);
+
+#endif
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_response.c b/yaf_response.c
new file mode 100644
index 0000000000..6675cdbd81
--- /dev/null
+++ b/yaf_response.c
@@ -0,0 +1,383 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "main/SAPI.h"
+#include "Zend/zend_interfaces.h"
+
+#include "php_yaf.h"
+#include "yaf_namespace.h"
+#include "yaf_response.h"
+#include "yaf_exception.h"
+
+zend_class_entry *yaf_response_ce;
+
+#include "response/http.c"
+#include "response/cli.c"
+
+/** {{{ yaf_response_t * yaf_response_instance(yaf_response_t *this_ptr, char *sapi_name TSRMLS_DC)
+ */
+yaf_response_t * yaf_response_instance(yaf_response_t *this_ptr, char *sapi_name TSRMLS_DC) {
+ zval *header;
+ zend_class_entry *ce;
+ yaf_response_t *instance;
+
+ if (strncasecmp(sapi_name, "cli", 3)) {
+ ce = yaf_response_http_ce;
+ } else {
+ ce = yaf_response_cli_ce;
+ }
+
+ if (this_ptr) {
+ instance = this_ptr;
+ } else {
+ MAKE_STD_ZVAL(instance);
+ object_init_ex(instance, ce);
+ }
+
+ MAKE_STD_ZVAL(header);
+ array_init(header);
+ zend_update_property(ce, instance, ZEND_STRL(YAF_RESPONSE_PROPERTY_NAME_HEADER), header TSRMLS_CC);
+ zval_ptr_dtor(&header);
+
+ zend_update_property_string(ce, instance, YAF_STRL(YAF_RESPONSE_PROPERTY_NAME_BODY), "" TSRMLS_CC);
+
+ return instance;
+}
+/* }}} */
+
+/** {{{ static int yaf_response_set_body(yaf_response_t *response, char *name, int name_len, char *body, long body_len TSRMLS_DC)
+ */
+#if 0
+static int yaf_response_set_body(yaf_response_t *response, char *name, int name_len, char *body, long body_len TSRMLS_DC) {
+ zval *zbody;
+ zend_class_entry *response_ce;
+
+ if (!body_len) {
+ return 1;
+ }
+
+ response_ce = Z_OBJCE_P(response);
+
+ zbody = zend_read_property(response_ce, response, ZEND_STRL(YAF_RESPONSE_PROPERTY_NAME_BODY), 1 TSRMLS_CC);
+
+ zval_dtor(zbody);
+ efree(zbody);
+
+ MAKE_STD_ZVAL(zbody);
+ ZVAL_STRINGL(zbody, body, body_len, 1);
+
+ zend_update_property(response_ce, response, ZEND_STRL(YAF_RESPONSE_PROPERTY_NAME_BODY), zbody TSRMLS_CC);
+
+ return 1;
+}
+#endif
+/* }}} */
+
+/** {{{ int yaf_response_alter_body(yaf_response_t *response, char *name, int name_len, char *body, long body_len, int prepend TSRMLS_DC)
+ */
+int yaf_response_alter_body(yaf_response_t *response, char *name, int name_len, char *body, long body_len, int prepend TSRMLS_DC) {
+ zval *zbody;
+ char *obody;
+
+ if (!body_len) {
+ return 1;
+ }
+
+ zbody = zend_read_property(yaf_response_ce, response, ZEND_STRL(YAF_RESPONSE_PROPERTY_NAME_BODY), 1 TSRMLS_CC);
+ obody = Z_STRVAL_P(zbody);
+
+ if (prepend) {
+ Z_STRLEN_P(zbody) = spprintf(&Z_STRVAL_P(zbody), 0, "%s%s", body, obody);
+ } else {
+ Z_STRLEN_P(zbody) = spprintf(&Z_STRVAL_P(zbody), 0, "%s%s", obody, body);
+ }
+
+ efree(obody);
+
+ return 1;
+}
+/* }}} */
+
+/** {{{ int yaf_response_clear_body(yaf_response_t *response TSRMLS_DC)
+ */
+int yaf_response_clear_body(yaf_response_t *response TSRMLS_DC) {
+ zend_update_property_string(yaf_response_ce, response, YAF_STRL(YAF_RESPONSE_PROPERTY_NAME_BODY), "" TSRMLS_CC);
+ return 1;
+}
+/* }}} */
+
+/** {{{ int yaf_response_set_redirect(yaf_response_t *response, char *url, int len TSRMLS_DC)
+ */
+int yaf_response_set_redirect(yaf_response_t *response, char *url, int len TSRMLS_DC) {
+ sapi_header_line ctr = {0};
+
+ ctr.line_len = spprintf(&(ctr.line), 0, "%s %s", "Location:", url);
+ ctr.response_code = 0;
+ if (sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC) == SUCCESS) {
+ efree(ctr.line);
+ return 1;
+ }
+ efree(ctr.line);
+ return 0;
+}
+/* }}} */
+
+/** {{{ int yaf_response_send(yaf_response_t *response TSRMLS_DC)
+ */
+int yaf_response_send(yaf_response_t *response TSRMLS_DC) {
+ zval *body = zend_read_property(yaf_response_ce, response, ZEND_STRL(YAF_RESPONSE_PROPERTY_NAME_BODY), 1 TSRMLS_CC);
+
+ if (IS_STRING == Z_TYPE_P(body) && Z_STRLEN_P(body) > 0) {
+ if (php_write(Z_STRVAL_P(body), Z_STRLEN_P(body) TSRMLS_CC) == FAILURE) {
+ return 0;
+ }
+ }
+ return 1;
+}
+/* }}} */
+
+/** {{{ zval * yaf_response_get_body(yaf_response_t *response TSRMLS_DC)
+ */
+zval * yaf_response_get_body(yaf_response_t *response TSRMLS_DC) {
+ zval *body = zend_read_property(yaf_response_ce, response, ZEND_STRL(YAF_RESPONSE_PROPERTY_NAME_BODY), 1 TSRMLS_CC);
+ return body;
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Response_Abstract::__construct()
+*/
+PHP_METHOD(yaf_response, __construct) {
+ (void)yaf_response_instance(getThis(), sapi_module.name TSRMLS_CC);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Response_Abstract::__desctruct(void)
+*/
+PHP_METHOD(yaf_response, __destruct) {
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Response_Abstract::appenBody($body, $name = NULL)
+*/
+PHP_METHOD(yaf_response, appendBody) {
+ char *body, *name = NULL;
+ uint body_len, name_len = 0;
+ yaf_response_t *self;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &body, &body_len, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ self = getThis();
+
+ if (yaf_response_alter_body(self, name, name_len, body, body_len, 0 TSRMLS_CC)) {
+ RETURN_ZVAL(self, 1, 0);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Response_Abstract::prependBody($body, $name = NULL)
+*/
+PHP_METHOD(yaf_response, prependBody) {
+ char *body, *name = NULL;
+ uint body_len, name_len = 0;
+ yaf_response_t *self;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &body, &body_len, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ self = getThis();
+
+ if (yaf_response_alter_body(self, name, name_len, body, body_len, 1 TSRMLS_CC)) {
+ RETURN_ZVAL(self, 1, 0);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Response_Abstract::setHeader($name, $value, $replace = 0)
+*/
+PHP_METHOD(yaf_response, setHeader) {
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto parotected Yaf_Response_Abstract::setAllHeaders(void)
+*/
+PHP_METHOD(yaf_response, setAllHeaders) {
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Response_Abstract::getHeader(void)
+*/
+PHP_METHOD(yaf_response, getHeader) {
+ RETURN_NULL();
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Response_Abstract::clearHeaders(void)
+*/
+PHP_METHOD(yaf_response, clearHeaders) {
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Response_Abstract::setRedirect(string $url)
+*/
+PHP_METHOD(yaf_response, setRedirect) {
+ char *url;
+ uint url_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &url, &url_len) == FAILURE) {
+ return;
+ }
+
+ if (!url_len) {
+ RETURN_FALSE;
+ }
+
+ RETURN_BOOL(yaf_response_set_redirect(getThis(), url, url_len TSRMLS_CC));
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Response_Abstract::setBody($body, $name = NULL)
+*/
+PHP_METHOD(yaf_response, setBody) {
+ char *body, *name = NULL;
+ uint body_len, name_len = 0;
+ yaf_response_t *self;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &body, &body_len, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ self = getThis();
+
+ if (yaf_response_alter_body(self, name, name_len, body, body_len, 0 TSRMLS_CC)) {
+ RETURN_ZVAL(self, 1, 0);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Response_Abstract::clearBody(void)
+*/
+PHP_METHOD(yaf_response, clearBody) {
+ if (yaf_response_clear_body(getThis() TSRMLS_CC)) {
+ RETURN_ZVAL(getThis(), 1, 0);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Response_Abstract::getBody(void)
+ */
+PHP_METHOD(yaf_response, getBody) {
+ zval *body;
+
+ body = yaf_response_get_body(getThis() TSRMLS_CC);
+
+ RETURN_ZVAL(body, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Response_Abstract::response(void)
+ */
+PHP_METHOD(yaf_response, response) {
+ RETURN_BOOL(yaf_response_send(getThis() TSRMLS_CC));
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Response_Abstract::__toString(void)
+ */
+PHP_METHOD(yaf_response, __toString) {
+ zval *body = zend_read_property(yaf_response_ce, getThis(), ZEND_STRL(YAF_RESPONSE_PROPERTY_NAME_BODY), 1 TSRMLS_CC);
+ RETURN_ZVAL(body, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Response_Abstract::__clone(void)
+*/
+PHP_METHOD(yaf_response, __clone) {
+}
+/* }}} */
+
+/** {{{ yaf_response_methods
+*/
+zend_function_entry yaf_response_methods[] = {
+ PHP_ME(yaf_response, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(yaf_response, __destruct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
+ PHP_ME(yaf_response, __clone, NULL, ZEND_ACC_PRIVATE)
+ PHP_ME(yaf_response, __toString, NULL, ZEND_ACC_PRIVATE)
+ PHP_ME(yaf_response, setBody, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_response, appendBody, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_response, prependBody, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_response, clearBody, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_response, getBody, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_response, setHeader, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_response, setAllHeaders, NULL, ZEND_ACC_PROTECTED)
+ PHP_ME(yaf_response, getHeader, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_response, clearHeaders, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_response, setRedirect, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_response, response, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(response) {
+ zend_class_entry ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Response_Abstract", "Yaf\\Response_Abstract", yaf_response_methods);
+
+ yaf_response_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+ yaf_response_ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
+
+ zend_declare_property_null(yaf_response_ce, YAF_STRL(YAF_RESPONSE_PROPERTY_NAME_HEADER), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_response_ce, YAF_STRL(YAF_RESPONSE_PROPERTY_NAME_BODY), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_bool(yaf_response_ce, YAF_STRL(YAF_RESPONSE_PROPERTY_NAME_HEADEREXCEPTION), 0, ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ YAF_STARTUP(response_http);
+ YAF_STARTUP(response_cli);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_response.h b/yaf_response.h
new file mode 100644
index 0000000000..1491572d68
--- /dev/null
+++ b/yaf_response.h
@@ -0,0 +1,39 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef PHP_YAF_RESPONSE_H
+#define PHP_YAF_RESPONSE_H
+
+#define YAF_RESPONSE_PROPERTY_NAME_HEADER "_header"
+#define YAF_RESPONSE_PROPERTY_NAME_BODY "_body"
+#define YAF_RESPONSE_PROPERTY_NAME_HEADEREXCEPTION "_sendheader"
+#define YAF_RESPONSE_PROPERTY_NAME_RESPONSECODE "_response_code"
+
+extern zend_class_entry *yaf_response_ce;
+extern zend_class_entry *yaf_response_http_ce;
+extern zend_class_entry *yaf_response_cli_ce;
+
+yaf_response_t * yaf_response_instance(yaf_response_t *this_ptr, char *sapi_name TSRMLS_DC);
+int yaf_response_alter_body(yaf_response_t *response, char *name, int name_len, char *body, long body_len, int prepend TSRMLS_DC);
+int yaf_response_send(yaf_response_t *response TSRMLS_DC);
+int yaf_response_set_redirect(yaf_response_t *response, char *url, int len TSRMLS_DC);
+int yaf_response_clear_body(yaf_response_t *response TSRMLS_DC);
+
+YAF_STARTUP_FUNCTION(response);
+
+#endif
diff --git a/yaf_router.c b/yaf_router.c
new file mode 100644
index 0000000000..4cead9e05e
--- /dev/null
+++ b/yaf_router.c
@@ -0,0 +1,378 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "main/SAPI.h"
+#include "Zend/zend_alloc.h"
+#include "Zend/zend_interfaces.h"
+#include "ext/pcre/php_pcre.h"
+
+#include "php_yaf.h"
+#include "yaf_namespace.h"
+#include "yaf_application.h"
+#include "yaf_exception.h"
+#include "yaf_request.h"
+#include "yaf_router.h"
+#include "yaf_config.h"
+#include "routes/interface.c"
+
+zend_class_entry *yaf_router_ce;
+
+/** {{{ yaf_router_t * yaf_router_instance(yaf_router_t *this_ptr TSRMLS_DC)
+ */
+yaf_router_t * yaf_router_instance(yaf_router_t *this_ptr TSRMLS_DC) {
+ zval *routes;
+ yaf_router_t *instance;
+ yaf_route_t *route;
+
+ if (this_ptr) {
+ instance = this_ptr;
+ } else {
+ MAKE_STD_ZVAL(instance);
+ object_init_ex(instance, yaf_router_ce);
+ }
+
+ MAKE_STD_ZVAL(routes);
+ array_init(routes);
+
+ MAKE_STD_ZVAL(route);
+ object_init_ex(route, yaf_route_static_ce);
+
+ zend_hash_update(Z_ARRVAL_P(routes), "_default", sizeof("_default"), (void **)&route, sizeof(zval *), NULL);
+ zend_update_property(yaf_router_ce, instance, ZEND_STRL(YAF_ROUTER_PROPERTY_NAME_ROUTERS), routes TSRMLS_CC);
+ zval_ptr_dtor(&routes);
+
+ return instance;
+}
+/** }}} */
+
+/** {{{ int yaf_router_route(yaf_router_t *router, yaf_request_t *request TSRMLS_DC)
+*/
+int yaf_router_route(yaf_router_t *router, yaf_request_t *request TSRMLS_DC) {
+ zval *routers, *ret;
+ yaf_route_t **route;
+ HashTable *ht;
+
+ routers = zend_read_property(yaf_router_ce, router, ZEND_STRL(YAF_ROUTER_PROPERTY_NAME_ROUTERS), 1 TSRMLS_CC);
+
+ ht = Z_ARRVAL_P(routers);
+ for(zend_hash_internal_pointer_end(ht);
+ zend_hash_has_more_elements(ht) == SUCCESS;
+ zend_hash_move_backwards(ht)) {
+
+ if (zend_hash_get_current_data(ht, (void**)&route) == FAILURE) {
+ continue;
+ }
+
+ zend_call_method_with_1_params(route, Z_OBJCE_PP(route), NULL, "route", &ret, request);
+
+ if (IS_BOOL != Z_TYPE_P(ret) || !Z_BVAL_P(ret)) {
+ zval_ptr_dtor(&ret);
+ continue;
+ } else {
+ char *key;
+ int len = 0;
+ long idx = 0;
+
+ switch(zend_hash_get_current_key_ex(ht, &key, &len, &idx, 0, NULL)) {
+ case HASH_KEY_IS_LONG:
+ zend_update_property_long(yaf_router_ce, router, ZEND_STRL(YAF_ROUTER_PROPERTY_NAME_CURRENT_ROUTE), idx TSRMLS_CC);
+ break;
+ case HASH_KEY_IS_STRING:
+ if (len) {
+ zend_update_property_string(yaf_router_ce, router, ZEND_STRL(YAF_ROUTER_PROPERTY_NAME_CURRENT_ROUTE), key TSRMLS_CC);
+ }
+ break;
+ }
+ yaf_request_set_routed(request, 1 TSRMLS_CC);
+ zval_ptr_dtor(&ret);
+ return 1;
+ }
+ }
+ return 0;
+}
+/* }}} */
+
+/** {{{ int yaf_router_add_config(yaf_router_t *router, zval *configs TSRMLS_DC)
+*/
+int yaf_router_add_config(yaf_router_t *router, zval *configs TSRMLS_DC) {
+ zval **entry;
+ HashTable *ht;
+ yaf_route_t *route;
+
+ if (!configs || IS_ARRAY != Z_TYPE_P(configs)) {
+ return 0;
+ } else {
+ char *key = NULL;
+ uint len = 0;
+ long idx = 0;
+ zval *routes;
+
+ routes = zend_read_property(yaf_router_ce, router, ZEND_STRL(YAF_ROUTER_PROPERTY_NAME_ROUTERS), 1 TSRMLS_CC);
+
+ ht = Z_ARRVAL_P(configs);
+ for(zend_hash_internal_pointer_reset(ht);
+ zend_hash_has_more_elements(ht) == SUCCESS;
+ zend_hash_move_forward(ht)) {
+ if (zend_hash_get_current_data(ht, (void**)&entry) == FAILURE) {
+ continue;
+ }
+
+ if (!entry || Z_TYPE_PP(entry) != IS_ARRAY) {
+ continue;
+ }
+
+ route = yaf_route_instance(NULL, *entry TSRMLS_CC);
+ switch (zend_hash_get_current_key_ex(ht, &key, &len, &idx, 0, NULL)) {
+ case HASH_KEY_IS_STRING:
+ if (!route) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to initialize route named '%s'", key);
+ continue;
+ }
+ zend_hash_update(Z_ARRVAL_P(routes), key, len, (void **)&route, sizeof(zval *), NULL);
+ break;
+ case HASH_KEY_IS_LONG:
+ if (!route) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to initialize route at index '%ld'", idx);
+ continue;
+ }
+ zend_hash_index_update(Z_ARRVAL_P(routes), idx, (void **)&route, sizeof(zval *), NULL);
+ break;
+ default:
+ continue;
+ }
+ }
+ return 1;
+ }
+}
+/* }}} */
+
+/** {{{ zval * yaf_router_parse_parameters(char *uri TSRMLS_DC)
+ */
+zval * yaf_router_parse_parameters(char *uri TSRMLS_DC) {
+ char *key, *ptrptr, *tmp, *value;
+ zval *params, *val;
+ uint key_len;
+
+ MAKE_STD_ZVAL(params);
+ array_init(params);
+
+ tmp = estrdup(uri);
+ key = php_strtok_r(tmp, YAF_ROUTER_URL_DELIMIETER, &ptrptr);
+ while (key) {
+ key_len = strlen(key);
+ if (key_len) {
+ MAKE_STD_ZVAL(val);
+ value = php_strtok_r(NULL, YAF_ROUTER_URL_DELIMIETER, &ptrptr);
+ if (value && strlen(value)) {
+ ZVAL_STRING(val, value, 1);
+ } else {
+ ZVAL_NULL(val);
+ }
+ zend_hash_update(Z_ARRVAL_P(params), key, key_len + 1, (void **)&val, sizeof(zval *), NULL);
+ }
+
+ key = php_strtok_r(NULL, YAF_ROUTER_URL_DELIMIETER, &ptrptr);
+ }
+
+ efree(tmp);
+
+ return params;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Router::__construct(void)
+ */
+PHP_METHOD(yaf_router, __construct) {
+ yaf_router_instance(getThis() TSRMLS_CC);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Router::route(Yaf_Request $req)
+*/
+PHP_METHOD(yaf_router, route) {
+ yaf_request_t *request;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &request) == FAILURE) {
+ return;
+ } else {
+ RETURN_BOOL(yaf_router_route(getThis(), request TSRMLS_CC));
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Router::addRoute(string $name, Yaf_Route_Interface $route)
+ */
+PHP_METHOD(yaf_router, addRoute) {
+ char *name;
+ zval *routes;
+ yaf_route_t *route;
+ uint len = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name, &len, &route) == FAILURE) {
+ return;
+ }
+
+ if (!len) {
+ RETURN_FALSE;
+ }
+
+ if (IS_OBJECT != Z_TYPE_P(route)
+ || !instanceof_function(Z_OBJCE_P(route), yaf_route_ce TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expects a %s instance", yaf_route_ce->name);
+ RETURN_FALSE;
+ }
+
+ routes = zend_read_property(yaf_router_ce, getThis(), ZEND_STRL(YAF_ROUTER_PROPERTY_NAME_ROUTERS), 1 TSRMLS_CC);
+
+ Z_ADDREF_P(route);
+ zend_hash_update(Z_ARRVAL_P(routes), name, len + 1, (void **)&route, sizeof(zval *), NULL);
+
+ RETURN_ZVAL(getThis(), 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Router::addConfig(Yaf_Config_Abstract $config)
+ */
+PHP_METHOD(yaf_router, addConfig) {
+ yaf_config_t *config;
+ zval *routes;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &config) == FAILURE) {
+ return;
+ }
+
+ if (IS_OBJECT == Z_TYPE_P(config) && instanceof_function(Z_OBJCE_P(config), yaf_config_ce TSRMLS_CC)){
+ routes = zend_read_property(yaf_config_ce, config, ZEND_STRL(YAF_CONFIG_PROPERT_NAME), 1 TSRMLS_CC);
+ } else if (IS_ARRAY == Z_TYPE_P(config)) {
+ routes = config;
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expect a %s instance or an array, %s given", yaf_config_ce->name, zend_zval_type_name(config));
+ RETURN_FALSE;
+ }
+
+ if (yaf_router_add_config(getThis(), routes TSRMLS_CC)) {
+ RETURN_ZVAL(getThis(), 1, 0);
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Router::getRoute(string $name)
+ */
+PHP_METHOD(yaf_router, getRoute) {
+ char *name;
+ uint len;
+ zval *routes;
+ yaf_route_t **route;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &len) == FAILURE) {
+ return;
+ }
+
+ if (!len) {
+ RETURN_FALSE;
+ }
+
+ routes = zend_read_property(yaf_router_ce, getThis(), ZEND_STRL(YAF_ROUTER_PROPERTY_NAME_ROUTERS), 1 TSRMLS_CC);
+
+ if (zend_hash_find(Z_ARRVAL_P(routes), name, len + 1, (void **)&route) == SUCCESS) {
+ RETURN_ZVAL(*route, 1, 0);
+ }
+
+ RETURN_NULL();
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Router::getRoutes(void)
+ */
+PHP_METHOD(yaf_router, getRoutes) {
+ zval * routes = zend_read_property(yaf_router_ce, getThis(), ZEND_STRL(YAF_ROUTER_PROPERTY_NAME_ROUTERS), 1 TSRMLS_CC);
+ RETURN_ZVAL(routes, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Router::isModuleName(string $name)
+ */
+PHP_METHOD(yaf_router, isModuleName) {
+ char *name;
+ uint len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &len) == FAILURE) {
+ return;
+ }
+
+ RETURN_BOOL(yaf_application_is_module_name(name, len TSRMLS_CC));
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Router::getCurrentRoute(void)
+ */
+PHP_METHOD(yaf_router, getCurrentRoute) {
+ zval *route = zend_read_property(yaf_router_ce, getThis(), ZEND_STRL(YAF_ROUTER_PROPERTY_NAME_CURRENT_ROUTE), 1 TSRMLS_CC);
+ RETURN_ZVAL(route, 1, 0);
+}
+/* }}} */
+
+/** {{{ yaf_router_methods
+ */
+zend_function_entry yaf_router_methods[] = {
+ PHP_ME(yaf_router, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(yaf_router, addRoute, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_router, addConfig, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_router, route, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_router, getRoute, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_router, getRoutes, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_router, getCurrentRoute, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+ */
+YAF_STARTUP_FUNCTION(router) {
+ zend_class_entry ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Router", "Yaf\\Router", yaf_router_methods);
+ yaf_router_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+
+ yaf_router_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+
+ zend_declare_property_null(yaf_router_ce, YAF_STRL(YAF_ROUTER_PROPERTY_NAME_ROUTERS), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_null(yaf_router_ce, YAF_STRL(YAF_ROUTER_PROPERTY_NAME_CURRENT_ROUTE), ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ YAF_STARTUP(route);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_router.h b/yaf_router.h
new file mode 100644
index 0000000000..573e40e18a
--- /dev/null
+++ b/yaf_router.h
@@ -0,0 +1,45 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef YAF_ROUTER_H
+#define YAF_ROUTER_H
+
+#define YAF_ROUTER_DEFAULT_ACTION "index"
+#define YAF_ROUTER_DEFAULT_CONTROLLER "Index"
+#define YAF_ROUTER_DEFAULT_MODULE "Index"
+#define YAF_DEFAULT_EXT "php"
+
+#define YAF_ROUTER_PROPERTY_NAME_ROUTERS "_routes"
+#define YAF_ROUTER_PROPERTY_NAME_CURRENT_ROUTE "_current"
+
+extern zend_class_entry * yaf_router_ce;
+
+yaf_router_t * yaf_router_instance(yaf_router_t *this_ptr TSRMLS_DC);
+zval * yaf_router_parse_parameters(char *uri TSRMLS_DC);
+int yaf_router_route(yaf_router_t *router, yaf_request_t *request TSRMLS_DC);
+
+YAF_STARTUP_FUNCTION(router);
+#endif
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_session.c b/yaf_session.c
new file mode 100644
index 0000000000..f8752674f0
--- /dev/null
+++ b/yaf_session.c
@@ -0,0 +1,376 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "Zend/zend_interfaces.h"
+#include "Zend/zend_objects.h"
+#include "main/SAPI.h"
+
+#include "php_yaf.h"
+#include "yaf_namespace.h"
+#include "yaf_session.h"
+#include "yaf_exception.h"
+
+zend_class_entry * yaf_session_ce;
+#ifdef HAVE_SPL
+extern PHPAPI zend_class_entry * spl_ce_Countable;
+#endif
+
+/* {{{ ARG_INFO
+ */
+ZEND_BEGIN_ARG_INFO_EX(yaf_session_void_arginfo, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_session_get_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_session_has_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_session_del_arginfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(yaf_session_set_arginfo, 0, 0, 2)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/** {{{ inline int yaf_session_start(yaf_session_t *session TSRMLS_DC)
+ */
+inline int yaf_session_start(yaf_session_t *session TSRMLS_DC) {
+ zval *status;
+
+ status = zend_read_property(yaf_session_ce, session, ZEND_STRL(YAF_SESSION_PROPERTY_NAME_STATUS), 1 TSRMLS_CC);
+ if (Z_BVAL_P(status)) {
+ return 1;
+ }
+
+ php_session_start(TSRMLS_C);
+ zend_update_property_bool(yaf_session_ce, session, ZEND_STRL(YAF_SESSION_PROPERTY_NAME_STATUS), 1 TSRMLS_CC);
+ return 1;
+}
+/* }}} */
+
+/** {{{ static yaf_session_t * yaf_session_instance(TSRMLS_D)
+*/
+static yaf_session_t * yaf_session_instance(TSRMLS_D) {
+ yaf_session_t *instance;
+ zval **sess, *member;
+ zend_object *obj;
+ zend_property_info *property_info;
+
+ MAKE_STD_ZVAL(instance);
+ object_init_ex(instance, yaf_session_ce);
+
+ yaf_session_start(instance TSRMLS_CC);
+
+ if (zend_hash_find(&EG(symbol_table), ZEND_STRS("_SESSION"), (void **)&sess) == FAILURE || Z_TYPE_PP(sess) != IS_ARRAY) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempt to start session failed");
+ zval_ptr_dtor(&instance);
+ return NULL;
+ }
+
+ MAKE_STD_ZVAL(member);
+ ZVAL_STRING(member, YAF_SESSION_PROPERTY_NAME_SESSION, 0);
+
+ obj = zend_objects_get_address(instance TSRMLS_CC);
+
+ property_info = zend_get_property_info(obj->ce, member, 1 TSRMLS_CC);
+
+ Z_ADDREF_P(*sess);
+ /** This is ugly , because we can't set a ref property through the stadard APIs */
+ zend_hash_quick_update(obj->properties, property_info->name,
+ property_info->name_length+1, property_info->h, (void **)sess, sizeof(zval *), NULL);
+
+ zend_update_static_property(yaf_session_ce, ZEND_STRL(YAF_SESSION_PROPERTY_NAME_INSTANCE), instance TSRMLS_CC);
+
+ efree(member);
+
+ return instance;
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Session::__construct(void)
+*/
+PHP_METHOD(yaf_session, __construct) {
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Session::__destruct(void)
+*/
+PHP_METHOD(yaf_session, __destruct) {
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Session::__sleep(void)
+*/
+PHP_METHOD(yaf_session, __sleep) {
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Session::__wakeup(void)
+*/
+PHP_METHOD(yaf_session, __wakeup) {
+}
+/* }}} */
+
+/** {{{ proto private Yaf_Session::__clone(void)
+*/
+PHP_METHOD(yaf_session, __clone) {
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Session::getInstance(void)
+*/
+PHP_METHOD(yaf_session, getInstance) {
+ yaf_session_t *instance = zend_read_static_property(yaf_session_ce, ZEND_STRL(YAF_SESSION_PROPERTY_NAME_INSTANCE), 1 TSRMLS_CC);
+
+ if (Z_TYPE_P(instance) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(instance), yaf_session_ce TSRMLS_CC)) {
+ if ((instance = yaf_session_instance(TSRMLS_C))) {
+ RETURN_ZVAL(instance, 1, 1);
+ } else {
+ RETURN_NULL();
+ }
+ } else {
+ RETURN_ZVAL(instance, 1, 0);
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Session::count(void)
+*/
+PHP_METHOD(yaf_session, count) {
+ zval *sess = zend_read_property(yaf_session_ce, getThis(), ZEND_STRL(YAF_SESSION_PROPERTY_NAME_SESSION), 1 TSRMLS_CC);
+ RETURN_LONG(zend_hash_num_elements(Z_ARRVAL_P(sess)));
+}
+/* }}} */
+
+/** {{{ proto public static Yaf_Session::start()
+*/
+PHP_METHOD(yaf_session, start) {
+ yaf_session_start(getThis() TSRMLS_CC);
+ RETURN_ZVAL(getThis(), 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public static Yaf_Session::get($name)
+*/
+PHP_METHOD(yaf_session, get) {
+ char *name = NULL;
+ int len = 0;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &len) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ } else {
+ zval **ret, *sess;
+
+ sess = zend_read_property(yaf_session_ce, getThis(), ZEND_STRL(YAF_SESSION_PROPERTY_NAME_SESSION), 1 TSRMLS_CC);
+ if (!len) {
+ RETURN_ZVAL(sess, 1, 0);
+ }
+
+ if (zend_hash_find(Z_ARRVAL_P(sess), name, len + 1, (void **)&ret) == FAILURE ){
+ RETURN_NULL();
+ }
+
+ RETURN_ZVAL(*ret, 1, 0);
+ }
+}
+/* }}} */
+
+/** {{{ proto public staitc Yaf_Session::set($name, $value)
+*/
+PHP_METHOD(yaf_session, set) {
+ zval *value;
+ char *name;
+ uint len;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name, &len, &value) == FAILURE) {
+ return;
+ } else {
+ zval *sess = zend_read_property(yaf_session_ce, getThis(), ZEND_STRL(YAF_SESSION_PROPERTY_NAME_SESSION), 1 TSRMLS_CC);
+ Z_ADDREF_P(value);
+ if (zend_hash_update(Z_ARRVAL_P(sess), name, len + 1, &value, sizeof(zval *), NULL) == FAILURE) {
+ Z_DELREF_P(value);
+ RETURN_FALSE;
+ }
+ }
+
+ RETURN_ZVAL(getThis(), 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public staitc Yaf_Session::del($name)
+*/
+PHP_METHOD(yaf_session, del) {
+ char *name;
+ uint len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &len) == FAILURE) {
+ return;
+ } else {
+ zval *sess = zend_read_property(yaf_session_ce, getThis(), ZEND_STRL(YAF_SESSION_PROPERTY_NAME_SESSION), 1 TSRMLS_CC);
+
+ if (zend_hash_del(Z_ARRVAL_P(sess), name, len + 1) == SUCCESS) {
+ RETURN_ZVAL(getThis(), 1, 0);
+ }
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Session::has($name)
+*/
+PHP_METHOD(yaf_session, has) {
+ char *name;
+ uint len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &len) == FAILURE) {
+ return;
+ } else {
+ zval *sess = zend_read_property(yaf_session_ce, getThis(), ZEND_STRL(YAF_SESSION_PROPERTY_NAME_SESSION), 1 TSRMLS_CC);
+ RETURN_BOOL(zend_hash_exists(Z_ARRVAL_P(sess), name, len + 1));
+ }
+
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Session::rewind(void)
+*/
+PHP_METHOD(yaf_session, rewind) {
+ zval *sess = zend_read_property(yaf_session_ce, getThis(), ZEND_STRL(YAF_SESSION_PROPERTY_NAME_SESSION), 1 TSRMLS_CC);
+ zend_hash_internal_pointer_reset(Z_ARRVAL_P(sess));
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Session::current(void)
+*/
+PHP_METHOD(yaf_session, current) {
+ zval *sess, **ppzval;
+ sess = zend_read_property(yaf_session_ce, getThis(), ZEND_STRL(YAF_SESSION_PROPERTY_NAME_SESSION), 1 TSRMLS_CC);
+ if (zend_hash_get_current_data(Z_ARRVAL_P(sess), (void **)&ppzval) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ RETURN_ZVAL(*ppzval, 1, 0);
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Session::key(void)
+*/
+PHP_METHOD(yaf_session, key) {
+ zval *sess;
+ char *key;
+ long index;
+
+ sess = zend_read_property(yaf_session_ce, getThis(), ZEND_STRL(YAF_SESSION_PROPERTY_NAME_SESSION), 1 TSRMLS_CC);
+ if (zend_hash_get_current_key(Z_ARRVAL_P(sess), &key, &index, 0) == HASH_KEY_IS_LONG) {
+ RETURN_LONG(index);
+ } else {
+ RETURN_STRING(key, 1);
+ }
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Session::next(void)
+*/
+PHP_METHOD(yaf_session, next) {
+ zval *sess = zend_read_property(yaf_session_ce, getThis(), ZEND_STRL(YAF_SESSION_PROPERTY_NAME_SESSION), 1 TSRMLS_CC);
+ zend_hash_move_forward(Z_ARRVAL_P(sess));
+}
+/* }}} */
+
+/** {{{ proto public Yaf_Session::valid(void)
+*/
+PHP_METHOD(yaf_session, valid) {
+ zval *sess = zend_read_property(yaf_session_ce, getThis(), ZEND_STRL(YAF_SESSION_PROPERTY_NAME_SESSION), 1 TSRMLS_CC);
+ RETURN_BOOL(zend_hash_has_more_elements(Z_ARRVAL_P(sess)) == SUCCESS);
+}
+/* }}} */
+
+/** {{{ yaf_session_methods
+*/
+zend_function_entry yaf_session_methods[] = {
+ PHP_ME(yaf_session, __construct, NULL, ZEND_ACC_CTOR|ZEND_ACC_PRIVATE)
+ PHP_ME(yaf_session, __clone, NULL, ZEND_ACC_CLONE|ZEND_ACC_PRIVATE)
+ PHP_ME(yaf_session, __sleep, NULL, ZEND_ACC_PRIVATE)
+ PHP_ME(yaf_session, __wakeup, NULL, ZEND_ACC_PRIVATE)
+ PHP_ME(yaf_session, getInstance, yaf_session_void_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ PHP_ME(yaf_session, start, yaf_session_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_session, get, yaf_session_get_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_session, has, yaf_session_has_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_session, set, yaf_session_set_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_session, del, yaf_session_del_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_session, count, yaf_session_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_session, rewind, yaf_session_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_session, next, yaf_session_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_session, current, yaf_session_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_session, key, yaf_session_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(yaf_session, valid, yaf_session_void_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_session, offsetGet, get, yaf_session_get_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_session, offsetSet, set, yaf_session_set_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_session, offsetExists, has, yaf_session_has_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_session, offsetUnset, del, yaf_session_del_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_session, __get, get, yaf_session_get_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_session, __isset, has, yaf_session_has_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_session, __set, set, yaf_session_set_arginfo, ZEND_ACC_PUBLIC)
+ PHP_MALIAS(yaf_session, __unset, del, yaf_session_del_arginfo, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(session) {
+ zend_class_entry ce;
+
+ YAF_INIT_CLASS_ENTRY(ce, "Yaf_Session", "Yaf\\Session", yaf_session_methods);
+
+ yaf_session_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+ yaf_session_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+
+#ifdef HAVE_SPL
+ zend_class_implements(yaf_session_ce TSRMLS_CC, 3, zend_ce_iterator, zend_ce_arrayaccess, spl_ce_Countable);
+#else
+ zend_class_implements(yaf_session_ce TSRMLS_CC, 2, zend_ce_iterator, zend_ce_arrayaccess);
+#endif
+
+ zend_declare_property_null(yaf_session_ce, ZEND_STRL(YAF_SESSION_PROPERTY_NAME_INSTANCE), ZEND_ACC_PROTECTED|ZEND_ACC_STATIC TSRMLS_CC);
+ zend_declare_property_null(yaf_session_ce, ZEND_STRL(YAF_SESSION_PROPERTY_NAME_SESSION), ZEND_ACC_PROTECTED TSRMLS_CC);
+ zend_declare_property_bool(yaf_session_ce, ZEND_STRL(YAF_SESSION_PROPERTY_NAME_STATUS), 0, ZEND_ACC_PROTECTED TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_session.h b/yaf_session.h
new file mode 100644
index 0000000000..4255e6d3bb
--- /dev/null
+++ b/yaf_session.h
@@ -0,0 +1,38 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef YAF_SESSION_H
+#define YAF_SESSION_H
+
+#define YAF_SESSION_PROPERTY_NAME_STATUS "_started"
+#define YAF_SESSION_PROPERTY_NAME_SESSION "_session"
+#define YAF_SESSION_PROPERTY_NAME_INSTANCE "_instance"
+
+extern zend_class_entry *yaf_session_ce;
+
+PHPAPI void php_session_start(TSRMLS_D);
+YAF_STARTUP_FUNCTION(session);
+#endif
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_view.c b/yaf_view.c
new file mode 100644
index 0000000000..52fea526d5
--- /dev/null
+++ b/yaf_view.c
@@ -0,0 +1,93 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "main/SAPI.h"
+#include "Zend/zend_interfaces.h"
+#include "Zend/zend_exceptions.h"
+#include "Zend/zend_alloc.h"
+
+#include "php_yaf.h"
+#include "yaf_namespace.h"
+#include "yaf_exception.h"
+#include "yaf_loader.h"
+#include "yaf_view.h"
+
+#include "views/interface.c"
+#include "views/simple.c"
+
+#if 0
+static yaf_view_struct yaf_buildin_views[] = {
+ {"classical", &yaf_view_simple_ce, yaf_view_simple_init},
+ {NULL, NULL, NULL}
+};
+#endif
+
+#if 0
+/** {{{ yaf_view_t * yaf_view_instance(yaf_view_t *this_ptr TSRMLS_DC)
+*/
+yaf_view_t * yaf_view_instance(yaf_view_t *this_ptr TSRMLS_DC) {
+ yaf_view_t *view = NULL;
+ yaf_view_struct *p = yaf_buildin_views;
+
+ for(;;++p) {
+ yaf_current_view = p;
+ yaf_view_ce = *(p->ce);
+ break;
+ }
+
+ yaf_view_ce = *(yaf_current_view->ce);
+
+ MAKE_STD_ZVAL(view);
+ object_init_ex(view, *(yaf_current_view->ce));
+
+ if (yaf_current_view->init) {
+ yaf_current_view->init(view TSRMLS_CC);
+ }
+ MAKE_STD_ZVAL(view);
+ object_init_ex(view, yaf_view_simple_ce);
+ yaf_view_simple_init(view TSRMLS_CC);
+
+ return view;
+}
+/* }}} */
+#endif
+
+/** {{{ YAF_STARTUP_FUNCTION
+*/
+YAF_STARTUP_FUNCTION(view) {
+ YAF_STARTUP(view_interface);
+ YAF_STARTUP(view_simple);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/yaf_view.h b/yaf_view.h
new file mode 100644
index 0000000000..7efffef650
--- /dev/null
+++ b/yaf_view.h
@@ -0,0 +1,42 @@
+/*
+ +----------------------------------------------------------------------+
+ | Yet Another Framework |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Xinchen Hui <laruence@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef YAF_VIEW_H
+#define YAF_VIEW_H
+
+#define yaf_view_instance yaf_view_simple_instance
+#define yaf_view_ce yaf_view_simple_ce
+
+#define YAF_VIEW_PROPERTY_NAME_TPLVARS "_tpl_vars"
+#define YAF_VIEW_PROPERTY_NAME_TPLDIR "_tpl_dir"
+
+extern zend_class_entry *yaf_view_interface_ce;
+extern zend_class_entry *yaf_view_simple_ce;
+
+yaf_view_t * yaf_view_instance(yaf_view_t * this_ptr, zval *tpl_dir, zval *options TSRMLS_DC);
+
+YAF_STARTUP_FUNCTION(view);
+#endif
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */