Skip to content

Commit

Permalink
Merge pull request #59 from racklin/dev/cli
Browse files Browse the repository at this point in the history
Added phalcon support for CLI console tasks.
  • Loading branch information
Phalcon committed Sep 7, 2012
2 parents 28b3bfe + c02b7ca commit 7093b8d
Show file tree
Hide file tree
Showing 10 changed files with 1,944 additions and 1 deletion.
377 changes: 377 additions & 0 deletions dev/cli/console.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,377 @@

/*
+------------------------------------------------------------------------+
| Phalcon Framework |
+------------------------------------------------------------------------+
| Copyright (c) 2011-2012 Phalcon Team (http://www.phalconphp.com) |
+------------------------------------------------------------------------+
| This source file is subject to the New BSD License that is bundled |
| with this package in the file docs/LICENSE.txt. |
| |
| If you did not receive a copy of the license and are unable to |
| obtain it through the world-wide-web, please send an email |
| to [email protected] so we can send you a copy immediately. |
+------------------------------------------------------------------------+
| Authors: Andres Gutierrez <[email protected]> |
| Eduar Carvajal <[email protected]> |
| Rack Lin <[email protected]> |
+------------------------------------------------------------------------+
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_phalcon.h"
#include "phalcon.h"

#include "Zend/zend_operators.h"
#include "Zend/zend_exceptions.h"
#include "Zend/zend_interfaces.h"

#include "kernel/main.h"
#include "kernel/memory.h"

#include "kernel/exception.h"
#include "kernel/fcall.h"
#include "kernel/object.h"
#include "kernel/array.h"
#include "kernel/concat.h"

/**
* Phalcon\CLI\Console
*
*
*/

PHP_METHOD(Phalcon_CLI_Console, __construct){

PHALCON_MM_GROW();

PHALCON_MM_RESTORE();
}

/**
* Sets the DependencyInjector container
*
* @param Phalcon\DI $dependencyInjector
*/
PHP_METHOD(Phalcon_CLI_Console, setDI){

zval *dependency_injector = NULL;
zval *default_router = NULL, *default_dispatcher = NULL;
zval *service = NULL;

PHALCON_MM_GROW();

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &dependency_injector) == FAILURE) {
PHALCON_MM_RESTORE();
RETURN_NULL();
}

if (Z_TYPE_P(dependency_injector) != IS_OBJECT) {
PHALCON_THROW_EXCEPTION_STR(phalcon_cli_console_exception_ce, "Dependency Injector is invalid");
return;
}

PHALCON_INIT_VAR(default_router);
ZVAL_STRING(default_router, "Phalcon\\CLI\\Router", 1);

PHALCON_INIT_VAR(default_dispatcher);
ZVAL_STRING(default_dispatcher, "Phalcon\\CLI\\Dispatcher", 1);

PHALCON_INIT_VAR(service);
ZVAL_STRING(service, "router", 1);
PHALCON_CALL_METHOD_PARAMS_2_NORETURN(dependency_injector, "set", service, default_router, PH_NO_CHECK);

PHALCON_INIT_VAR(service);
ZVAL_STRING(service, "dispatcher", 1);
PHALCON_CALL_METHOD_PARAMS_2_NORETURN(dependency_injector, "set", service, default_dispatcher, PH_NO_CHECK);

phalcon_update_property_zval(this_ptr, SL("_dependencyInjector"), dependency_injector TSRMLS_CC);

PHALCON_MM_RESTORE();
}

/**
* Returns the DependencyInjector container
*
* @return Phalcon\DI
*/
PHP_METHOD(Phalcon_CLI_Console, getDI){

zval *dependency_injector = NULL;

PHALCON_MM_GROW();
PHALCON_INIT_VAR(dependency_injector);
phalcon_read_property(&dependency_injector, this_ptr, SL("_dependencyInjector"), PH_NOISY_CC);

RETURN_CCTOR(dependency_injector);
}

/**
* Sets the events manager
*
* @param Phalcon\Events\Manager $eventsManager
*/
PHP_METHOD(Phalcon_CLI_Console, setEventsManager){

zval *events_manager = NULL;

PHALCON_MM_GROW();

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &events_manager) == FAILURE) {
PHALCON_MM_RESTORE();
RETURN_NULL();
}

phalcon_update_property_zval(this_ptr, SL("_eventsManager"), events_manager TSRMLS_CC);

PHALCON_MM_RESTORE();
}

/**
* Returns the internal event manager
*
* @return Phalcon\Events\Manager
*/
PHP_METHOD(Phalcon_CLI_Console, getEventsManager){

zval *events_manager = NULL;

PHALCON_MM_GROW();
PHALCON_INIT_VAR(events_manager);
phalcon_read_property(&events_manager, this_ptr, SL("_eventsManager"), PH_NOISY_CC);

RETURN_CCTOR(events_manager);
}

/**
* Register an array of modules present in the console
*
*<code>
* $this->registerModules(array(
* 'frontend' => array(
* 'className' => 'Multiple\Frontend\Module',
* 'path' => '../apps/frontend/Module.php'
* ),
* 'backend' => array(
* 'className' => 'Multiple\Backend\Module',
* 'path' => '../apps/backend/Module.php'
* )
* ));
*</code>
*
* @param array $modules
*/
PHP_METHOD(Phalcon_CLI_Console, registerModules){

zval *modules = NULL;

PHALCON_MM_GROW();

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &modules) == FAILURE) {
PHALCON_MM_RESTORE();
RETURN_NULL();
}

if (Z_TYPE_P(modules) != IS_ARRAY) {
PHALCON_THROW_EXCEPTION_STR(phalcon_cli_console_exception_ce, "Modules must be an Array");
return;
}
phalcon_update_property_zval(this_ptr, SL("_modules"), modules TSRMLS_CC);

PHALCON_MM_RESTORE();
}

/**
* Return the modules registered in the console
*
* @return array
*/
PHP_METHOD(Phalcon_CLI_Console, getModules){

zval *modules = NULL;

PHALCON_MM_GROW();
PHALCON_INIT_VAR(modules);
phalcon_read_property(&modules, this_ptr, SL("_modules"), PH_NOISY_CC);

RETURN_CCTOR(modules);
}

/**
* Handle the whole command-line tasks
*
* @return mixed
*/
PHP_METHOD(Phalcon_CLI_Console, handle){

zval *dependency_injector = NULL, *events_manager = NULL;
zval *event_name = NULL, *status = NULL;
zval *arguments = NULL;
zval *module_name = NULL;
zval *task_name = NULL;
zval *action_name = NULL;
zval *params = NULL;
zval *modules = NULL, *module = NULL;
zval *path = NULL, *exception_msg = NULL, *exception = NULL;
zval *class_name = NULL, *module_object = NULL;
zval *task = NULL;
zval *service = NULL, *router = NULL, *dispatcher = NULL;
int eval_int = 0;

PHALCON_MM_GROW();

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &arguments) == FAILURE) {
PHALCON_MM_RESTORE();
RETURN_NULL();
}

if (!arguments) {
PHALCON_ALLOC_ZVAL_MM(arguments);
array_init(arguments);
}

phalcon_update_property_zval(this_ptr, SL("_arguments"), arguments TSRMLS_CC);

PHALCON_INIT_VAR(dependency_injector);
phalcon_read_property(&dependency_injector, this_ptr, SL("_dependencyInjector"), PH_NOISY_CC);
if (Z_TYPE_P(dependency_injector) != IS_OBJECT) {
PHALCON_THROW_EXCEPTION_STR(phalcon_mvc_micro_exception_ce, "A dependency injection container is required to access related dispatching services");
return;
}

PHALCON_INIT_VAR(events_manager);
phalcon_read_property(&events_manager, this_ptr, SL("_eventsManager"), PH_NOISY_CC);

PHALCON_INIT_VAR(service);
ZVAL_STRING(service, "router", 1);

PHALCON_INIT_VAR(router);
PHALCON_CALL_METHOD_PARAMS_1(router, dependency_injector, "getshared", service, PH_NO_CHECK);
PHALCON_CALL_METHOD_PARAMS_1_NORETURN(router, "handle", arguments, PH_NO_CHECK);

PHALCON_INIT_VAR(module_name);
PHALCON_CALL_METHOD(module_name, router, "getmodulename", PH_NO_CHECK);
if (zend_is_true(module_name)) {
if (Z_TYPE_P(events_manager) == IS_OBJECT) {
PHALCON_INIT_VAR(event_name);
ZVAL_STRING(event_name, "console:beforeStartModule", 1);

PHALCON_INIT_VAR(status);
PHALCON_CALL_METHOD_PARAMS_2(status, events_manager, "fire", event_name, this_ptr, PH_NO_CHECK);
if (Z_TYPE_P(status) == IS_BOOL && !Z_BVAL_P(status)) {
PHALCON_MM_RESTORE();
RETURN_FALSE;
}
}
PHALCON_INIT_VAR(modules);
phalcon_read_property(&modules, this_ptr, SL("_modules"), PH_NOISY_CC);
eval_int = phalcon_array_isset(modules, module_name);
if (!eval_int) {
PHALCON_INIT_VAR(exception_msg);
PHALCON_CONCAT_SVS(exception_msg, "Module '", module_name, "' isn't registered in the console container");
PHALCON_THROW_EXCEPTION_STR(phalcon_cli_console_exception_ce, Z_STRVAL_P(exception_msg));
return;
}

PHALCON_INIT_VAR(module);
phalcon_array_fetch(&module, modules, module_name, PH_NOISY_CC);
if (Z_TYPE_P(module) != IS_ARRAY) {
PHALCON_THROW_EXCEPTION_STR(phalcon_cli_console_exception_ce, "Invalid module definition path");
return;
}

eval_int = phalcon_array_isset_string(module, SL("path")+1);
if (eval_int) {
PHALCON_INIT_VAR(path);
phalcon_array_fetch_string(&path, module, SL("path"), PH_NOISY_CC);
if (phalcon_file_exists(path TSRMLS_CC) == SUCCESS) {
if (phalcon_require(path TSRMLS_CC) == FAILURE) {
return;
}
} else {
PHALCON_INIT_VAR(exception_msg);
PHALCON_CONCAT_SVS(exception_msg, "Module definition path '", path, "\" doesn't exists");
PHALCON_THROW_EXCEPTION_STR(phalcon_cli_console_exception_ce, Z_STRVAL_P(exception_msg));
return;
}
}

eval_int = phalcon_array_isset_string(module, SL("className")+1);
if (eval_int) {
PHALCON_INIT_VAR(class_name);
phalcon_array_fetch_string(&class_name, module, SL("className"), PH_NOISY_CC);
} else {
PHALCON_INIT_VAR(class_name);
ZVAL_STRING(class_name, "Module", 1);
}

PHALCON_INIT_VAR(module_object);
PHALCON_CALL_METHOD_PARAMS_1(module_object, dependency_injector, "get", class_name, PH_NO_CHECK);
PHALCON_CALL_METHOD_NORETURN(module_object, "registerautoloaders", PH_NO_CHECK);
PHALCON_CALL_METHOD_PARAMS_1_NORETURN(module_object, "registerservices", dependency_injector, PH_NO_CHECK);
if (Z_TYPE_P(events_manager) == IS_OBJECT) {
phalcon_update_property_zval(this_ptr, SL("_moduleObject"), module_object TSRMLS_CC);

PHALCON_INIT_VAR(event_name);
ZVAL_STRING(event_name, "console:afterStartModule", 1);

PHALCON_INIT_VAR(status);
PHALCON_CALL_METHOD_PARAMS_2(status, events_manager, "fire", event_name, this_ptr, PH_NO_CHECK);
if (Z_TYPE_P(status) == IS_BOOL && !Z_BVAL_P(status)) {
PHALCON_MM_RESTORE();
RETURN_FALSE;
}
}
}

PHALCON_INIT_VAR(task_name);
PHALCON_CALL_METHOD(task_name, router, "gettaskname", PH_NO_CHECK);

PHALCON_INIT_VAR(action_name);
PHALCON_CALL_METHOD(action_name, router, "getactionname", PH_NO_CHECK);

PHALCON_INIT_VAR(params);
PHALCON_CALL_METHOD(params, router, "getparams", PH_NO_CHECK);

PHALCON_INIT_VAR(service);
ZVAL_STRING(service, "dispatcher", 1);

PHALCON_INIT_VAR(dispatcher);
PHALCON_CALL_METHOD_PARAMS_1(dispatcher, dependency_injector, "getshared", service, PH_NO_CHECK);
PHALCON_CALL_METHOD_PARAMS_1_NORETURN(dispatcher, "settaskname", task_name, PH_NO_CHECK);
PHALCON_CALL_METHOD_PARAMS_1_NORETURN(dispatcher, "setactionname", action_name, PH_NO_CHECK);
PHALCON_CALL_METHOD_PARAMS_1_NORETURN(dispatcher, "setparams", params, PH_NO_CHECK);

if (Z_TYPE_P(events_manager) == IS_OBJECT) {
PHALCON_INIT_VAR(event_name);
ZVAL_STRING(event_name, "console:beforeHandleTask", 1);

PHALCON_INIT_VAR(status);
PHALCON_CALL_METHOD_PARAMS_2(status, events_manager, "fire", event_name, this_ptr, PH_NO_CHECK);
if (Z_TYPE_P(status) == IS_BOOL && !Z_BVAL_P(status)) {
PHALCON_MM_RESTORE();
RETURN_FALSE;
}
}

PHALCON_INIT_VAR(task);
PHALCON_CALL_METHOD(task, dispatcher, "dispatch", PH_NO_CHECK);

if (Z_TYPE_P(events_manager) == IS_OBJECT) {
PHALCON_INIT_VAR(event_name);
ZVAL_STRING(event_name, "application:afterHandleTask", 1);

PHALCON_INIT_VAR(status);
PHALCON_CALL_METHOD_PARAMS_2(status, events_manager, "fire", event_name, this_ptr, PH_NO_CHECK);
if (Z_TYPE_P(status) == IS_BOOL && !Z_BVAL_P(status)) {
PHALCON_MM_RESTORE();
RETURN_FALSE;
}
}

PHALCON_MM_RESTORE();
}
Loading

0 comments on commit 7093b8d

Please sign in to comment.