Following on from the previous post, this post describes my adventures into the Moodle forums source code.
Forums, I understand, can be activities (a Moodle term) that can be presented within individual weeks or topics. I also know that forums can be presented through blocks (which can be presented on the left or right hand side of course areas).
To begin, and remembering the success that I had when trying to understand how blocks work, I start by looking at what the database can tell me and quickly discover quite a substantial number of tables. These are named: forum (obviously), forum_discussions, forum_posts, forum_queue, forum_ratings (ratings is not something that I have used within the version of Moodle that I am familiar with), forum_read, forum_descriptions, forum_subscriptions and forum_track_prefs.
Knowing that some of the data tables are called, I put aside my desire to excitedly eyeball source code and sensibly try to find some documentation.
I begin by having a look at the database schema introduction page (Moodledocs), but find nothing that immediately helps. I then discover an end user doc page that describes the forum module (and the different types of forum that are on offer in Moodle). I then uncover a whole forum documentation category (Moodledocs) and I'm immediately assaulted by my own lack of understanding of the capabilities system (which I'll hopefully blog about at some point in the future – one page that I'll take note of here is the forum permissions page).
From the forums category page I click on the various 'forum view pages', which hints that there are some strong connections with user settings.
Up to this point, what have I learnt?
I have learnt that Moodle permits only certain users to carry out certain actions to Moodle forums. I have also learnt that Moodle forums have different types. These, I am lead to believe (according to this documentation page) are: standard, single discussion, each person posts one discussion, and question and answer. I'm impressed: I wasn't expecting so much functionality!
So, can we discover any parallels with the database structures?
The forum table contains fields which are named: course, type, name, description followed by a whole other bunch of fields I don't really understand. The course field associates a forum with a course (I'm assuming that somewhere in the database there will be some data that connects the forum to a particular part or section of a course) and the type (which is interestingly, an enumerated type) which can hold data values that roughly represents the forum types that were mentioned earlier.
A brief look at the code
I remember that the documentation that I uncovered told me that the 'forums' was a module. In the 'mod' directory I see notice a file called view.php. Other interesting files are named: post.php, lib.php, search.php and discuss.php. View.php seems to be one big script which contains a big case statement in the middle. Post.php looks similar, but has a beguiling sister called post_form which happens to be a class. Lib, I discover, is a file of mystery that contains functions and fragments of SQL and HTML. Half of the search file seems to retrieve input parameters, and discuss is commented as, 'displays a post, and all the posts below it'.
Creating test data
To learn more about the data structures I decide to create some test data by creating a forum and making a couple of posts. I open up an imaginatively titled course called 'test' and add an equally imaginatively titled forum called 'test forum'. When creating the forum I'm asked to specify a forum type (the options are: single simple discussion, Q and A forum, standard forum for general use). I choose the standard forum and choose the default values for aggregate type and time period for blocking. The aggregate type appears to be related to functionality that allows students to grade or rate posts.
When the forum is live, I then make a forum post to my test forum that has the title 'test post'.
Reviewing the database
The action of creating a new forum appears to have created a record in the forum table which is associated to a particular course, using the course id. The act of adding a post to the test forum has added data to forum_discussions, where the name field corresponds to the title of my thread: 'test post'. A link is made with the forum table through a foreign key, and a primary key keeps track of all the discussions held by Moodle.
The forum_posts table also contains data. This table stores the text that is associated with a particular post. There is a link to the discussion table through a discussion id number. Other tables that I looked at included forum_queue (not quite sure what this is all about yet), forum_ratings (which probably stores stuff depending on your forum settings), and forum read, which simply stores an association between user id, forum id, discussion id and post id.
One interesting thing about forums is that they can have a recursive structure (you can send a reply to a reply to a reply and so on). To gain more insight into how this works, I send a reply to myself which has the imaginative content, 'this is a test post 2'.
Unexpectedly, no changes are made to the forum_discussions table, but a new entry is added to the forum_posts table. To indicate hierarchy a 'parent' field is populated (where the parent relates to an earlier entry within the forum_posts table). I'm assuming that the sequence of posts is represented by the 'created' field which stores a numerical representation of the time.
Tracing the execution flow
These experiments have given me with three questions to explore:
- What happens within the world of Moodle code the user creates a new forum?
- What happens when a user adds a new discussion to a forum?
- What happens when a user posts a reply?
Creating a new forum
Creating a new forum means adding an activity. To learn about what code is called when a forum is added, I click on 'add forum' and capture the URL. I then give my debugger the same parameters that are called (id, section, sesskey and add) and then begin to step through the course/mod.php script. The id number seems to relate to the id of the course, and the add parameter seems to specify the type of the activity or resource that is to be added.
I quickly discover a redirect to a script called modedit.php, where the parameters add=forum, type= (empty), course=4, section=1, return=0. To further understand what is going on, I stop my debugger and start modedit.php with these parameters.
There is a call to the database to check the validity of the course parameter, fetching of a course instance, something about the capability, fetching of an object that corresponds to a course section (call to get_course_section in course/lib code). Data items are added to a $form variable (which my debugger tells me is a global). There is then the instantiation of a class called mod_forum_mod_form (which is defined within mod/forum/mod_form.php). The definition class within mod_forum_mod_form defines how the forum add or modification form will be set out. There is then a connection between the data held within $form and the form class that stores information about what information will be presented to the user.
After the forum editing interface is displayed, the action of clicking the 'save and return to course' (for example) there is a postback to the same script, modedit.php. Further probing around reveals a call to forum_add_instance within forum/lib.php (different activities will have different versions of this function) and forum_update_instance. At the end of the button clicking operation there is then a redirect to a script that shows any changes that have been made.
The code to add a forum to course will be similar (in operation) to the code used to add other activities. What is interesting is that I have uncovered the classes and script files that relate to the user interface forms that are presented to the user.
Adding a new discussion
A new discussion can be added by clicking on the 'Add a new discussion topic' button once you are within a forum. The action of clicking on this button is connected to the forum/post.php script. The most parameter associated to this action is the forum number (forum=7, for example).
It's important to note the use of the class mod_frum_post_form contained within post_form.php which represents the structure of the form that the user enters discussion information to.
The code checks the forum id and then finds out which course it relates to. It then creates the form class (followed by some further magic code that I quickly stepped through).
The action of clicking on the 'post to forum' button appears to send a post back (along with all of the contents of the form) to post.php (the same script used to create the form). When this occurs, a message is displayed and then a redirect occurs to the forum view summary. But where in the code is the database updated? One way to do this is to begin with a search to the redirect. Whilst browsing through the code I stumble across a comment that says 'adding a new discussion'. The database appears to be updated through a call to forum_add_discussion.
Posting a reply to a discussion
The post.php script is also used to save replies to discussions (as well as adding new discussions) to the database. When a user clicks on a discussion (from a list of discussions created by discuss.php), the link to send replies are represented by calls to post.php with a reply parameter (along with a post number, i.e. post.php?reply=4). The action of clicking on this link presents the previous message, along with the form where the user can enter a response.
To learn more about how this code works, I browse through the forums lib file and uncover a function called forum_add_new_post. I then search for this in post.php and discover a portion of code that handles the postback from the HTML form. I don't explore any further having learnt (quite roughly) where various pieces of code magic seems to lie.
The post.php script does loads of stuff. It weighs in at around seven hundred lines in length and contains some huge conditional statements.
Not only does post appear to manage the adding of new discussions to a forum but it also appears to manage the adding, editing and deletion of forum messages. To learn about how this script is structured I haven't been able to look at function definitions (because it doesn't contain any) but instead I have had to read comments. Comments, it has been said, can lie, whereas code always tells the truth. More functions would have helped me to more quickly learn the structure of the post.php script.
The creation of the user interfaces is partially delegated to the mod and post form classes. Database updates are performed through the forum/lib.php file. I like some of the function abstractions that are beginning to emerge but any programming file that contains both HTML and SQL indicates there is more work to be done. The reason for this aesthetic (and person) opinion is simple: keeping these two types of code separate has the potential to help developers to become quickly familiar where certain types of software actions are performed. This, in turn, has the potential to save developer time.
One of the central areas of functionality that forum developers need to understand is how Moodle works and uses forms. This remains an area of mystery to me, and one that I hope to continue to learn about. Another area that I might explore is how PHP has been used to implement different forum systems so I can begin to get a sense of how PHP is written by different groups of developers.
Acknowledgements: Photograph licenced under creative commons by ciaron, liberated from Flickr.