Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Manual para Desarrolladores-Elastix PDF
Manual para Desarrolladores-Elastix PDF
VERSIONAMIENTO
Introducción
Imagen 1.- Identificación del addon “Developer”.
§ Luego de esto se inicia el proceso de instalación del addon, por lo que se debe
esperar unos minutos hasta que finalice la instalación.
Imagen 2.- Finalización de la instalación del addon “Developer”.
El addon para desarrolladores tiene tres submenús pero el que nos interesa se llama
“Constructor de Módulos” o “Build Module” y es el primer submenú.
Imagen 3.-
El constructor de módulos incluido en el addon Developer
§ Información General.
§ Localización.
§ Descripción del módulo.
Información General
Esta sección nos permite definir el nombre e identificador único del módulo, así
como también los datos de la persona que crea el modulo para comentarlas en las
cabeceras de cada archivo de programación en PHP. También nos permite
Localización
En esta sección se configura el lugar, dentro del menú general, donde vamos a
ubicar el nuevo módulo. Por omisión esta sección luce como la siguiente figura.
Imagen 5.- Sección donde se configura la ubicación del módulo
Imagen 6.- Aparecen nuevos campos si se dice que el módulo será de nivel 3
A continuación se explica qué significan los tres tipos de módulos que se pueden
crear.
Con los botones ">>", "<<" podemos añadir o quitar los campos a insertar en nuestro
formulario.
Al guardar los datos establecidos para el nuevo módulo se creará el siguiente árbol
de directorios (exceptuando para los módulos tipo enmarcado, en cuyo caso el
módulo será simplemente un link al URL proporcionado) en la ruta
documentRoot/modules donde documentRoot es /var/www/html para Elastix.
Esto nos permite de forma inmediata hacer una similitud entre las
carpetas que tienen las siguientes relaciones:
• themes es la capa vista.
• index.php es la capa control.
• libs es la capa modelo.
1.3 Breve descripción de cada carpeta que se crea dentro del módulo
configs
Por default esta carpeta se crea con un archivo denominado “default.conf.php”, este
archivo debe contener las configuraciones básicas del módulo.
Almacena dentro de este archivo variables de configuración que serán muy usadas
a lo largo del módulo, por ejemplo DSN
§ Sqlite3: “sqlite3:///$arrConf[elastix_dbdir]/base.db”
§ Mysql: se puede usar la función “generarDSNSistema” la cual ya nos devuelve
el string de conexión. A continuación se detallará un poco esta función que la
podemos encontrar en /var/www/html/libs/misc.lib.php
/**
* Función para construir un DSN para conectarse a varias bases de datos
* frecuentemente utilizadas en Elastix. Para cada base de datos reconocida, se
* busca la clave en /etc/elastix.conf o en /etc/amportal.conf según corresponda.
*
* @param string $sNombreUsuario Nombre de usuario para interrogar
* @param string $sNombreDB Nombre de base de datos para DSN
* @param string $ruta_base Ruta base para inclusión de librerías
*
* @return mixed NULL si no se reconoce usuario, o el DSN con clave resuelta
*/
function generarDSNSistema($sNombreUsuario, $sNombreDB, $ruta_base='')
help
Es recomendable que una vez que hayas terminado tu módulo por completo,
elabores la ayuda embebida que no es otra cosa que una especie de manual
de usuario, indicando las diferentes opciones que ofrece este módulo. Es
recomendable que sea escrita en inglés.
<html>
<header>
<link rel="stylesheet" href="/themes/{$THEMENAME}/styles.css">
<link rel="stylesheet" href="/themes/{$THEMENAME}/help.css">
</header>
<body>
<h1>{$node_name}</h1>
</body>
</html>
images
Dentro de esta carpeta se guardarán todas las imágenes propias del módulo, por
ejemplo ícono, imágenes usadas para la ayuda embebida, etc.
lang
Archivo Idioma
bg.lang Búlgaro
br.lang Portugués
ca.lang Catalán
cn.lang Chino Simplificado
da.lang Danés
de.lang Alemán
en.lang Inglés
el.lang Griego
es.lang Español
fa.lang Persa
fr.lang Francés
it.lang Italiano
hu.lang Húngaro
hr.lang Croata
pl.lang Polaco
ro.lang Rumano
ru.lang Ruso
sl.lang Esloveno
sv.lang Sueco
ko.lang Coreano
ja.lang Japonés
sr.lang Serbio
<?php
global $arrLangModule;
$arrLangModule=array(
"Module" => "Módulo",
"This is a test module" => "Este es un módulo prueba”,
);
?>
libs
Todos los querys que se realicen deben de ser parametrizados, esto evitará la
inyección de código SQL arbitrario a nuestra base. Más adelante se explicará
con mayor detalle como hacerlo.
Recuerda que nuestro servicio de apache corre usando el usuario “asterisk”, por
ende sólo tendremos acceso a archivos y carpetas a los cuales “asterisk” tenga
acceso. No podrás leer o escribir sobre un archivo o carpeta por ejemplo que tenga
solo permisos para “root”.
Pero y que pasa si nuestro script o librería necesita obligadamente usar comandos
que requieren privilegios de “root”? Es ahí donde entra en acción nuestro script
elastix-helper.
Es aquí donde ubicaremos al script que realizará tareas que necesiten privilegios de
“root”, este script debe ser propietario “root” y pertenecer al grupo “root” además
tener permisos 755. Para poder usarlo debemos ejecutar el siguiente código en la
función que deseemos de nuestra librería.
themes
Por ejemplo, un módulo puede contener como vista principal una grilla, por lo que se
necesitará una vista (un archivo tpl) que contendrá los filtros para la grilla (en caso
de haberlos, caso contrario no se necesitaría un archivo tpl), y también podría ser
que al presionar un botón se muestre un formulario, por lo que necesitaríamos otro
archivo tpl que contendrá los campos del formulario.
A continuación mostraremos una plantilla típica de una vista para tpl y otra para un
formulario.
name="new" value="{$New}"></td>
<td width="10%" align="left"> </td>
<td width="10%" align="right">
{$filter_type.LABEL}: {$filter_type.INPUT}
{$filter_txt.INPUT}
<input class="button" type="submit" name="show" value="{$SHOW}" />
</td>
</tr>
</table>
Como se puede observar en este módulo de grilla se consta con un botón “New” y
con un filtrado.
Para este formulario se consta con un botón “Save” y con un campo al cual se le
denominó “manufacturer”.
Estas son plantillas básicas, en realidad uno lo puede hacer tan complejo como uno
quiera.
archivos automáticamente.
index.php
Si hemos usado el developer para la creación del módulo, podremos observar que
este archivo ya viene escrito con una plantilla por default, y sobre esta plantilla
podemos hacer las modificaciones que queramos de acuerdo a la necesidad de
nuestro módulo.
Bien, hasta ahora ya tenemos creado nuestro módulo con una configuración básica
pero todavía no tenemos un claro conocimiento de las diferentes facilidades y
librerías que nos ofrece el framework Elastix.
§ function _tr($s)
Esta es la función que utilizamos para realizar la traducción de algún texto. Recibe
como parámetro un string que es el texto a traducir.
Busca el string pasado como parámetro en las claves del arreglo de lenguajes del
framework y del módulo (archivo .lang dentro de la carpeta lang del módulo,
escogerá el archivo correspondiente al lenguaje que este configurado en el servidor
Elastix), en caso de encontrarla la función devuelve el valor del arreglo para esa
clave, caso contrario devuelve el mismo string pasado como parámetro.
Ejemplo:
§ function getParameter($parameter)
Ejemplo:
Supongamos que tenemos un módulo con un botón que dice guardar y el nombre
del botón es “save” y queremos saber si ese botón fue presionado,
if(getParameter(“save”))
§ function obtenerClaveCyrusAdmin($ruta_base='')
§ function obtenerClaveAMIAdmin($ruta_base='')
Esta función retorna la clave para AMI (Asterisk Manager Interface) del usuario
admin. El parámetro $ruta_base debe ser pasado como “/var/www/html/” si
llamamos a esta función fuera de esa ruta.
Ya nos habíamos topado antes en este manual con esta función. Pero afianzaremos
más lo que se dijo acerca de esta útil función. Como ya lo habíamos mencionado
antes esta función retorna el DSN (Data Source Name) para una conexión con el
motor de bases de datos mysql.
Una vez más es importante recordar que el servicio httpd que usa Elastix tiene como
usuario a “asterisk” por lo tanto sólo podrá escribir sobre archivos a los cuales
“asterisk” tenga permiso. En el caso de que $logFILE no exista, no hay problema ya
que “asterisk” es propietario de la carpeta /var/log/elastix por lo que podrá
Ejemplo:
Esta clase se encarga de crear un objeto con la conexión a una base de datos. El
objetivo de esta clase es encapsular o abstraerse del proceso de conexión a la base
de datos, de tal forma que el desarrollador simplemente tenga que instanciar esta
clase y pueda realizar las consultas (queries) que desee. Esta clase tampoco es
necesario incluirla en nuestro módulo, ya que el framework Elastix se encarga de
ello.
Ejemplo:
Supongamos que queremos instanciar una clase de paloDB en nuestro módulo para
crear una conexión a la base de datos mysql llamada “miBase” a la cual sólo tiene
acceso el usuario “root”. Tendríamos que hacer lo siguiente:
$dsn = generarDSNSistema(“root”,”miBase”);
$pDB = new paloDB($dsn);
Una vez instanciada esta clase recuerda pasarla por referencia a las funciones
requeridas, esto será muy importante sobre todo cuando trabajemos con
transacciones.
Ejemplo:
Supongamos que queremos insertar en la tabla “miTabla” un nuevo registro con los
campos “campo1” y “campo2”, con los valores $value1 y $value2 respectivamente y
que llegan al servidor mediante el cliente. Tendríamos que realizar lo siguiente
(supongamos que ya tenemos instanciada la clase con el DSN a la base
correspondiente en la variable $pDB).
Es el procedimiento que recupera todas las filas resultado de una petición SQL que
devuelve una o más filas.
Los parámetros $query y $param tienen los mismos propósitos que los descritos en
la función anterior.
El parámetro $arr_colnames será FALSE si deseamos que cada tupla tenga como
índice un número incremental, si es TRUE cada tupla tendrá como índice el nombre
de la columna.
Ejemplo:
Procedimiento para recuperar una sola fila del query que devuelve una o más filas.
Devuelve una fila con campos si el query devuelve al menos una fila, caso contrario
devuelve un arreglo vacío o FALSE en caso de error.
Los parámetros $query, $arr_colnames y $param tienen los mismos propósitos que
Ejemplo:
§ function beginTransaction()
§ function rollBack()
§ function commit()
Ejemplo:
Supongamos que queremos crear una función que inserte los valores $value1 y
$value2 en los campos “campo1” y “campo2” respectivamente*, en la tabla
“miTabla1” (la cual tiene como id el campo “id” que es autoincremental). Luego de
esto deseamos insertar en la tabla “miTabla2” el id del registro recién ingresado en
“miTabla1” en el campo “id_miTabla1” y en el campo “fecha” la fecha actual.
*Nota: no puede haber otro registro que tenga exactamente los mismos valores tanto en
“campo1” como en “campo2
}
else{
$pDB->commit();
return TRUE;
}
}
}
Observemos que el objeto $pDB fue pasado por referencia a la función, lo cual es
necesario para que la transacción tenga el comportamiento deseado.
NOTA: Ten en cuenta que existen motores de bases de datos que no soportan
transacciones como es el caso del motor MyISAM de mysql, en estos casos se debe
asegurar que la tabla que queremos que funcione con transacciones tenga un motor
compatible con transacciones como InnoDB o BDB.
Esta clase se encarga de administrar los controles de acceso para los diferentes
tipos de usuarios. El framework Elastix la incluye automáticamente.
Para instanciar la clase se debe pasar el string DSN para la conexión a la base de
datos “acl.db” o también se le puede pasar un objeto que sea una instancia de la
clase paloDB que se le haya pasado el DSN para “acl.db”.
global $arrConf;
$pACL = new paloACL($arrConf['elastix_dsn']['acl']);
§ function getUserExtension($username)
Ejemplo:
§ function isUserAdministratorGroup($username)
Ejemplo:
Si deseamos que nuestro módulo haga ciertas tareas si el usuario logoneado es del
grupo “administrador” y otras si no, podríamos hacer lo siguiente:
$username = $_SESSION[“elastix_user”];
if($pACL->isUserAdministratorGroup($username)){
//Do some task for administrators
}
else{
//Do some task for non administrators
}
Esta clase es muy útil sobre todo para parsear archivos de configuración,
permitiéndonos leer o escribir sobre los mismos.
include_once “libs/paloSantoConfig.class.php”;
user = usuario
password = 12345
email = usuario@dominio.com
privileges = all
§ function leer_configuracion($bComentarios=true)
§ function escribir_configuracion($arr_reemplazos,
$overwrite=FALSE)
Procedimiento que devuelve el valor de una palabra clave del archivo. El parámetro
$lista es el arreglo que contiene el archivo de configuración. El parámetro $clave es
la palabra clave a buscar en el archivo.
Ejemplo:
include_once “libs/paloSantoConfig.class.php”;
$pConfig = new paloConfig(“/etc”,”miModulo.conf”,” = ”,”\s*=\s*”);
$content = $pConfig->leer_configuracion(FALSE);
$password = $pConfig->privado_get_valor($content,”password”);
if($password == “12345”){
$arrReplaces = array(“password” => “new12345”);
$pConfig->escribir_configuracion($arrReplaces);
}
Esta clase nos sirve para manejar de una manera sencilla los módulos tipo
formulario. Es necesaria incluirla en nuestro módulo en caso de desear usarla.
TEXTAREA
Ejemplo:
Se desea un textarea cuyo label sea “descripción” y que tenga 6 columnas y 4 filas.
$arrFormElements = array(
"description" => array( "LABEL" => _tr("Description"),
"REQUIRED" => "yes",
"INPUT_TYPE" => "TEXTAREA",
"INPUT_EXTRA_PARAM" => array("style" => ”width:400px"),
"VALIDATION_TYPE" => "text",
TEXT
Ejemplo:
$arrFormElements = array(
"name" => array( "LABEL" => _tr("Name"),
"REQUIRED" => "yes",
"INPUT_TYPE" => "TEXT",
"INPUT_EXTRA_PARAM" => array("style" => ”width:200px"),
"VALIDATION_TYPE" => "text",
"VALIDATION_EXTRA_PARAM" => ""
),
);
CHECKBOX
Ejemplo:
$arrFormElements = array(
"enable" => array( "LABEL" => _tr("Enable"),
"REQUIRED" => "yes",
"INPUT_TYPE" => "CHECKBOX",
"INPUT_EXTRA_PARAM" => " ",
"VALIDATION_TYPE" => "text",
"VALIDATION_EXTRA_PARAM" => ""
),
);
$enable = getParameter(“enable”);
if($enable == “on”){
//Do something
}
else{
//Do something
}
PASSWORD
Ejemplo:
$arrFormElements = array(
"password" => array( "LABEL" => _tr("Password"),
"REQUIRED" => "yes",
"INPUT_TYPE" => "PASSWORD",
"INPUT_EXTRA_PARAM" =>array("style" => ”width:200px"),
"VALIDATION_TYPE" => "text",
"VALIDATION_EXTRA_PARAM" => ""
),
);
HIDDEN
Ejemplo:
$arrFormElements = array(
"id" => array( "LABEL" => " ",
"REQUIRED" => "yes",
"INPUT_TYPE" => "HIDDEN",
"INPUT_EXTRA_PARAM" => " ",
"VALIDATION_TYPE" => "text",
"VALIDATION_EXTRA_PARAM" => ""
),
);
FILE
Ejemplo:
$arrFormElements = array(
"file" => array( "LABEL" => _tr("File"),
"REQUIRED" => "yes",
"INPUT_TYPE" => "FILE",
"INPUT_EXTRA_PARAM" => " ",
"VALIDATION_TYPE" => "filename",
"VALIDATION_EXTRA_PARAM" => ""
),
);
RADIO
Ejemplo:
SELECT
Ejemplo:
Se desea un combo para seleccionar el método de pago que va a realizar un cliente,
siendo las opciones “efectivo”, “tarjeta de crédito”, “cheque”, “transferencia bancaria”.
DATE
Ejemplo:
Se desea un campo para ingresar la fecha en la cual se realizó un pago.
$arrFormElements = array(
"paymentDate" => array( "LABEL" => _tr("Payment Date"),
"REQUIRED" => "yes",
"INPUT_TYPE" => "DATE",
"INPUT_EXTRA_PARAM" => "",
"VALIDATION_TYPE" => "ereg",
"VALIDATION_EXTRA_PARAM" => "^[[:digit:]]{1,2}[[:space:]]+[[:alnum:]]
{3}[[:space:]]+[[:digit:]]{4}$"
),
);
El formato por default de la fecha es el día en dos dígitos, luego espacio seguido del
mes en formato de tres letras, luego espacio y el año en cuatro dígitos. Si se desea
cambiar este formato simplemente habría que colocar en “INPUT_EXTRA_PARAM”
el nuevo formato, y si deseamos también poder ingresar la hora colocamos “TIME”
=> true.
Como se pudo observar en los ejemplos anteriores existen índices que coincidían en
todos y otros que simplemente eran propios del tipo de elemento, como por ejemplo
el índice “COLS” en el “TEXTAREA”. Ahora explicaremos sobre los índices comunes
u obligatorios.
Esta función genera una cadena que contiene un formulario HTML. Para hacer esto,
toma una plantilla de formulario (que es la pasada en el parámetro $templateName)
e inserta en ella los elementos de formulario. El parámetro $title es el título que
tendrá el formulario y el parámetro $arrPreFilledValues es un arreglo que contiene
valores por defecto para el formulario, donde el índice es el id del elemento y el valor
es el (valga la redundancia) valor que tendría ese campo por defecto.
§ function validateForm($arrCollectedVars)
Esta función devuelve TRUE en caso de que los datos ingresados en el formulario
fueron correctos, caso contrario FALSE. El parámetro $arrCollectedVars contiene
los valores ingresados en el formulario.
Ejemplo:
Supongamos que deseamos un módulo tipo formulario, el cual tenga los campos:
“Nombre” que es una caja de texto, “Apellido” que es una caja de texto, “Género”
que es un radio button que puede ser masculino o femenino, “Email” que es una caja
de texto y “Estado Civil” que puede ser Soltero, Viudo, Casado, Divorciado o Unión
Libre. Todos estos campos son requeridos. También hay un botón “Save” que al
presionar se validan los datos ingresados, en caso de haber un error se mantiene
persistencia en los datos y se indica el error, caso contrario se muestra un mensaje
indicando los datos ingresados.
File themes/default/form.tpl
</table>
<table class="tabForm" style="font-size: 16px;" width="100%" >
<tr class="letra12">
<td align="left" width="130px"><b>{$name.LABEL}: <span
class="required">*</span></b></td>
<td align="left">{$name.INPUT}</td>
</tr>
<tr class="letra12">
<td align="left"><b>{$last_name.LABEL}: <span
class="required">*</span></b></td>
<td align="left">{$last_name.INPUT}</td>
</tr>
<tr class="letra12">
<td align="left"><b>{$gender.LABEL}: <span
class="required">*</span></b></td>
<td align="left">{$gender.INPUT}</td>
</tr>
<tr class="letra12">
File index.php
<?php
include_once "libs/paloSantoForm.class.php";
//global variables
global $arrConf;
global $arrConfModule;
global $arrLang;
global $arrLangModule;
$arrConf = array_merge($arrConf,$arrConfModule);
$arrLang = array_merge($arrLang,$arrLangModule);
$local_templates_dir="$base_dir/modules/$module_name/".$templates_dir.'/'.
$arrConf['theme'];
//conexion resource
//$pDB = new paloDB($arrConf['dsn_conn_database']);
$pDB = ""; //In this case we do not use a database
//actions
$action = getAction();
$content = "";
switch($action){
case "save":
$content = saveTestModule($smarty, $module_name,
$local_templates_dir);
break;
default: // view_form
$content = viewFormTestModule($smarty, $module_name,
$local_templates_dir);
break;
}
return $content;
}
$smarty->assign("SAVE", _tr("Save"));
$smarty->assign("REQUIRED_FIELD", _tr("Required field"));
$smarty->assign("icon", "images/list.png");
$htmlForm = $oForm->fetchForm("$local_templates_dir/form.tpl",_tr("Test
Module"), $_DATA);
$content = "<form method='POST' style='margin-bottom:0;'
action='?menu=$module_name'>".$htmlForm."</form>";
return $content;
}
else{
$smarty->assign("mb_title", _tr("Message"));
$message = _tr("The following data was entered").":<br />";
$message .= "<b>"._tr("Name").":</b>
".htmlentities($name)."<br /><b>"._tr("Last Name").":</b>
".htmlentities($last_name)."<br /><b>"._tr("Gender").":</b>
".htmlentities($gender)."<br /><b>"._tr("Email").":</b>
".htmlentities($email)."<br /><b>"._tr("Marital Status").":</b>
".htmlentities($marital_status);
$smarty->assign("mb_message",$message);
}
}
return viewFormTestModule($smarty, $module_name, $local_templates_dir);
}
function createFieldForm()
{
$gender = array("male" => _tr("Male"), "female" => _tr("Female"));
$marital_status = array("single" => _tr("Single"), "widowed" =>
_tr("Widowed"), "married" => _tr("Married"), "divorced" => _tr("Divorced"),
"cohabiting" => _tr("Cohabiting"));
$arrFields = array(
"name" => array("LABEL" => _tr("Name"),
"REQUIRED" => "yes",
"INPUT_TYPE" => "TEXT",
"INPUT_EXTRA_PARAM" => "",
"VALIDATION_TYPE" => "text",
"VALIDATION_EXTRA_PARAM" => ""
),
"last_name" => array("LABEL" => _tr("Last Name"),
"REQUIRED" => "yes",
"INPUT_TYPE" => "TEXT",
"INPUT_EXTRA_PARAM" => "",
"VALIDATION_TYPE" => "text",
"VALIDATION_EXTRA_PARAM" => ""
),
"gender" => array("LABEL" => _tr("Gender"),
"REQUIRED" => "yes",
"INPUT_TYPE" => "RADIO",
"INPUT_EXTRA_PARAM" => $gender,
"VALIDATION_TYPE" => "text",
"VALIDATION_EXTRA_PARAM" => ""
),
"email" => array("LABEL" => _tr("Email"),
"REQUIRED" => "yes",
"INPUT_TYPE" => "TEXT",
"INPUT_EXTRA_PARAM" => "",
function getAction()
{
if(getParameter("save"))
return "save";
else
return "report";
}
?>
Imagen 8.- Vista del módulo tipo formulario según el código descrito anteriormente
Esta clase nos sirve para manejar de una manera sencilla los módulos tipo grilla. Es
necesaria incluirla en nuestro módulo en caso de desear usarla.
§ function paloSantoGrid($smarty)
Esta función permite agregar un elemento a la grilla tipo link. El parámetro $href es
hacia dónde apunta el link, el parámetro $alt es el label que se mostrará para el
elemento, el parámetro $icon es la ruta a una imagen que será el ícono
representativo del elemento y el parámetro $onclick es el evento que se va a vincular
Esta función permite agregar un elemento a la grilla tipo submit. El parámetro $task
es el atributo “name” del elemento, el parámetro $alt es el label que se mostrará
para el elemento, el parámetro $icon es la ruta a una imagen que será el ícono
representativo del elemento y el parámetro $onclick es el evento que se va a vincular
al hacer click en dicho elemento (opcional).
Esta función permite agregar un elemento a la grilla tipo botón. El parámetro $name
es el atributo “name” del elemento, el parámetro $alt es el label que se mostrará
para el elemento, el parámetro $icon es la ruta a una imagen que será el ícono
representativo del elemento y el parámetro $onclick es el evento que se va a vincular
al hacer click en dicho elemento (opcional).
Esta función permite agregar un elemento a la grilla tipo “input text”. El parámetro
$name_input es el atributo “name” del elemento, el parámetro $label es el label que
se mostrará para el elemento, el parámetro $value_input es el valor por default del
input, el parámetro $task es la acción que se envía al servidor al presionar el “botón”
asociado a la caja de texto y el parámetro $onkeypress_text es el evento que se
asociará a la caja de texto cada vez que se presiona una tecla.
Esta función permite agregar un elemento a la grilla tipo “combo box”. El parámetro
$name_select es el atributo “name” del elemento, el parámetro $label es el label
que se mostrará para el elemento, el parámetro $data es un arreglo con los datos
del combo, el parámetro $selected es el elemento seleccionado por default, el
parámetro $task es la acción que se envía al servidor al presionar el “botón”
asociado al combo y el parámetro $onchange_select es el evento que se asociará al
§ function addHTMLAction($html)
Esta función permite agregar un nuevo elemento tipo html a la grilla. El parámetro
$html es el código html a añadir.
Esta clase sirve para codificar en formato JSON. Nos puede ser de gran ayuda
cuando se haga una petición AJAX al servidor, y enviarle la respuesta al cliente en
formato JSON. Codifica un arreglo de tres elementos, cuyos índices son “error”, en
esta se almacenan los errores en caso de haberlos, “statusResponse” que almacena
un estado de la respuesta, por default se setea en OK y “message” que almacena la
respuesta deseada.
El constructor es el siguiente:
§ function PaloSantoJSON()
§ function createJSON()
Codifica la respuesta en JSON con el formato mencionado anteriormente.
§ function set_error($error)
Setea el valor del índice “error” por lo que tenga el parámetro $error.
§ function set_status($status)
Setea el valor del índice “statusResponse” por lo que tenga el parámetro $status.
§ function set_message($message)
Setea el valor del índice “message” por lo que tenga el parámetro $message.
3. AJAX en Elastix
El framework Elastix también cuenta con una función javascript para realizar
peticiones AJAX!!. Esta función es la siguiente:
Ejemplo:
Se desea crear una función javascript que realice una petición AJAX al módulo
“testModule”. Esta función recibe como parámetro un texto el cual se debe pasar al
servidor. El servidor debe responder el texto traducido en el lenguaje que este
seleccionado en el servidor Elastix en caso de contar con esa traducción, caso
contrario devolverá el mismo texto. En el cliente se debe mostrar un alert con el texto
devuelto por el servidor.
Archivo testModule/themes/default/js/javascript.js
function getTextTranslate(text)
{
var arrAction = new Array();
arrAction["menu"] = "testModule";
arrAction["action"] = "translate";
arrAction["text"] = text;
arrAction["rawmode"] = "yes"; //Remember, this is necessary
because in this way the server will only response the content of the module
that will be a JSON.
request("index.php",arrAction,false,
function(arrData,statusResponse,error)
{
//The variable statusResponse contains the value assigned to
statusResponse in the JSON response.
//The variable error contains tha value assigned to error in the
JSON response.
//The variable arrData contains the value assigned to message in
the JSON response.
alert(arrData);
}
);
}
Archivo testModule/index.php
<?php
include_once "libs/paloSantoForm.class.php";
include_once "libs/paloSantoJSON.class.php";
$action = getAction();
$content = "";
switch($action){
case "save":
case "translate":
$content = translateText();
break;
default: // view_form
$content = viewFormTestModule($smarty, $module_name,
$local_templates_dir);
break;
}
return $content;
}
function translateText()
{
$jsonObject = new PaloSantoJSON();
$text = getParameter("text");
$translated = _tr($text);
$jsonObject->set_message($translated);
return $jsonObject->createJSON();
}
function getAction()
{
if(getParameter("save"))
return "save";
elseif(getParameter("action") == "translate")
return "translate";
else
return "report";
}
§ El archivo menu.xml es un XML que contiene los módulos que serán integrados
a Elastix, indicando la ubicación, nombre, tipo, permisos,etc.
Ejemplo:
Como se puede observar, dentro de la etiqueta “menulist” van todos los módulos y
cada módulo se describe mediante la etiqueta “menuitem” donde el atributo “menuid”
es el id del módulo, el atributo “desc” es la etiqueta que se mostrará en la interfaz
web, el atributo “parent” es el id del módulo que lo contendrá, el atributo “module”
puede ser “yes” si es un módulo propiamente dicho o “no” si es un módulo padre o si
es un módulo tipo link, el atributo “link” es el link al cual apuntará el módulo y el
módulo “order” es el orden que ocupará el módulo.
Ahora lo único que hay que hacer es usar el script elastix-menumerge pasándole el
archivo XML para que quede realizada la integración con Elastix. Así mismo si
deseamos remover algún menú, se ejecuta el script elastix-menuremove pasándole
el id del mismo. Esto se lo debe realizar en el archivo spec.
Ejemplo:
Construir un archivo db.info para un addon que tendrá que una base de datos sqlite3
llamada “myDBSqlite” la cual se debe hacer un backup en caso de existir y no debe
poder ser eliminable, y una base de datos mysql llamada “myDBMysql” con las
mismas caracerísticas.
[myDBSqlite]
ignore_backup = no
engine = sqlite3
path = /var/www/db
deletable = no
[myDBMysql]
ignore_backup = no
engine = mysql
path = /var/lib/mysql
deletable = no
Dentro de la carpeta “install” habrá una carpeta para cada base de datos con el
mismo nombre de la base. Dentro de esta carpeta habrá scripts sql que sólo se
ejecutarán en la instalación del paquete (y se aplicarán sobre la base de datos
correspondiente al nombre de la carpeta). Estos scripts tendrán los nombres
“1_schema.sql”, “2_schema.sql”, “3_schema.sql”, etc (usualmente sólo se necesitará
de uno), el número de prefijo es importante porque indica el orden de ejecución.
Para bases de datos “sqlite3” simplemente se crean tablas y se añaden registros por
default (de ser necesarios) pero para bases mysql también es necesario la creación
de la base (CREATE DATABASE dbname;) seguido de un USE dbname; para de
ahí si proseguir con la creación de las tablas y demás.
En la carpeta “update” así mismo habrá una carpeta para cada base de datos con el
mismo nombre de la base. Dentro de cada una de estas carpetas habrá otra
carpeta llamada “version_sql” que contendrán los scripts sql de actualización. El
nombre de estos scripts es sumamente importante, deben tener la siguiente
estructura:
#number_#lastVersion_#newVersion.sql
Donde:
Ejemplo:
Una vez armado el fuente ahora es cuestión de crear el archivo spec, para terminar
con el proceso de construcción del RPM o empaquetado.
A continuación se mostrará un pequeño ejemplo de un archivo spec sin entrar en
mayores detalles, ya que se asume que el desarrollador tiene claros conocimientos
en cuanto a la construcción de paquetes RPM.
%description
Elastix Module Example
%prep
%setup -n %{modname}
%install
rm -rf $RPM_BUILD_ROOT
# The following folder should contain all the data that is required by the
installer,
# that cannot be handled by RPM.
mkdir -p $RPM_BUILD_ROOT/usr/share/elastix/module_installer/%{name}-
%{version}-%{release}/
mv setup/ $RPM_BUILD_ROOT/usr/share/elastix/module_installer/%{name}-
%{version}-%{release}/
mv menu.xml $RPM_BUILD_ROOT/usr/share/elastix/module_installer/%{name}-
%{version}-%{release}/
%pre
mkdir -p /usr/share/elastix/module_installer/%{name}-%{version}-%{release}/
touch /usr/share/elastix/module_installer/%{name}-%{version}-
%{release}/preversion_%{modname}.info
if [ $1 -eq 2 ]; then
rpm -q --queryformat='%{VERSION}-%{RELEASE}' %{name} >
/usr/share/elastix/module_installer/%{name}-%{version}-
%{release}/preversion_%{modname}.info
fi
%post
pathModule="/usr/share/elastix/module_installer/%{name}-%{version}-
%{release}"
# Run installer script to fix up ACLs and add module to Elastix menus.
elastix-menumerge $pathModule/menu.xml
pathSQLiteDB="/var/www/db"
mkdir -p $pathSQLiteDB
preversion=`cat $pathModule/preversion_%{modname}.info`
%clean
rm -rf $RPM_BUILD_ROOT
%preun
if [ $1 -eq 0 ] ; then # Validation for desinstall this rpm
echo "Delete example menus"
elastix-menuremove "%{modname}"
# Here you should call to elastix-dbprocess for deleting, the same way
that it was for install, just that instead of word “install” goes word
“delete”. But this is not often used due to the databases usually are not
deleted
fi
%files
%defattr(-, asterisk, asterisk)
%{_localstatedir}/www/html/*
/usr/share/elastix/module_installer/*
%changelog
* Mon Jan 30 2012 Alberto Santos <asantos@palosanto.com> 2.2.0-1
− Initial version.