/** * Función para consultar actualizaciones desde el servidor. * Devuelve un arreglo con las actualizaciones. En caso de error se * retorna FALSE. * * @return array|FALSE */ public function find_updates() { // Obtenemos el manejador de paquetes. $pkg_manager = Plugin_Manager::get_instance(); // Generamos el listado de paquetes. $pkg_list = array(); foreach (array_keys($pkg_manager->load()) as $nombre) { // TODO: ver si es lógico omitir los desactivados. // Cargamos el paquete. $pkg_info = $pkg_manager->get($nombre)->info(); $pkg_list[Update_Utils::make_hash($pkg_info->nombre)] = $pkg_info->version; } unset($pkg_manager); // Cargamos la clase de peticiones. $c_o = new Update_Client($this->server, $this->token); // Pedimos la lista de actualizaciones. try { $upd_list = $c_o->check_updates($pkg_list); } catch (Update_Exception_Client_Token $e) { return FALSE; } catch (Update_Exception_Client_Forbiden $e) { return FALSE; } catch (Update_Exception_Client_Missed $e) { return FALSE; } return $upd_list; }
/** * Agregamos un nuevo plugins al sistema. * NO REALIZA LA INSTALACIÓN. Por motivos de recursos hacer ambas cosas * puede provocar que la instalación no termine. * */ public function action_agregar_plugin() { // Cargamos la vista. $vista = View::factory('admin/configuracion/agregar_plugin'); // Valores por defecto. $vista->assign('error_carga', FALSE); if (Request::method() == 'POST') { $error = FALSE; // Verifico el envio correcto de datos. if (isset($_FILES['plugin'])) { // Cargo los datos del archivo. $file = $_FILES['plugin']; // Verifico el estado. if ($file['error'] !== UPLOAD_ERR_OK) { $error = TRUE; switch ($file['error']) { case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: $vista->assign('error_carga', 'El tamaño del archivo es incorrecto.'); break; case UPLOAD_ERR_PARTIAL: $vista->assign('error_carga', 'Los datos enviados están corruptos.'); break; case UPLOAD_ERR_NO_FILE: $vista->assign('error_carga', 'No has seleccionado un archivo.'); break; case UPLOAD_ERR_NO_TMP_DIR: case UPLOAD_ERR_CANT_WRITE: $vista->assign('error_carga', 'Error interno al cargar el archivo. Reintente. Si el error persiste contacte al administrador.'); break; case UPLOAD_ERR_EXTENSION: $vista->assign('error_carga', 'La configuración del servidor no permite archivo con esa extensión.'); break; } } else { // Cargo el mime. $file['type'] = Update_Utils::get_mime($file['tmp_name']); // Verifico esté dentro de los permitidos. if (!in_array(Update_Utils::mime2compresor($file['type']), Update_Compresion::get_list())) { $error = TRUE; $vista->assign('error_carga', 'El tipo de archivo no es soportado. Verifique la configuración del servidor.'); } } } else { $error = TRUE; $vista->assign('error_carga', 'No has seleccionado un archivo.'); } // Verifico el contenido de los datos. if (!$error) { // Armo directorio temporal para la descargar. $tmp_dir = TMP_PATH . uniqid('pkg_') . DS; mkdir($tmp_dir, 0777, TRUE); // Realizo la descompresión. $compresor = Update_Compresion::get_instance(Update_Utils::mime2compresor($file['type'])); $compresor->set_temp_path($tmp_dir); if (!$compresor->decompress($file['tmp_name'])) { // Limpio salidas. Update_Utils::unlink($file['tmp_name']); Update_Utils::unlink($tmp_dir); // Informo del error. $error = TRUE; $vista->assign('error_carga', 'No se pudo descomprimir el archivo. Compruebe que sea correcto.'); } else { // Obtenemos la información del paquete. if (!file_exists($tmp_dir . 'info.json')) { // Limpio salidas. Update_Utils::unlink($file['tmp_name']); Update_Utils::unlink($tmp_dir); // Informo del error. $error = TRUE; $vista->assign('error_carga', 'El paquete no es un plugins válido.'); } else { // Obtengo la información. $data = json_decode(file_get_contents($tmp_dir . 'info.json')); // Obtenemos el nombre del paquete. $pkg_name = $data->nombre; // Verifico no exista. if (Plugin_Manager::get_instance()->get(Plugin_Manager::make_name($pkg_name)) !== NULL) { // Limpio salidas. Update_Utils::unlink($file['tmp_name']); Update_Utils::unlink($tmp_dir); //TODO: Efectuar actualizacion. // Informo del error. $error = TRUE; $vista->assign('error_carga', 'El plugin no puede ser importado porque ya existe.'); } else { // Cargamos el archivo para personalizar la actualización. if (file_exists($tmp_dir . '/install.php')) { @(include $tmp_dir . '/install.php'); if (class_exists('Install')) { // Cargamos el instalador. $install = new Install($tmp_dir, $update); } } // Ejecutamos pre_instalacion. if (isset($install)) { // Verificamos soporte. if (method_exists($install, 'before')) { $install->before(); } } // Movemos los archivos. Update_Utils::copyr($tmp_dir . DS . 'files' . DS, Plugin_Manager::nombre_as_path($pkg_name)); // Ejecutamos post_instalacion. if (isset($install)) { // Verificamos soporte. if (method_exists($install, 'after')) { $install->after(); } } // Actualizo la cache. Plugin_Manager::get_instance()->regenerar_lista(); // Limpiamos archivos de la instalación y salimos. Update_Utils::unlink($tmp_dir); Update_Utils::unlink($file['tmp_name']); // Informo resultado. $_SESSION['flash_success'] = 'El plugin se importó correctamente.'; // Redireccionamos. Request::redirect('/admin/configuracion/plugins'); } } } } } // Seteamos el menu. $this->template->assign('master_bar', parent::base_menu('admin')); // Cargamos plantilla administracion. $admin_template = View::factory('admin/template'); $admin_template->assign('contenido', $vista->parse()); unset($portada); $admin_template->assign('top_bar', Controller_Admin_Home::submenu('configuracion_plugins')); // Asignamos la vista a la plantilla base. $this->template->assign('contenido', $admin_template->parse()); }
/** * Función encargada de enrutar una petición a controlador indicado. * @param string $url URL de la petición. * @param bool $throw Si en caso de error debe generar una excepción o mostrar un error. * @author Ignacio Daniel Rostagno <*****@*****.**> */ private static function route($url, $throw = FALSE) { // Obtenemos los segmentos de la URL $segmentos = explode('/', $url); // Verificamos si es un plugin. if (count($segmentos) >= 2) { if (strtolower($segmentos[0]) === 'plugin') { // Formateo el plugins. $p_name = strtolower($segmentos[1]); // Validamos que tenga el formato requerido. if (preg_match('/^[a-z0-9]+$/D', $p_name) < 1) { if (!$throw) { Error::show_error('Petición inválida', 404); } else { throw new Exception('Petición inválida', 404); } return FALSE; } // Verifico su existencia y que este activo. $p_obj = Plugin_Manager::get_instance()->get($p_name); if ($p_obj === NULL || !$p_obj->estado()) { if (!$throw) { Error::show_error('Plugin inexistente', 404); } else { throw new Exception('Plugin inexistente', 404); } return FALSE; } $p_dir = Plugin_Manager::nombre_as_path($p_name); if (file_exists($p_dir) && is_dir($p_dir)) { // Cargamos el plugin. // Obtenemos el controlador $controller = empty($segmentos[2]) ? 'home' : strtolower($segmentos[2]); // Validamos que tenga el formato requerido. if (preg_match('/^[a-z0-9_]+$/D', $controller) < 1) { if (!$throw) { Error::show_error('Petición inválida', 404); } else { throw new Exception('Petición inválida', 404); } return FALSE; } // Obtenemos la acción. $accion = empty($segmentos[3]) ? 'index' : strtolower($segmentos[3]); // Validamos que tenga el formato requerido. if (preg_match('/^[a-z0-9_]+$/D', $accion) < 1) { if (!$throw) { Error::show_error('Petición inválida', 404); } else { throw new Exception('Petición inválida', 404); } return FALSE; } // Obtenemos los argumentos. if (is_array($segmentos) && count($segmentos) > 4) { $args = array_slice($segmentos, 4); } else { $args = array(); } // Normalizamos el nombre del controlador para usar en las clases. $controller_name = 'Plugin_' . ucfirst($p_name) . '_Controller_' . ucfirst($controller); //Instanciamos el controllador if (!class_exists($controller_name)) { if (!$throw) { Error::show_error("No existe el controlador: '{$controller_name}'", 404); } else { throw new Exception("No existe el controlador: '{$controller_name}'", 404); } } else { // Verificamos exista método. $r_c = new ReflectionClass($controller_name); if (!$r_c->hasMethod('action_' . $accion)) { if (!$throw) { Error::show_error("No existe la acción '{$accion}' para el controlador '{$controller_name}'", 404); } else { throw new Exception("No existe la acción '{$accion}' para el controlador '{$controller_name}'", 404); } } else { $cont = new $controller_name(); } } // Obtenemos la cantidad de parámetros necesaria. $r_m = new ReflectionMethod($cont, 'action_' . $accion); $p_n = $r_m->getNumberOfRequiredParameters(); // Expandemos el arreglo de parámetros con NULL si es necesario. while (count($args) < $p_n) { $args[] = NULL; } Request::add_stack(NULL, $controller, $accion, $args, $p_name); // No hubo problemas, llamamos. $rst = call_user_func_array(array($cont, 'action_' . $accion), $args); Request::pop_stack(); return $rst; } else { // Plugin Inválido. if (!$throw) { Error::show_error("El plugin '{$p_name}' no existe", 404); } else { throw new Exception("El plugin '{$p_name}' no existe", 404); } return FALSE; } } } // Verificamos subdirectorio. if (!empty($segmentos[0])) { // Directorio $directorio = strtolower($segmentos[0]); // Obtenemos el controlador $controller = empty($segmentos[1]) ? 'home' : strtolower($segmentos[1]); // Obtenemos la acción. $accion = empty($segmentos[2]) ? 'index' : strtolower($segmentos[2]); if (preg_match('/^[a-z0-9_]+$/D', $controller) && preg_match('/^[a-z0-9_]+$/D', $accion)) { // Obtenemos los argumentos. if (is_array($segmentos) && count($segmentos) > 3) { $args = array_slice($segmentos, 3); } else { $args = array(); } // Normalizamos el nombre del controlador para usar en las clases. $controller_name = 'Controller_' . ucfirst($directorio) . '_' . ucfirst($controller); //Instanciamos el controllador if (class_exists($controller_name)) { // Verificamos exista método. $r_c = new ReflectionClass($controller_name); if ($r_c->hasMethod('action_' . $accion)) { $cont = new $controller_name(); // Obtenemos la cantidad de parámetros necesaria. $r_m = new ReflectionMethod($cont, 'action_' . $accion); $p_n = $r_m->getNumberOfRequiredParameters(); // Expandemos el arreglo de parámetros con NULL si es necesario. while (count($args) < $p_n) { $args[] = NULL; } Request::add_stack(NULL, $controller, $accion, $args, NULL); // No hubo problemas, llamamos. $rst = call_user_func_array(array($cont, 'action_' . $accion), $args); Request::pop_stack(); return $rst; } } } } // Obtenemos el controlador $controller = empty($segmentos[0]) ? 'home' : strtolower($segmentos[0]); if (preg_match('/^[a-z0-9_]+$/D', $controller) < 1) { if (!$throw) { Error::show_error('Petición inválida', 404); } else { throw new Exception('Petición inválida', 404); } return FALSE; } // Obtenemos la acción. $accion = empty($segmentos[1]) ? 'index' : strtolower($segmentos[1]); if (preg_match('/^[a-z0-9_]+$/D', $accion) < 1) { if (!$throw) { Error::show_error('Petición inválida', 404); } else { throw new Exception('Petición inválida', 404); } return FALSE; } // Obtenemos los argumentos. if (is_array($segmentos) && count($segmentos) > 2) { $args = array_slice($segmentos, 2); } else { $args = array(); } // Normalizamos el nombre del controlador para usar en las clases. $controller_name = 'Controller_' . ucfirst($controller); //Instanciamos el controllador if (!class_exists($controller_name)) { if (!$throw) { Error::show_error("No existe el controlador: '{$controller_name}'", 404); } else { throw new Exception("No existe el controlador: '{$controller_name}'", 404); } } else { // Verificamos exista método. $r_c = new ReflectionClass($controller_name); if (!$r_c->hasMethod('action_' . $accion)) { if (!$throw) { Error::show_error("No existe la acción '{$accion}' para el controlador '{$controller_name}'", 404); } else { throw new Exception("No existe la acción '{$accion}' para el controlador '{$controller_name}'", 404); } } else { $cont = new $controller_name(); } } // Obtenemos la cantidad de parámetros necesaria. $r_m = new ReflectionMethod($cont, 'action_' . $accion); $p_n = $r_m->getNumberOfRequiredParameters(); // Expandemos el arreglo de parámetros con NULL si es necesario. while (count($args) < $p_n) { $args[] = NULL; } Request::add_stack(NULL, $controller, $accion, $args, NULL); // No hubo problemas, llamamos. $rst = call_user_func_array(array($cont, 'action_' . $accion), $args); Request::pop_stack(); return $rst; }
/** * Prueba descarga de un plugin. */ public function action_install() { Dispatcher::call(''); // Prueba del uso de memoria. // Nombre del plugin. $p_nombre = "Test Plugin"; // Borramos el plugin. // if (file_exists(Plugin_Manager::nombre_as_path($p_nombre))) // { // Update_Utils::unlink(Plugin_Manager::nombre_as_path($p_nombre)); // } // Objeto manejador de plugins. $pkg_manager = Plugin_Manager::get_instance(); // Verificamos su existencia $o_plugin = $pkg_manager->get(Plugin_Manager::make_name($p_nombre)); if ($o_plugin === NULL) { // Realizamos la instalación. // Cargamos el actualizador. $o_updater = new Update_Updater(); // Descargamos el paquete e instalamos el paquete. Se usa 1 para mostrar actualizaciones. if ($o_updater->install_package(Update_Utils::make_hash($p_nombre), 1)) { // Actualizamos la cache. $pkg_manager->regenerar_lista(); // Cargamos el paquete. $o_plugin = new Plugin_Plugin($p_nombre); // Realizamos la actualizacion. $o_plugin->install(); // Activamos el paquete. $pkg_manager->set_state(Plugin_Manager::make_name($p_nombre), TRUE, TRUE); echo "Instalación existosa"; } else { echo "Problema al realizar la instalación"; } } else { // Buscamos actualizaciones. $upd_id = $o_plugin->check_updates(); if ($upd_id === FALSE) { echo "No hay actualizaciones"; } else { // Instalamos la actualizacion. // Desactivo el plugin. if ($o_plugin->info()->estado) { $o_plugin->remove(); } // Directorio del plugin. $orig_path = Plugin_Manager::nombre_as_path($p_nombre); $tmp_path = rtrim($orig_path, '/') . '.bkp'; // Realizamos una copia. Update_Utils::copyr($orig_path, $tmp_path); // Borramos el original. Update_Utils::unlink($orig_path); // Cargamos el actualizador. $o_updater = new Update_Updater(); // Descargamos el paquete e instalamos el paquete. if (!$o_updater->install_package(Update_Utils::make_hash($p_nombre), $upd_id)) { // Recuperamos el original. Update_Utils::copyr($tmp_path, $orig_path); echo "No se pudo actualizar a la versión {$upd_id}."; } else { echo "Actualización a la versión {$upd_id} exitosa."; } // Realizamos la instalación. $o_plugin->install(); // Borramos la copia. Update_Utils::unlink($tmp_path); } } if (!Request::is_cli()) { echo "<br />"; } }
/** * Extensión de los archivos a incluir. */ define('FILE_EXT', 'php'); /** * Directorio de plugins. */ define('PLUGINS_PATH', 'plugin'); /** * Directorio de la cache. */ define('CACHE_PATH', APP_BASE . DS . 'cache'); // Cargador de CLI. require_once SHELL_PATH . DS . 'classes' . DS . 'loader.php'; spl_autoload_register('Shell_Loader::load'); // Cargamos la libreria de carga de clases del nucleo. require_once APP_BASE . DS . 'function.php'; // Iniciamos el proceso de carga automatica de librerias. spl_autoload_register('loader_load'); // Comprobamos que exista la configuración de la base de datos. if (!file_exists(CONFIG_PATH . DS . 'database.php')) { //TODO: lo mandamos al instalador. die("Falta configurar la base de datos"); } // Comprobamos que existe la lista de plugins. if (!file_exists(APP_BASE . DS . PLUGINS_PATH . DS . 'plugin.php')) { // Generamos la lista de plugins. Plugin_Manager::get_instance()->regenerar_lista(); } // Cargamos el despachador y damos el control al controlador correspondiente. Shell_Dispatcher::dispatch();
/** * Función para desinstalar un plugin. * @return bool Si fue correcta o no la desistalación. */ public function remove() { // Comprobamos el estado. if ($this->data === NULL || $this->data->estado === FALSE) { return FALSE; } // Quitamos las sobreescrituras. $this->revert_core(); // Nombre de la clase del plugin. $pc = 'Plugin_' . ucfirst($this->nombre) . '_Index'; // Llamamos al instalador. $p = new $pc(); $p->remove(); // Guardamos el estado en el sistema. Plugin_Manager::get_instance()->set_state($this->nombre, FALSE); return TRUE; }