------------------------------------------------------------------------------- $Id$ -----------------------------------------------------------------------------*/ require_once 'YATTA/Proceso.php'; require_once 'YATTA/ProcesoDB.php'; require_once 'YATTA/Servidor.php'; define ('PATH_TACHO', '/var/www/sistemas/yatta/tacho/'); /** * Clase para el manejo centralizado de toda la informacion de YATTA. * * @access public */ class YATTA_Controlador { /** * Obtiene el nombre del servidor al cual asignar un nuevo proceso. * * @param DB $db Conexion a la base de datos. * * @return mixed * @access private */ function _obtenerServidor($db) { $res = $db->query('SELECT s.id, s.escala * s.procesos AS ponderacion FROM yatta.servidores AS s ORDER BY ponderacion ASC, s.escala DESC'); // Si hay error lo devuelve. if (DB::isError($res)) { return $res; } $res = $res->fetchRow(DB_FETCHMODE_ASSOC); return $res['id']; } /** * Agrega un proceso a la base de datos * Recibe un array asociativo con: * Obligatorios * script : Path completo para el require_once. * id_sistema : Identificador del sistema al que pertenece. (Es el id que * asigna SAMURAI) * descripcion: Es lo que permite al usuario identificar al proceso. * owner : Login@Organismo de la persona responsable del proceso. * * Opcionales * destinos : Login@Organismo separado por comas de aquellos usuarios * que deben poder ver los resultados del proceso. * prioridad : Indica la prioridad del proceso. * notificar : Indica si hay que notificar al owner y a los destinos * cuando finalize el proceso. * resultado : En caso que el proceso genere archivos resultado, se debe * indicar aqui el nombre del archivo que deben visualizar * los usuarios. * parametros : Parametros que hay que pasarle al metodo run del script. * * @param DB $db Conexion a la base de datos. * @param mixed $datos Datos necesarios del proceso. * * @return mixed * @access public */ function agregarProceso($db, $datos) { //XXX Dentro de los datos puede estar el tiempo estimado de ejecucion //del proceso. Esta informacion podria ser utilizada en futuras //versiones para asignar servidores. //Si no es un array if (is_object($datos) && is_a ($datos, 'YATTA_ProcesoDB')) { $datos = $datos->obtenerDatos(); } elseif (!is_array($datos)) { return new PEAR_Error ("Error con los datos pasados. El segundo". " parametro debe ser un array asociativo o una instancia". " del objeto YATTA_ProcesoDB."); } $res = $this->_obtenerServidor($db); //Serializo los parametros if (@$datos['parametros']) { $datos['parametros'] = serialize($datos['parametros']); } if (DB::isError($res)) { return $res; } $datos['server'] = $res; $datos['fecha'] = date('Y-m-d'); $res = $db->autoExecute('yatta.procesos', $datos, DB_AUTOQUERY_INSERT); if (DB::isError($res)) { return $res; } $SERVER =& new YATTA_Servidor; return $SERVER->agregarProceso($db, $datos['server']); } /** * Obtiene los procesos de un usuario. * * @param DB $db Conexion a la base de datos. * @param string $owner Usuario duenio de los procesos. * @param int $id Identificador del proceso a buscar * * @return mixed * @access public */ function obtenerProcesosUsuario($db, $owner, $id = null) { $proceso =& new YATTA_ProcesoDB; $proceso->owner = $owner; if (@$id) { $proceso->id = $id; $res = $proceso->buscar($db, MECON_DBO_AND, ' id ASC'); $res = $proceso->cargar($res); return $proceso; } else { return $proceso->buscar($db, MECON_DBO_AND, ' id ASC'); } } /** * Actualiza los datos de un proceso al terminar. * * @param DB $db Conexion a la base de datos. * @param int $id_proceso Identificador del proceso. * @param int $id_server Identificador del Servidor. * @param int $status Identificador del estado de finalizacion. * @param string $nota Nota de error o similar. * @param string $archivo Nombre del archivo temporal que esta en el fs. * @param int $notificar Indica si hay que notificar al owner. * * @return mixed * @access public */ function terminarProceso($db, $id_proceso, $id_server, $status, $nota = null, $archivo = null, $notificar = 0) { //NOTIFICO if (@$notificar) { $this->_emailUsuario ($db, $id_proceso, $status, $nota, $archivo); } //COPIO EL ARCHIVO if (@$archivo) { $arch = basename ($archivo); rename ($archivo, PATH_TACHO.$arch); } //ACTUALIZO LA BASE PROCESOS $sql = 'UPDATE yatta.procesos SET status = '. $db->quoteSmart($status); if (@$nota) { $sql.= ', nota = '. $db->quoteSmart($nota); } if (@$archivo) { $sql.= ', archivo = '. $db->quoteSmart(PATH_TACHO.$arch); } if (@$notificar) { $sql.= ', notificar = '. $db->quoteSmart($notificar); } $sql.= ' WHERE id = '. $db->quoteSmart($id_proceso); $res = $db->query($sql); if (DB::isError($res)) { return $res; } //Actualizo los servidores $SERVER =& new YATTA_Servidor; return $SERVER->quitarProceso($db, $id_server); } /** * Busca un proceso en cola para el servidor * * @param DB $db Conexion a la base de datos. * @param int $id Identificador del servidor. * * @return mixed * @access public */ function obtenerNuevoProceso($db, $id) { $res = $db->query('SELECT p.id AS id, p.script AS script, p.parametros AS parametros FROM yatta.procesos AS p WHERE p.server = '.$id.' AND status = 0 ORDER BY p.prioridad, p.id'); // Si hay error lo devuelve. if (DB::isError($res)) { return $res; } return $res->fetchRow(DB_FETCHMODE_ASSOC); } /** * Busca si un proceso que se esta ejecutando tiene pedido de cancelacion. * * @param DB $db Conexion a la base de datos. * @param int $id Identificador del proceso. * * @return mixed * @access public */ function abortar($db, $id) { $res = $db->query('SELECT count(*) AS cuenta FROM yatta.procesos WHERE id = '.$id.' AND status = 5'); // Si hay error lo devuelve. if (DB::isError($res)) { return $res; } $res = $res->fetchRow(DB_FETCHMODE_ASSOC); return $res['cuenta']; } /** * Envia el email al usuario informandole la finalizacion de uno de sus * procesos. * * @param DB $db Conexion a la base de datos. * @param int $id_proceso Identificador del proceso. * @param int $status Identificador del estado de finalizacion. * @param string $nota Nota de error o similar. * @param string $archivo Nombre del archivo temporal que esta en el fs. * * @return void * @access private */ function _emailUsuario($db, $id_proceso, $status, $nota = null, $archivo = null) { $res = $db->query( "SELECT p.descripcion AS descripcion, p.owner AS owner, ". "p.destinos AS destinos, p.resultado AS resultado, ". "p.estado AS estado, p.nota AS nota ". "FROM yatta.procesos AS p". "WHERE p.id = ". $id_proceso); if (DB::isError($res)) { return $res; } $res = $res->fetchRow(DB_FETCHMODE_ASSOC); //@FIXME El email se lo envio al owner y a los destinos, o al owner solamente? $dest = split (',', @$res['destinos']); $to = $owner.'.gov.ar'; foreach ($dest as $d) { $to = $to . ", $d.gov.ar"; } $headers = "From: Intranet - YATTA \r\n"; $subject = "INTRANET - YATTA - Proceso Finalizado"; $body = "El proceso {$res['descripcion']} ha finalizado "; switch ($status) { case 2: $body .= "con éxito.\n"; break; case 3: $body .= "con errores.\n"; if ($nota) { $body .= "Motivo:\n$nota\n"; } break; case 4: $body .= "porque se abortó su ejecución.\n"; if ($nota) { $body .= "Motivo:\n$nota\n"; } break; } if ($archivo) { $body .= "Usted puede obtener el archivo resultado del proceso\n". "en la seccion Archivos del sistema YATTA.\n". "Recuerde que este archivo puede ser borrado sin previo aviso\n". "por tres motivos:\n". "\t1- El archivo supera la antigüedad máxima establecida.\n". "\t2- Se supero la capacidad máxima de información permitida\n". "\t por usuario.\n". "\t3- Decisión administrativa por mantenimiento de los servidores.\n"; } $body .="\n\n\n". "************************************************************\n". "Este es un mensaje generado automaticamente por MECON_YATTA.\n". "Por favor no responder a esta direccion de e-mail.\n". "************************************************************\n"; mail($to, $subject, $body, $headers); } /** * Verifica si un usuario tiene alguna informacion en la base de yatta para * mostrarle el icono en la lista de sistemas de la intranet. * * @param DB $db Conexion a la base de datos. * @param string $login Usuario que se esta verificando * * @return bool * @access public * @static */ function visible($DB, $login) { $res = $db->query('SELECT count (p.id) AS id FROM yatta.procesos AS p'. ' WHERE (p.owner LIKE \'%'. $login .'%\') OR'. ' (p.destinos LIKE \'%'. $login .'%\')'); if (DB::isError($res)) { return $res; } $res = $res->fetchRow(DB_FETCHMODE_ASSOC); return $res['id']; } /** * Busca los usuarios que tienen al menos una entrada en el mysql como * owners. * * @param DB $db Conexion a la base de datos. * * @return mixed * @access public */ function obtenerListaOwners($db) { return $db->query('SELECT DISTINCT p.owner AS owner FROM yatta.procesos As p'); } /** * Obtiene las cuotas especiales de los usuarios. * * @param DB $db Conexion a la base de datos. * * @return mixed * @access public */ function obtenerListaCuotas($db) { return $db->query('SELECT login, cuota FROM yatta.cuotas'); } } ?>