Exemplo n.º 1
0
/**
 * Adds a internal hooks after decrypts an encrypted text
 *
 * @param callable $handler
 */
PHP_METHOD(Phalcon_Crypt, afterDecrypt){

	zval *handler;

	phalcon_fetch_params(0, 1, 0, &handler);
	
	if (Z_TYPE_P(handler) != IS_OBJECT && !phalcon_is_callable(handler)) {
		PHALCON_THROW_EXCEPTION_STRW(phalcon_crypt_exception_ce, "Handler must be an callable");
		return;
	}
	
	phalcon_update_property_zval(getThis(), SL("_afterDecrypt"), handler);
	RETURN_THISW();
}
Exemplo n.º 2
0
/**
 * Adds a internal hooks after decrypts an encrypted text
 *
 * @param callable $handler
 */
PHP_METHOD(Phalcon_Crypt, afterDecrypt){

	zval *handler;

	PHALCON_MM_GROW();

	phalcon_fetch_params(1, 1, 0, &handler);
	
	if (Z_TYPE_P(handler) != IS_OBJECT && !phalcon_is_callable(handler TSRMLS_CC)) {
		PHALCON_THROW_EXCEPTION_STR(phalcon_crypt_exception_ce, "Handler must be an callable");
		return;
	}
	
	phalcon_update_property_this(this_ptr, SL("_afterDecrypt"), handler TSRMLS_CC);
	RETURN_THIS();
}
Exemplo n.º 3
0
/**
 * Detach a listener from the events manager
 *
 * @param object|callable $handler
 */
PHP_METHOD(Phalcon_Events_Manager, detach){

	zval *type, *handler, events = {}, queue = {}, priority_queue = {}, *listener;
	zend_string *str_key;
	ulong idx;

	phalcon_fetch_params(0, 2, 0, &type, &handler);

	if (Z_TYPE_P(handler) != IS_OBJECT && !phalcon_is_callable(handler)) {
		PHALCON_THROW_EXCEPTION_STRW(phalcon_events_exception_ce, "Event handler must be an object or callable");
		return;
	}

	phalcon_return_property(&events, getThis(), SL("_events"));
	if (Z_TYPE(events) != IS_ARRAY) {
		RETURN_FALSE;
	}

	if (!phalcon_array_isset_fetch(&queue, &events, type)) {
		RETURN_FALSE;
	}

	if (Z_TYPE(queue) == IS_OBJECT) {
		object_init_ex(&priority_queue, spl_ce_SplPriorityQueue);
		if (phalcon_has_constructor(&priority_queue)) {
			PHALCON_CALL_METHODW(NULL, &priority_queue, "__construct");
		}

		PHALCON_CALL_METHODW(NULL, &queue, "top");

		while (1) {
			zval r0 = {}, listener0 = {}, handler_embeded = {}, priority = {};
			PHALCON_CALL_METHODW(&r0, &queue, "valid");
			if (!zend_is_true(&r0)) {
				break;
			}

			PHALCON_CALL_METHODW(&listener0, &queue, "current");
			PHALCON_CALL_METHODW(&handler_embeded, &listener0, "getlistener");

			if (!phalcon_is_equal(&handler_embeded, handler)) {
				PHALCON_CALL_METHODW(&priority, &listener0, "getpriority");
				PHALCON_CALL_METHODW(NULL, &priority_queue, "insert", &listener0, &priority);
			}
			
			PHALCON_CALL_METHODW(NULL, &queue, "next");
		}
	} else {
		PHALCON_CPY_WRT_CTOR(&priority_queue, &queue);
		ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL(queue), idx, str_key, listener) {
			zval key = {}, handler_embeded = {};
			if (str_key) {
				ZVAL_STR(&key, str_key);
			} else {
				ZVAL_LONG(&key, idx);
			}

			PHALCON_CALL_METHODW(&handler_embeded, listener, "getlistener");

			if (phalcon_is_equal_object(&handler_embeded, handler)) {
				phalcon_array_unset(&priority_queue, &key, PH_COPY);
			}

		} ZEND_HASH_FOREACH_END();
	}
Exemplo n.º 4
0
/**
 * Attach a listener to the events manager
 *
 * @param string $eventType
 * @param callable $handler
 * @param int $priority
 */
PHP_METHOD(Phalcon_Events_Manager, attach){

	zval *event_type, *handler, *_priority = NULL, priority = {}, events = {}, listener = {}, enable_priorities = {}, priority_queue = {};

	phalcon_fetch_params(0, 2, 1, &event_type, &handler, &_priority);

	if (!_priority) {
		ZVAL_LONG(&priority, 100);
	} else {
		PHALCON_CPY_WRT(&priority, _priority);
	}

	if (unlikely(Z_TYPE_P(event_type) != IS_STRING)) {
		PHALCON_THROW_EXCEPTION_STRW(phalcon_events_exception_ce, "Event type must be a string");
		return;
	}

	if (Z_TYPE_P(handler) != IS_OBJECT && !phalcon_is_callable(handler)) {
		PHALCON_THROW_EXCEPTION_STRW(phalcon_events_exception_ce, "Event handler must be an object or callable");
		return;
	}

	if (phalcon_instance_of_ev(handler, phalcon_events_listener_ce)) {
		PHALCON_CPY_WRT(&listener, handler);
		PHALCON_CALL_METHODW(NULL, &listener, "setpriority", &priority);
		PHALCON_CALL_METHODW(NULL, &listener, "setevent", event_type);
	} else {
		object_init_ex(&listener, phalcon_events_listener_ce);
		PHALCON_CALL_METHODW(NULL, &listener, "__construct", handler, &priority, event_type);
	}

	phalcon_return_property(&events, getThis(), SL("_events"));
	if (Z_TYPE(events) != IS_ARRAY) {
		array_init(&events);
	}

	if (!phalcon_array_isset_fetch(&priority_queue, &events, event_type)) {
		phalcon_return_property(&enable_priorities, getThis(), SL("_enablePriorities"));
		if (zend_is_true(&enable_priorities)) {
			/** 
			 * Create a SplPriorityQueue to store the events with priorities
			 */
			object_init_ex(&priority_queue, spl_ce_SplPriorityQueue);
			if (phalcon_has_constructor(&priority_queue)) {
				PHALCON_CALL_METHODW(NULL, &priority_queue, "__construct");
			}

			/** 
			 * Extract only the Data, Set extraction flags
			 */
			PHALCON_CALL_METHODW(NULL, &priority_queue, "setextractflags", &PHALCON_GLOBAL(z_one));

			/** 
			 * Append the events to the queue
			 */
			phalcon_array_update_zval(&events, event_type, &priority_queue, PH_COPY);
			phalcon_update_property_this(getThis(), SL("_events"), &events);
		} else {
			array_init(&priority_queue);
		}
	}

	/** 
	 * Insert the handler in the queue
	 */
	if (unlikely(Z_TYPE(priority_queue) == IS_OBJECT)) {
		PHALCON_CALL_METHODW(NULL, &priority_queue, "insert", &listener, &priority);
	} else {
		phalcon_array_append(&priority_queue, &listener, PH_COPY);
	}

	/** 
	 * Append the events to the queue
	 */
	phalcon_array_update_zval(&events, event_type, &priority_queue, PH_COPY);
	phalcon_update_property_this(getThis(), SL("_events"), &events);
}
Exemplo n.º 5
0
/**
 * Decrypts an encrypted text
 *
 *<code>
 *	echo $crypt->decrypt($encrypted, "decrypt password");
 *</code>
 *
 * @param string $text
 * @param string $key
 * @return string
 */
PHP_METHOD(Phalcon_Crypt, decrypt){

	zval *text, *key = NULL, *decrypt_key = NULL, *cipher, *mode, *iv_size = NULL;
	zval *key_size, *text_size, *iv, *text_to_decipher, *decrypted = NULL;
	zval *padding_type, *block_size = NULL;
	zval *handler, *arguments = NULL, *value = NULL;

	PHALCON_MM_GROW();

	phalcon_fetch_params(1, 1, 1, &text, &key);

	if (phalcon_function_exists_ex(SS("mcrypt_get_iv_size") TSRMLS_CC) == FAILURE) {
		PHALCON_THROW_EXCEPTION_STR(phalcon_crypt_exception_ce, "mcrypt extension is required");
		return;
	}

	PHALCON_OBS_VAR(handler);
	phalcon_read_property_this(&handler, this_ptr, SL("_beforeDecrypt"), PH_NOISY TSRMLS_CC);

	if (phalcon_is_callable(handler TSRMLS_CC)) {
		PHALCON_SEPARATE_PARAM(text);

		PHALCON_INIT_NVAR(arguments);
		array_init_size(arguments, 1);
		phalcon_array_append(&arguments, text, 0);

		PHALCON_INIT_NVAR(value);
		PHALCON_CALL_USER_FUNC_ARRAY(value, handler, arguments);

		PHALCON_CPY_WRT(text, value);
	}

	if (!key || Z_TYPE_P(key) == IS_NULL) {
		decrypt_key = phalcon_fetch_nproperty_this(this_ptr, SL("_key"), PH_NOISY TSRMLS_CC);
	} else {
		decrypt_key = key;
	}

	if (PHALCON_IS_EMPTY(decrypt_key)) {
		PHALCON_THROW_EXCEPTION_STR(phalcon_crypt_exception_ce, "Decryption key cannot be empty");
		return;
	}

	cipher = phalcon_fetch_nproperty_this(this_ptr, SL("_cipher"), PH_NOISY TSRMLS_CC);
	mode   = phalcon_fetch_nproperty_this(this_ptr, SL("_mode"), PH_NOISY TSRMLS_CC);

	PHALCON_CALL_FUNCTION(&iv_size, "mcrypt_get_iv_size", cipher, mode);
	if (unlikely(Z_TYPE_P(iv_size) != IS_LONG)) {
		convert_to_long(iv_size);
	}

	PHALCON_INIT_VAR(key_size);
	phalcon_fast_strlen(key_size, decrypt_key);
	if (PHALCON_GT(key_size, iv_size)) {
		PHALCON_THROW_EXCEPTION_STR(phalcon_crypt_exception_ce, "Size of key is too large for this algorithm");
		return;
	}

	PHALCON_INIT_VAR(text_size);
	phalcon_fast_strlen(text_size, text);
	if (PHALCON_GT(key_size, text_size)) {
		PHALCON_THROW_EXCEPTION_STR(phalcon_crypt_exception_ce, "Size of IV is larger than text to decrypt");
		return;
	}

	PHALCON_INIT_VAR(iv);
	phalcon_substr(iv, text, 0, Z_LVAL_P(iv_size));

	PHALCON_INIT_VAR(text_to_decipher);
	phalcon_substr(text_to_decipher, text, Z_LVAL_P(iv_size), 0);

	PHALCON_CALL_FUNCTION(&decrypted, "mcrypt_decrypt", cipher, decrypt_key, text_to_decipher, mode, iv);
	if (unlikely(Z_TYPE_P(decrypted) != IS_STRING)) {
		convert_to_string(decrypted);
	}

	PHALCON_CALL_FUNCTION(&block_size, "mcrypt_get_block_size", cipher, mode);
	if (unlikely(Z_TYPE_P(block_size) != IS_LONG)) {
		convert_to_long(block_size);
	}

	padding_type = phalcon_fetch_nproperty_this(this_ptr, SL("_padding"), PH_NOISY TSRMLS_CC);

	assert(Z_TYPE_P(padding_type) == IS_LONG);
	assert(Z_TYPE_P(block_size) == IS_LONG);
	assert(Z_TYPE_P(mode) == IS_STRING);
	assert(Z_TYPE_P(decrypted) == IS_STRING);

	phalcon_crypt_unpad_text(return_value, decrypted, mode, Z_LVAL_P(block_size), Z_LVAL_P(padding_type) TSRMLS_CC);

	PHALCON_OBS_NVAR(handler);
	phalcon_read_property_this(&handler, this_ptr, SL("_afterDecrypt"), PH_NOISY TSRMLS_CC);

	if (phalcon_is_callable(handler TSRMLS_CC)) {
		PHALCON_INIT_NVAR(arguments);
		array_init_size(arguments, 1);
		phalcon_array_append(&arguments, return_value, 0);

		PHALCON_INIT_NVAR(value);
		PHALCON_CALL_USER_FUNC_ARRAY(value, handler, arguments);

		RETURN_CTOR(value);
	}

	RETURN_MM();
}
Exemplo n.º 6
0
/**
 * Encrypts a text
 *
 *<code>
 *	$encrypted = $crypt->encrypt("Ultra-secret text", "encrypt password");
 *</code>
 *
 * @param string $text
 * @param string $key
 * @return string
 */
PHP_METHOD(Phalcon_Crypt, encrypt){

	zval *source, *text, *key = NULL, *encrypt_key = NULL, *cipher, *mode, *padding_type, *iv_size = NULL;
	zval *rand, *iv = NULL, *encrypt = NULL, *block_size = NULL, *padded;
	zval *handler, *arguments = NULL, *value = NULL;

	PHALCON_MM_GROW();

	phalcon_fetch_params(1, 1, 1, &source, &key);

	PHALCON_OBS_VAR(handler);
	phalcon_read_property_this(&handler, this_ptr, SL("_beforeEncrypt"), PH_NOISY TSRMLS_CC);

	if (phalcon_is_callable(handler TSRMLS_CC)) {
		PHALCON_SEPARATE_PARAM(source);

		PHALCON_INIT_NVAR(arguments);
		array_init_size(arguments, 1);
		phalcon_array_append(&arguments, source, 0);

		PHALCON_INIT_NVAR(value);
		PHALCON_CALL_USER_FUNC_ARRAY(value, handler, arguments);

		PHALCON_CPY_WRT(source, value);
	}

	/* Do not use make_printable_zval() here: we need the conversion with type juggling */
	if (Z_TYPE_P(source) != IS_STRING) {
		PHALCON_INIT_VAR(text);
		phalcon_cast(text, source, IS_STRING);
	}
	else {
		text = source;
	}

	if (phalcon_function_exists_ex(SS("mcrypt_get_iv_size") TSRMLS_CC) == FAILURE) {
		PHALCON_THROW_EXCEPTION_STR(phalcon_crypt_exception_ce, "mcrypt extension is required");
		return;
	}

	if (!key || Z_TYPE_P(key) == IS_NULL) {
		encrypt_key = phalcon_fetch_nproperty_this(this_ptr, SL("_key"), PH_NOISY TSRMLS_CC);
	} else {
		PHALCON_CPY_WRT_CTOR(encrypt_key, key);
		if (Z_TYPE_P(encrypt_key) != IS_STRING) {
			convert_to_string(encrypt_key);
		}
	}

	if (PHALCON_IS_EMPTY(encrypt_key)) {
		PHALCON_THROW_EXCEPTION_STR(phalcon_crypt_exception_ce, "Encryption key cannot be empty");
		return;
	}

	cipher = phalcon_fetch_nproperty_this(this_ptr, SL("_cipher"), PH_NOISY TSRMLS_CC);
	mode   = phalcon_fetch_nproperty_this(this_ptr, SL("_mode"), PH_NOISY TSRMLS_CC);

	PHALCON_CALL_FUNCTION(&iv_size, "mcrypt_get_iv_size", cipher, mode);
	if (unlikely(Z_TYPE_P(iv_size) != IS_LONG)) {
		convert_to_long(iv_size);
	}

	if (Z_STRLEN_P(encrypt_key) > Z_LVAL_P(iv_size)) {
		PHALCON_THROW_EXCEPTION_STR(phalcon_crypt_exception_ce, "Size of key is too large for this algorithm");
		return;
	}

	PHALCON_INIT_VAR(rand);
	ZVAL_LONG(rand, 2);

	PHALCON_CALL_FUNCTION(&iv, "mcrypt_create_iv", iv_size, rand);
	if (unlikely(Z_TYPE_P(iv) != IS_STRING)) {
		convert_to_string(iv);
	}

	PHALCON_CALL_FUNCTION(&block_size, "mcrypt_get_block_size", cipher, mode);
	if (unlikely(Z_TYPE_P(block_size) != IS_LONG)) {
		convert_to_long(block_size);
	}

	padding_type = phalcon_fetch_nproperty_this(this_ptr, SL("_padding"), PH_NOISY TSRMLS_CC);

	assert(Z_TYPE_P(padding_type) == IS_LONG);
	assert(Z_TYPE_P(block_size) == IS_LONG);
	assert(Z_TYPE_P(mode) == IS_STRING);
	assert(Z_TYPE_P(text) == IS_STRING);

	PHALCON_INIT_VAR(padded);
	phalcon_crypt_pad_text(padded, text, mode, Z_LVAL_P(block_size), Z_LVAL_P(padding_type) TSRMLS_CC);
	assert(Z_TYPE_P(padded) == IS_STRING);

	PHALCON_CALL_FUNCTION(&encrypt, "mcrypt_encrypt", cipher, encrypt_key, padded, mode, iv);

	PHALCON_CONCAT_VV(return_value, iv, encrypt);

	PHALCON_OBS_NVAR(handler);
	phalcon_read_property_this(&handler, this_ptr, SL("_afterEncrypt"), PH_NOISY TSRMLS_CC);

	if (phalcon_is_callable(handler TSRMLS_CC)) {
		PHALCON_INIT_NVAR(arguments);
		array_init_size(arguments, 1);
		phalcon_array_append(&arguments, return_value, 0);

		PHALCON_INIT_NVAR(value);
		PHALCON_CALL_USER_FUNC_ARRAY(value, handler, arguments);

		RETURN_CTOR(value);
	}

	RETURN_MM();
}
Exemplo n.º 7
0
/**
 * Generates a URL
 *
 *<code>
 *
 * //Generate a URL appending the URI to the base URI
 * echo $url->get('products/edit/1');
 *
 * //Generate a URL for a predefined route
 * echo $url->get(array('for' => 'blog-post', 'title' => 'some-cool-stuff', 'year' => '2012'));
 * echo $url->get(array('for' => 'blog-post', 'hostname' => true, 'title' => 'some-cool-stuff', 'year' => '2012'));
 *
 *</code>
 *
 * @param string|array $uri
 * @param array|object args Optional arguments to be appended to the query string
 * @param bool|null $local
 * @return string
 */
PHP_METHOD(Phalcon_Mvc_Url, get){

	zval *uri = NULL, *args = NULL, *local = NULL, *base_uri = NULL, *router = NULL, *dependency_injector;
	zval *service, *route_name, *hostname, *route = NULL, *exception_message;
	zval *pattern = NULL, *paths = NULL, *processed_uri = NULL, *query_string;
	zval *matched, *regexp;
	zval *generator = NULL, *arguments;

	PHALCON_MM_GROW();

	phalcon_fetch_params(1, 0, 3, &uri, &args, &local);

	if (!uri) {
		uri = &PHALCON_GLOBAL(z_null);
	}

	if (!args) {
		args = &PHALCON_GLOBAL(z_null);
	}

	if (!local) {
		local = &PHALCON_GLOBAL(z_null);
	} else {
		PHALCON_SEPARATE_PARAM(local);
	}

	PHALCON_CALL_METHOD(&base_uri, getThis(), "getbaseuri");

	if (Z_TYPE_P(uri) == IS_STRING) {
		if (strstr(Z_STRVAL_P(uri), ":")) {
			PHALCON_INIT_VAR(matched);
			PHALCON_INIT_VAR(regexp);
			ZVAL_STRING(regexp, "/^[^:\\/?#]++:/");
			RETURN_MM_ON_FAILURE(phalcon_preg_match(matched, regexp, uri, NULL));
			if (zend_is_true(matched)) {
				PHALCON_INIT_NVAR(local);
				ZVAL_FALSE(local);
			}
		}

		if (Z_TYPE_P(local) == IS_NULL || zend_is_true(local)) {
			PHALCON_CONCAT_VV(return_value, base_uri, uri);
		} else {
			ZVAL_ZVAL(return_value, uri, 1, 0);
		}
	} else if (Z_TYPE_P(uri) == IS_ARRAY) {
		if (!phalcon_array_isset_str_fetch(&route_name, uri, SL("for"))) {
			PHALCON_THROW_EXCEPTION_STR(phalcon_mvc_url_exception_ce, "It's necessary to define the route name with the parameter \"for\"");
			return;
		}

		router = phalcon_read_property(getThis(), SL("_router"), PH_NOISY);

		/**
		 * Check if the router has not previously set
		 */
		if (Z_TYPE_P(router) != IS_OBJECT) {
			dependency_injector = phalcon_read_property(getThis(), SL("_dependencyInjector"), PH_NOISY);
			if (!zend_is_true(dependency_injector)) {
				PHALCON_THROW_EXCEPTION_STR(phalcon_mvc_url_exception_ce, "A dependency injector container is required to obtain the \"url\" service");
				return;
			}

			PHALCON_INIT_VAR(service);
			ZVAL_STR(service, IS(router));

			router = NULL;
			PHALCON_CALL_METHOD(&router, dependency_injector, "getshared", service);
			PHALCON_VERIFY_INTERFACE(router, phalcon_mvc_routerinterface_ce);
			phalcon_update_property_this(getThis(), SL("_router"), router);
		}

		/**
		 * Every route is uniquely identified by a name
		 */
		PHALCON_CALL_METHOD(&route, router, "getroutebyname", route_name);
		if (Z_TYPE_P(route) != IS_OBJECT) {
			PHALCON_INIT_VAR(exception_message);
			PHALCON_CONCAT_SVS(exception_message, "Cannot obtain a route using the name \"", route_name, "\"");
			PHALCON_THROW_EXCEPTION_ZVAL(phalcon_mvc_url_exception_ce, exception_message);
			return;
		}

		PHALCON_CALL_METHOD(&pattern, route, "getpattern");

		/**
		 * Return the reversed paths
		 */
		PHALCON_CALL_METHOD(&paths, route, "getreversedpaths");

		/**
		 * Return the Url Generator
		 */
		PHALCON_CALL_METHOD(&generator, route, "geturlgenerator");

		if (phalcon_is_callable(generator) ||
			(Z_TYPE_P(generator) == IS_OBJECT && instanceof_function(Z_OBJCE_P(generator), zend_ce_closure))) {
			PHALCON_INIT_VAR(arguments);
			array_init_size(arguments, 3);
			phalcon_array_append(arguments, base_uri, PH_COPY);
			phalcon_array_append(arguments, paths, PH_COPY);
			phalcon_array_append(arguments, uri, PH_COPY);
			PHALCON_CALL_USER_FUNC_ARRAY(&return_value, generator, arguments);
		} else {
			/**
			 * Replace the patterns by its variables
			 */
			PHALCON_INIT_NVAR(processed_uri);
			phalcon_replace_paths(processed_uri, pattern, paths, uri);

			PHALCON_CONCAT_VV(return_value, base_uri, processed_uri);

			if (phalcon_array_isset_str_fetch(&hostname, uri, SL("hostname"))) {
				if (zend_is_true(hostname)) {
					PHALCON_CALL_METHOD(&hostname, route, "gethostname");

					PHALCON_INIT_NVAR(processed_uri);
					PHALCON_CONCAT_VV(processed_uri, hostname, return_value);

					ZVAL_ZVAL(return_value, processed_uri, 1, 0);
				}
			}
		}
	}

	if (zend_is_true(args)) {
		PHALCON_INIT_VAR(query_string);
		phalcon_http_build_query(query_string, args, "&");
		if (Z_TYPE_P(query_string) == IS_STRING && Z_STRLEN_P(query_string)) {
			if (phalcon_memnstr_str(return_value, "?", 1)) {
				PHALCON_SCONCAT_SV(return_value, "&", query_string);
			}
			else {
				PHALCON_SCONCAT_SV(return_value, "?", query_string);
			}
		}
	}

	RETURN_MM();
}
Exemplo n.º 8
0
/**
 * Decrypts an encrypted text
 *
 *<code>
 *	echo $crypt->decrypt($encrypted, "decrypt password");
 *</code>
 *
 * @param string $text
 * @param string $key
 * @param int $options
 * @return string
 */
PHP_METHOD(Phalcon_Crypt, decrypt){

	zval *source, *key = NULL, *options = NULL, handler = {}, arguments = {}, value = {}, text = {}, encrypt_key = {}, encrypt_options = {};
	zval method = {}, iv_size = {}, iv = {}, text_to_decipher = {};

	phalcon_fetch_params(0, 1, 2, &source, &key, &options);

	if (phalcon_function_exists_ex(SL("openssl_encrypt")) == FAILURE) {
		PHALCON_THROW_EXCEPTION_STRW(phalcon_crypt_exception_ce, "openssl extension is required");
		return;
	}

	phalcon_read_property(&handler, getThis(), SL("_beforeDecrypt"), PH_NOISY);

	if (phalcon_is_callable(&handler)) {
		PHALCON_SEPARATE_PARAM(source);

		array_init_size(&arguments, 1);
		phalcon_array_append(&arguments, source, PH_COPY);

		PHALCON_CALL_USER_FUNC_ARRAYW(&value, &handler, &arguments);

		source = &value;
	}

	/* Do not use make_printable_zval() here: we need the conversion with type juggling */
	if (Z_TYPE_P(source) != IS_STRING) {
		phalcon_cast(&text, source, IS_STRING);
	} else {
		PHALCON_CPY_WRT_CTOR(&text, source);
	}

	if (!key || Z_TYPE_P(key) == IS_NULL) {
		phalcon_return_property(&encrypt_key, getThis(), SL("_key"));
	} else {
		PHALCON_CPY_WRT_CTOR(&encrypt_key, key);
		if (Z_TYPE(encrypt_key) != IS_STRING) {
			convert_to_string(&encrypt_key);
		}
	}

	if (!options || Z_TYPE_P(options) == IS_NULL) {
		phalcon_return_property(&encrypt_options, getThis(), SL("_options"));
	} else {
		PHALCON_CPY_WRT_CTOR(&encrypt_options, options);
	}

	phalcon_read_property(&method, getThis(), SL("_method"), PH_NOISY);
	PHALCON_CALL_FUNCTIONW(&iv_size, "openssl_cipher_iv_length", &method);

	if (Z_LVAL(iv_size) <= 0) {
		ZVAL_NULL(&iv);
		PHALCON_CPY_WRT_CTOR(&text_to_decipher, &text);
	} else {
		phalcon_substr(&iv, &text, 0, Z_LVAL(iv_size));
		phalcon_substr(&text_to_decipher, &text, Z_LVAL(iv_size), 0);
	}

	PHALCON_CALL_FUNCTIONW(return_value, "openssl_decrypt", &text_to_decipher, &method, &encrypt_key, &encrypt_options, &iv);
	if (unlikely(Z_TYPE_P(return_value) != IS_STRING)) {
		convert_to_string(return_value);
	}

	phalcon_read_property(&handler, getThis(), SL("_afterDecrypt"), PH_NOISY);

	if (phalcon_is_callable(&handler)) {
		array_init_size(&arguments, 1);
		phalcon_array_append(&arguments, return_value, PH_COPY);

		PHALCON_CALL_USER_FUNC_ARRAYW(&value, &handler, &arguments);

		RETURN_CTORW(&value);
	}
}