Ejemplo n.º 1
0
static PHP_RINIT_FUNCTION(phalcon){

	phalcon_memory_entry *start;
	zend_phalcon_globals *phalcon_globals_ptr = PHALCON_VGLOBAL;
	size_t i;

	php_phalcon_init_globals(phalcon_globals_ptr TSRMLS_CC);
	phalcon_init_interned_strings(TSRMLS_C);

	start = (phalcon_memory_entry *) pecalloc(num_preallocated_frames, sizeof(phalcon_memory_entry), 1);
/* pecalloc() will take care of these members for every frame
	start->pointer      = 0;
	start->hash_pointer = 0;
	start->prev = NULL;
	start->next = NULL;
*/
	for (i = 0; i < num_preallocated_frames; ++i) {
		start[i].addresses       = pecalloc(24, sizeof(zval*), 1);
		start[i].capacity        = 24;
		start[i].hash_addresses  = pecalloc(8, sizeof(zval*), 1);
		start[i].hash_capacity   = 8;

#ifndef PHALCON_RELEASE
		start[i].permanent = 1;
#endif
	}

	start[0].next = &start[1];
	start[num_preallocated_frames - 1].prev = &start[num_preallocated_frames - 2];

	for (i = 1; i < num_preallocated_frames - 1; ++i) {
		start[i].next = &start[i + 1];
		start[i].prev = &start[i - 1];
	}

	phalcon_globals_ptr->start_memory = start;
	phalcon_globals_ptr->end_memory   = start + num_preallocated_frames;

	phalcon_globals_ptr->fcache = pemalloc(sizeof(HashTable), 1);
#ifndef PHALCON_RELEASE
	zend_hash_init(phalcon_globals_ptr->fcache, 128, NULL, phalcon_fcall_cache_dtor, 1);
#else
	zend_hash_init(phalcon_globals_ptr->fcache, 128, NULL, NULL, 1);
#endif

	/* 'Allocator sizeof operand mismatch' warning can be safely ignored */
	ALLOC_INIT_ZVAL(phalcon_globals_ptr->z_null);
	Z_SET_REFCOUNT_P(phalcon_globals_ptr->z_null, 2);

	/* 'Allocator sizeof operand mismatch' warning can be safely ignored */
	ALLOC_INIT_ZVAL(phalcon_globals_ptr->z_false);
	Z_SET_REFCOUNT_P(phalcon_globals_ptr->z_false, 2);
	ZVAL_FALSE(phalcon_globals_ptr->z_false);

	/* 'Allocator sizeof operand mismatch' warning can be safely ignored */
	ALLOC_INIT_ZVAL(phalcon_globals_ptr->z_true);
	Z_SET_REFCOUNT_P(phalcon_globals_ptr->z_true, 2);
	ZVAL_TRUE(phalcon_globals_ptr->z_true);

	/* 'Allocator sizeof operand mismatch' warning can be safely ignored */
	ALLOC_INIT_ZVAL(phalcon_globals_ptr->z_zero);
	Z_SET_REFCOUNT_P(phalcon_globals_ptr->z_zero, 2);
	ZVAL_LONG(phalcon_globals_ptr->z_zero, 0);

	/* 'Allocator sizeof operand mismatch' warning can be safely ignored */
	ALLOC_INIT_ZVAL(phalcon_globals_ptr->z_one);
	Z_SET_REFCOUNT_P(phalcon_globals_ptr->z_one, 2);
	ZVAL_LONG(phalcon_globals_ptr->z_one, 1);

	return SUCCESS;
}
Ejemplo n.º 2
0
/**
 * Traverses a collection calling the callback to generate its HTML
 *
 * @param Phalcon\Assets\Collection $collection
 * @param callback $callback
 * @param string $type
 */
PHP_METHOD(Phalcon_Assets_Manager, output){

	zval *collection, *callback, *type = NULL, *output, *use_implicit_output;
	zval *resources = NULL, *filters = NULL, *prefix = NULL, *source_base_path = NULL;
	zval *target_base_path = NULL, *options, *collection_source_path = NULL;
	zval *complete_source_path = NULL, *collection_target_path = NULL;
	zval *complete_target_path = NULL, *filtered_joined_content = NULL;
	zval *join = NULL, *exception_message = NULL, *is_directory;
	zval *resource = NULL, *filter_needed = NULL, *local = NULL, *source_path = NULL;
	zval *target_path = NULL, *path = NULL, *prefixed_path = NULL, *attributes = NULL;
	zval *parameters = NULL, *html = NULL, *content = NULL, *must_filter = NULL;
	zval *filter = NULL, *filtered_content = NULL, *target_uri = NULL;
	HashTable *ah0, *ah1;
	HashPosition hp0, hp1;
	zval **hd;
	zval *type_css;

	PHALCON_MM_GROW();

	phalcon_fetch_params(1, 2, 1, &collection, &callback, &type);
	
	PHALCON_INIT_VAR(output);
	
	PHALCON_OBS_VAR(use_implicit_output);
	phalcon_read_property_this(&use_implicit_output, this_ptr, SL("_implicitOutput"), PH_NOISY TSRMLS_CC);
	
	/** 
	 * Get the resources as an array
	 */
	PHALCON_CALL_METHOD(&resources, collection, "getresources");
	
	/** 
	 * Get filters in the collection
	 */
	PHALCON_CALL_METHOD(&filters, collection, "getfilters");
	
	/** 
	 * Get the collection's prefix
	 */
	PHALCON_CALL_METHOD(&prefix, collection, "getprefix");

	PHALCON_INIT_VAR(type_css);
	ZVAL_STRING(type_css, "css", 1);
	
	/** 
	 * Prepare options if the collection must be filtered
	 */
	if (Z_TYPE_P(filters) == IS_ARRAY) { 
	
		PHALCON_INIT_VAR(source_base_path);
	
		PHALCON_INIT_VAR(target_base_path);
	
		PHALCON_OBS_VAR(options);
		phalcon_read_property_this(&options, this_ptr, SL("_options"), PH_NOISY TSRMLS_CC);
	
		/** 
		 * Check for global options in the assets manager
		 */
		if (Z_TYPE_P(options) == IS_ARRAY) { 
	
			/** 
			 * The source base path is a global location where all resources are located
			 */
			if (phalcon_array_isset_string(options, SS("sourceBasePath"))) {
				PHALCON_OBS_NVAR(source_base_path);
				phalcon_array_fetch_string(&source_base_path, options, SL("sourceBasePath"), PH_NOISY);
			}
	
			/** 
			 * The target base path is a global location where all resources are written
			 */
			if (phalcon_array_isset_string(options, SS("targetBasePath"))) {
				PHALCON_OBS_NVAR(target_base_path);
				phalcon_array_fetch_string(&target_base_path, options, SL("targetBasePath"), PH_NOISY);
			}
		}
	
		/** 
		 * Check if the collection have its own source base path
		 */
		PHALCON_CALL_METHOD(&collection_source_path, collection, "getsourcepath");
	
		/** 
		 * Concatenate the global base source path with the collection one
		 */
		if (PHALCON_IS_NOT_EMPTY(collection_source_path)) {
			PHALCON_INIT_VAR(complete_source_path);
			PHALCON_CONCAT_VV(complete_source_path, source_base_path, collection_source_path);
		} else {
			PHALCON_CPY_WRT(complete_source_path, source_base_path);
		}
	
		/** 
		 * Check if the collection have its own target base path
		 */
		PHALCON_CALL_METHOD(&collection_target_path, collection, "gettargetpath");
	
		/** 
		 * Concatenate the global base source path with the collection one
		 */
		if (PHALCON_IS_NOT_EMPTY(collection_target_path)) {
			PHALCON_INIT_VAR(complete_target_path);
			PHALCON_CONCAT_VV(complete_target_path, target_base_path, collection_target_path);
		} else {
			PHALCON_CPY_WRT(complete_target_path, target_base_path);
		}
	
		/** 
		 * Global filtered content
		 */
		PHALCON_INIT_VAR(filtered_joined_content);
	
		/** 
		 * Check if all the resources in the collection must be joined
		 */
		PHALCON_CALL_METHOD(&join, collection, "getjoin");
	
		/** 
		 * Check for valid target paths if the collection must be joined
		 */
		if (zend_is_true(join)) {
	
			/** 
			 * We need a valid final target path
			 */
			if (PHALCON_IS_EMPTY(complete_target_path)) {
				PHALCON_INIT_VAR(exception_message);
				PHALCON_CONCAT_SVS(exception_message, "Path '", complete_target_path, "' is not a valid target path (1)");
				PHALCON_THROW_EXCEPTION_ZVAL(phalcon_assets_exception_ce, exception_message);
				return;
			}
	
			PHALCON_INIT_VAR(is_directory);
			phalcon_is_dir(is_directory, complete_target_path TSRMLS_CC);
	
			/** 
			 * The targetpath needs to be a valid file
			 */
			if (PHALCON_IS_TRUE(is_directory)) {
				PHALCON_INIT_NVAR(exception_message);
				PHALCON_CONCAT_SVS(exception_message, "Path '", complete_target_path, "' is not a valid target path (2)");
				PHALCON_THROW_EXCEPTION_ZVAL(phalcon_assets_exception_ce, exception_message);
				return;
			}
		}
	}
	
	phalcon_is_iterable(resources, &ah0, &hp0, 0, 0);
	
	while (zend_hash_get_current_data_ex(ah0, (void**) &hd, &hp0) == SUCCESS) {
	
		PHALCON_GET_HVALUE(resource);
	
		PHALCON_INIT_NVAR(filter_needed);
		ZVAL_FALSE(filter_needed);

		if (!type) {
			PHALCON_CALL_METHOD(&type, resource, "gettype");
		}

		/** 
		 * Is the resource local?
		 */
		PHALCON_CALL_METHOD(&local, resource, "getlocal");
	
		/** 
		 * If the collection must not be joined we must print a HTML for each one
		 */
		if (Z_TYPE_P(filters) == IS_ARRAY) { 
			if (zend_is_true(local)) {

				/** 
				 * Get the complete path
				 */
				PHALCON_CALL_METHOD(&source_path, resource, "getrealsourcepath", complete_source_path);

				/** 
				 * We need a valid source path
				 */
				if (!zend_is_true(source_path)) {
					PHALCON_CALL_METHOD(&source_path, resource, "getpath");

					PHALCON_INIT_NVAR(exception_message);
					PHALCON_CONCAT_SVS(exception_message, "Resource '", source_path, "' does not have a valid source path");
					PHALCON_THROW_EXCEPTION_ZVAL(phalcon_assets_exception_ce, exception_message);
					return;
				}
			} else {
				/** 
				 * Get the complete source path
				 */
				PHALCON_CALL_METHOD(&source_path, resource, "getpath");

				/** 
				 * resources paths are always filtered
				 */
				PHALCON_INIT_NVAR(filter_needed);
				ZVAL_TRUE(filter_needed);
			}

			/** 
			 * Get the target path, we need to write the filtered content to a file
			 */
			PHALCON_CALL_METHOD(&target_path, resource, "getrealtargetpath", complete_target_path);

			/** 
			 * We need a valid final target path
			 */
			if (PHALCON_IS_EMPTY(target_path)) {
				PHALCON_INIT_NVAR(exception_message);
				PHALCON_CONCAT_SVS(exception_message, "Resource '", source_path, "' does not have a valid target path");
				PHALCON_THROW_EXCEPTION_ZVAL(phalcon_assets_exception_ce, exception_message);
				return;
			}

			if (zend_is_true(local)) {

				/** 
				 * Make sure the target path is not the same source path
				 */
				if (PHALCON_IS_EQUAL(target_path, source_path)) {
					PHALCON_INIT_NVAR(exception_message);
					PHALCON_CONCAT_SVS(exception_message, "Resource '", target_path, "' have the same source and target paths");
					PHALCON_THROW_EXCEPTION_ZVAL(phalcon_assets_exception_ce, exception_message);
					return;
				}
				if (phalcon_file_exists(target_path TSRMLS_CC) == SUCCESS) {
					if (phalcon_compare_mtime(target_path, source_path TSRMLS_CC)) {
						PHALCON_INIT_NVAR(filter_needed);
						ZVAL_TRUE(filter_needed);
					}
				} else {
					PHALCON_INIT_NVAR(filter_needed);
					ZVAL_TRUE(filter_needed);
				}
			}
		}
	
		/** 
		 * If there are no filters, just print/buffer the HTML
		 */
		if (Z_TYPE_P(filters) != IS_ARRAY) { 
			PHALCON_CALL_METHOD(&path, resource, "getrealtargeturi");
			if (Z_TYPE_P(prefix) != IS_NULL) {
				PHALCON_INIT_NVAR(prefixed_path);
				PHALCON_CONCAT_VV(prefixed_path, prefix, path);
			} else {
				PHALCON_CPY_WRT(prefixed_path, path);
			}
	
			/** 
			 * Gets extra HTML attributes in the resource
			 */
			PHALCON_CALL_METHOD(&attributes, resource, "getattributes");
	
			/** 
			 * Prepare the parameters for the callback
			 */
			PHALCON_INIT_NVAR(parameters);
			array_init_size(parameters, 2);
			if (Z_TYPE_P(attributes) == IS_ARRAY) { 
				phalcon_array_update_long(&attributes, 0, prefixed_path, PH_COPY | PH_SEPARATE);
	
				phalcon_array_append(&parameters, attributes, 0);
			} else {
				phalcon_array_append(&parameters, prefixed_path, 0);
			}

			phalcon_array_append(&parameters, local, 0);
	
			/** 
			 * Call the callback to generate the HTML
			 */
			PHALCON_INIT_NVAR(html);/**/
			PHALCON_CALL_USER_FUNC_ARRAY(html, callback, parameters);
	
			/** 
			 * Implicit output prints the content directly
			 */
			if (zend_is_true(use_implicit_output)) {
				zend_print_zval(html, 0);
			} else {
				phalcon_concat_self(&output, html TSRMLS_CC);
			}
	
			zend_hash_move_forward_ex(ah0, &hp0);
			continue;
		}
	
		if (zend_is_true(filter_needed)) {
	
			/** 
			 * Get the resource's content
			 */
			PHALCON_CALL_METHOD(&content, resource, "getcontent", complete_source_path);
	
			/** 
			 * Check if the resource must be filtered
			 */
			PHALCON_CALL_METHOD(&must_filter, resource, "getfilter");
	
			/** 
			 * Only filter the resource if it's marked as 'filterable'
			 */
			if (zend_is_true(must_filter)) {
	
				phalcon_is_iterable(filters, &ah1, &hp1, 0, 0);
	
				while (zend_hash_get_current_data_ex(ah1, (void**) &hd, &hp1) == SUCCESS) {
	
					PHALCON_GET_HVALUE(filter);
	
					/** 
					 * Filters must be valid objects
					 */
					if (Z_TYPE_P(filter) != IS_OBJECT) {
						PHALCON_THROW_EXCEPTION_STR(phalcon_assets_exception_ce, "Filter is invalid");
						return;
					}
	
					/** 
					 * Calls the method 'filter' which must return a filtered version of the content
					 */
					PHALCON_CALL_METHOD(&filtered_content, filter, "filter", content);
					PHALCON_CPY_WRT_CTOR(content, filtered_content);

					zend_hash_move_forward_ex(ah1, &hp1);
				}

				/**
				 * Update the joined filtered content
				 */
				if (zend_is_true(join)) {
					if (PHALCON_IS_EQUAL(type, type_css)) {
						if (Z_TYPE_P(filtered_joined_content) == IS_NULL) {
							PHALCON_INIT_NVAR(filtered_joined_content);
							PHALCON_CONCAT_VS(filtered_joined_content, content, "");
						} else {
							PHALCON_SCONCAT_VS(filtered_joined_content, content, "");
						}
					} else {
						if (Z_TYPE_P(filtered_joined_content) == IS_NULL) {
							PHALCON_INIT_NVAR(filtered_joined_content);
							PHALCON_CONCAT_VS(filtered_joined_content, content, ";");
						} else {
							PHALCON_SCONCAT_VS(filtered_joined_content, content, ";");
						}
					}
				}

			} else {
				/** 
				 * Update the joined filtered content
				 */
				if (zend_is_true(join)) {
					if (Z_TYPE_P(filtered_joined_content) == IS_NULL) {
						PHALCON_CPY_WRT(filtered_joined_content, content);
					} else {
						phalcon_concat_self(&filtered_joined_content, content TSRMLS_CC);
					}
				} else {
					PHALCON_CPY_WRT(filtered_content, content);
				}
			}
	
			if (!zend_is_true(join)) {
				/** 
				 * Write the file using file-put-contents. This respects the openbase-dir also
				 * writes to streams
				 */
				phalcon_file_put_contents(NULL, target_path, filtered_content TSRMLS_CC);
			}
		}
	
		if (!zend_is_true(join)) {
	
			/** 
			 * Generate the HTML using the original path in the resource
			 */
			PHALCON_CALL_METHOD(&path, resource, "getrealtargeturi");
			if (Z_TYPE_P(prefix) != IS_NULL) {
				PHALCON_INIT_NVAR(prefixed_path);
				PHALCON_CONCAT_VV(prefixed_path, prefix, path);
			} else {
				PHALCON_CPY_WRT(prefixed_path, path);
			}
	
			/** 
			 * Gets extra HTML attributes in the resource
			 */
			PHALCON_CALL_METHOD(&attributes, resource, "getattributes");
	
			/** 
			 * Filtered resources are always local
			 */
			PHALCON_INIT_NVAR(local);
			ZVAL_TRUE(local);
	
			/** 
			 * Prepare the parameters for the callback
			 */
			PHALCON_INIT_NVAR(parameters);
			array_init_size(parameters, 2);
			if (Z_TYPE_P(attributes) == IS_ARRAY) { 
				phalcon_array_update_long(&attributes, 0, prefixed_path, PH_COPY | PH_SEPARATE);
	
				phalcon_array_append(&parameters, attributes, 0);
			} else {
				phalcon_array_append(&parameters, prefixed_path, 0);
			}

			phalcon_array_append(&parameters, local, 0);

			/** 
			 * Call the callback to generate the HTML
			 */
			PHALCON_INIT_NVAR(html);/**/
			PHALCON_CALL_USER_FUNC_ARRAY(html, callback, parameters);
	
			/** 
			 * Implicit output prints the content directly
			 */
			if (zend_is_true(use_implicit_output)) {
				zend_print_zval(html, 0);
			} else {
				phalcon_concat_self(&output, html TSRMLS_CC);
			}
		}
	
		zend_hash_move_forward_ex(ah0, &hp0);
	}
	
	if (Z_TYPE_P(filters) == IS_ARRAY) { 
		if (zend_is_true(join)) {
	
			/** 
			 * Write the file using file_put_contents. This respects the openbase-dir also
			 * writes to streams
			 */
			phalcon_file_put_contents(NULL, complete_target_path, filtered_joined_content TSRMLS_CC);
	
			/** 
			 * Generate the HTML using the original path in the resource
			 */
			PHALCON_CALL_METHOD(&target_uri, collection, "gettargeturi");
			if (Z_TYPE_P(prefix) != IS_NULL) {
				PHALCON_INIT_NVAR(prefixed_path);
				PHALCON_CONCAT_VV(prefixed_path, prefix, target_uri);
			} else {
				PHALCON_CPY_WRT(prefixed_path, target_uri);
			}
	
			/** 
			 * Gets extra HTML attributes in the resource
			 */
			PHALCON_CALL_METHOD(&attributes, collection, "getattributes");
			PHALCON_CALL_METHOD(&local, collection, "gettargetlocal");
	
			/** 
			 * Prepare the parameters for the callback
			 */
			PHALCON_INIT_NVAR(parameters);
			array_init_size(parameters, 2);
			if (Z_TYPE_P(attributes) == IS_ARRAY) { 
				phalcon_array_update_long(&attributes, 0, prefixed_path, PH_COPY | PH_SEPARATE);
	
				phalcon_array_append(&parameters, attributes, 0);
			} else {
				phalcon_array_append(&parameters, prefixed_path, 0);
			}

			phalcon_array_append(&parameters, local, 0);

			/** 
			 * Call the callback to generate the HTML
			 */
			PHALCON_INIT_NVAR(html);/**/
			PHALCON_CALL_USER_FUNC_ARRAY(html, callback, parameters);
	
			/** 
			 * Implicit output prints the content directly
			 */
			if (zend_is_true(use_implicit_output)) {
				zend_print_zval(html, 0);
			} else {
				phalcon_concat_self(&output, html TSRMLS_CC);
			}
		}
	}
	
	RETURN_CCTOR(output);
}