Php - Bibliotools Ofrece un conjunto de clases preparadas para controlar, ejecutar y mostrar el avance de procesos por lotes, que podrían tomar tiempos muy largos de proceso, de modo que que puedan ser invocados desde páginas en las que se mostrarán mensajes de estado y avance de aquellos, sincronizados con su marcha. Así mismo, permite integrar, familias de mensajes, con información asociada con la naturaleza u objetivos de dichos procedimientos, mostrar reportes de resultados y finalmente redirigir a lugares adecuados para continuar el trabajo sin incurrir en repeticiones.
La biblioteca esta integrada por dos componentes gráficos que son ofrecidos por TwBs2ls y cuatro clases controladoras que se ocupan de simplificar el manejo de las definiciones, registro y control de operación de los procesos. Son las siguientes:
La biblioteca ha sido inspirada por el utilitario "batch" del API de Drupal 6x y puede se configura de manera muy similar. Pero, a diferencia de Drupal, incluye asistentes para facilitar la escritura del código necesario. Abajo se documenta e ilustra su manejo.
Asistente para definición, registro y acceso a procesos por lotes. Tiene como propósito asegurar que la sintaxis y el registro de los mismos en la base de datos sean correctos, y es empleada por BatchProccessor para controlar la ejecución de los mismos.
Instanciación:
// directa, su constructor no requiere de parámetros especiales, pero se puede usar el id del batch // si se desea recargar una definición almacenada en DB durante la sesión en curso. $batchdef = new \Biblio2ls\Library\Batch\DefineBatch($batchId);
Uso:
Se presume que los conjuntos de funciones a ejecutar han sido bien definidos y las funciones han sido probadas.
// se cuenta con al menos un array de definición de conjuntos de funciones $batchsets = [$batchset01, ..., $batchset_N]; // se asigna nombre al batch (para manejar referencias internas y registrarlo) $batchId = 'ejemploDeBatch01'; // se crea una instancia del asistente de definición $batchdef = new \Biblio2ls\Library\Batch\DefineBatch(); // se emplean los métodos del asistente para configurar y guardar la definición $batchdef->setBatchId($batchId) ->setReportRedirect($urlderedireccion) // path relativo a home del sitio ->setOperationSets($batchsets) ->save(); // los demás métodos ofrecidos por el asistente son opcionales. // No se requieren para contar con un batch bien definido.
Esta ofrece una interfaz gráfica integrada para lanzar y hacer seguimiento de la ejecución de "procesos por lotes". Esta sincronizada con las utilidades dispuestas para definirlos, registrarlos y controlarlos. Así mismo, permite integrar, familias de mensajes, con información asociada con la naturaleza u objetivos de dichos procedimientos. Por ejemplo: tips o información utilitaria vinculada con el proceso de instalación y configuración de un módulo de extensión.
$Batch = new \TwBs2l\Component\BindedBatchComponent($batchid, $maxsteps, $pagesets, $hasreport, $rotatorsettings); donde:
$Batch->toString(); Inserta el controlador (oculto) dentro de la página a mostrar. Una vez sea activado mostrará una barra de progreso. $Batch->getEstatusFlags($head, $operationsets); Devuelve una lista de tareas con marcas de verificación ocultas para motrar indicadores de paso por las mismas una vez hayan sido completadas. $head es un título opcional que debe se formateado antes de pasarlo al llamado. $Batch->getEnlace('0', 'texto del enlace'); Entrega un enlace listo para agregar a la página en cualquier parte. $Batch->ScriptLlamador($itemid, $conprefijo) Devuelve un script que puede ser pasado como atributo action o target a buttons o forms para poder activarlo desde el formulario. $Batch->getButton($itemid, $TextoAMostrar, $context) Devuelve un botón de comando con id y atributos configurados adecuadamente para invocar el batch, de modo que quede oculto definitivamente en caso de que el batch deba presentar reportes.
En muchos casos resulta conveniente utilizar batchs para procesamiento de
solicitudes preparadas mediante formularios que recogen información del
usuario por pasos y responden activando procesos que pueden ser muy grandes
(p.ej Activar/desactivar módulos de extensión ó importar bases de datos con
formato csv, etc.).
En tales circunstancias se debe tener presente que la acción de salida
del reporte del batch (lanzada desde su botón aceptar) disparará los eventos
registrados mediante los atributos #validate y #submit del formulario; pero
con cambios significativos en la claves 'post' y 'values' de $form_state
que se pueden emplear para identificar el cambio de estatus así:
$form_state['post'] contiene el item 'ID_DEL_BATCH-report-ok' => 'ok'
y la clave $form_state['values'] posiblemente exista pero conteniendo un
array vacío. de modo que en el método registrado bajo $form['#validate']
en este caso será metodo_preparador_de_form_validate($form, &$form_state)
(ver más abajo) se puede emplear la instrucción:
if(isset($form_state['post']['ID_DEL_BATCH-report-ok'])){ // pasa la validación y sigue hacia submit // poner flags o marcas p.ej $form_state['onsubmit'] = 'success'; // que van a ser empleadas en el siguiente paso para evitar recarga del batch // o errores de validación que no se produjeron }else{ // procesamiento de validación normal }
De modo que el mecanismo de definición del formulario refleje las condiciones siguiendo caminos alternativos así:
<?php // En el metodo de preparación del form, invocado por hybridzd_get_form() que es // el generador universal de formularios empleado por el sistema ver Foliate/FormAPI; // se inicia con un juego alternativo: function metodo_preparador_de_form(&$form_state){ $formdef = [ '#title' => 'Título a mostrar en el formulario', ]; if(isset($form_state['submitted']) && (is_array($form_state['submitted']))){ $formdef['body'] = metodo_preparador_del_batch($form_state['submitted']); // es necesario incluir el archivo "batchscommon.inc" que ofrece el contenedor de reportes de batchs module_load_include('inc', 'Biblio2ls', 'includes/batchs2l/batchscommon'); // y agregar el contenedor como sufijo para asegurar que el form que lo contiene // no se anide en el form principal. Además, al crear el body (ver abajo metodo_preparador_del_batch) // se hace una anotación complementaria pasando un parámetro opcional como FALSE explícitamente. $formdef['#suffix'] = batchs2l_report_container('ID_DEL_BATCH'); }else{ $formdef['body'] = bloques_normales_para_recoger_data($form_state); } return $formdef; } // Las operaciones validate y submit se procesan con sendos métodos asociados a form function metodo_preparador_de_form_submit($form, &$form_state){ // sólo se ejecuta si la validación no devolvio error. // si no viene flag de terminación desde _validate y $form_state['values'] // contiene los valores esperados se crean los sets de operaciones necesarias if(!isset($form_state['onsubmit'])){ // se crean los arrays de definición de operaciones // de acuerdo con las necesidades. $oopsets = metodo_definidor_de_operaciones($form_state['values']); // si hay sets de operaciones a ejecutar se pasan if(count($oopsets) > 0){ $form_state['submitted'] = $oopsets; } } } function metodo_preparador_de_form_validate($form, &$form_state){ // sólo debe devolver un array que contenga la clave 'error' en caso de error // si la validación pasa puede devolver null. // Y, en caso de proceso terminado puede inyectar un flag en &$form_state // que fue pasado por referencia, para que sea usado en _form_submit() y en _form() } // Se escribe un método para preparación normal del cuerpo del formulario de entrada function bloques_normales_para_recoger_data($form_state){ // instrucciones creando el array de definiciones de elementos html } // Se escribe un método para instanciar el componente y mostrar su interfaz de usuario // dentro de un elemento markup que será pasado como body function metodo_preparador_del_batch($oopsets){ // los parametros fueron recogidos en el metodo submit, que los ha debido emplear // para definir los sets de operaciones y luego pasarlos como array a $form_state['submitted'] $componente = new \TwBs2l\Component\BindedBatchComponent('ID_DEL_BATCH', 100, 1, 1, [], FALSE); // notese que se pasó rotatorsettings = [] y usaform = FALSE éste último es muy importante para // evitar que se aniden forms y se generen choques de trenes al validar los requests ajax $head = 'Carretazo a mostrar como encabezado del batch' // Se crea la GUI de control del batch $block = $componente->getEstatusFlags($head , $oopsets, TRUE). $componente->toString(); // Prepara un botón llamador $button = '<p class="centrado">'.$componente->getButton(0, 'Configurar', 'primary').'</p>'; $body = [ '#type' = 'markup', '#requiere_dialogo_modal' = 1, // fuerza la carga de dialogo modal sin que se solape '#value' = $block . $button, ]; return $body; // NÓTESE QUE NO SE PASA URL DE REDIRECCIÓN PORQUE TODO SE TRATA EN LOS CONTROLADORES DEL FORM }
Bajo esta línea se mostrará una barra de progreso para hacer una simulación de avance en la ejecución de un proceso por lotes (haga click en el enlace o en el botón situados abajo para lanzarlo)
Este componente utilitario fue creado para lanzar batchs de "sólo una vez" que deben ser ejecutados para completar tareas complejas previas a la carga de un formulario. Es definido como un "elemento" extensor de Foliate/FormAPI cuyos atributos simplifican el mecanismo de declaración y registro del batch asociado.
<?php $form['autoajuste_menus'] = autoajuste_progresivo_content_type(); ... function autoajuste_progresivo_content_type(){ module_load_include('inc', 'Biblio2ls', 'includes/setup/setupbatch'); $mnurgtit = 'Ajuste de definiciones de Menús'; $mnurgmsg = 'Ajustando menú del módulo @step de @total: @name...'; $mnrgbch = setupbatch_operationsSet_RegisterMenu($mnurgtit, $mnurgmsg); $mnubtch = setupbatch_operationsSet_Configure_menu_tree(); $oppsets = [ $mnrgbch->toArray(), $mnubtch->toArray() ]; $bloque = [ '#title' => '', '#value' => '', '#name' => 'content_autoajuste', '#type' => 'progressive_loader', '#animated' => 1, '#hasreport' => 0, '#reportembeded' => 0, '#oppsets' => $oppsets, '#weight' => -1000, ]; return $bloque; }
<?php function setupbatch_operationsSet_RegisterMenu($titulo = '', $msgpad = ''){ // al asignar los parámetros opcionales se establecen tanto el título como // el mensaje de progreso para el batch. $tit = ($titulo) ? $titulo : 'Registro de definiciones de Menús'; $msg = ($msgpad) ? $msgpad : 'Registrando menú del módulo @step de @total: @name...'; // Las operaciones se establecen como un array de arrays en las que cada subarray // tiene dos elementos: el nombre de un ejecutable y un array de parámetros. $operaciones = [ ['setupbatch_registrar_menu_del_modulo', []], ]; // Para registrar y controlar los sets de operaciones se crea una instancia del // asistemte para manejo de los mismos BatchOppsSet $batchset = new \Biblio2ls\Library\Batch\BatchOppsSet(); // Y se asignan sus atributos: $batchset->setTitle($tit) ->setInitMessage('Leyendo definiciones ...') ->setProgressMessage($msgpad) ->setErrorMessage('Hubo errores de acceso a la base de datos. No fue posible registrar correctamente los módulos.') ->setCallstype('extend') ->setModule('Biblio2ls') // Importante (módulo que contiene el código a ejecutar) ->setFile('includes/setup/setupbatch') // archivo con el código a ejecutar ->setFileExt('inc') /* declaración del método configurador del proceso */ ->setInitialMethod('setupbatch_identificar_modulos_implementadores_de_hook_menu') /* declaración del método preparador del reporte de salida */ ->setFinishedMethod('setupbatch_register_modules_menus_report') /* paso del set de operaciones a registrar */ ->setOperations($operaciones); return $batchset; }
<?php // En el ejemplo arriba la operación apunta a: function setupbatch_registrar_menu_del_modulo(&$context){ // ... } // de modo que en general debe definirse para cada operación registrada: function operacion_x_del_set_y(&$context){ // y para recuperar los argumentos diferentes de $context que es requerido y pasado por referencia // en caso de haberlos definido, usar: $args = array_slice(func_get_args(), 1, func_num_args()); } // El método iniciador se establece así: // en el ejemplo: function setupbatch_identificar_modulos_implementadores_de_hook_menu(&$context){ // ... } // En general function metodo_iniciador_del_set_y_del_batch(&$context){ // Nótese la presencia de $context siendo pasado por referencia } // El método reportadodor se establece así: // en el ejemplo: function metodo_reportador($success, $results, $operations){ // dónde $success es un booleano indicando si el proceso fue satisfactorio // $results es un array de resultados recogidos en $context // y $operations es un array que recoge errores reportados por las operaciones // ... return $html; bloque html a mostrar como salida }
Como se indicó arriba, en el ejemplo de carga progresiva, el alma del control de batchs se encuentra en el parámetro $context que es común a los métodos declarados para realizar las acciones y sirve como vehículo de paso de valores entre ellos. Dicho parámetro es un array cuyas claves son literales (algunas reservadas para uso interno) y otras dispuestas para paso de información entre operaciones (de modo que se asegure su persistencia) entre llamados sucesivos al servidor
<?php $context = [ 'sandbox' => [], // array persistente para paso de valores entre métodos 'results' => [], // array para almacenar resultados por set de operaciones 'finished' => 0, // real entre 0 y 1, indica el porcentaje de avance del set de operaciones actual 'message' => '', // mensaje de salida del juego de iteraciones en curso 'progress' => 0, // medida de avance (entera, iteración en curso) 'max' => 0, // entero (default 100) cantidad de iteraciones del set de operaciones en curso // Claves reservadas. Se enumeran destacando que no deben ser modificadas por las operaciones // pueden ser consultadas en caso de necesidad (para depuración) 'callinfo' => [] // parametrización de acceso para invocar la operación en curso 'operaciones' => [] // Set de operaciones actual 'operacionencurso' => 0,...,n // identificador de la operación invocada 'error' => [], // array de operaciones que reportan errores 'error_message' => Mensaje (por defecto) a mostrar en caso de error en el grupo actual de operaciones ];
Php - BiblioTools [Documentación]