• PFC 12.09.2008 No Comments

    Once I’ve programmed the PHP part of the prototype, I had to program the other part of the project: the XSLT file.

    Let’s go back for a while; the main purpose of the project is, having a syllabi (OpenSyllabus XML course file), I have to make a moodle course automatically according to that syllabi.

    Moodle courses can be saved as XML files and be restored with that XML file. With this premise, and knowing that syllabi are also XML files, we can see that we need to transform in some way the syllabi into a Moodle course. The way for doing it is called XSLT (eXtensible StyleSheet Language Tranform).

    The process for making the XSL file:

    1. First, having a syllabi example, I’ve made manually a Moodle course.
    2. Then, I’ve stored the XML file into my computer to work with it (making a backup of the course). Now, the objective is to transform the syllabi XML file into a Moodle XML course file with the aid of XSLT language.

    (in the previous entry of my blog I wrote about the PHP part and his relantionship with XSLT part).

    I never did any XSL transformation or programmed a XSL file, and I needed learning some advanced XSL features immediatelly not recommended for a newbie who wants to learn XSL as a hobby :) . Also I had to adapt the xsl syntax to moodle, because Moodle needs “special” considerations:

    1. Moodle xml files have very separated parts in the document. However, some parts have a very close relationship, and this relation can only be linked with an Identifier. But this identifier needs to be independent of the XML syllabi, so after some heavy research, the XSL function I needed for this was “generate-id” (this function generates a unique ID for a node, ideal for the lesson bucle).
    2. I didn’t know why Moodle, after the point 1 application, gave me errors didn’t allow me to create a course. The explanation was that generate-id generates an id like “id7623472″. Moodle only reads numbers, not strings!, so I have to discard the “id” string with “substring” xsl function.
    3. In bucles, I needed incremental variables (aka i++ :) ). Nevertheless, “variable” xsl element doesn’t allow changing his first assigned value (OMG, problem!), because XSL is a declarative language, not a procedural one like C++ or PHP. The first and valid approach I found to solve this problem was the “number” xsl element. In a bucle, it makes something like a counter, from 1 to N being N the number of iterations. I found it a rustic and ‘vaste’ method, but valid for my purposes :)

    After all these ones, and spending some time, finally I’ve finished the XSL file and it works perfectly. But this XSL file is built over a syllabi prototype, not over a final version, so I will have to modify it a lot when I recive it.

    Now, I’ve finished all my work on OpenSyllabus integration prototype for Moodlemoot for now until “new external requirements” (probably they will arrive soon).

    As you can see, in my blog entries I’m writing about XML files and other kind of resources, but I don’t put any example to allow you understanding me clearly. Once I finish the project I will upload all those files and will modify all posts adding to them the mentioned ones (or until my teacher tells me that it could be good to upload them while they are in process).

    Tags: , , ,

  • PFC 07.09.2008 No Comments

    Finally, the requirements for OpenSyllabus integration into Moodle are clearly defined. The main purpose: having a Syllabi (an OpenSyllabus XML file), Moodle has to process this XML file by means of an XSL file, which transforms the original Osyl XML file into a Moodle XML course file, and then process it to have a new Moodle course ready for being used.

    However, I only have two more weeks to finish the work (all must be ready soon for Moodlemoot).

    The main abstraction (God heavens, I love this word!) is (the main tasks):

    1. Create a new administration option, called ‘Import OpenSyllabus course’.
    2. That option will link to a Moodle Form, where the administrator will be able to upload an XML file.
    3. Once the user has selected an Osyl XML file, and he submits it, the file is uploaded.
    4. After that, the uploaded file will be parsed with an XSL parser, who will transform the original XML into another Moodle readable XML course file.
    5. In order to reuse some original Moodle code (concretely the course restoration code) the output XML file needs to be zipped.
    6. Once the file has been zipped, now is the time to invoke the restoration process with the zipped file as parameter.

    Until here, all seems to be tidy and clear. Yes, it is. This is the main specification however, I’ve found some personal problems (the design, how can I made it? how can I implement it?):

    1. I’ve no idea about PHP (I’m a pure Java developer, I’ve never touched PHP).
    2. How can I add a new link (which points to the import form) in the Moodle admin block?
    3. How can I create a form for allowing a user to upload a file compatible with Moodle?
    4. How can I retrieve the file? And the name of the file?
    5. How can I store a file into an specific folder in PHP?
    6. How can I process a XML file with an XSL parser with my XSL file to transform it into another XML file in PHP?
    7. How can I zip files in PHP?
    8. How can I reuse the restore implementation?

    Well, all these questions have their proper answer. But where can I find the answers and understand them? Afortunately I’ve already found them, however, it has not been easy:

    • Or I’m stupid and I can’t find it, or Moodle lacks of a good developer documentation (such as complete class diagrams, specifications, sequence diagrams, proper explanations…). It only has an API over hundreds of files composing Moodle (omg, finding something has been really hard).
    • I’m tired of searching concrete functions among the API files. Is the Moodle API useful or useless? Can I do my job with brute programming? Or has someone implemented what I need yet?

    After some days of desperate study:

    1. PHP is an Object Oriented language, so a port from Java should not be too difficult. PHP is rather different than Java, however it has some similarities (like classes, attributes…), so with some practice, learning PHP should be easier (in fact, I believe I know now PHP and now I can program better than some time ago)
    2. I’ve found the admin block is implemented in admin/settings. I’ve located my option link in courses.php file:

      $ADMIN->add(‘courses’, new admin_externalpage(‘osylimp’, get_string(‘osylimp’, ‘admin’), $CFG->wwwroot . ‘/course/osyl.php’));

    3. Moodle has a superclass for forms, called moodleform (located at lib/formslib.php). Using a form example (edit_form.php located in course folder), I’ve created a new subclass, called syllabi_import_form.

      But the form example doesn’t have a field for uploading files. How can I make one? After lot of websearching and coffees, I’ve found that I can add a line into the definition function of my new class:

      $mform->addElement('file','syllabi', 'XML course file','maxlength="150" size="20"');

      There were lots of similar lines in the document, however, replacing the first parameter with ‘file’ I’ve created a field for uploading files.

    4. For retrieving the file value, exists a moodle function for forms: getElementValue. Passing as parameter the name of the file, it will retrieve the value entered by the user. Nevertheless, the value returned by getElementValue for the file field was an array. Arrays in PHP are rather different than Java:

      For expressing an array, in Java we use this expression: namevariable[integer]. In PHP, is something similar, but different. Arrays can be used in many ways, like hash tables, priority queues, stacks… so you can use also strings into the [], and mapping a key to a value in the array. See PHP documentation for further explanation.

      Finally, I could retrieve the name of the file :)

    5. For retrieving the file and store it, Moodle forms have a method for storing into an specific path all files the user wants to upload: “save_files”.
    6. There are lots of XSL parser for PHP: the most interesting I found was Sablotron. However, I couldn’t get it working, so I’ve used the built-in XSLT parser (libxslt library). In PHP documentation about XSL I’ve found some functions to get it working. This is the main procedure:

      $xp = new XSLTProcessor(); //First we create a XSLT process
      $xsl = new DomDocument; //Then, we must load an XSL file
      $xsl->load('../OsylCourse.xsl');

      $xp->importStylesheet($xsl); //After that, we must import the XSL file
      //to the XSLT process
      $xml_doc = new DomDocument; //now we have to load the XML file
      $xml_doc->load($CFG->dataroot.'/3/backupdata/'.$file['name']);

      /*finally, we have to apply the transformation to the document and
      save it to a file*/
      if ($xml_out = $xp->transformToDOC($xml_doc)) {
      $xml_out->save($CFG->dataroot.'/3/backupdata/moodle.xml');
      } else {
      trigger_error('XSL transformation failed.', E_USER_ERROR);
      }

    7. Zipping a file is quite easy:


      $zip = new ZipArchive(); //First we create an instance of a Zip file
      /*Then, with open system call we create a zip file*/
      if ($zip->open($CFG->dataroot.'/3/backupdata/course.zip', ZIPARCHIVE::CREATE)!==TRUE) {
      exit("cannot open");
      }
      //Add as many files as you want (also directories)
      $zip->addFile($CFG->dataroot.'/3/backupdata/moodle.xml', 'moodle.xml');
      //Close the zip file
      $zip->close();

      For further information see PHP Documentation for ZIP.

    8. Reuse the restoration code is easy. Simply pass as a parameter the recently zipped file.

    Well, that’s all for now. However, there are plenty of bugs. For now, I’m only making a functional prototype for Moodlemoot… Doing things well requires time :)

    Tags: , , , , ,

  • Learning a programming language is easier than it seems. But if you claim to learn any language without spending lot of time, you need a good scheduling and a little organization.

    It’s logical, a building can’t start from the roof: We need a solid base where we can begin to build a house; However, the methods I learnt from my University 3 years ago were not the best method to begin.

    I begin learning Java, a full Object Oriented programming language. Omg, that was horrible for me! OO languages are great, fantastic, but are horribly for beginners, especially if you’ve never programmed before. In OO, there are lots of concepts that at first, they may be “innocuous” (Inheritance, Polymorph, Encapsulation…).

    When I began, teacher spoke to us about unknown words: class??? method??? (I understood the word method like ‘methodology’, not ‘function’!), and bad explanations about that… I was really disappointed and I lose my heart. Leer más…

    Tags: , , , ,

El autor: David Jiménez

Soy Ingeniero Técnico en Informática de Gestión titulado por la Facultad de Informática de Barcelona, donde me encuentro actualmente cursando un Máster en Computación especializado en Sistemas de Información e Ingeniería de Servicios.

He trabajado como desarrollador de la plataforma educativa Moodle durante casi dos años en la UPC, y mis intereses profesionales están enfocados hacia la excelencia en el mundo empresarial.

Como pasatiempo favorito me gustan los juegos de estrategia y postear mis reflexiones sobre el mundo que nos rodea, sea de la temática que sea, en este blog personal.

Si necesitas contactar conmigo puedes hacerlo a través de este formulario.

Recuerda también que puedes suscribirte al feed de este blog para así estar siempre al corriente de nuevos posts.