Developer documentation
From EFrontWiki
This will be the developer manual. Please add chapters as you see fit. You can also check the extensive eFront code documentation at http://wiki.efrontlearning.net/API/index.html
[edit] Directory structure
eFront's directory structure consists of 4 main folders:
1. eFront/www/ 2. eFront/libraries/ 3. eFront/upload/ 4. eFront/backups
These folders, along with the most important of their subfolders, are presented in the following chapters.
[edit] www/
This is the system's document root, that is, anything that lies within this directory is accessible through the web. Typically, php files that need to be user-accessible are put here. These files usually correspond to user actions. In addition, this folder contains non-php files, such as Images and Javascripts. Below is explained the use of each of its subfolders:
a. www/install/
The installation folder. This folder must not be present in running efront installations. For development purposes only, it is renamed to _install. In normal mode, it should be renamed to install, in order for the installation to start up automatically.
b. www/charts_library/
c. www/chat/
The chat folder contains all the files needed for the chat to be accessible and functional
d. www/content/
The content folder is used mainly for holding the lessons folder. The www/content/lessons folders contains one folder per lesson, named after its id. For example, a lesson with id 15 has a corresponding www/content/lessons/15 folder, where every uploaded file resides. Furthermore, the content folder hosts the admin folder, used by the administrator to upload files such as CMS. Finally, there may be created a "scorm_data" folder which is used as temporary decompression folder when uploading SCORM files. Temporary files may also be created inside www/content during other situations, such as importing/exporting lessons.
This folder MUST be writable, including its subfolders.
e. www/css/
This folder contains the CSS file used to the system, as well as the custom_css/ folder. The css/custom_css/ folder is where the administrator may upload custom CSS files, so this folder must be writable
g. www/editor/
The editor folder contains all the files necessary for the javascript WYSIWYG editor to function properly.
h. www/forum/
This folder contains the php files tha provide the forum and personal messages functionality
i. www/images/
The images folder contains all the images used to the system. The images are organised to subfolders based on their size (i.e. 32x32) or their scope (i.e. drag-drop-tree). The images/avatars/ folder holds the user avatars, so this folder must be writable. Furthermore, the logo.png file may be changed by the administrator, so the images/ folder itself must be writable (but except for avatars, not its subfolders)
j. www/js/
This folder holds the javascript files. For a complete explanation of its uses, see the corresponding chapter
k. www/modules/
This folder is where new modules are uploaded and decompressed.
l. www/tools/
The tools folder contains several development-oriented tools. This folder should not be part of an official eFront distribution, so it must be removed prior to packaging
[edit] libraries/
This is the main php tools folder. It contains all php (and more) files that mustn't or shouldn't be accessible through the web
[edit] upload/
This folder is used mainly for user-uploaded files, such as message attachments, projects, etc and is not accessible through the web for security reasons.
[edit] backup/
This is where the system backups are stored.
[edit] Architecture outline
[edit] Database
[edit] File system
eFront users upload and use files in regular basis. We need to be able to manipulate efficiently these files, attach metadata to them and address multilinguality issues. For these reasons, a custom file handling infrastructure is implemented.
When a file is uploaded, a corresponding database entry is created. Afterwards, the newly uploaded file is given this entry's id as name, and the string 'efront' is appended to the end of it. For example, if the file 'example.doc' is uploaded, it actually becomes: '21.doc.efront' (where 21 is the database entry id for this file). The same stands for folders, that is, if we create a folder with name 'test_folder', then a folder with name (i.e.) '43/' will be created in the file system.
All the functions needed to manipulate the files in the filesystem are provided from the filesystem.class.php. For more information and examples on the use of this class, please refer to its phpdoc documentation
In order to view or download the files, we may use the files view_file.php and downloadfile.php
[edit] Basic Entities
[edit] Class eF_Configuration
The eF_Configuration static class is used to retrieve configuration values from the database. These values may be changed by the
administrator and specify many aspects of the system behaviour. The class is called at the start of each script call, so that all variables
are made available trhough the $configuration or the $GLOBALS['configuration'] variable.
For example: $configuration['default_language'] is the system default language. So, there is never the need to query directly the 'configuration' database table.
In order to set a new configuration value, the developer needs only to add the variable name/default value pair to the configuration.class.php
file, as a member of the static $default_options array. The class will automatically update the database with the new variable at the next script execution.
See the class documentation for more info
[edit] Multilinguality and Unicode
[edit] HTML Forms
[edit] Pop ups
[edit] Ajax
[edit] Ajax and SortedTable
In order to ajax-enable a sortedTable, some minor conversions need to take place, both at the php and the template file. Let's take a look at them, using an example. Supposingly we need to ajax-enable a sortedTable containing users. What we already have is the data source at the PHP file and the data display, at the TPL file (i.e. file.php and file.tpl):
PHP file:
<code>
$users = eF_getTableData("users", "login,name,surname,languages_NAME");<br/>
$smarty -> assign("T_USERS", $users);
</code>
TPL file:
<code>
<table class = "sortedTable">
<tr class = "topTitle">
<td class = "topTitle">Login</td>
<td class = "topTitle">Name</td>
<td class = "topTitle">Surname</td>
<td class = "topTitle">Language</td>
</tr>
{foreach name = 'users_list' item = 'item' key = 'key' from = $T_USERS}
<tr class = "{cycle values = "oddRowColor, evenRowColor"}">
<td>{$item.login}</td>
<td>{$item.name}</td>
<td>{$item.surname}</td>
<td>{$item.languages_NAME}</td>
</tr>
{/foreach}
</table>
</code>
In order to ajax-enable the above table, the following steps must be followed:
A. In PHP file:
Create a separate if clause, for the ajax case, where the sorting and data handling requested will be taking place. for the above example:
<code>
$load_scripts = array_merge($load_scripts, array('scriptaculous/prototype'));
if (isset($_GET['ajax'])) {
isset($_GET['limit']) ? $limit = $_GET['limit'] : $limit = 20;
$users = eF_getTableData("users", "login, name, surname, languages_NAME");
$smarty -> assign("T_USERS_SIZE", sizeof($users));
if (isset($_GET['sort'])) {
isset($_GET['order']) ? $order = $_GET['order'] : $order = 'asc';
$users = eF_multiSort($users, $_GET['sort'], $order);
}
if (isset($_GET['filter'])) {
$users = eF_filterData($users, $_GET['filter']);
}
$smarty -> assign("T_USERS_SIZE", sizeof($users));
if (isset($_GET['limit']) && eF_checkParameter($_GET['limit'], 'int')) {
isset($_GET['offset']) && eF_checkParameter($_GET['offset'], 'int') ? $offset = $_GET['offset'] : $offset = 0;
$users = array_slice($users, $offset, $_GET['limit']);
}
$smarty -> assign("T_USERS", $users);
$smarty -> display('test.tpl');
exit;
} else {
$users = eF_getTableData("users", "login,name,surname,languages_NAME", "", "login limit 10");
$smarty -> assign("T_USERS", $users);
}
</code>
B. In tpl file:
1. Insert extra attributes to the table tag: size, userAjax, url, id. The "url" must contain the query qttribute, "?" or "&" at the end. Pay attention to put the full url needed to access the ajax source, for example, administrator.php?ctg=users&
2. Append special tags before and after the table tag, using the same name as the table id
3. Each header td MUST have a name, matching the name of the database result data column
<code>
<!--ajax:usersTable-->
<table class = "sortedTable" size = {$T_USERS_SIZE} sortBy = "0" id = "usersTable" useAjax = "1" rowsPerPage = "10" url = "test.php?">
<tr class = "topTitle">
<td name = "login" class = "topTitle">Login</td>
<td name = "name" class = "topTitle">Name</td>
<td name = "surname" class = "topTitle">Surname</td>
<td name = "languages_NAME" class = "topTitle">Language</td>
</tr>
{foreach name = 'users_list' item = 'item' key = 'key' from = $T_USERS}
<tr class = "{cycle values = "oddRowColor, evenRowColor"}">
<td>{$item.login}</td>
<td>{$item.name}</td>
<td>{$item.surname}</td>
<td>{$item.languages_NAME}</td>
</tr>
{/foreach}
</table>
<!--/ajax:usersTable-->
</code>
[edit] Content tree
[edit] Smarty templates
[edit] WYSIWYG editor
[edit] Javascripts
[edit] SCORM
[edit] Modules
Modules are a powerful yet simple way to create new or enhance existing eFront functionalities. They may incur database changes, relate to any user role, be stand-alone or lesson specific, use eFront libraries and generally make use of every available resource to provide the desired functionality.
A detailed manual with a step-by-step guide and example on how to create new eFront module is available here.
[edit] System and browser compatibility
[edit] Handling Internet Explorer 6's PNG incompatibility
One of IE6's major drawbacksis that it cannot properly display transparent pngs. In order to overcome this inconvenience in eFront, a second set of images was imported, which is a transparent GIF version of the originals.
This set of images comes in only when the user's browser is IE6. The browser version is derived through the $_SERVER['HTTP_USER_AGENT'] variable. In this case, we apply a smarty output filter that converts all .png extensions to .gif (but only if the equivalent gif file really exists).
So, in order to have the pages display correctly in IE6, one has only to provide the equivalent gif image of the original png he intended to use, with the same name and in the same place.
The only pitfall in the above procedure lies when using external Javascripts which display images. Since these files are not rendered through smarty, the filter is not applied. The workaround is to replace extension 'png' with the keyword 'globalImageExtension'. This is a global Javascript variable that holds either 'gif' or 'png' depending on the current setting. So, for example, 'book.png' should become 'book.'+globalImageExtension

