sábado, 7 de junio de 2008

Configuración del nivel de profundidad de las categorias a mostrar

insert into m_config (name, value) values ('max_category_depth', $nivel_de_profundidad);
o bien añadiendo al fichero config.php la siguiente línea:
$CFG->max_category_depth = 2;

Español como lengua por defecto

1.Para la configuración del idioma es necesario descargar dos paquetes con los ficheros de traducción desde inglés (idioma por defecto) a español: es_utf8.zip y es_es_utf8.zip. Para ello accede a la plataforma como administrador y descarga los paquetes de idiomas “Españo – España” y “Español – Internacional” desde el panel de Language->Language packs.

2.Una vez descargados, añadir el siguiente código al final del fichero setup.php del directorio /moodle/lib:

/*========================================================*/
/*Configuración del lenguaje */
if(empty($_GET['lang'])){
$lang = 'es_es_utf8';
if (file_exists($CFG->dataroot .'/lang/'. $lang) or
file_exists($CFG->dirroot .'/lang/'. $lang)) {
$SESSION->lang = $lang;
}
else if (file_exists($CFG->dataroot.'/lang/'.$lang.'_utf8') or
file_exists($CFG->dirroot .'/lang/'.$lang.'_utf8')) {
$SESSION->lang = $lang.'_utf8';
}
}
setup_lang_from_browser();
/*========================================================*/

De esta forma queda el español internacional como idioma por defecto.

Triggers Oracle para Moodle 2.0

Este bug está registrado y comprobado en Moodle Tracker: http://tracker.moodle.org/browse/MDL-14567

En Moodle 2.0 sobre Oracle podemos crear triggers directamente sobre la base de datos para cualquier implementación que estemos haciendo (módulos, bloques...). Sin embargo, debemos tener en cuenta los siguientes aspectos:

1.Al contrario que en MySQL, en Oracle no podemos especificar un campo de una tabla como autoincrementable, lo que resulta útil para la genernación de identificadores de las tuplas (en Moodle siempre se les llama ID). Esto implica el uso de triggers, creados por defecto, que, cada vez que se hace una inserción, se disparan generando un nuevo identificador a partir de una secuencia.
2.Moodle se abstrae del tipo de la base de datos sobre la que trabaja y maneja las inserciones con objetos XMLDBTable. Con esto el sistema puede trabajar sobre cualquier base de datos que pueda no ser MySQL (la que exige por defecto).

Sabiendo esto, aparentemente la creación de nuestros propios triggers no implica ningún problema sobre el funcionamiento del sistema, pues el manejo de triggers es un trabajo del SGBD Oracle y no de Moodle.

Sin embargo, sí existe un problema al crear triggers: Cuando queremos hacer una inserción sobre una tabla del sistema (por ejemplo, moodle_course) a la que le hemos asociado un trigger propio, la función encargada de la inserción genera el siguiente problema:

Esta función trabaja con un objeto XMLDBTable con el que realiza la inserción. A este se le asocia la nueva tupla a insertar asignándole además el identificador real que tendrá la nueva tupla en la base de datos. Para conocer dicho identificador, se lanza una consulta sobre la base de datos para tomar el cuerpo del trigger asociado a la tabla y así manejar desde el código PHP la sentencia encargada de la creación del nuevo ID. Concretamente, la función es “getSequenceFromDB” de moodle/lib/xmldb/classes/generator/oci8po/oci8po.class.php:

function getSequenceFromDB($xmldb_table) {
$tablename = strtoupper($this->getTableName($xmldb_table));
$sequencename = false;
if ($trigger = get_record_sql("SELECT trigger_name, trigger_body
FROM user_triggers
WHERE table_name = '{$tablename}'")) {

/// If trigger found, regexp it looking for the sequence name
preg_match('/.*SELECT (.*)\.nextval/i', $trigger->trigger_body, $matches);
if (isset($matches[1])) {
$sequencename = $matches[1];
}
}
return $sequencename;
}


Si la observamos, vemos que se usa la función “get_record_sql” que solo devuelve la primera tupla encontrada por la consulta lanzada. Esto es un problema para nosotros, pues estamos en la situación en la que tenemos una tabla con dos triggers asociados: el asignador por defecto para la generación de ID y el que nosotros hemos creado. Entonces, esta consulta podría devolver el cuerpo del trigger que hemos creado y no el que existe por defecto. Lo que probocaría un error (página en blanco) dado que es implosible generar un nuevo identificador.

¿Qué solución le damos a esto?

Necesitamos distinguir el trigger encargado de la generación de IDs del resto. Esto se puede hacer de muchísimas maneras, pero la que yo propongo es esta:

Modificamos la consulta lanzada con la función “get_record_sql” de manera que solo se obtenga el trigger correspondiente a la creación del nuevo ID. Esto lo podemos hacer porque sabemos que Moodle asigna al nombre de los triggers de este tipo un nombre de la forma “*_ID*_TRG”. Así nos quedaría la consulta de la siguiente forma:

SELECT trigger_name, trigger_body
FROM user_triggers
WHERE table_name = '{$tablename}'
AND trigger_name like upper('{$CFG->prefix}')||'%ID%_TRG'

Con esto podemos crear Triggers Oracle en Moodle 2.0 sin problemas. La solución es muy cómoda aunque para aplicarla hay que suponer que Moodle siempre asignará a los triggers de este tipo un nombre de la forma “*_ID*_TRG”, además de, evidentemente, nosotros tener siempre presente que no debemos crear triggers cuyo nombre termine como estos. Seguro que hay soluciones mejores y menos “arriesgadas”, algo de lo que espero tener constancia.

Notas:

1.Con esta solución, podemos crear triggers de tipo AFTER y BEFORE sin problemas.

2.Para el caso concreto de la inserción de un nuevo curso por parte de Moodle una vez rellenado el formulario, la secuencia completa de invocaciones hasta obtener el nombre del trigger generador es:
1.edit.php: create_course($data), línea 98 aprox.
2.lib.php: insert_record('course', $data), línea 2819 aprox.
3.dmllib.php: find_sequence_name($xmldb_table);, línea 1496 aprox.
4.ddllib.php: getSequenceFromDB($CFG->dbtype, $CFG->prefix); línea 590 aprox
5.XMLDBTable.class.php: getSequenceFromDB($this); línea 1076 aprox.
6.oci8po.class.php: get_record_sql("SELECT...”); línea 541 aprox.

3.En el intérprete SQL podemos imprimir los errores al crear un trigger con la sentencia “show errors” inmediatamente debajo del código del trigger.

4.Podríamos no tocar la consulta comentada. Dejar el código tal y como está. Pero esto nos obliga a incluir código a nuestro trigger para desde este generar el nuevo ID. Sin embargo, esta solución solo sirve si el nuestro es de tipo BEFORE INSERT.
Ésto tendríamos que añadir:
IF :NEW.id IS NULL THEN
SELECT .nextval INTO :NEW.id FROM dual;
END IF;
Para el caso de inserciones en la tabla de cursos, la secuencia es: _cour_id_seq

5.Para conocer los triggers asociados a una determinada tabla:
SELECT trigger_name, trigger_type, trigger_body
FROM user_triggers
WHERE table_name = '';

Instalación de Moodle sobre Ubuntu 7.10

Sigue los siguientes 6 pasos:

1.Sistema Operativo Ubuntu.
1.1.Descargar la versión 7.10 del sitio web oficial (www.ubuntu.com).
1.2.Instalarlo en una partición de al menos 10Gb y memoria swap de al menos 1006Mb*.

2.Servidor Apache.
2.1.Instalar Apache desde el gestor de paquetes Synaptic o con el comando siguiente: sudo apt-get install apache2.

3.Servidor Oracle.
3.1.Dado que Ubuntu se basa en la distribución Debian Linux, necesitamos descargar el paquete .deb de Oracle. Concretamente, descargaremos la versión 10g Release 2 (10.2.0.1) Express Edition (Universal)** del servidor Oracle (no el cliente). Podemos hacerlo en http://www.oracle.com/technology/software/products/database/xe/htdocs/102xelinsoft.html.
3.2.Una vez descargado, simplemente con doble click sobre el paquete, el gestor de paquetes Synaptec se encargará de la instalación.
3.3.Ya instalado, ejecutamos el siguiente comando para la configurar Oracle: sudo /etc/init.doracle-xe. Podemos dejar los valores por defecto, siendo además los más usados por otras aplicaciones que puedan comunicarse con la BD. Estos valores por defecto son: puerto 8080 para HTTP, puerto 1521 para el Listener y contraseña vacía para los usuarios SYS y SYSTEM.

4.Usuario Oracle para Moodle.
Desde cualquier interfaz para lanzar sentencias SQL (por ejemplo, http://127.0.0.1:8080/apex) autenticado como usuario SYS o SYSTEM, creamos el espacio de tablas y usuario que asignaremos a la sesión de Moodle con las siguientes cuatro sentencias:
4.1.create tablespace
datafile ''
size 50m
autoextend on
next 10m
maxsize 100m;
4.2.create user identified by ;
grant connect, resource to ;
grant create view to ;
grant create trigger to ;
4.3.alter user
identified by
default tablespace ;
4.4.alter user default role all;

Instanciando los campos entre '<' y '>', podríamos usar los siguientes valores:
'<'espacio_tablas'>': tablespace_moodle
'<'path del fichero de datos .dbf'>': /home/usuarioubuntu/xe_moodle_01.dbf
'<'usuario'>': usuario_moodle
'<'clave_usuario'>': usuario_modle

5.Librería OCI8.
Moodle utiliza la librería en PHP ADOdb (Database Abstraction Library for PHP and Python) para poder integrarlo con cualquier sistema gestor de bases de datos. Esta librería, a su vez, utiliza otras de enlace dinámico que permiten comunicarse con la base de datos resolviendo las funciones concretas que utiliza cada gestor en tiempo de ejecución. Para nuestro caso en concreto, donde queremos comunicar Moodle con una BD Oracle, necesitamos la librería de enlace dinámico denominada OCI8 (Oracle Call Interface).
La librería OCI8 la instalamos en el sistema siguiendo los siguientes pasos:
5.1.Definimos las siguientes variables de entorno en el fichero /etc/environment:
ORACLE_HOME="/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/"
ORACLE_SID="XE"
ORATAB="/etc/oratab"
ORACLE_BASE=$ORACLE_HOME
ORACLE_HOME_LISTENER=$ORACLE_HOME
En caso de haber instalado Oracle en un directorio distinto al indicado o haber llamado de otra forma al SID, personalizar las variables respectivas correspondientes.
5.2.Reiniciar el sistema para que las variables de entorno queden registradas***.
5.3.Descargamos los códigos fuente de PHP5 para poder generar la librería:
sudo apt-get install php-pear php5-dev php5-cli
5.4.Generamos la librería, es decir, el fichero “oci8.so”:
pecl install oci8
Este fichero se generará en el directorio /usr/lib/php5/20060613+lfs.
5.5.Modificamos los ficheros “php.ini” para empezar a utiliar la librería:
echo “extension=oci8.so” >> /etc/php5/apache2/php.ini
echo “extension=oci8.so” >> /etc/php5/cli/php.ini
5.6.Modificamos el script de Apache para que éste utilice las variables de entorno creadas en el paso 5.1. Concretamente, modificamos el fichero /etc/init.d/apache2 ampliando la cadena que se asigna a la variable “ENV”:
ENV=” ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/ LD_LIBRARY_PATH=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/ ORACLE_SID=XE"
5.7.Reiniciamos Apache para que considere los cambios en los dos últimos pasos: sudo /etc/init.d/apache2 restart
5.8.Una forma de comprobar la correcta instalación de la librería consiste en lanzar la función “phpinfo()” en una página PHP local. Así, los parámetros de la configuración de OCI8 deben ser:
default_prefetch => 10 => 10
max_persistent => -1 => -1
old_oci_close_semantics => 0 => 0
persistent_timeout => -1 => -1
ping_interval => 60 => 60
provileged_connect => Off => Off
statement_cache_size => 20 => 20
5.9.Además, puede comprobar la comunicación con la BD creada para Moodle con este código de prueba también desde un script PHP local:
";
}
OCILogoff($conn);
?>

6.Moodle.
6.1.Descargamos la versión 1.8.5+ que es la más estable hasta ahora. Lo hacemos desde la web oficial descargando el paquete .tgz: http://download.moodle.org/download.php/stable18/moodle-weekly-18.tgz
6.2.Lo descomprimimos en el directorio de Apache /var/www.
6.3.Comenzamos la instalación desde el navegador con la URL http://127.0.0.1/moodle.
6.4.El desarrollo de la instalación es muy intuitivo, por lo que solamente comentamos el paso para la selección de la BD. Debe indicarse cuidadosamente los siguientes parámetros de configuración:
SSID (por defecto “XE”).
Usuario (si hemos seguido el ejemplo del paso 4, el usuario será “usuario_moodle”).
Contraseña (si hemos seguido el ejemplo del paso 4, el usuario será “usuario_moodle”).
Prefijo de las tablas (solo permite 2 caracteres, por ejemplo podemos indica “m_”).

* En caso de haber instalado Ubuntu sobre una partición swap de menos de 1006Mb, Oracle no podrá se instalado. En este caso, para aumentar su tamaño sigue los siguientes pasos:
1.Redimensionar la partición desde cualquier aplicación que permita modificar particiones. Por ejemplo, tenemos la aplicación Gparted ejecutable desde el CD de Ubuntu.
2.Una vez redimensionada la partición, si en el paso dedicado a la instalación de Oracle nos encontramos con el problema de éste no reconoce la partición swap modificada, entonces es que hay un problema de correspondencia entre la partición que busca Oracle y la que hemos modificado. Esto se soluciona cambiando el UUID de la partición swap por el identificador que se espera encontrar. Para ello sigamos los siguientes pasos:
2.1.Si Oracle busca una partición swap identificada como sdaX, generamos su UUID para posteriormente utilizarlo: sudo vol_id -u /etc/sdaX.
2.2.Una vez conocido el UUID, identificamos la particińo swap en el fichero /etc/fstab: sudo nano /etc/fstab.
2.3.Reemplazamos el identificador de dicha partición por el que Oracle espera encontrar (sdaX). Por ejemplo, si Oracle espera /dev/sda2 y en el fichero se identifica como /dev/sda5, cambiamos el 5 por el 2.
2.4.Por último, reemplazamos también su UUID por el generado en el paso 2.1. Por ejemplo, UUID=ca7e8e6a-1d94-4397-80c7-65c062c6e1d5 lo sustituimos por el generado UUID=9c44d435-de59-4655-96ef-8d8e908606be.
2.5.Reiniciamos Ubuntu para que los cambios queden reconocidos por este.
2.6.Si queremos comprobar si se han realizado los cambios, ejecutamos: sudo fdisk -l

** La versión Universal es imprescindible e insustituible por ninguna otra versión. Esto es así porque con esta versión las bases de datos utilizarán el juego de caracteres AL32UTF8 que es el que Moodle exige como requisito para su instalación. En caso de estar utilizando una BD con un juego de caracteres diferente (por ejemplo, WE8MSWIN1252), podrá adaptarse al juego exigido de estas tres formas:
1.Modificando el juego de caracteres. Esto es costoso porque implica seguir los siguientes paso:
1.1.Crear una nueva BD con el juego de caracteres AL32UTF8 que hará de backup de la existente.
1.2.Trasladar el contenido de la original a la nueva.
1.3.Eliminar el contenido de la original y cambiar el juego de caracteres.
1.4.Trasladar desde la BD de backup de nuevo a la original ya modificada.
2.Creando una nueva BD. Esto es menos costoso que la forma anterior pero el hecho de crear una nueva BD implica la dedicación de procesos y recursos físicos (disco duro y memoria RAM) a esta nueva. Lo que llega a relentizar el funcionamiento del servidor considerablemente.
3.Utilizando PHP como traductor. Existe una variable de entorno llamada “NLS_LANG” que se utiliza para que PHP se encargue de hacer las conversiones desde la BD hacia la página PHP en el navegador. De esta forma, el juego de caracteres indicado en la variable será al que se traduzcan los caracteres que se lean en la BD para ser tratados desde la página PHP o, en nuestro caso, cualquier página de Moodle. Sin embargo, esta forma de resolver nuestro problema es tan cómoda como inútil dado que su funcionamiento no está garantizado.

*** Si en lugar de trabajar sobre el fichero /etc/environment, lo hacemos desde un terminal utilizando “export =”, las variables no serán visibles globalmente sino solo desde cualquier aplicación lanzada desde el mismo terminal. Es decir, con el comando “export” la variable solo es visible dentro de la sesión correspondiente al terminal por sus procesos hijo. Una vez cerrado el terminal, la variable definida dejará de existir.