lunes, marzo 26, 2007

Reenginyeria del WikiStorage

En l'estat actual de la NWiki tenim una macro variable que conté tota la informació per el correcte funcionament de la wiki. Això no pot ser. Cal aplicar una mica de reenginyeria.

Una mica d'historia...

Els primers dies de la DFWiki, a Moodle es permetia l'ús de variables globals. Per gestionar de forma ràpida i senzilla tota la informació provinent dels formularis, s'usava una variable global anomenada $dfform. Aquesta variable era un array amb una infinitat de posicions, tantes com elements en tots els formularis de la wiki.

Per exemple, en l'utilitat de import XML hi ha aquest formulari:

El codi que genera el botó "Yes" és el seguent:
<input type="submit" name="dfform[sure]" value="<?php print_string('yes');?>" />
Per recullir aquesta informació, només començar l'execució del codi de la wiki, el que es feia era declarar la variable global y recullir els seus possibles valors amb una crida a optional_param().

global $dfform;
$dfform=optional_param('dfform');

Per saber si l'usuari havia premut aquest botó, només calia mirar si $dfform["sure"] tenia valor en el moment adequat i com que era una variable global no hi havia cap problema.


A principis d'Octubre de 2007, se'ns va avisar desde Moodle que l'ús d'aquest tipus de variables esta prohibit. Per aquest motiu, dos projectistes van estar pensant com eliminar-les de la forma menys danyina per l'evolució del codi i dels PFCs. Va apareixer la classe WikiStorage.

D'aquesta manera, vam passar a tindre una macro variable que contenia tota la informació i que s'anava passant per referència amunt i avall.

Bàsicament, el procediment va ser:
  1. Crear l'arxiu wikistorage.class.php per definir els atributs i unes quantes funcions.
  2. Substituir tots els "global ......" per "global $WS".
  3. Concatenar a totes les variables globals $WS-> per davant.
  4. Eliminar els "global $WS" i afegir-lo com a parametre a les funcions.

Un cop acabada aquesta tasca, en Petr Skoda ens va dir que no estavam utilitzant correctament la funció optional_param() i que per aquest motiu tenim molt bugs de seguretat.

Va resultar ser que la funció tenia 3 parametres i que moltes vegades, només en feiem fer servir 1.
function optional_param($parname, $default=NULL, $type=PARAM_CLEAN) ;

on $parname és el nom de la variable que es vol agafar, $default és el valor que ha de pendre la variable si no es troba valor ni per GET ni POST i $type és el tipus de parametre que s'ha d'anar a buscar.

PARAM_CLEAN és l'opció més restrictiva de les que es pot escullir per fer la crida i per tant la més ineficient (com a curiositat, PARAM_CLEAN = 0x666;). En Petr ens va dir que escullissim l'opció correcte en cada cas. Si el parametre era un numero, PARAM_INT; si era un string, PARAM_ALPHA; etc. Així, es podria fer un tractament més correcte del contingut de la variable.

En cap de les crides a aquesta funció de la wiki s'especificava el tercer parametre. Per tant un grup de projectistes van estar adaptant el codi a aquesta nova norma.

Ja que $dfform és un array de tipus heterogenis, no es podia fer una crida directa a optional_param() , ja que no existeix "type" amb aquest objectiu. Per aquest motiu, es va decidir agafar els parametres un per un. Primer de tot, es van renombrar tots els elements de formularis del tipus dfform[xxx] per dfformxxx. Després es va fer crear la funció wiki_dfform_param() on es recullien una per una les variables dels formularis.

En l'exemple de la finestra d'import XML, el botó va passar a
<input type="submit" name="dfformsure" value="<?php print_string('yes');?>" />
i el seu valor es recollia de la següent manera:
$WS->dfform['sure'] = optional_param('dfformsure',NULL,PARAM_INT);

Estat actual

Si ja no tenim variables globals i no podem agafar tots els parametres dels formularis de cop, perque seguim mantenin la mateixa filosofia que fa un any?

Tranquilament, podem eliminar l'atribut dfform i molts altres de la classe WikiStorage i agafar el seu valor només quan ens faci falta. A més a més, cal que tinguin aquest comportament de variable global? Si sabem quan ens fan falta aquests valors (normalment, dins del context d'una funció), perque no poden ser variables locals?

jueves, marzo 15, 2007

Carn fresca

Ha començat el quatrimestre i ja tenim gent nova currant en NWiki.

Aquesta nova remesa de projectistes faran coses tan variades com:
  • Crear plugins per OpenOffice i MSWord
  • Afegir a la wiki la posibilitat de crear/importar plantilles
  • Seguir amb el desenvolupament per entrar al HEAD de Moodle
  • I com sempre, manteniment...
He afegit tots els RSS feeds en el meu blog per poder fer un seguiment de la seva feina i ajudar-los en el que pugui.