Forums | Mahara Community

Developers /
How Mahara database and file system works


anonymous profile picture
Deleted user
Posts: 19

20 June 2013, 10:00 AM

I am trying to customize mahara and develop some custom forms and retireve this information. I have found out how to present the information in the .tpl forms which are called by the .php files.

Can someone explain how information is saved to the database and file system (mahara data folder) and how these are retrieved. For instance, when I use the .tpl files and ask users to fill out a form, how is this saved to the database and how do I know what to save to the database and what to save to the mahara data folder? (What files and folders are used by mahara to achieve this?)

Also how do I retrieve from both the database and data folder?

In  normal php script I would set up a string to connect to the database and then use the query string to send sql queries to the database and then I would close the connection. I do not see any files opening the connection to the database or in the case of the file system, I dont see this happening.

Can someone explain how these work in mahara or point me to the information on these. I have searched the wiki and not enough information on these are available.

Thanks in advance.

Desperate Mahara developer Cry

 

Aaron Wells's profile picture
Posts: 896

20 June 2013, 2:59 PM

Hi Delvon,

Yeah, the Mahara wiki could use a thorough clean-up. The developer's documentation is all over the place, and in most cases it's easier to just look at the code in an existing page that does something similar to what you want.

We use the dwoo template engine to display pages, which is what thoes .tpl files are. Dwoo is a fork of Smarty, so you'll see that mentioned in the code a lot of places as well.

For forms, we use a form library called Pieforms, which was written specifically for Mahara.

When I was first getting up to speed on Mahara, I put together this sample page showing how to use dwoo and Pieforms: https://wiki.mahara.org/index.php/BasicPHPFileTemplates#Sample_page_using_pieforms_and_dwoo

The connection to the database is opened in the "init.php" file which must be included at the top of each Mahara PHP script, and stored in a global variable for internal use. The way you access the database is through the functions defined in lib/dml.php; primarily insert_record(), update_record(), delete_record(), and all the variants of select_record().

As for storing files into the $cfg->dataroot directory and retrieving them... well, that's a bit tricky. Most of the code is in artefact/file/lib.php (because user-uploaded files are stored as File artefacts), and there's a pieforms "filebrowser" element (under artefact/file/form/elements/filebrowser.php) to pick files, but in practice it requires a bit of massaging to get it to work on new pages. I'd recommend checking out the code for blog post attachments, under artefact/blog/post.php

Cheers,Aaron

anonymous profile picture
Deleted user
Posts: 19

22 June 2013, 2:23 AM

Thanks very much Aaron, this will help me a long way. One other specific is how I would add additional fields to the database. For instance, if I want to add an additional field to the users table in the database, how would I do that and what other dependencies in Mahara for me to get this working.

Would I then also add an additional funtion to the dml.php file?

Delvon

Aaron Wells's profile picture
Posts: 896

24 June 2013, 11:53 PM

Well, if you're just hacking your own Mahara site, the easiest way to add columns to a table in the database is to just run an "ALTER TABLE usr ADD COLUMN ..." SQL query in your database, using the command-line psql/mysql utility, or phpMyAdmin or what have you. Check out the postgres or mysql manuals for syntax details.

The fancy Mahara API way to do it, which will cause the column to be added via the "upgrade" page in your Mahara site, is basically a port of the DB install/upgrade API from Moodle 1.9. Mahara, as you may know, is architected to be extremely "pluggable"; most of the functionality is written into "plugins". Each plugin has its own DB install and upgrade script. To take the artefact/blog plugin for example, the salient files are:

  • artefact/blog/db/install.xml: This is an XMLDB file, which contains an XML description of all the tables that should be created for this plugin. It is evaluated when the plugin is first installed, but is ignored after that.
  • artefact/blog/version.php: This PHP script defines a $config->version variable which tells Mahara what version of the plugin it is. The value in this file is stored in the artefact_installed.version column in the database. When you go to the site admin page, it compares the version number for this plugin in the database, to the version number in version.php. If the version number in version.php is higher, it means the plugin's code has been updated, and it'll need to run the upgrade script for that plugin.
  • artefact/blog/db/upgrade.php: This is the DB upgrade script for the plugin. You'll note it has a single function, xmldb_artefact_blog_upgrade($oldversion), which contains a series of "if" blocks. When you update the plugin's version.php, you also add an "if" block to upgrade.php, and Mahara will run the contents of that if block.

Within db/upgrade.php, you can add/alter tables and columns using the generic function "execute_sql()" to execute an arbitrary SQL statement, or you can use the XMLDB table/field classes and the functions in lib/ddl.php. You can see examples of both in artefact/blog/db/upgrade.php.

Now, the "usr" table is kind of a special case. It's a "core" table, so rather than belonging to a plugin it is stored in the core install.xml file, lib/db/install.xml. Probably what I would do is update the "usr" table in lib/db/install.xml, and then add an update section to local/upgrade.php. The "local" directory is a special all-purpose plugin specifically to handle local hacks that don't fit neatly into any of the other plugin types.

As for how you would then access the new column, it would still be through calls to the "get_records" functions. By default the get_records() functions retrieve all the columns in the table it's querying. You can optionally provide a list of specific columns to fetch; in such cases you would need to add your column to the list.

Depending on how you actually want to use this new usr table column, it might also make sense to create a new Profile artefact type (like, if you want this to show up on a user's profile). That'd be under artefact/internal/lib.php

Cheers,
Aaron

anonymous profile picture
Deleted user
Posts: 19

25 June 2013, 3:39 AM

This is excellent information Aaron. Thank you very much.

anonymous profile picture
Deleted user
Posts: 19

26 June 2013, 11:03 AM

I have tried using only a small amount of fields from the create user option but the records are not been added to the database and I get no errors. What I did was just to remove some of the elements from the pieform template (theme/raw/pieforms/adduser.php).

Below is my elements that are left from in my adduser.php of the standard 1.7 version:

<?php
echo $form_tag;
?>

<table id="adduser-t">
    
   <table>
<?php foreach (array('firstname', 'lastname') as $field) { ?>
                    <tr>
                        <th><?php echo $elements[$field]['labelhtml']; ?></th>
                        <td><?php echo $elements[$field]['html']; ?></td>
                    </tr>
<?php if ($elements[$field]['error']) { ?>
                    <tr>
                        <td class="errmsg" colspan="2"><?php echo $elements[$field]['error']; ?></td>
                    </tr>
<?php } ?>
<?php } ?>
                </table>

                
            </td>
            <td class="filler">&raquo;</td>
            <td class="step step2">
                <table>
<?php foreach(array('username', 'password') as $field) { ?>
                    <tr>
                        <th><?php echo $elements[$field]['labelhtml']; ?></th>
                        <td><?php echo $elements[$field]['html']; ?></td>
                    </tr>
<?php if (isset($elements[$field]['error'])) { ?>
                    <tr>
                        <td class="errmsg" colspan="2"><?php echo $elements[$field]['error']; ?></td>
                    </tr>
<?php } ?>
<?php } ?>
                </table>
            </td>
            <td class="filler">&raquo;</td>
            <td class="step step3">
<?php echo $elements['submit']['html']; ?>
            </td>
        </tr>
    </tbody>
</table>
<?php
echo '</form>';
?>

I am wondering if the fields with required rules have to be included like email? I setup a string for a default email and added that in the email array element in hte /admin/user/add.php file.

Is there other things that need to be considered for the account to be created? I only wanted the firstname, surname, username and password and wanted to keep the other fields as their defaults.  Do I need to have an authentication method?

 

Regards,

Delvon

Aaron Wells's profile picture
Posts: 896

27 June 2013, 1:56 PM

Well, I haven't worked on adduser.php before, but by searching for occurrences of "adduser.php", I see that it's only used in admin/users/add.php. If you look at the pieform that is instantiated there, its name is "adduser" and no specific validation or submission function name is supplied, so it will use the default naming patterns and call the validation function "adduser_validate()" and the submission function "adduser_submit()", which are also defined in admin/users/add.php .

If you look towards the end of adduser_validate(), it does indeed require that firstname, lastname, and email are filled in. So, you'll want to edit that function, and probably also adduser_submit().

Cheers,
Aaron

anonymous profile picture
Deleted user
Posts: 1

07 July 2013, 1:38 PM

@Aaron That was informative. I was wondering if we can create a separate tab to menu for a custom page (mostly forms ) and store / retrive from database . Do I have to used the file strucutre and how to create new tables in db in that case. 

Aaron Wells's profile picture
Posts: 896

15 July 2013, 5:29 PM

Hi esha,

Sorry for the slow reply.

I'm not entirely clear what you're asking. If you want to know how to create new tables in the database, take a look at my earlier post: https://mahara.org/interaction/forum/topic.php?id=5515&offset=0&limit=10#post23753

Basically:

1. You add the table to the appropriate "install.xml" file (either under one of the plugins, or under local/db/install.xml). This will cause it to be installed on a new Mahara installation (or newly installing the plugin).

2. You add code to generate the table, into the appopriate db/upgrade.php file (the one in the same directory as the install.xml file you updated). Also update the version.php file for the plugin or local. This will cause the table to be created as an upgrade to existing Mahara sites. The code for how to do this is mostly in htdocs/lib/ddl.php. It's based on Moodle 1.9's DDL functions: http://docs.moodle.org/dev/DDL_functions_-_pre_2.0

This could all use some better documentation in the wiki, it's true.

Cheers,
Aaron

9 results