* @copyright 2008-2008 Emilio Rafael Silveira Tovar * @copyright 2007-2009 Deivinson Jose Tejeda Brito * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt GNU/GPL * @version SVN:$id * @see Object */ //require CORE_PATH.'library/kumbia/object.php'; /** * Esta es la clase principal del framework, contiene metodos importantes * para cargar los controladores y ejecutar las acciones en estos ademas * de otras funciones importantes * * @category Kumbia * @package Kumbia * @author Andres Felipe Gutierrez * @copyright 2005-2007 Andres Felipe Gutierrez (andresfelipe at vagoogle.net) * @copyright 2007-2009 Deivinson Jose Tejeda Brito(deivinsontejeda at gmail.com) * @copyright 2008-2008 Emilio Rafael Silveira Tovar (emilio.rst at gmail.com) * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt GNU/GPL */ abstract class Kumbia { /** * Almacena la version actual del Framework * */ const KUMBIA_VERSION = '0.5.1'; /** * Almacena datos compartidos en la aplicacion * * @var array */ static public $data = array(); /** * Almacena los modelos que son persistentes * * @var array */ static private $_persistence = array(); /** * Cachea la salida al navegador * * @var string */ static public $content = ''; /** * Almacena el objeto Smarty * * @var string */ private static $_smarty_object = ''; /** * Configuracion del Config.ini * * @var Object */ //public static $config = null; /** * Lista de todos los modelos disponibles en la aplicacion * Es creado por el _init_models * @var array */ static public $models = array(); /** * Nombre del controlador actual * * @var string */ static public $controller; /** * Nombre de la aplicacion activa * * @var string */ static public $active_app; /** * Directorio de controladores activo * * @var string */ public static $active_controllers_dir; /** * Directorio de modelos activo * * @var string */ public static $active_models_dir; /** * Directorio de vistas activo * * @var string */ public static $active_views_dir; /** * Directorio de helpers activo * * @var string */ public static $active_helpers_dir; /** * Enlace a la base de datos actual * * @var DbBase */ static public $db; static public function init_application() { /** * Inicializar el ExceptionHandler */ set_exception_handler(array('Kumbia', 'manage_exceptions')); /** * Crear el KUMBIA_PATH */ $path = dirname($_SERVER['PHP_SELF']); if ($path == '/') { define('KUMBIA_PATH', '/'); } else { $path = substr($path, 0, -6); define('KUMBIA_PATH', $path); } /** * Aplicacion Activa */ self::$active_app = $active_app = Router::get_application(); /** * @see Controller */ require CORE_PATH.'library/kumbia/controller/application/application.php'; /** * @see ApplicationController */ include_once CORE_PATH."apps/$active_app/application.php"; /** * La variable kumbia en el apartado modules en config/boot.ini * tiene valores estilo logger... esto hace que Kumbia cargue * automaticamente en el directorio library/kumbia/logger/logger.php. * * Esta variable tambien puede ser utilizada para cargar modulos de * usuario y clases personalizadas, en la variable extensions. * */ $kumbia_boot = Config::read('boot.ini'); if($kumbia_boot){ if($kumbia_boot->modules->extensions){ $kumbia_boot->modules->extensions = str_replace(' ', '', $kumbia_boot->modules->extensions); $extensions = explode(',', $kumbia_boot->modules->extensions); foreach ($extensions as $extension){ require_once CORE_PATH .'library/'. $extension .'/'.$extension.'.php'; } unset($extensions); } if($kumbia_boot->modules->kumbia){ $kumbia_boot->modules->kumbia = str_replace(' ', '', $kumbia_boot->modules->kumbia); $extensions = explode(',', $kumbia_boot->modules->kumbia); foreach ($extensions as $extension){ require_once CORE_PATH .'library/kumbia/'. $extension .'/'.$extension.'.php'; } unset($extensions); } } /** * Establecer el timezone para las fechas y horas */ $config = Config::read('config.ini'); if (isset($config->$active_app->timezone)) { date_default_timezone_set($config->$active_app->timezone); } else { date_default_timezone_set('America/New_York'); } /** * Establecer el charset de la app en la constante APP_CHARSET */ define('APP_CHARSET', strtoupper($config->$active_app->charset)); } /** * Función Principal donde se ejecutan los controladores * * @params string $url url * @return boolean */ static function main($url) { /** * El Router analiza la url **/ Router::rewrite($url); /** * Define el path para la cache **/ define('CACHE_PATH', CORE_PATH.'cache/'.Router::get_application().'/'); if(!is_dir(CACHE_PATH)) mkdir(CACHE_PATH); /** * Carga la libreria para cache * * @see Cache **/ require_once CORE_PATH.'library/kumbia/cache/cache.php'; /** * Rutas Base */ $config = Config::read('config.ini'); //Aplicacion Activa $active_app = Router::get_application(); /** * Asigna localizacion **/ if(isset($config->$active_app->locale)) setlocale(LC_ALL, $config->$active_app->locale); /** * Desactiva la cache **/ if(!$config->$active_app->production) Cache::active(false); /** * Verifico si esta cacheado un template para la url indicada * **/ if($cached_template = Cache::get($url, 'kumbia.templates')) { echo $cached_template; exit(0); } //Directorio de controladores Activo $controllers_dir = self::$active_controllers_dir = CORE_PATH."apps/$active_app/controllers"; //Directorio de modelos activo $models_dir = self::$active_models_dir = CORE_PATH."apps/$active_app/models"; //Directorio de Vistas Activo $views_dir = self::$active_views_dir = CORE_PATH."apps/$active_app/views"; //Directorio de Helpers Activo $helpers_dir = self::$active_helpers_dir = CORE_PATH."apps/$active_app/helpers"; /** * Kumbia reinicia las variables de aplicacin cuando cambiamos * entre una aplicacin y otra. Init Application define KUMBIA_PATH */ self::init_application(); /** * Incluyendo las librerias del Framework */ self::_load_library_kumbia(); /** * Carga los helpers de usuario del modulo principal * */ use_helper('main'); try { /** * Iniciar el buffer de salida */ ob_start(); /** * Carga los modelos del directorio models y las clases necesarias */ if(!isset($config->$active_app->databases) || $config->$active_app->databases){ /** * @see Db */ require CORE_PATH.'library/kumbia/db/db.php'; /** * @see ActiveRecordBase */ require CORE_PATH.'library/kumbia/db/active_record_base/active_record_base.php'; /** * El driver de Kumbia es cargado segun lo que diga en config.ini */ if (!DbLoader::load_driver()) { return false; } /** * Inicializa los Modelos. model_base es el modelo base */ include_once CORE_PATH."apps/$active_app/model_base.php"; if($config->$active_app->models_autoload) self::_init_models($models_dir); } /** * Ciclo del enrutador */ $controller = Dispatcher::execute(); while (router::get_routed()) { Router::set_routed(false); $controller = Dispatcher::execute(); } $view = self::_get_view($views_dir, $controller, $url); ob_end_clean(); echo $view; } catch(DispatcherException $e) { //if (!isset($config->$active_app->interactive) || !$config->$active_app->interactive) { //ob_end_clean(); //ob_start(); //header('HTTP/1.1 404 Not Found'); //render_view('not_found'); //} else { $e->show_message(); //} Kumbia::$content = ob_get_contents(); ob_end_clean(); xhtml_template('white'); } catch(KumbiaException $e) { $controller = Dispatcher::get_controller(); if ($_SESSION['session_data']) { $_SESSION['session_data'] = serialize($_SESSION['session_data']); } /** * Si no es una Accion AJAX incluye index.phtml y muestra * el contenido de las excepciones dentro de este. */ if (!$controller) { $controller = new ApplicationController(); } if (!$controller->response){ if (!isset($config->$active_app->interactive) || !$config->$active_app->interactive) { ob_end_clean(); Kumbia::$content = ''; ob_start(); $e->set_trace = false; $e->show_message(); Kumbia::$content = ob_get_contents(); ob_end_clean(); xhtml_template('white'); return; } $e->show_message(); Kumbia::$content = ob_get_contents(); ob_end_clean(); echo Kumbia::$content; } else { ob_end_clean(); $e->show_message(); } return; } } /** * Inicializa los modelos en el directorio models * * @param string $models_dir */ private static function _init_models($models_dir) { $models_dir = realpath($models_dir); /** *Path de los modelos incluidos */ if ($models = Cache::get('models', 'kumbia')) { $models = unserialize($models); foreach($models as $model) { list($object_model, $m) = $model; require_once $m; self::$models[$object_model] = new $object_model(); } } else { $models = array(); foreach(new DirectoryIterator($models_dir) as $model) { if($model->isDot() || $model->isDir()) continue; require_once $model->getPathname(); $object_model = str_replace('.php', '', $model->getFilename()); $object_model = camelize($object_model); $models[] = array($object_model,$model->getPathname()); if (!class_exists($object_model)) { throw new KumbiaException("No se encontró la Clase \"$object_model\"", "Es necesario definir una clase en el modelo '$model' llamado '$object_model' para que esto funcione correctamente."); } else { self::$models[$object_model] = new $object_model(); if (!is_subclass_of(self::$models[$object_model], 'ActiveRecord')) { throw new KumbiaException("Error inicializando modelo \"$object_model\"", "El modelo '$model' debe ser una clase o sub-clase de ActiveRecord"); } if (!self::$models[$object_model]->get_source()) { self::$models[$object_model]->set_source($model); } } } $config = Config::read('config.ini'); $lifetime = isset($config->{self::$active_app}->metadata_lifetime) ? $config->{self::$active_app}->metadata_lifetime : null; Cache::save(serialize($models), $lifetime, 'models', 'kumbia'); } } /** * Esta función realiza la integración con Smarty, creando los * directorios necesarios para que un controlador pueda * utlizar templates Smarty * * @param $controllerObj */ private static function _kumbia_smarty($controller_object) { $controller_name = $controller_object->controller_name; if ($controller_object->module_name) { $controller_name = "{$controller_object->module_name}/$controller_name"; } if (!Kumbia::$_smarty_object) { foreach($controller_object as $property => $value) { if (@get_class($value) == 'Smarty') { Kumbia::$smarty_object = $value; } } } if (!Kumbia::$_smarty_object) { Kumbia::$_smarty_object = new Smarty(); } if (!file_exists("cache/$controller_name")) { mkpath("cache/$controller_name/compile"); mkpath("cache/$controller_name/cache"); mkpath("cache/$controller_name/config"); } Kumbia::$_smarty_object->template_dir = "views/$controller_name/"; Kumbia::$_smarty_object->compile_dir = "cache/$controller_name/compile"; Kumbia::$_smarty_object->cache_dir = "cache/$controller_name/cache"; Kumbia::$_smarty_object->config_dir = "cache/$controller_name/config"; } /** * Verifica si $model es un modelo del Proyecto * * @param string $model * @return boolean */ public static function is_model($model) { if (!$model) { return false; } return isset (self::$models[camelize($model)]); } /** * Carga Librerias JavaScript Importantes en el Framework * */ public static function javascript_base() { $application = Router::get_active_app(); $controller_name = Router::get_controller(); $action_name = Router::get_action(); $module = Router::get_module(); $id = Router::get_id(); echo "\r\n"; echo "\r\n"; echo "\r\n"; echo "\r\n"; echo "\r\n"; echo "\r\n"; echo "\r\n"; echo "\r\n"; echo "\r\n"; /** * Cargo constantes para el objeto javascript * */ echo "\r\n"; } /** * Imprime los CSS cargados mediante stylesheet_link_tag * */ public static function stylesheet_link_tags() { $imports = self::$data['KUMBIA_CSS_IMPORTS']; if ($imports && is_array($imports)) { foreach ($imports as $css) { echo $css; } } else { echo $imports; } } /** * Realiza un escaneo recursivo en un directorio * * @param string $package_dir * @param array $files * @return array */ private static function _scandir_recursive($package_dir, $files = array()) { foreach(scandir($package_dir) as $file) { if ($file != '.' && $file != '..') { if (is_dir($package_dir . '/' . $file)) { $files = self::_scandir_recursive($package_dir . '/' . $file, $files); } else { if (ereg("(.)+\.php$", $file)) { $files[] = $package_dir . '/' . $file; } } } } return $files; } /** * Importa un paquete recursivamente * * @param string $package */ public static function import($package) { $package_array = explode('.', $package); $package_dir = ''; $class = ''; if ($package_array[count($package_array) - 1] == '*') { unset($package_array[count($package_array) - 1]); $package_dir = join('.', $package_array); $class = '*'; } else { $package_dir = $package; } if ($class == '*') { $package_dir = strtr($package_dir, '.', '/'); if (!file_exists($package_dir)) { throw new kumbiaException("No existe el directorio '$package_dir'\n"); } $files = self::scandir_recursive($package_dir); foreach($files as $file) { include_once $file; } } else { $package_dir = strtr($package_dir, '.', '/'); if (file_exists($package_dir . '.php')) { $package_dir = escapeshellcmd($package_dir); include_once $package_dir . '.php'; } else { throw new kumbiaException("No existe el directorio '$package_dir'\n"); } } } /** * Permite lanzar excepciones de PHP o externas a Kumbia como propias * * @param Exception $exception */ public static function manage_exceptions($exception) { throw new KumbiaException($exception->getMessage(), $exception->getCode()); } /** * Permite obtener el mode de la aplicacion activa * @return string * */ //public static function get_active_app_mode() { // $core = Config::read('config.ini'); // return $core->{self::$active_app}->mode; //} /** * Permite obtener el tipo de codificacion de caracteres de la aplicacion activa * @return string * */ //public static function get_active_app_charset() { // return APP_CHARSET; //} /** * Obtiene la informacion del config.ini * * @return Object */ //public static function get_config(){ // return self::$_config; //} /** * Metodo para incluir las librerias de Framework * */ private static function _load_library_kumbia(){ /** * @see Dispatcher */ require CORE_PATH.'library/kumbia/dispatcher/dispatcher.php'; /** * @see Session */ require CORE_PATH.'library/kumbia/session/session.php'; /** * @see Flash */ require CORE_PATH.'library/kumbia/messages/flash.php'; /** * @see Helpers */ require CORE_PATH.'library/kumbia/helpers/helpers.php'; } /** * Renderiza una Vista (Templates, Layouts, Views) * * @param string $view_dir * @param string $view * @param string $file */ public static function render($view_dir='', $view='templates', $file='index.phtml') { $view_file = "$view_dir/$view/$file"; if(include $view_file){ Kumbia::$content = ob_get_contents(); } else{ throw new KumbiaException("La vista '$view_file' en '$view_dir' no existe o no se puede cargar"); } } /** * Obtiene la vista * * @param string $views_dir directorio de vistas * @param object $controller controlador * @param string $url url * @return string **/ protected static function _get_view($views_dir, $controller, $url) { /** * Mapea los atributos del controller en el scope * **/ extract(get_object_vars($controller), EXTR_OVERWRITE); /** * Intenta cargar la vista desde la cache **/ self::$content = $cache['type']=='view' ? Cache::get($url, 'kumbia.views') : ''; if(!self::$content) { /** * Carga el el contenido del buffer de salida * **/ self::$content = ob_get_contents(); ob_clean(); if ($module_name){ $controller_views_dir = "$views_dir/$module_name/$controller_name"; } else { $controller_views_dir = "$views_dir/$controller_name"; } /** * Renderizar vista * **/ if($controller->view) { if(defined('USE_SMARTY')) { if (!self::$_smarty_object) { self::_kumbia_smarty($controller); } foreach ($controller as $_key=>$_value){ self::$_smarty_object->assign($_key, $_value); } self::$_smarty_object->display("$controller->view.tpl"); self::$content = ob_get_contents(); ob_clean(); } else{ ob_start(); include "$controller_views_dir/$view.phtml"; self::$content = ob_get_clean(); } } if($cache['type'] == 'view') { Cache::save(self::$content, $cache['time'], $url, 'kumbia.views'); } } /** * Verifica si se debe renderizar solo la vista * **/ if($controller->response == 'view' || $controller->response == 'xml') { return self::$content; } /** * Renderizar template * **/ if($controller->template) { $template = "$views_dir/templates/$controller->template.phtml"; } else { $template = "$views_dir/templates/$controller_name.phtml"; } if(file_exists($template)) { ob_start(); include $template; self::$content = ob_get_clean(); if($cache['type'] == 'template') { Cache::save(self::$content, $cache['time'], $url, 'kumbia.templates'); } } return self::$content; } /** * Obtiene un modelo * * @param string $model * @return ActiveRecord **/ public static function model($model) { if(isset(self::$models[$model])) { return self::$models[$model]; } if(!class_exists($model)) { $model_file = self::$active_models_dir.'/'.uncamelize(lcfirst($model)).'.php'; include $model_file; } self::$models[$model] = new $model(); return self::$models[$model]; } }