예제 #1
0
파일: annotations.c 프로젝트: 9466/cphalcon
/**
 * Produce the routing parameters from the rewrite information
 *
 * @param string $uri
 */
PHP_METHOD(Phalcon_Mvc_Router_Annotations, handle){

	zval *uri = NULL, *real_uri = NULL, *processed, *annotations_service = NULL;
	zval *handlers, *controller_suffix, *scope = NULL, *prefix = NULL;
	zval *dependency_injector = NULL, *service = NULL, *handler = NULL;
	zval *controller_name = NULL;
	zval *namespace_name = NULL, *module_name = NULL, *suffixed = NULL;
	zval *handler_annotations = NULL, *class_annotations = NULL;
	zval *annotations = NULL, *annotation = NULL, *method_annotations = NULL;
	zval *collection = NULL, *method = NULL;
	HashTable *ah0, *ah1, *ah2, *ah3;
	HashPosition hp0, hp1, hp2, hp3;
	zval **hd;

	PHALCON_MM_GROW();

	phalcon_fetch_params(1, 0, 1, &uri);
	
	if (!uri) {
		uri = PHALCON_GLOBAL(z_null);
	}
	
	if (!zend_is_true(uri)) {
		/** 
		 * If 'uri' isn't passed as parameter it reads $_GET['_url']
		 */
		PHALCON_CALL_METHOD(&real_uri, this_ptr, "getrewriteuri");
	} else {
		PHALCON_CPY_WRT(real_uri, uri);
	}
	
	PHALCON_OBS_VAR(processed);
	phalcon_read_property_this(&processed, this_ptr, SL("_processed"), PH_NOISY TSRMLS_CC);
	if (!zend_is_true(processed)) {
	
		PHALCON_INIT_VAR(annotations_service);
	
		PHALCON_OBS_VAR(handlers);
		phalcon_read_property_this(&handlers, this_ptr, SL("_handlers"), PH_NOISY TSRMLS_CC);
		if (Z_TYPE_P(handlers) == IS_ARRAY) { 
	
			PHALCON_OBS_VAR(controller_suffix);
			phalcon_read_property_this(&controller_suffix, this_ptr, SL("_controllerSuffix"), PH_NOISY TSRMLS_CC);
	
			phalcon_is_iterable(handlers, &ah0, &hp0, 0, 0);
	
			while (zend_hash_get_current_data_ex(ah0, (void**) &hd, &hp0) == SUCCESS) {
	
				PHALCON_GET_HVALUE(scope);
	
				if (Z_TYPE_P(scope) == IS_ARRAY) { 
	
					/** 
					 * A prefix (if any) must be in position 0
					 */
					PHALCON_OBS_NVAR(prefix);
					phalcon_array_fetch_long(&prefix, scope, 0, PH_NOISY);
					if (Z_TYPE_P(prefix) == IS_STRING) {
						if (!phalcon_start_with(real_uri, prefix, NULL)) {
							zend_hash_move_forward_ex(ah0, &hp0);
							continue;
						}
					}
	
					if (Z_TYPE_P(annotations_service) != IS_OBJECT) {
	
						PHALCON_OBS_NVAR(dependency_injector);
						phalcon_read_property_this(&dependency_injector, this_ptr, SL("_dependencyInjector"), PH_NOISY TSRMLS_CC);
						if (Z_TYPE_P(dependency_injector) != IS_OBJECT) {
							PHALCON_THROW_EXCEPTION_STR(phalcon_mvc_router_exception_ce, "A dependency injection container is required to access the 'annotations' service");
							return;
						}
	
						PHALCON_INIT_NVAR(service);
						ZVAL_STRING(service, "annotations", 1);
	
						PHALCON_CALL_METHOD(&annotations_service, dependency_injector, "getshared", service);
						PHALCON_VERIFY_INTERFACE(annotations_service, phalcon_annotations_adapterinterface_ce);
					}
	
					/** 
					 * The controller must be in position 1
					 */
					PHALCON_OBS_NVAR(handler);
					phalcon_array_fetch_long(&handler, scope, 1, PH_NOISY);
					if (phalcon_memnstr_str(handler, SL("\\"))) {
						/** 
						 * Extract the real class name from the namespaced class
						 */
						PHALCON_INIT_NVAR(controller_name);
						phalcon_get_class_ns(controller_name, handler, 0 TSRMLS_CC);
	
						/** 
						 * Extract the namespace from the namespaced class
						 */
						PHALCON_INIT_NVAR(namespace_name);
						phalcon_get_ns_class(namespace_name, handler, 0 TSRMLS_CC);
					} else {
						PHALCON_CPY_WRT(controller_name, handler);
	
						PHALCON_INIT_NVAR(namespace_name);
					}
	
					phalcon_update_property_null(this_ptr, SL("_routePrefix") TSRMLS_CC);
	
					/** 
					 * Check if the scope has a module associated
					 */
					if (phalcon_array_isset_long(scope, 2)) {
						PHALCON_OBS_NVAR(module_name);
						phalcon_array_fetch_long(&module_name, scope, 2, PH_NOISY);
					} else {
						PHALCON_INIT_NVAR(module_name);
					}
	
					PHALCON_INIT_NVAR(suffixed);
					PHALCON_CONCAT_VV(suffixed, handler, controller_suffix);
	
					/** 
					 * Get the annotations from the class
					 */
					PHALCON_CALL_METHOD(&handler_annotations, annotations_service, "get", suffixed);
	
					/** 
					 * Process class annotations
					 */
					PHALCON_CALL_METHOD(&class_annotations, handler_annotations, "getclassannotations");
					if (Z_TYPE_P(class_annotations) == IS_OBJECT) {
	
						/** 
						 * Process class annotations
						 */
						PHALCON_CALL_METHOD(&annotations, class_annotations, "getannotations");
						if (Z_TYPE_P(annotations) == IS_ARRAY) { 
	
							phalcon_is_iterable(annotations, &ah1, &hp1, 0, 0);
	
							while (zend_hash_get_current_data_ex(ah1, (void**) &hd, &hp1) == SUCCESS) {
	
								PHALCON_GET_HVALUE(annotation);
	
								PHALCON_CALL_METHOD(NULL, this_ptr, "processcontrollerannotation", controller_name, annotation);
	
								zend_hash_move_forward_ex(ah1, &hp1);
							}
	
						}
					}
	
					/** 
					 * Process method annotations
					 */
					PHALCON_CALL_METHOD(&method_annotations, handler_annotations, "getmethodsannotations");
					if (Z_TYPE_P(method_annotations) == IS_ARRAY) { 
	
						phalcon_is_iterable(method_annotations, &ah2, &hp2, 0, 0);
	
						while (zend_hash_get_current_data_ex(ah2, (void**) &hd, &hp2) == SUCCESS) {
	
							PHALCON_GET_HKEY(method, ah2, hp2);
							PHALCON_GET_HVALUE(collection);
	
							if (Z_TYPE_P(collection) == IS_OBJECT) {
								PHALCON_CALL_METHOD(&annotations, collection, "getannotations");
	
								phalcon_is_iterable(annotations, &ah3, &hp3, 0, 0);
	
								while (zend_hash_get_current_data_ex(ah3, (void**) &hd, &hp3) == SUCCESS) {
	
									PHALCON_GET_HVALUE(annotation);
	
									PHALCON_CALL_METHOD(NULL, this_ptr, "processactionannotation", module_name, namespace_name, controller_name, method, annotation);
	
									zend_hash_move_forward_ex(ah3, &hp3);
								}
	
							}
	
							zend_hash_move_forward_ex(ah2, &hp2);
						}
	
					}
				}
	
				zend_hash_move_forward_ex(ah0, &hp0);
			}
	
		}
	
		phalcon_update_property_bool(this_ptr, SL("_processed"), 1 TSRMLS_CC);
	}
	
	/** 
	 * Call the parent handle method()
	 */
	PHALCON_CALL_PARENT(NULL, phalcon_mvc_router_annotations_ce, this_ptr, "handle", real_uri);
	
	PHALCON_MM_RESTORE();
}
예제 #2
0
파일: route.c 프로젝트: 11mariom/cphalcon
/**
 * Reconfigure the route adding a new pattern and a set of paths
 *
 * @param string $pattern
 * @param array $paths
 */
PHP_METHOD(Phalcon_Mvc_Router_Route, reConfigure){

	zval *pattern, *paths = NULL, *module_name = NULL, *controller_name = NULL;
	zval *action_name = NULL, *parts, *number_parts, *route_paths = NULL;
	zval *real_class_name = NULL, *namespace_name, *lower_name;
	zval *pcre_pattern = NULL, *compiled_pattern = NULL;

	PHALCON_MM_GROW();

	phalcon_fetch_params(1, 1, 1, &pattern, &paths);
	
	if (!paths) {
		PHALCON_INIT_VAR(paths);
	}
	
	if (Z_TYPE_P(pattern) != IS_STRING) {
		PHALCON_THROW_EXCEPTION_STR(phalcon_mvc_router_exception_ce, "The pattern must be string");
		return;
	}
	if (Z_TYPE_P(paths) != IS_NULL) {
		if (Z_TYPE_P(paths) == IS_STRING) {
	
			PHALCON_INIT_VAR(module_name);
	
			PHALCON_INIT_VAR(controller_name);
	
			PHALCON_INIT_VAR(action_name);
	
			/** 
			 * Explode the short paths using the :: separator
			 */
			PHALCON_INIT_VAR(parts);
			phalcon_fast_explode_str(parts, SL("::"), paths);
	
			PHALCON_INIT_VAR(number_parts);
			phalcon_fast_count(number_parts, parts TSRMLS_CC);
	
			/** 
			 * Create the array paths dynamically
			 */
	
			switch (phalcon_get_intval(number_parts)) {
	
				case 3:
					PHALCON_OBS_NVAR(module_name);
					phalcon_array_fetch_long(&module_name, parts, 0, PH_NOISY);
	
					PHALCON_OBS_NVAR(controller_name);
					phalcon_array_fetch_long(&controller_name, parts, 1, PH_NOISY);
	
					PHALCON_OBS_NVAR(action_name);
					phalcon_array_fetch_long(&action_name, parts, 2, PH_NOISY);
					break;
	
				case 2:
					PHALCON_OBS_NVAR(controller_name);
					phalcon_array_fetch_long(&controller_name, parts, 0, PH_NOISY);
	
					PHALCON_OBS_NVAR(action_name);
					phalcon_array_fetch_long(&action_name, parts, 1, PH_NOISY);
					break;
	
				case 1:
					PHALCON_OBS_NVAR(controller_name);
					phalcon_array_fetch_long(&controller_name, parts, 0, PH_NOISY);
					break;
	
			}
	
			PHALCON_INIT_VAR(route_paths);
			array_init(route_paths);
	
			/** 
			 * Process module name
			 */
			if (Z_TYPE_P(module_name) != IS_NULL) {
				phalcon_array_update_string(&route_paths, SL("module"), &module_name, PH_COPY | PH_SEPARATE);
			}
	
			/** 
			 * Process controller name
			 */
			if (Z_TYPE_P(controller_name) != IS_NULL) {
	
				/** 
				 * Check if we need to obtain the namespace
				 */
				if (phalcon_memnstr_str(controller_name, SL("\\"))) {
	
					/** 
					 * Extract the real class name from the namespaced class
					 */
					PHALCON_INIT_VAR(real_class_name);
					phalcon_get_class_ns(real_class_name, controller_name, 0 TSRMLS_CC);
	
					/** 
					 * Extract the namespace from the namespaced class
					 */
					PHALCON_INIT_VAR(namespace_name);
					phalcon_get_ns_class(namespace_name, controller_name, 0 TSRMLS_CC);
	
					/** 
					 * Update the namespace
					 */
					if (zend_is_true(namespace_name)) {
						phalcon_array_update_string(&route_paths, SL("namespace"), &namespace_name, PH_COPY | PH_SEPARATE);
					}
				} else {
					PHALCON_CPY_WRT(real_class_name, controller_name);
				}
	
				/** 
				 * Always pass the controller to lowercase
				 */
				PHALCON_INIT_VAR(lower_name);
				phalcon_uncamelize(lower_name, real_class_name);
	
				/** 
				 * Update the controller path
				 */
				phalcon_array_update_string(&route_paths, SL("controller"), &lower_name, PH_COPY | PH_SEPARATE);
			}
	
			/** 
			 * Process action name
			 */
			if (Z_TYPE_P(action_name) != IS_NULL) {
				phalcon_array_update_string(&route_paths, SL("action"), &action_name, PH_COPY | PH_SEPARATE);
			}
		} else {
			PHALCON_CPY_WRT(route_paths, paths);
		}
	} else {
		PHALCON_INIT_NVAR(route_paths);
		array_init(route_paths);
	}
	
	if (Z_TYPE_P(route_paths) != IS_ARRAY) { 
		PHALCON_THROW_EXCEPTION_STR(phalcon_mvc_router_exception_ce, "The route contains invalid paths");
		return;
	}
	
	/** 
	 * If the route starts with '#' we assume that it is a regular expression
	 */
	if (!phalcon_start_with_str(pattern, SL("#"))) {
		if (phalcon_memnstr_str(pattern, SL("{"))) {
			/** 
			 * The route has named parameters so we need to extract them
			 */
			PHALCON_INIT_VAR(pcre_pattern);
			phalcon_extract_named_params(pcre_pattern, pattern, route_paths);
		} else {
			PHALCON_CPY_WRT(pcre_pattern, pattern);
		}
	
		/** 
		 * Transform the route's pattern to a regular expression
		 */
		PHALCON_INIT_VAR(compiled_pattern);
		phalcon_call_method_p1(compiled_pattern, this_ptr, "compilepattern", pcre_pattern);
	} else {
		PHALCON_CPY_WRT(compiled_pattern, pattern);
	}
	
	/** 
	 * Update the original pattern
	 */
	phalcon_update_property_this(this_ptr, SL("_pattern"), pattern TSRMLS_CC);
	
	/** 
	 * Update the compiled pattern
	 */
	phalcon_update_property_this(this_ptr, SL("_compiledPattern"), compiled_pattern TSRMLS_CC);
	
	/** 
	 * Update the route's paths
	 */
	phalcon_update_property_this(this_ptr, SL("_paths"), route_paths TSRMLS_CC);
	
	PHALCON_MM_RESTORE();
}