Saturday, May 11, 2013

Moodle - Simple workflow

Finally, it's time to let others see the changes I have made although it just fixes a very simple bug.

The brief workflow should be as follows:

1) At the beginning of the day, check the upstream changes and push to my own repository at github.

2) Do the modification to the code.

3) git diff -U1 // check the changes

4) git status // check the correct status

5) git add [file/directory] // add the changed files or directories for commit

6) git commit -m "[track number] [module changed]: [changes]"

7) git push origin [working branch]

Then the changes are visible on the github.

Wednesday, May 8, 2013

Moodle - Initial try for bug fixing of MDL-36020

As a prerequisite, fixing existing Moodle bugs is crucial to the GSoC application for Moodle projects. Among the list of bugs suggested by Tim, it is hard to justify their difficulty for a beginner.

Anyway, browsing through the list and finally decide to try this one:

From the description, it is some bug related to the re-grading function. The first step would thus to locate where these actions are processed. 

Directly diving into the codes makes me even confusing and cannot find even a start. Have to do the other way, i.e. trying the system. 

Creating a dummy course, registering a bunch of dummy users and design a set of questions to form a quiz. Using different accounts to attempt the quiz and finally the regrading button shows up.

The regrading lies in the Results section of Quiz module. In the source code it doesn't have a separate page but a set of functions. 

The codes are under the path moodle/mod/quiz/
Especially in the file moodle/mod/quiz/overview/report.php

Following are the functions responsible for the regrading:

process_actions($quiz, $cm, $currentgroup, $groupstudents, $allowed, $redirecturl)
Based on the action received, calling corresponding functions. Actions include "regrade", "regradeall", "regradealldry", "regradealldrydo".

regrade_attempt($attempt, $dryrun = false, $slots = null)
Regrade a particular quiz attempt. This is where the actual regrading happens. It is called by other methods.

regrade_attempts($quiz, $dryrun = false,
            $groupstudents = array(), $attemptids = array())
Regrade a set of attempts for this quiz. The set of attempts are specified by the input parameters. For each attempt, the regrading is done by the above regrade_attempt() function.

regrade_attempts_needing_it($quiz, $groupstudents)
Regrade all the attempts of the specified quiz that are marked as needing regrading.

count_question_attempts_needing_regrade($quiz, $groupstudents)
Count the number of attempts that needs regrading for the specified quiz.

has_regraded_questions($from, $where, $params)
Check whether there are any pending regrades to show.

clear_regrade_table($quiz, $groupstudents)
Remove all information about pending/complete regrades from database.

Update the final grades for all attempts in the quiz.

These are probably the place to resolving the bug and a general problem for all the regrading action, we may need to fix it in the process_actions() function. 

Next, how to fix the problem. From the description, the problem is due to the long processing time of the regrading which leads to the user session time out. 

Personally, I don't like the questions such as how good are you at xxx? how familiar are you with xxx? I have no idea what standards could be used to evaluated such as goodness or familiarity. No matter what standard you took, the answer will always be subjective and most of time  helpless.

Regarding Tim's question "what the session is". As I have never studies PHP in a systematical way, I only knows it keeps track of a user's information during his/her visiting of the website. And the only thing I have touched session in PHP is during last summer's GSoC. 
a) After a user logs in, the session_start() is called;
b) $_SESSION['variable']=value is used when I need to pass over some variables between different pages;
c) session_destroy() is called when the user logs out.
That's all I know about sessions in PHP.

Regarding the second question "why it might normally lock?", I have no idea. But with the help of Google, I learned following aspects:

a) From, the session locks due to multiple requests to access the same session file and could be solved by closing the session with session_write_close() before starting the long running process. This function only close the write session capability, the session variables are still readable. 

It seems a solution but how can we guarantee that there will be no session write requests after this?

Tuesday, May 7, 2013

Moodle - First attempt

After reading the Moodle community documents for several days, I finally decide to try it out and hope to fix several bugs before they give the final decision on my GSoC 2013 application.

Initially, I followed the steps provided in on my current machine. First apply for those accounts and then fork a brunch on Github ( and checking out a local copy with SHH-key setup. Then I'm totally lost where to start. That's a pretty big project with lots of source files. Need to find an IDE.

During the process of figuring out which is the popular IDE for Moodle development, I decided to use a completely clean system to do all the development. A Ubuntu 12.04 system is thus created in VirtualBox. 

1. Setup the LAMP system following instructions on . It simply includes two steps:

First install tasksel...

    $ sudo apt-get install tasksel

... and then the LAMP stack:

    $ sudo tasksel install lamp-server

The only change to the steps is the one that inputs "Source Git repository". Use the previously forked Github repository and my own gihub account and password. Instead of using SSH, the HTTPS is used as there is always error when I tried SSH.

3. Till now, it is almost done. Put a symbolic link under the path /var/www to the git repository folder for Moodle (for mine, it is ~/git/moodle). And make sure the folder has been granted correct permission. I simply used chmod 777 to it as this is for development not for public testing. 

Then, open the browser and type in the http://localhost/moodle . A web-based installation will automatically start for the first time. It requires the creation of a proper permission data folder moodledata, which is better to be under the /var/www path with permission right 777. 

During the installation, it will check the system environments. For my case, I the php5-curl, php5-gd, php5-xmlrpc packages are missing. Using the Ubuntu's apt-get install to get them ready and restart the apache server by /etc/init.d/apache restart. Then click the button at the bottom of the page to redo the checking until all the items are OK. 

Next, the database configuration is required. For Ubuntu, MySql is the default one for LAMP setup, the Improved MySql (native/mysqli) is thus chosen. It at first gave me errors of PHP not configured for mysqli. This was solved by uncomment the line "mysqli.allow_local_infile = On" in the /etc/php5/aphace2/php.ini as all the other lines with mysqli configurations are by default enabled.

Meanwhile, create a MySql database and user for Moodle:

Create a mysql database

    $ mysql> CREATE DATABASE moodel;

Create a mysql user

For creating a new user with all privileges on the moodle database at mysql prompt type:

    $ mysql> GRANT ALL PRIVILEGES ON moodel.* TO 'yourusername'@'localhost' IDENTIFIED BY 'yourpassword' WITH GRANT OPTION;

Next fill out the corresponding information to Moodle.

After updating the admin account information for Moodle site, the final admin workspace will be presented to you.

4. Taking Tim's suggestions on . Following configuration is done at the admin workspace:

After installing a copy of Moodle for development, the first thing you should do is:

  1. Go to Site administration -> Development -> Debugging
  2. Set Debug messages to DEVELOPER, and Turn on Display debug messages. (Consider turning on some of the other options too.)
  3. In the administration block, search for "Cache" then
    1. Turn off Cache all language strings.
    2. Set Text cache lifetime to No
    3. Turn on Theme designer mode
    4. Turn off Cache Javascript
5. Next as the remote repository we used to setup the Eclipse is forked from Moodle and to keep it updated with changes in Moodle, the instructions in the section "Keeping your public repository update to date" on was followed. 

Before addressing the problem, make sure the suggested git configuration is done:

Immediately after the installation, set your name and contact e-mail. The name and e-mail will become part of your commits and they can't be changed later once your commits are accepted into the Moodle code. Therefore we ask contributors to use their real names written in capital letters, eg "John Smith" and not "john smith" or even "john5677".

   git config --global "Your Name"     git config --global yourmail@domain.tld  

Unless you are the repository maintainer, it is wise to set your Git to not push changes in file permissions:

   git config --global core.filemode false

Then register the upstream remote:

   cd moodle     git remote add upstream git://  

Then use following commands to keep the standard Moodle branches at your Github repository synced with the upstream repository. You may wish to store them in a script so that you can run it every week after the upstream repository is updated.

   #!/bin/sh     git fetch upstream     for BRANCH in MOODLE_19_STABLE MOODLE_20_STABLE MOODLE_21_STABLE MOODLE_22_STABLE MOODLE_23_STABLE MOODLE_24_STABLE master; do         git push origin refs/remotes/upstream/$BRANCH:$BRANCH     done

However, as in the Eclipse configuration, the git repository is using HTTPS instead of SSH, running the update shell script will require the input of both Github username and password for each push command, which is really annoying. To avoid the trouble of tying, first the SHH-Key configuration should be done (c.f. and added to GitHub account's SHH Keys. 

Then change the repository url by:
git remote set-url origin[username]/moodle.git

With this successfully done, running the above update scripts will bypass the log in phase.

6. From my understanding the changes fetched from upstreams are directly pushed to the Gibhub origin. The local working copy is not affected. It may thus require to fetch/pull changes from my own Github repository and merge with my local copy. Not sure yet. To be confirmed later. 

It seems the setup is almost done to me. It's time to start fixing some bugs!