Server-Side Coding

XML Structure

The core of any module in iQDesk Engine v.2.0 is a main XML file in the root folder of the module. As we explained in the Overview section it contains of different important definitions which describes how does your module will be presented in the system, such as: Module title, its description, author identification, version data and etc. So seems like it's good time to take a look into the main XML file structure.

General structure of XML file

<?xml version="1.0" encoding="UTF-8"?> <module> <title>Module title</title> <name>module_system_name</name> <description>Module description</description> <version>Module version</version> <author>Module author</author> <dependencies> <dependedOnModule>depended_on_module_name</dependedOnModule> </dependencies> <primaryNavigationItem> <section>primary_navigation_section</section> <action>primary_navigation_action</action> </primaryNavigationItem> <sections> <section> <title>Section title</title> <name>section_system_name</name> <description>Section description</description> <actions> <action> <title>Action title</title> <name>action_system_name</name> </action> </actions> </section> </sections> </module>

<module> (required) node is the root container for all options, which present your module in the system. Following is detailed description for each possible child node.

<title> (required) node determines the public title of the module. In this node you can set up title only for one language but anyway you still have ability to manipulate the public title of the module via language file (see Language Library & Translation chapter for more details).

<name> (required) node determines the system name of the module. Should be unique and have only lowercase letters. This name will match the folder name of your module, so please use only allowed chars for the folder name in your operating system. If you're going to sell your module online, please use only "_" and "-" chars.

<description> (not required) node determines the public description of the module. In this node you can set up description only for one language but anyway you still have ability to manipulate the public description of the module via language file (see Language Library & Translation chapter for more details).

<version> (required) node determines the system version of the module. Allowed two-digits version format XX.YY. If you're going to sell your module, you should be careful with this value, because the users will get updates of your module only based on the version you will put here. Bigger value of YY means newer version. Bigger value of XX - means cardinally new version. If you're going to sell your module, you should start the versioning from 1.0.

<author> (not required) node determines the author of the module. Put your name or your company name here. It's not required node, but to be sure the people will know you, please don't miss this node.

<dependencies> (not required) node determines the relation with other modules, which are required for installing your module. As iQDesk Engine v.2.0 built so to be simple extendable, we did it so you can use some functionality of other modules. Right in this node, you set up child nodes which determines modules which are required by your module. Can have unlimited child nodes.

<dependedOnModule> (not required) node determines the related module, which should be installed in the system, if the user will want to install your module. Put here the system name of the required module. Complete list of all public modules is available on the project's website.
If required module will not be found in system, your module will be installed, but it will not be enabled. Once user will try to enable your module manually, the system will prevent this action and module will be stay disabled. The user will be able to enable it only all required modules are installed on the system.

<primaryNavigationItem> (required) node determines the section and action which will called once the user will click on the link of your module in navigation bar. This node required 2 child nodes called section and action. Be careful, if you miss one of the child nodes, the link in navigation bar will will work wrong.

<section> (required) node determines the controller which will be called once the user will click the link of your module in navigation bar. Should have lowercase letters and numbers and should match the one of your controllers. In the case if value of this node is not matched to no one of your controllers, error will happen.

<action> (required) node determines the action of controller which will be called once the user will click the link of your module in navigation bar. Should have lowercase letters and numbers and should match the one of the actions in controller, which set up in <section> node. In the case if value of this node is not matched to no one of the actions of specified controller, error will happen.

<sections> (required) node enumerates the presented controllers in your module. This node can have unlimited number of child nodes, every direct child node should be <section>. Be careful, this node should contains at least one child node.

<section> (required) node determines one controller in your module. This node is container for the controller's options. Can have only following child nodes: <title>, <name>, <description> and <actions>.

<title> (required) node determines the controller public title. In this node you can set up title only for one language but anyway you still have ability to manipulate the public title of the controller via language file (see Language Library & Translation chapter for more details).

<name> (required) node determines the controller system name. Should be unique for your module and have only lowercase letters and numbers, should match the class name of specified controller. This name should also match the file name of specified controller, so please use only allowed chars for the file names in your operating system. If you're going to sell your module online, please use only "_" and "-" chars.

<description> (not required) node determines the public description of the specified controller. In this node you can set up description only for one language but anyway you still have ability to manipulate the public description of the controller via language file (see Language Library & Translation chapter for more details).

<actions> (required) node enumerates the presented actions of specified controller. This node can have unlimited number of child nodes, every direct child node should be <action>. Be careful, this node should contains at least one child node.

<action> (required) node determines one action of specified controller. This node is container for the action's options. Can have only following child nodes: <title>, <name>.

<title> (required) node determines the action public title. In this node you can set up title only for one language but anyway you still have ability to manipulate the public title of the action via language file (see Language Library & Translation chapter for more details).

<name> (required) node determines the action system name. Should be unique for the specified controller and have only lowercase letters and numbers, should match the function name of specified controller and exactly for this reason it can have only one additional char which is "_".

Controller

Placing & Naming

As you remember, in the Overview we explained the structure of module files, and all controllers files should be placed directly in the "controllers" folder of your module. No sub-folders needed.
The file name of your controller file should be in format [controller_name].php, the [controller_name] should be lowercase, and should match with specified section in the main XML file and should match with specified class name of controller.

Controller Structure

Every controller in iQDesk Engine v.2.0 is presented as typical CodeIgniter controller, and should extend the predefined MX_Controller class. As long your controller is based on the original CodeIgniter class, so you can find a lot of related documentation on the official CodeIgniter documentation website. In this section we will just take a look on the specific things, which is important during developing modules for iQDesk Engine v.2.0.

Firstly we would like to attract your attention on the public properties of MX_Controller class, which being used through the system:

public $check_permissions; is a boolean property, which defines the behavior of the system during initiation controller action. iQDesk Engine v.2.0 is a roles based system, so it requires to check access current user to every action he would like to call. Each time when the system calls the controller's action, it firstly checks user's permissions to access the controller actions. Exactly this property controls, will the actions of this controller be checked for access or not. If value of this property is TRUE - every calling action will be checked for access, using built-in ACL library. If value is FALSE - no one action of controller will not be checked for access by current user.

public $view_data; is an array property, contains the data which will be transmitted to the views. Once your controller start any action, this property already has one predefined empty element with key page_title. The value of this element being used for displaying on the tab title. Don't miss this element to fill in to make your tabs looks good. All other elements of this property is user defined, and you can name them as you wish.

Now let's take a look into the controller file structure.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); //first what we do is to check is it direct accessing the PHP script or not. If it's, then prevent any following actions class [controller_name] extends MX_Controller { public $check_permissions=true; //set TRUE or FALSE if you want or don't want to check user access to this controller public function [action_name](){ $this->view_data['page_title']=[Section tab title]; //set the page title related to this Section/Action $this->load->model('[model_name]'); //load the model related to the data, which you would like to use for process //prepare here all statements to get filtration and pagination parameters, if it's needed $this->view_data['items']=$this->[model_name]->[model_function]; //retrive the data, which you would like to process //basing on the given filtration and pagination parameters //in this place we usually place the function which takes total count //of all records the data we would like to process and attach it to Pagination Library //read more about paginating in Pagination Library chapter //in this place we usually place the function which register //sidebar for displaying on the view //read more about sidebar in Sidebar Library chapter $this->load->view('[path_to_header]',$this->view_data); $this->load->view('[path_to_view]',$this->view_data); $this->load->view('[path_to_footer]',$this->view_data); } } ?>

Let's take a look on the highlighted definitions:

[controller_name] is a section name you specified in main XML file. No matter if it will be lowercase or not. This name should match the file name of this controller.

$check_permissions=true; Using this definition, we tells the system to force access checking during access this controller. If you would like to not check the access to this controller, you can set FALSE.

[action_name] is an action name you specified in main XML file for this controller. No matter if it will be lowercase or not. Make sure, this name is not match any PHP predefined function's names.

$this->view_data['page_title']=[Section tab title]; Using this definition, we set the page tab title for the opened Section/Action. You can skip definition, if this action is going be processed by AJAX, because in this case you shouldn't to set up any page tab title.

[model_name] - is the name of the model you want to use on this step. The model name definition should match the class definition in the model file. Read more about models naming in the Model chapter.

Important!

If you're going to load the model of current module, then you need just to specify the class name of needed model. But in other case, if you're going to load model of other module, then you should to specify this model in following format [module_name]/[model_name]. [module_name] - is a lowercase, system name of module, which you would like to use.


[model_function] - is the name of the model's function you would like to call on this step. Read more about models and its functions in Model chapter.

[path_to_header] - defines the path to the header view, which should contain the doctype definition, page tab title, linked stylesheets, JavaScript libraries, Navigation and etc. iQDesk Engine v.2.0 has built in header view, which could be specified in [path_to_header] as general/header.

[path_to_view] - defines the path to the main view, which you would like to use to displaying your data. The root folder for this path is "views" folder of your module. For example, needed view file is placed in "views/listing/index.php", then you should to specify [path_to_view] as listing/index. The best way to prevent any problems with case-sensitive in names of views is to use the lowercase in file names and in paths to this files.

[path_to_footer] - defines the path to the footer view, which should contain the closing of all opened tags, language selection and etc. iQDesk Engine v.2.0 has built in footer view, which could be specified in [path_to_footer] as general/footer.

Important!

If you're going to process the action via AJAX, you no need to load the header and footer views.


Of course, it's a simple one example of controller file, but it gives enough information about how to write the actions. If you still have some questions regarding structure and functions calling in controller, please check the official CodeIgniter documentation about controllers.

Model

Placing & Naming

From the Overview section of this manual, you know that all the models files should be placed into the "model" folder, no need any sub-folders.
The file name of your model should be in format [model_name].php, the [model_name] should be lowercase, and should match with specified class name of the model.

Model Structure

The model files are presented in iQDesk Engine v.2.0 in the same format and structure as model files for CodeIgniter framework. So the base knowledges about the models you can find on the official documentation website. Let's see into the simple example of the model file:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); //first what we do is to check is it direct accessing the PHP script or not. If it's, then prevent any following actions class [model_name] extends CI_Model { function __construct() { parent::__construct(); //we're going to reload constructor of the class, then we should make sure, that parent constructor is called $this->load->database(); //coders like to switch off the autoloading option in database configuration file, then we should make sure, //that database will be loaded //here you can put your own definitions of class constructor } //start here with the model functions } ?>

As you can see the structure of model file is pretty simple, all what you need is to define the class name of your controller which should extends the CI_Model class, define constructor and write specific functions which will process the data related to this model.

In module structure is a one definition you should pay attention:

[model_name] is a class name of your model. No matter if it will be lowercase or not. This name should match the file name of your model.

Rules

If you're going to sell your module online, you should follow few simple rules for writing the model file:

  1. All the function names should be user-friendly named.
  2. Good practice for models which operates with the listing data from database is to have in module few typical functions, which provides the quick understanding your code. These functions are:

    getItems($filtration_parameters,$sorting_parameters,$pagination_parameters) - should return the list of records from database, based on the input data.

    getItem($item_id) - should return the single object of found record from database, based on the input parameter $item_id. Also should return FALSE in the case if record not found in the database.

    create($data) - should insert new record into the database, and return the boolean result of the operation.

    update($item_id,$data) - should update the record in database. Updating should be based on given $item_id and updated data in $data. In the end of the function, should be returned boolean result of the operation.

    delete($item_id) - should delete the record from database, based on $item_id and return the boolean result of the deleting operation.

  3. Retrieving all the input data transmitted via $_GET should be processed by function $this->input->get(). The default library "input" is auto-loaded in the system. More details about the function "get" of the library "input" you can find in the official documentation for CodeIgniter Framework.
  4. Retrieving all the input data transmitted via $_POST should be processed by function $this->input->post(). More details about the function "post" of the library "input" you can find in the official documentation for CodeIgniter Framework.

Filtration in Model through Controller

iQDesk Engine v.2.0 being distributed with built in Sidebar library. This library helps you to quick organize filtration form on the listing view. It has few specific methods and public properties to work with your data, more detailed about this library you can read in the "Sidebar Library" chapter of this section. But right now we would like to attract your attention exactly on the process of filtering data inside the model file through appropriate controller. Ok, let's take a quick look on the simple part of the function of controller, which collects the filtration parameters.

$params=array(); //define default empty array of filtration parameters $get=$this->input->get(NULL, TRUE, TRUE); //retrive $_GET data if (isset($get['apply_filters']) && isset($get['filter'])) { //if filter parameters were passed $params=$get['filter']; //store them into the local variable }

Now we should to pass the given filtration parameters into the model's function. Let's imagine, the function parameter, which takes the filtration data in model called "$params". Below is what we should put into the model function. All the given filtration parameters should be checked and applied, if they satisfy the condition of correct value.

if (isset($params['[filter_paramater_name]'])) { //check if specific filter parameter was passed, which we're interesting in if ([condition_of_correctly_value]) { //if paased filter parameter value is correct $this->db->where("[table_field]",$params['[filter_paramater_name]']); //set "where" clause according obtained filter parameter } }

As you can see, they primary idea of this approach is based on getting filter data, checking this data to make sure it's correct, and putting "where" clause in database query statement according given data. Pretty simple, no?
Let's take a look on the interesting highlighted expressions in the examples above:

$get['apply_filters'] and $get['filter'], they are the fields, which generates automatically by the filtration form, built with Sidebar library, on submitting. apply_filters is the "name" attribute of the submit button, and for us it serves only for one reason is to check that query has come from the filtration form and not from somewhere else. Element filter of $_GET contains the filtration data from the from.

[filter_paramater_name] is the key of element of the filtration data array, which passed from the filtration form. It's user defined key. More details about naming keys of the filtration data you can find in "Sidebar Library" chapter of this section.

[condition_of_correctly_value] is the condition of additional checking of input filter parameter. Over here you can check value for only the numbers, or only the positive number, or only strings and etc. So, fell free to remove it if you're not need in this, but by our opinion, it's a good way to prevent processing wrong filter values.

[table_field] is the real name of the field in your table, which you would like to use fo filtration with current filter value. where() is the default public function of the Database library of CodeIgniter framework. It has different number of input parameters for this function, to lear more please visit the official CodeIgniter documentation.

Sorting in Model through Controller

One of the interesting feature of iQDesk Engine v.2.0 is the built in JS event, which helps you to create sortable lists. It hooks the clicking on the field headings and sends request to refresh the page with parameters, which contain the field, which name you want to sort, and direction of sorting. We'll back to the handling this event in the chapter "Sorting Tables" of the section "JS Implementing". For now we're interested in the processing passed parameters in model file, but before we should catch these parameters in appropriate controller file. Below is a simple example of how it could look.

$get=$this->input->get(NULL, TRUE, TRUE); //retrive $_GET data $sorting=array(); //define empty array for future sorting parameters if (isset($get['sort-column']) && @$get['sort-column']!="") { //if passed $_GET array contains the key "sort-column" and value of this element is not empty string $sorting['sort-column']=$get['sort-column']; //assign received value to appropriate element in sorting array $sorting['sort-direction']="asc"; //define default direction of sorting if (isset($get['sort-direction'])) { //if passed $_GET array contains the key "sort-direction" if (strtolower($get['sort-direction'])=="asc" || strtolower($get['sort-direction'])=="desc") { //if passed direction value matchs "asc" or "desc" only $sorting['sort-direction']=$get['sort-direction']; //assign received value to appropriate element in sorting array } } }

Next step is to pass completed $sorting array to model's function. Let's imagine, the argument of model's function, which passes the sorting parameters, has name "$sorting". Now let's see what we do in model.

if (isset($sorting['sort-column']) && isset($sorting['sort-direction'])) { //if sorting parameters contain needed keys $this->db->order_by($sorting['sort-column'],$sorting['sort-direction']); //setup Order by statement in query, according the given parameteres } else { //if there are no incomming sorting parameters $this->db->order_by([default_table_field],[default_direction]); //setup Order by statement in query, according the defaults }

As you can see, the idea of processing sorting is pretty simple: you should get the $_GET array, define default sorting parameters, try to find needed keys in $_GET array and elements in it, if they exist, overwrite default sorting parameters, and in the end just pass completed sorting parameters array to the model's function. Let's see on the specific elements, which defines default sorting parameters and which provides us info, which column user clicked and what is the current direction of sorting.

$get['sort-column'] is the element of $_GET array, which contains the field name on which user clicked. Please, be careful, this value should match the real field name in your database table, because it being directly passed into the database query statement. In case if this value will be different of existing fields in table, it will cause the database error. About how to correctly define value of the $get['sort-column'], you can read in the chapter "Sorting Tables" of the section "JS Implementing".

$get['sort-direction'] is the element of $_GET array, which contains the direction of sorting. It can be "ASC" or "DESC", but you don't need to think how to define these values, because the built in JS event handler, will take care about this. Find more about how it works in the chapter "Sorting Tables" of the section "JS Implementing".

[default_table_field] and [default_direction] are the name of the field of your tabe in database, which you would like to have be sorted in by default and default direction of sorting. Default in this case means when user just opened the listing view of your data, and don't sort any fields. [default_direction] can be "ASC" or "DESC". The function order_by is the public function of the Database library of CodeIgniter framework. To learn more about this function please visit the official CodeIgniter documentation.

Pagination in Model through Controller

iQDesk Engine v.2.0 has the useful buil-tin Pagination library, which helps you to insert the pagination on your listing views. But let's see, how we can define which exactly records we need to get from the database for the current page.

Firstly, what you should to do is to get the current page, right in the controller before calling model's getItems, to pass it into this function.

$get=$this->input->get(NULL, TRUE, TRUE); //retrive $_GET data $page=0; //set default value of the current page 0 if (isset($get['page'])) { //if the parameter "page" was passed by $_GET if (is_numeric($get['page']) && $get['page']>=0) { //if the parameter "page" is numeric value and it's not negative number $page=$get['page']; //define current page } }

In the end of this code, you have the variable called "page", which contains the current displayed page. Now you have to pass it into the model's function getItems. As we told in the rules for writing models, one of the primary model's functions is getItems, which can receive one of the parameter, which defines the current page. So, all what you need is to pass defined $page to this function via according parameter. Let's imagine we get this variable in model, using parameter $page.

$this->db->limit($this->pagination->count_per_page,$page*$this->pagination->count_per_page); //we need only to setup SQL query limits

As you can see nothing difficult is here, all what you need is to get the $_GET['page'], and limit query result. One thing you could pay attention is $this->pagination->count_per_page. It's the predefined public property of the Pagination library, read more about it in the chapter "Pagination Library" of this section. Another important thing is, that you can setup default value for argument $page, for example "-1", and before the SQL limit statement can be concluded into the condition if ($page!=-1). It will help you to get all the records from the database, without creating new model function, all what you will need is to skip the $page parameter in calling this function. It's pretty simple, but very powerful solution, to merge different functions into the one.

Also, one important thing is getting total number of filtrated records, by given filtration parameters. It will be useful, on the step when you will want to define the Pagination library's numbers. Read more about function "setNumbers" of Pagination library, in the chapter "Pagination Library" of this section. So how to get the total number of filtrated records? In fact, it's very simple, just before the limit SQL statement and after all JOINs and WHEREs, put the one line $this->total_count=$this->db->get_total_count();. This will store into public property of model "total_count" total number of filtered records. After that, when you will set up pagination in the controller, you will just get this value by calling $this->[model_name]->total_count.

Important!

Function get_total_count() of built in Database library of CodeIgniter Framework is not documented on the official documentation website, because it's our extended method. This method takes the current complied query (in case of using inside the model function, this query will contain the "select", "join", "where" and other statements), runs it, and calculates the total number of records, which satisfy the "where" statement. This function returns only the positive integer.

Of course, presented method of pagination can be modified by you, for example you can get and define current page in the model functions and etc. You have a lot of ways to realize your own ideas, how it could be more correctly.

Putting Log Records in Model

iQDesk Engine v.2.0 has built in module, called "Log". The primary purpose of this module is to store in the database all the actions what user do. It's pretty important to track the problems in the system. So, your models should contains the calling of functions, which will write the log records. Of course, not every model functions should have this, but there are several which are required to have log writing: create, update and delete. Other functions you should to detect yourself, the rule of detecting is: if the function makes some changes in the database, then it should contains the callings of the write log records functions. Ok let's see, what is the format of calling Log module function, which writes log records.

$this->SystemLog->write($module,$controller,$action,$record_type,$record_description)

Firstly, what we would like to pay attention, that the model SystemLog of Log module is auto-loaded model in iQDesk Engine v.2.0, so you can access this object by $this->SystemLog from every point of your module. Now let's see what the arguments takes the function "write".

  • $module (string) defines the system name of your module. Required parameter.
  • $controller (string) defines the system name of the controller, from which the model function was called. Required parameter.
  • $action (string) defines the system name of the controller's action function, from which the model function was called. Required parameter.
  • $record_type (integer) defines the type of the log record. Required parameter. Can have 3 different values: 1 - "Create" type, 2 - "Update" type, 3 - "Delete" type.
  • $record_description (string) defines the short description of the action, which model just performed. Required parameter.

Function write() of Log module doesn't return any value.

Writing log records is the good one way to give the user ability to track everything what is going in his system, and you have to use it. The log writing in the models is required, if you're going to sell your module online.

View

Placing & Naming

In the Overview section we explained the module files structure, and you remember, that all view files should be placed in the "Views" folder. The file name of your view should be in format [view_name].php, the [view_name] should be lowercase, and should match with specified view file in linked controller. To prevent mixing of different views, for different controllers and for different actions, we advice to follow one simple idea: in "views" folder create a sub-folder with name of your controller, and put in this folder the view file with the same name, as the called action should be displayed. In this case don't forget that you should correctly specify the path for this view, when you try to load it from controller. For example, our controller is "hello", and called action is "world", than if you will follow our advice, you will create sub-folder "hello" in "views" folder, and inside the "hello" sub-folder you will create a view file with name "world.php", then you should load this view from "hello" controller with the function $this->load->view("hello/world"). As you can see this way provides simple reading of code and understanding structure of the files.

If your controller action requires to display some information on the viewport of iQDesk Engine v.2.0, you should to create specific view file exactly for this action. In the system we have 2 main view types: Listing Data View and Form Data View. Listing Data View allows us to displays multiple records from the database, manipulate this data, filter, sort it and etc. Form Data View provides us a control form, which allows to manage single record for the database.

Listing Data View

Let's take a look on the structure of view file, which should display the listing of data taken by your model from the database. To correctly understand below example, imagine, that we passed single variable called "items" to the view. This variable contains the records which we should display.

<section class="content"> //define the main container for the content <div class="content-inner"> //define the internal container which has side margins //and has fixed width for large screens //next step is to define the primary tabs <div class="tabs-wrapper"> <ul class="tabs-list" id="tabs-list"> <li class="active"> <a href="#"> [title_of_your_module] <i class="typcn typcn-info-large" tooltip-text="[description_of_your_module]"></i> </a> </li> //over here you can specify so many tabs as you wish </ul> <script> var _tabs=new Tabs("#tabs-list").bindEvents(); //create the tabs object and bind events on this //read more about Tabs class in chapter "Tabs" of "JS implementing" section </script> <div class="clearfix"></div> </div> <div class="content-header"> //define the main header of your view //now is the time to define main action buttons on your view <a href="[action_url]" class="button big-button primary-button"> <i class="typcn typcn-plus"></i> [title_of_button] </a> //over here you can specify so many action buttons as you wish </div> <div class="content-body"> //define the body of your content, which displays right below the header <?php $this->sidebar->renderSidebar([sidebar_name]); ?> //display the sidebar, which was registered in the controller file //read more about sidebar in "Sidebar Library" chapter of this section <div class="content-action bordered-left-sidebar"> //define the main wrapper of active content <div class="content-action-inner"> //define the internal wrapper of active content <div class="content-action-header xs-static-hide"> //define the current action header box. Now it's empty, but //you can put here everything you want </div> <div class="content-action-subheader"> //define the current action sub-header box. Now it's empty, but //you can put here everything you want </div> //the main part of our view file is the working table, which //displays the listing of our records from the database <table class="work-table" cellpadding="0" cellspacing="0"> <thead> <tr> <th>[column_name_1]</th> <th>[column_name_2]</th> //specify here so many columns as you need </tr> </thead> <tbody> //start iterating of records taken from the database <?php for($i=0;$i<count($items);$i++) { ?> <tr> <td>[row_$i_column_1]</td> //specify here so many columns to display as you defined in <thead> //the last column should contains the icon-buttons, which should provide //user the functions to manage the records <td> <a href="[row_action_url]" class="table-action-button" > <i class="typcn typcn-edit"></i> </a> //specify here so many buttons as you wish </td> </tr> <?php } if (count($items)==0) { //if number of records is zero, let's display some row, which //telling about missed records in the database ?> <tr> <td class="no-records-found-row" colspan="[columns_number]"> [no_records_text] </td> </tr> <?php } ?> </tbody> </table> </div> <div class="clearfix"></div> </div> <div class="clearfix"></div> <div class="content-footer"> //define the content footer //display the pagination action form, using built in Pagination library. //Read more about this library in the "Pagination Library" chapter of this section. <?php $this->pagination->drawPagination(); ?> </div> </div> </div> </section> //make sure, you close all opened tags

[title_of_your_module] defines the title of your module, which will appear on the tab. It can be static text, or can be embed PHP function which gets a translation of the row for the current language. If you're going to sell your module online, you should use translating function. Read more about translation in "Language Library & Translation" chapter of this section.

[description_of_your_module]. Put here a little description of your module, to help user to understand what he is seeing right now on the opened page. It can be static text or translated.

[action_url] defines the url, which will processed when you click this button. It can be some url for adding new record, or some other action which you will want to write in your module.

[title_of_button] displays a title of the action button. Can be static text or translated. Don't forget, for the public modules you should use translation function.

[sidebar_name] is the name of registered sidebar via built in Sidebar library. Read more about sidebars, their initialization and registering in the "Sidebar Library" chapter of this section.

[column_name_1] and [column_name_2] serve to indicate what the data from the database is displayed under this column. Can be a static text or translated. For public modules, please use the translation function.

[row_$i_column_1] displays the data for row [$i] and for related column.

[row_action_url] defines the action url, which will be processed with given record. For example it could be a link for editing page of the record, or deleting.

[columns_number] should contains the number of columns you defined in <thead> tag.

[no_records_text] defines the test, which user see, when your model returns empty result from the database. It can be static or translated text. For public modules, please use the transaltion function.

Form Data View

In fact, this type of view has the same wrappers as the listing data view, but it has not extra controls, like sidebar or pagination. This type of the view, can be used for creating or editing the single records in the database.

<section class="content"> //define the main container for the content <div class="content-inner"> //define the internal container which has side margins //and has fixed width for large screens //next step is to define the primary tabs <div class="tabs-wrapper"> <ul class="tabs-list" id="tabs-list"> <li class="active"> <a href="#"> [title_of_your_module] <i class="typcn typcn-info-large" tooltip-text="[description_of_your_module]"></i> </a> </li> //over here you can specify so many tabs as you wish </ul> <script> var _tabs=new Tabs("#tabs-list").bindEvents(); //create the tabs object and bind events on this //read more about Tabs class in chapter "Tabs" of "JS implementing" section </script> <div class="clearfix"></div> </div> //define the main control form <form method="post" action="[form_action_url]"> <div class="content-header"> //define the main header of your view //now is the time to define main action buttons for the form <button type="submit" class="button big-button primary-button" /> <i class="typcn typcn-plus"></i> [title_of_button] </button> //over here you can specify so many action buttons as you wish </div> <div class="content-body"> //define the body of your content, which displays right below the header <div class="content-action"> //define the main wrapper of active content <div class="content-action-inner"> //define the internal wrapper of active content <div class="column-6 right-offset-10 left-offset-10 box-sized"> //define the left column of your form <br/> <h4 class="inline-form-row align-center">[form_left_column_name]</h4> <div class="inline-form-row"> <div class="column-6"> <label>[field_label_1]</label> </div> <div class="column-6"> <input type="text" name="[field_name_1]" value="" class="full-width" /> </div> <div class="clearfix"></div> </div> //define here so many fields as you wish </div> <div class="column-6 right-offset-10 left-offset-10 box-sized"> //define the left column of your form <br/> <h4 class="inline-form-row align-center">[form_right_column_name]</h4> <div class="inline-form-row"> <div class="column-6"> <label>[field_label_2]</label> </div> <div class="column-6"> <input type="text" name="[field_name_2]" value="" class="full-width" /> </div> <div class="clearfix"></div> </div> //define here so many fields as you wish </div> <div class="clearfix"></div> <br/> </div> <div class="clearfix"></div> </div> </div> <div class="clearfix"></div> <div class="content-footer"> //define the content footer //here you can duplicate the same buttons, which you defined //in header, or put new buttons or leave empty <button type="submit" class="button big-button primary-button" /> <i class="typcn typcn-plus"></i> [title_of_button] </button> </div> </form> </div> </section> //make sure, you close all opened tags

[form_action_url] defines the url which will be processed when form will be submitted. Good way to organize all the actions in your controller is define the same action for displaying the form data view and for processing submitted form, by checking incoming $_POST data.

[title_of_button] displays a title of the form action button, usually in this place should stay the submit button. Can be static text or translated. Don't forget, for the public modules you should use translation function.

[form_left_column_name] and [form_right_column_name] define the heading of the form columns, which displays the main purpose of the fields below. In this example, we decided that the form will be divided into two columns, but in your case it can be one column or multiple columns, it depends on your vision how to manage the record data.

[field_label_1] and [field_label_2] display the labels of fields which you provide to be edited. Can be static or translated text. Don't forget, for the public modules you should use translation function.

[field_name_1] and [field_name_2] are the names of the fields, which you will process later in your model.

Form Data View via Ajax Request

iQDesk Engine v.2.0 has an idea, that no need to redirect user on some other page when he wants to create new record, or edit this record, if there should be filled couple fields. Other words, if the form is small we no need to create new page, much better way in this case is to display this form by Ajax Request. For this purposes, we created a JS class for handling ajax requests and display the response in the modal window. Read more about modal windows in iQDesk Engine v.2.0 in chapter "Modal Windows" of "JS Implementing" section. For now is more interesting the question, how the markup of modal windows should look. Below is presented the structure of modal view.

<form method="post" action="[form_action_url]" class="modal-wrapper column-4"> //define the form of modal window, pay attention on the class //.modal-wrapper - defines that it's a modal wrapper //.column-4 - defines the relative width of the modal window <div class="modal-header"> //define the header of modal window [title_of_modal_window] </div> <div class="modal-content"> //define the modal window content box //below is going definition of all fields, which you want //to collect from this form <div class="inline-form-row"> <div class="column-6"> <label>[field_label]</label> </div> <div class="column-6"> <input type="text" name="[field_name]" value="" class="full-width" /> </div> <div class="clearfix"></div> </div> //define the box which will display the errors of the form //read more about form validation in the chapter "Form Validation" //of section "JS Implementing" <div class="form-error-handler" error-handler="true"></div> </div> <div class="modal-footer"> //define the modal window footer //two buttons you need to have there: submit and close buttons <input type="submit" value="[title_of_submit_button]" class="button medium-button primary-button" /> <a href="#" class="button medium-button secondary-button close-modal-window"> [title_of_close_button] </a> </div> </form>

[form_action_url] defines the url which will be processed when form will be submitted. Good way to organize all the actions in your controller is define the same action for displaying the form data view and for processing submitted form, by checking incoming $_POST data.

[title_of_modal_window] - every modal window should have the header, to help user to understand what he is doing right now. Put here the title of your modal window. It can be static or translated text. Don't forget, for the public modules you should use translation function.

[field_label] displays the label of the field which you want to collect from this form. Can be static or translated text. Don't forget, for the public modules you should use translation function.

[field_name] is the name of the field, which you will process later in your model.

[title_of_submit_button] defines what the text will be displayed on the submit button. Can be static or translated text. Don't forget, for the public modules you should use translation function.

[title_of_close_button] defines what the text will be displayed on the close modal window button. Can be static or translated text. Don't forget, for the public modules you should use translation function.

As you can see, nothing complicated to create a modal window view. The main what you have to remember about the modal views, is that it should have root tag with classes "modal-wrapper" and "column-[X]", where [X] is the definition of the relative width (read more about relative width, and the whole grid system in "Grids" chapter of "Using CSS" section). Also modal view should have: header, content and footer elements. So this way you can put into the modal view any info you want, not only the forms but everything!

Important!

Presented structures of the view files are given only for understanding of building the iQDesk Engine v.2.0 interfaces, and they designed, using the built in PHP libraries, CSS classes and has default structure for the system. But be brave, you shouldn't follow all the requirements we explained above, in your module you can use your own markup with your styles! But don't forget, that every interface you design, should be clear for user.

Events Catcher

General Info

One of the amazing feature of iQDesk Engine v.2.0 is the events catching. What is it? Every action in the system, every function and every view file in the system can have related registered events. Your module, if it's enabled, can catch these events and operate with the income data. During catching an event, your Events catcher can modify the income data, if it was passed by reference, and it will affect the data in the original place where it being processed. Or the income data can be passed as value, in this case you can read this data, make some actions, which you would like to do, but the original data will not be changed. This feature of iQDesk Engine makes the system so flexible as you even couldn't imagine. With this feature, you can build the modules which will be connected to every type of data and take an active part in the processes in the system. Read more about registering events in "Events Library" chapter of this section.

Placing & Naming

From the Overview section of this manual, you know that the events catcher file should be placed into the "events" folder of root module folder.
The file name of your events catcher should be in format [module_name].php, the [module_name] should be lowercase, and should match with specified system name of your module.

Events Catcher Structure

Let's see how the events catcher file looks inside, and which the special properties it have.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); //first what we do is to check is it direct accessing the PHP script or not. If it's, then prevent any following actions class [module_name]Catcher { private $CI; //define the private property, which will contain the reference on application object //define the priority of calling your event catcher function //this property should be public, and has the name "priority" public $priority=array( "on[event_name]"=>[priority] ); function __construct() { //define constructor $this->CI=& get_instance(); //assign the reference on application object to the private property //over here you can prepare some data for the future using by your event catcher } public function on[event_name]([arg_1],[arg_2],...,[arg_n]){ //put here the actions which you would like to process with the income arguments } } ?>

As you can see see there are not many rules for structure of event catcher file, so let's take a quick look on them one-by-one.

[module_name] is the system name of your module, no matter upper or lower the case of chars it will have, but our good advice is to have the first letter upper case. Example: your module has system name "hello", then the class name of your event catcher will be "HelloCatcher".

[event_name] is the user defined or system event name. iQDesk Engine v.2.0 already has several predefined system events, so you can use them, or you can define your own events in your module, and then use them. Also, if you define your own events, then other developers who will write other modules will be able to use your defined events. Example: you have defined event in your module called "HelloWorld", then to catch this event you should write a function with name "onHelloWorld". Read more about registering your own events in the chapter "Event Library & System Events" of this section.

[priority] defines the priority of calling specified event catcher function. By default, in iQDesk Engine v.2.0 every event catcher function has priority 100, but if you're cleary know, that your catcher should be processed before all other, then you need to specify this event catcher with lowest value of priority, and on the other hand, if you know that your event catcher function should be processed last in the calling chain, then you need to setup bigger value.

[arg_1], [arg_2], ..., [arg_n] are the arguments, which the event passes into the catcher function. There can be no arguments at all, if event doesn't pass any arguments, as well there can be unlimited number of arguments. In every case of catching some event, you should find related documentation, to know which arguments the event passes. The arguments can be passed as the value or as the reference on value. Logically, if the reference was passed, then you will be able to affect the data on the side, where the event was registered. This ability makes iQDesk Engine v.2.0 so flexible, as you couldn't even imagine. Read more about passing arguments into the event catcher function in the chapter "Event Library & System Events" of this section.

ACL Library

General Info

iQDesk Engine v.2.0 is the roles based system, every action which user would like to do, before performing being checked for access by current user. Of course, this idea required designed ACL library which will check access for different modules/controllers/actions. This library has hard coded relations with the built in Users module, that;s why you cannot delete this module or disable. As we told before, every controller has public property called $check_permissions, so exactly this library checks the access to called action by current user.

Public Properties

$roles /array contains the array of currently defined roles id in the system.

$permissions /array contains the structured array of permissions for all roles in the system. The key of its elements defines the role id in the system, the element of array itself represents the array of modules with their controllers and actions.

$default_role /string contains the name of the default role in the system.

$session_variable_name /string defines the name of session variable, which contains value of role id currently logged in user.

$redirect_on_access_denied /string defines the URL where user will be redirected if he will try to access restricted module or controller or action.

$redirect_on_ajax_access_denied /string defines the URL where user will be redirected if he will try to access restricted module or controller or action via AJAX request.

Public Functions


checkPermissions($module,$controller,$action,$role="") checks the access given role to the given module/controller/action.

Parameters:

  • $module (string) the module name, which you check the access. Required parameter.
  • $controller (string) the controller name of given module, which you check the access. Required parameter.
  • $action (string) the action name of given controller of given module, which you check the access. Required parameter.
  • $role (string) the role id in the system, which you would like to check for access. Not required parameter. if this parameter not passed or is empty, then the function will check the current logged in user.

Returns: boolean result. TRUE - if access granted, FALSE - if role has no access to requested source.


isGuest() checks if the currently logged in user is guest. Has no incoming parameters.

Returns: boolean result. TRUE - if user is guest, FALSE - if user is currently authorized in system.


checkNavigationItem($module,$controller,$action) checks if the given source (module/controller/action) can be displayed in navigation bar for currently logged in user.

Parameters:

  • $module (string) the module name, which you would like to check for displaying in navigation bar. Required parameter.
  • $controller (string) the controller name of given module, which you would like to check for displaying in navigation bar. Required parameter.
  • $action (string) the action name of given controller of given module, which you would like to check for displaying in navigation bar. Required parameter.

Returns: boolean result. TRUE - if given navigation source can be displayed, FALSE - if given navigation source can not be displayed.


Using

ACL library is auto-loaded in iQDesk Engine v.2.0. You can access this library from every point of your module by $this->acl. You may have a lot of cases where you will use this library, for example in the view files, when you wants to display some action button or link, firstly you should to check if current user has access to this action. Use function checkPermissions every time before you want to display some action link or button to user. Other example of using this library is in controller. For example you want to have the controller "hello" be opened for all users (including guests), then you set up the public property of controller $check_permissions=false, but you have one function, which should be allowed only for logged in users, then you will need in this function write a first line - calling checkPermissions function and only if the access is granted then do the action, in other case, redirect user to somewhere you want.

Pagination Library

General Info

A lot of data in iQDesk Engine v.2.0 can presented to user in listing view, like users list, or roles list, or log records and etc. Of course, you can display all the rows at the same time, but just imagine, what happen with user, if he opens your module and will see thousand of records from the database on the one page. We think it will drive him crazy. Exactly for this, we developed buil in Pagination library, which helps you to split all the records from db to pages, with fixed number of records on every page. Using this library, will protect you of the time wasting with HTML markup, or writing some own functions to calculate number of pages, or detect current page and etc.

Public Properties

$page /integer contains the current page number.

$displayed /integer contains the number of currently displayed rows.

$total_count /integer contains the total number of all rows.

$count_per_page /integer defines how many rows will be displayed per one page.

$count_of_pages /integer contains calculated number of pages.

Public Functions


setNumbers($displayed,$total_count) sets the current numbers of displayed and total of records.

Parameters:

  • $displayed (integer) defines number of currently displayed records. Required parameter.
  • $total_count (integer) defines the total number of all records. Required parameter.

Returns: FALSE. Nothing else function returns.


prevPageURL() returns the action URL for the previous page.

Parameters: no incoming parameters.

Returns: string result. URL of the previous page, based on the currently detected page number.


nextPageURL() returns the action URL for the next page.

Parameters: no incoming parameters.

Returns: string result. URL of the next page, based on the currently detected page number.


lastPageURL() returns the action URL for the latest page.

Parameters: no incoming parameters.

Returns: string result. URL of the latest page, based on the currently detected page number.


firstPageURL() returns the action URL for the first page.

Parameters: no incoming parameters.

Returns: string result. URL of the first page, based on the currently detected page number.


createURL($page) returns the action URL for the given page number.

Parameters:

  • $page (integer) defines the page number, which you would like to get in action URL. Required parameter.

Returns: string result. Action URL of the given page number.


getItemsNumbers() returns the string which displays which exactly numbers displayed right now.

Parameters: no incoming parameters.

Returns: string result. The text in format (XX-YY), where XX - from which number the records start, and YY - to which number the records displayed.


drawPagination($return_html=false) renders the pagination form HTML markup.

Parameters:

  • $return_html (boolean) defines return HTML markup as text, or directly put rendered HTML in the place where the function was called. Not required parameter.

Returns:

  • If $return_html=true;, then the string containing the HTML markup will be returned.
  • If $return_html=false;, then boolean FALSE will be returned.

Using

Pagination library is auto-loaded in iQDesk Engine v.2.0, and it can be called from every point of your module by $this->pagination. So how to use this library correctly? First, you need to set the numbers in the controller, before loading view. Let's imagine you get the items which you need to display in the view data array $this->view_data['items'], and also you get a total number of records in variable $total, then you can set up pagination numbers by calling $this->pagination->setNumbers(count($this->view_data['items']),$total). Next, let's open your view file and go to the footer section, over here you have to put the single line which will render the pagination form, based on given numbers $this->pagination->drawPagination(). You will see render pagination form on your listing view, by clicking any button here, or by changing number in the text field, the page will be reloaded automatically, and the current URL will contains the page parameter. Now you can take this $_GET parameter in your module, and limit the output of records based in this value. Read more how to get this parameter and limit output, in "Model" chapter of this section.

Notifications Library

General Info

iQDesk Engine v.2.0 is designed so be so transparent for user as it's possible. That's why we think that's one of the important features of the engine should be the notifications system. If user does something, he should know what was done, and if there happened some error he should know about them. Notification library serves exactly for this purpose. This library helps you to put in stack warning errors or confirmation messages, when your module processes some data, and get them in any moment.

Public Properties

$errors_template /string defines current template of error messages. Can be adjusted on the fly, or from the notifications.php of config files.

$messages_template /string defines current template of confirmation messages. Can be adjusted on the fly, or from the notifications.php of config files.

$notifications /stdClass contains the stack of all current notifications, it has two public properties:

$errors /array contains the stack of current errors.
$messages /array contains the stack of current messages.

Public Functions


setError($error) puts the new error on the notifications stack.

Parameters:

  • $error (string) defines the text of the error. Required parameter. Can be static or translated text. Don't forget, for the public modules you should use translation function.

Returns: FALSE. Nothing else function returns.


clearError($error) erases the given error text from the notifications stack.

Parameters:

  • $error (string) defines the text of the error you would like to erase from stack. Required parameter. Can be static or translated text. Don't forget, for the public modules you should use translation function.

Returns: FALSE. Nothing else function returns.


setMessage($message) puts the new confirmation message on the notifications stack.

Parameters:

  • $message (string) defines the text of the message. Required parameter. Can be static or translated text. Don't forget, for the public modules you should use translation function.

Returns: FALSE. Nothing else function returns.


clearMessage($message) erases the given message text from the notifications stack.

Parameters:

  • $message (string) defines the text of the message you would like to erase from stack. Required parameter. Can be static or translated text. Don't forget, for the public modules you should use translation function.

Returns: FALSE. Nothing else function returns.


getErrors() gets the current errors stack.

Parameters: no incoming parameters.

Returns: array, which contains all the currently stacked errors.


getMessages() gets the current messages stack.

Parameters: no incoming parameters.

Returns: array, which contains all the currently stacked messages.


checkNotifications() checks if at least one error or message was put on the notifications stack.

Parameters: no incoming parameters.

Returns: boolean result. TRUE - if at least one message or error was stacked, FALSE - if no notifications were stacked.


getNotifications() gets the whole notifications stack.

Parameters: no incoming parameters.

Returns: stdClass, which contains all the current notifications stack. It has the same structure as public property $notifications of Notifications library.


drawErrors() draws the currently stacked errors, using defined errors template.

Parameters: no incoming parameters.

Returns: FALSE. Nothing else function returns.


drawMessages() draws the currently stacked messages, using defined messages template.

Parameters: no incoming parameters.

Returns: FALSE. Nothing else function returns.


drawNotifications() draws the currently stacked messages and errors, using defined appropriate templates.

Parameters: no incoming parameters.

Returns: FALSE. Nothing else function returns.


clearNotifications() clears the current notifications stack. All errors and messages will be erased.

Parameters: no incoming parameters.

Returns: FALSE. Nothing else function returns.


Using

Notifications library is auto-loaded in iQDesk Engine v.2.0. You can access the object of this library by calling $this->notifications. This library seems like has a lot of public functions, but in fact we can assume, you will use just couple of them. Let's see how it can be implemented in your code. For example, you have an action in you controller, after successful performing which you would like to put a confirmation message. In this case you have in your controller put a function $this->notifications->setMessage(), and define one parameter which will displayed as confirmation message text. Another example, if you're going to check something in model before modifying data. You will write all your conditions, which should be passed to perform an action, and if one of the conditions was not passed, you can call $this->notifications->setError(), which will put an error in the stack, and will be displayed on the work space after the page loaded. Given examples take just one line of your code, but they make user feel full control on the system, and in every moment, user will know what and why happened. Don't forget, that messages and errors can be presented as static or translated text, but if you're going to sell your module, you should to use only translated texts.

Theme Library

General Info

iQDesk Engine v.2.0 has theme based interface, and this library helps to manipulate theme on the fly. It has several public properties and methods which could be useful for you, but the primary idea of this library is for the internal system using. So let's take a quick look what the features this library can give us.

Public Properties

$main_title /string defined the main title of the all pages in the system. It's a primary part of title, which comes first, and only after that all other parts of title will be inserted.

$direction /string defines the text direction in the system. Can be "ltr" or "rtl".

$color_scheme /string defines the current color scheme in the system. For now we have two completed color schemes "green" and "red". About how to create your own theme, please read in "Theming" chapter of the section "Using CSS".

$page_title_delimiter /string defines the delimiter in page title between the parts.

$logout_in_navigation /boolean defines if logout button will be displayed in navigation bar or not.

Public Functions


getModuleIcon($module,$hover=false) gets the URL of the module icon accordingly the current color scheme.

Parameters:

  • $module (string) defines the system name of the module. Required parameter.
  • $hover (boolean) if TRUE - hover icon URL will be returned, if FALSE - usual icon URL will be returned. Not required parameter.

Returns: string value. URL of the specified module icon accordingly the current color scheme.


getLogoutIcon($hover=false) gets the URL of the logout icon accordingly the current color scheme.

Parameters:

  • $hover (boolean) if TRUE - hover icon URL will be returned, if FALSE - usual icon URL will be returned. Not required parameter.

Returns: string value. URL of the logout icon accordingly the current color scheme.

Using

Theme library is auto-loaded in iQDesk Engine v.2.0 and it can be accessed from any point of your module by calling $this->theme. The way how you can use this library is pretty limited, but we still have few examples how you can use it:

  • You create a module which operates with installed modules in system - you will have to get the module icons.
  • You create a module which operates with color scheme of the system.
  • You create a module, which allows to adjust some theme appearing and etc.

As you can see you can find a lot of the ways how to use this library.

Language Library & Translation

General Info

iQDesk Engine v.2.0 is multi-language engine, and for now it's available in English and Hebrew. If you have some experience with CodeIgniter Framework, you probably know about built in "Lang" library, but it's functionality it's not enough for all purposes of iQDesk Engine v.2.0, that why we decided to design additional Language library which will extend exists functionality.

Public Properties

Language library has no any public properties.

Public Functions


getModuleTitle($module) gets translated module title accordingly current language.

Parameters:

  • $module (string) defines the system name of the module, which title you want to get. Required parameter.

Returns: string value. Translated module title accordingly current language. Empty value will be returned if the translation not found.


getSectionTitle($module,$section) gets translated section title of specified module accordingly current language.

Parameters:

  • $module (string) defines the system name of the module, which section title you want to get. Required parameter.
  • $section (string) defines the system name of the section of specified module, which title you want to get. Required parameter.

Returns: string value. Translated section title of specified module accordingly current language. Empty value will be returned if the translation not found.


getActionTitle($module,$section,$action) gets translated action title of specified section of specified module accordingly current language.

Parameters:

  • $module (string) defines the system name of the module, which action title you want to get. Required parameter.
  • $section (string) defines the system name of the section of specified module, which action title you want to get. Required parameter.
  • $action (string) defines the system name of the action of specified section of specified module, which title you want to get. Required parameter.

Returns: string value. Translated action title of specified action of specified module accordingly current language. Empty value will be returned if the translation not found.


getSectionDescription($module,$section) gets translated section description of specified module accordingly current language.

Parameters:

  • $module (string) defines the system name of the module, which section description you want to get. Required parameter.
  • $section (string) defines the system name of the section of specified module, which description you want to get. Required parameter.

Returns: string value. Translated section description of specified module accordingly current language. Empty value will be returned if the translation not found.


getModuleLanguageLine($module,$line_name) gets specified line from the language file of specified module accordingly current language.

Parameters:

  • $module (string) defines the system name of the module, which language file you want to use. Required parameter.
  • $line_name (string) defines the system name of translated phrase, which you want to get. Required parameter.

Returns: string value. Translated line from the language file of specified module accordingly current language. Empty value will be returned if the translation not found.

Important!

Function getModuleLanguageLine($module,$line_name) will perform search only in specified module language file. If you want to get the translation of the line from the global set of translated phrases, please use $this->lang->line(). Read more more about CodeIgniter built in "Lang" library on the official documentation website.


drawLanguageNavigator($return_html=false) renders the language selector controls HTML markup.

Parameters:

  • $return_html (boolean) defines return HTML markup as text, or directly put rendered HTML in the place where the function was called. Not required parameter.

Returns:

  • If $return_html=true;, then the string containing the HTML markup will be returned.
  • If $return_html=false;, then boolean FALSE will be returned.

Using

Language library is auto-loaded in iQDesk Engine v.2.0 and it can be accessed by calling $this->language. One of the way how you can use this library, is getting the section description when you want to place it on the "i" icon near the section title on the view's main tabs. In fact, the main purpose is to be able to get translated lines from the not currently loaded modules.

Important to remember, that when you're using translation in your module, you have to call built in CodeIgniter Lang library function $this->lang->line(), if the line which you want to translate is a global one or specified in currently loaded module. In the case, if need line is specified in not current module - you should use our Language library function $this->language->getModuleLanguageLine().

We pretty sure, you will find a lot of good ways how to use our Language library in your module. But really important thing is to remember, that all what you put as text in your views, should be translated.

Translating Your Module

As we explained in Overview section, all language files of your module are placed in the "language" folder of the root module folder. But how exactly it should be named? Firstly, you have to create subfolders in "language" folder. This subfolders should have the format [language_name], where [language_name] - is lowercase system name of lanuage (Examples: english, hebrew or russian and etc.). Right in created sub-folder you have to create a language file, and give the name in format [module_name]_lang.php, where [module_name] - is lowercase system name of your module. Ok, it's time to a little example. Let's imagine we would like to create a an english language file for the module "hello". In this case you should follow the next steps:

  1. Open "language" folder
  2. Create sub-folder "english" and open it
  3. Create in sub-folder file with name "hello_lang.php"

That is! You just created the language file for your module. Inside this file you can place the transaltion lines, every translation line presented by the array element, in which key is a system anme of the line, and value is the transaltion of this line. For example: $lang['hello']="Hello";. More detailed about how to fill language file you can read in the CodeInginter official documentation.

Now it's time to tell about important few important transaltion lines which your language file should have:

  • _module_name defines the title of your module. This value will be taken by system, when it will opearte with your module.
  • _section_[section_name] defines the title of specified in [section_name] section. This value will be taken by system, when it will opearte with different sections of your module.
  • _[section_name]_section_description defines the description of specified in [section_name] section. This value will be taken by system, when it will opearte with different sections of your module.
  • _section_[section_name]_action_[action_name] defines the title of specified in [action_name] action of specified in [section_name] section. This value will be taken by system, when it will opearte with different actions of your module.

All other translated phrases in your language file can have any system line name. To find more information about default translated pharse, please take a look into the file application/language/english/main_lang.php. Over here is presented phrases which you no need to duplicate in your language file, and which is accessed from every point of the whole system.

Event Library & System Events

General Info

As we told in the "Events Catcher" chapter of this section, the catching of events in iQDesk Engine v.2.0 is an amazing feature of the whole system. It allows register events, and catch them in the moment when you want it, without changing original module files. The catching of events allows to display some info, if the event is registered in view files, or operate the income data, if the event is registered in model or controller files. So, all of this functionality provides the one built in library, called "Event". This library do the background processes to call the event catchers, and has just one public function which allows you to register your own events, which could be used by other developers. So let's take a look on functionality which provides us this library.

Public Properties

$defined_catchers /array contains all the detected events catchers in the system, and related event catcher functions in the system. This property can be useful, if you're going to disable some event catchers on the fly, or rearrange their calling.

$defined_events /array contains all the registerde events, which were called during the system current life-cycle. This public property exists only for your to know, what the events were called, and what is the priority of calling different events.

Public Functions


register($event_name,$arg_1,$arg_2,...,$arg_n) registers new event in the system, which will be called right in the place where this event was registered.

Parameters:

  • $event_name (string) defines the system name of new event. Should not match to the system predefined event names. Required parameter.
  • $arg_1, $arg_2, ..., $arg_n (mixed) defines variables which will be passed into the event catcher function. Can be real value, or the reference for the value. You can pass unlimited number of arguments. Not required parameter.

    Important!

    Be careful with passing values by reference, it gives the other developers affect the data you give by reference. Analyze, which data you pass, and which of them can be changed without breaking your module working flow. If you're pretty sure that one of the values, should not be changed, please pass it as the real value. In other case, it will cause the problems in your module, and probably in the whole system. Please be careful with passing variables by reference.

Returns: FALSE. Nothing else function returns.


Using

Event library is auto-loaded in iQDesk Engine v.2.0, and can be accessed by $this->event from every place of your module. So let's see in which cases you could use this library to register new event. Registering of new events is very useful in the model files, where it changes or creates some new records in the database. In this case, other developer who will use this event will be able adjust the data of their own modules accordingly the changes which happened in your module, if this two modules related between by some rules. Or other example of using the registering event function, is in view files, if you would like to extend the view file, by some new displayed data. We are pretty sure, you will find a lot of the places where you will want to register new events. And don't forget, that every new registered event name should not match already registered event names, and if you're going to sell your module online, you will have to write some little explanation on every registered event.

Built in Events

iQDesk Engine v.2.0 already has several predefined events, which you can use in your module. Some of them are registered directly in the system structure, some in the built in modules. So let's take a quick look on all predefined events in the system.

System Events

1. BeforeControllerInitiated being called before the parent controller class calls the constructor method.

Arguments:

  • $module contains the name of requested module.
  • $controller contains the name of requested controller.
  • $action contains the name of requested action.

2. BeforeCheckPermissions being called before the checking permissions in constructor of parent class of your controller.

Arguments:

  • $module contains the name of requested module.
  • $controller contains the name of requested controller.
  • $action contains the name of requested action.

3. AfterCheckPermissions being called right after the checking permissions in constructor of parent class of your controller.

Arguments:

  • $module contains the name of requested module.
  • $controller contains the name of requested controller.
  • $action contains the name of requested action.

4. AfterControllerInitiated being called right after the constructor method of parent class of your controller completed.

Arguments:

  • $module contains the name of requested module.
  • $controller contains the name of requested controller.
  • $action contains the name of requested action.

5. BeforeHeadHTML being called before rendering the section of the system work space.

Arguments: No passed arguments.

6. AfterHeadHTML being called right after rendering the section of the system work space, before closing tag.

Arguments: No passed arguments.

7. BeforeNavigationHTML being called before rendering the navigation.

Arguments: No passed arguments.

8. AfterNavigationHTML being called right after rendering the navigation.

Arguments: No passed arguments.

9. BeforeNotificationsHTML being called before rendering the notifications box. Will be called, only if there are any notification to display.

Arguments: No passed arguments.

10. AfterNotificationsHTML being called right after rendering the notifications box. Will be called, only if there are any notification to display.

Arguments: No passed arguments.

11. BeforeModuleHTML being called before rendering the view file of the module.

Arguments: No passed arguments.

12. AfterModuleHTML being called right after rendering the view file of the module.

Arguments: No passed arguments.

Users Module Events

1. BeforeLogin being called after user submit login form, but before any actions and requests to the database will be processed.

Arguments:

  • $data contains the submitted data from the form.

2. AfterLogin being called after user submit login form and after all actions and requests to the database were processed.

Arguments:

  • $data contains the submitted data from the form.
  • $id contains ID of logged in the user. Can be 0 if user was not logged in.
  • $result contains result of user logging in. TRUE - if user was logged in successfully, FALSE - if user was not logged in.

3. BeforeLogout being called after user requested logout action, but before any actions and requests to the database will be processed.

Arguments:

  • $id contains ID of logged in the user.

4. AfterLogout being called after user requested logout action and after all actions and requests to the database were processed.

Arguments:

  • $id contains ID of logged in the user.

5. BeforeCreateUser being called after user submitted the create user form, but before any actions and requests to the database will be processed.

Arguments:

  • $data contains the submitted data from the form.

6. AfterCreateUser being called after user submitted the create user form and after all actions and requests to the database were processed. Will be called only if user has been created successfully.

Arguments:

  • $data contains the submitted data from the form.
  • $id contains ID of created user.

7. BeforeUpdateUser being called after user submitted the update user form, but before any actions and requests to the database will be processed.

Arguments:

  • $data contains the submitted data from the form.
  • $id contains ID of updating user.

8. AfterUpdateUser being called after user submitted the update user form and after all actions and requests to the database were processed. Will be called only if user has been updated successfully.

Arguments:

  • $data contains the submitted data from the form.
  • $id contains ID of updated user.

9. BeforeDeleteUser being called after user requested delete user action, but before any actions and requests to the database will be processed.

Arguments:

  • $id contains ID of deleting user.

10. AfterDeleteUser being called after user requested delete user action and after all actions and requests to the database will be processed.

Arguments:

  • $id contains ID of deleted user.

11. BeforeCreateRole being called after user submitted the create role form, but before any actions and requests to the database will be processed.

Arguments:

  • $data contains the submitted data from the form.

12. AfterCreateRole being called after user submitted the create role form and after all actions and requests to the database were processed.

Arguments:

  • $data contains the submitted data from the form.
  • $id contains ID of created role.

13. BeforeUpdateRole being called after user submitted the update role form, but before any actions and requests to the database will be processed.

Arguments:

  • $data contains the submitted data from the form.
  • $id contains ID of updating role.

14. AfterUpdateRole being called after user submitted the update role form and after all actions and requests to the database were processed.

Arguments:

  • $data contains the submitted data from the form.
  • $id contains ID of updated role.

15. BeforeDeleteRole being called after user requested delete role action, but before any actions and requests to the database will be processed.

Arguments:

  • $id contains ID of deleting role.

16. AfterDeleteRole being called after user requested delete role action and after all actions and requests to the database will be processed.

Arguments:

  • $id contains ID of deleted role.

17. UsersTableHeading being called before displaying last heading cell of the users table.

Arguments:

  • &$columns contains the reference on the current count of columns.

18. UsersTableRow being called before displaying last cell of the users table body row.

Arguments:

  • $item contains the object of current displaying row.
  • $number contains the current iteration number in the table body.

19. BuildUsersQuery being called during the building the query, which takes the user records from the database. In the event catcher, you can access current database object via $this->CI->db.

Arguments: No passed arguments.

20. BuildUserQuery being called during the building the query, which takes the single user record from the database. In the event catcher, you can access current database object via $this->CI->db.

Arguments:

  • $id contains ID of getting user record.

21. UserCreateFormRow being called after the last field on the create user form.

Arguments: No passed arguments.

22. UserUpdateFormRow being called after the last field on the update user form.

Arguments:

  • $item contains the object of editing user.

23. UsersFilterFormRow being called after the last field on the filter users form.

Arguments:

  • $filter contains the array of current filtration parameters.

24. RolesTableHeading being called before displaying last heading cell of the roles table.

Arguments:

  • &$columns contains the reference on the current count of columns.

25. RolesTableRow being called before displaying last cell of the roles table body row.

Arguments:

  • $item contains the object of current displaying row.
  • $number contains the current iteration number in the table body.

26. BuildRolesQuery being called during the building the query, which takes the role records from the database. In the event catcher, you can access current database object via $this->CI->db.

Arguments: No passed arguments.

27. BuildRoleQuery being called during the building the query, which takes the single role record from the database. In the event catcher, you can access current database object via $this->CI->db.

Arguments:

  • $id contains ID of getting role record.

28. RoleCreateFormRow being called after the last field on the create role form.

Arguments: No passed arguments.

29. RoleUpdateFormRow being called after the last field on the update role form.

Arguments:

  • $item contains the object of editing role.

30. RolesFilterFormRow being called after the last field on the filter roles form.

Arguments:

  • $filter contains the array of current filtration parameters.

Modules Module Events

1. BeforeRefreshModules being called after user requested refresh modules action, but before any actions and requests to the database will be processed.

Arguments: No passed arguments.

2. AfterRefreshModules being called after user requested delete role action and after all actions and requests to the database will be processed.

Arguments:

  • $refreshed contains an array of all refreshed modules. Each element of this array will contains the new data for each refreshed module.

3. BeforeInstallModule being called after user submitted install module form, but before any actions and requests to the database will be processed.

Arguments:

  • $file contains the data array of uploaded ZIP archive. The structure of this array matches the structure of single passed file via $_FILES.

4. AfterInstallModule being called after user submitted install module form and after all actions and requests to the database will be processed.

Arguments:

  • $file contains the data array of uploaded ZIP archive. The structure of this array matches the structure of single passed file via $_FILES.

5. BeforeDeleteModule being called after user requested delete module action, but before any actions and requests to the database will be processed.

Arguments:

  • $id contains ID of deleting module.

6. AfterDeleteModule being called after user requested delete module action and after all actions and requests to the database will be processed.

Arguments:

  • $id contains ID of deleted module.

7. BeforeSaveModulesOrder being called after user requested change modules order action, but before any actions and requests to the database will be processed.

Arguments:

  • $data contains the passed data array. Each element of this array has following structure:

    Array ( [id] => [module_id] [order] => [module_order] )

    [module_id] (integer) contains the module id, which order will be changed.
    [module_order] (integer) contains the new order number, of according module.

8. AfterSaveModulesOrder being called after user requested change modules order action and after all actions and requests to the database will be processed.

Arguments:

  • $data contains the passed data array. Each element of this array has the same structure as for "BeforeSaveModulesOrder" event passed argument.

9. BeforeChangeModuleState being called after user requested change module state action, but before any actions and requests to the database will be processed.

Arguments:

  • $id contains ID of changing state module.
  • $state contains the new state of according module. Can have 2 different values: 1 - module enabled, 0 - module disabled.

10. AfterChangeModuleState being called after user requested change module state action and after all actions and requests to the database will be processed.

Arguments:

  • $id contains ID of chaged state module.
  • $state contains the new state of according module. Can have 2 different values: 1 - module enabled, 0 - module disabled.

11. ModulesTableHeading being called before displaying last heading cell of the modules table.

Arguments:

  • &$columns contains the reference on the current count of columns.

12. ModulesTableRow being called before displaying last cell of the modules table body row.

Arguments:

  • $item contains the object of current displaying row.
  • $number contains the current iteration number in the table body.

13. BuildModulesQuery being called during the building the query, which takes the module records from the database. In the event catcher, you can access current database object via $this->CI->db.

Arguments: No passed arguments.

14. BuildModuleQuery being called during the building the query, which takes the single module record from the database. In the event catcher, you can access current database object via $this->CI->db.

Arguments:

  • $id contains ID of getting module record.

15. ModuleInstallFormRow being called after the last field on the install module form.

Arguments: No passed arguments.

16. ModuleViewBoxRow being called after the last row on the view module box.

Arguments:

  • $item contains the object of displaying module.

17. ModulesFilterFormRow being called after the last field on the filter modules form.

Arguments:

  • $filter contains the array of current filtration parameters.

Log Module Events

1. BeforeWriteLogRecord being called after the write() function of Log module was called, bur before any actions and requests to the database will be processed.

Arguments:

  • $module contains the system name of module, which was passed into write() function.
  • $controller contains the system name of controller, which was passed into write() function.
  • $action contains the system name of action, which was passed into write() function.
  • $type contains the type of new log record, which was passed into write() function. Can have 3 different values: 1 - "Create" type of record, 2 - "Update" type of record, 3 - "Delete" type of record.
  • $description contains the description of new log record, which was passed into write() function.

2. AfterWriteLogRecord being called after the write() function of Log module was called and after all actions and requests to the database will be processed. Will be called only if new log record has been created successfully.

Arguments:

  • $module contains the system name of module, which was passed into write() function.
  • $controller contains the system name of controller, which was passed into write() function.
  • $action contains the system name of action, which was passed into write() function.
  • $type contains the type of new log record, which was passed into write() function. Can have 3 different values: 1 - "Create" type of record, 2 - "Update" type of record, 3 - "Delete" type of record.
  • $description contains the description of new log record, which was passed into write() function.
  • $id contains ID of new log record.

3. BeforeDeleteLogRecord being called after user requested delete log record action, but before any actions and requests to the database will be processed.

Arguments:

  • $id contains ID of deleting log record.

4. AfterDeleteLogRecord being called after user requested delete log record action and after all actions and requests to the database will be processed.

Arguments:

  • $id contains ID of deleted log record.

5. BeforeClearLog being called after user requested clear log action, but before any actions and requests to the database will be processed.

Arguments: No passed arguments.

6. AfterClearLog being called after user requested clear log action and after all actions and requests to the database will be processed.

Arguments: No passed arguments.

7. BeforeDeleteLogRecords being called after user requested batch delete log records action, but before any actions and requests to the database will be processed.

Arguments:

  • $ids contains the array of log record ID, which were marked for deletion.

8. AfterDeleteLogRecords being called after user requested batch delete log records action and after all actions and requests to the database will be processed.

Arguments:

  • $ids contains the array of log record ID, which were deleted.

9. LogTableHeading being called before displaying last heading cell of the log table.

Arguments:

  • &$columns contains the reference on the current count of columns.

10. LogTableRow being called before displaying last cell of the log table body row.

Arguments:

  • $item contains the object of current displaying row.
  • $number contains the current iteration number in the table body.

11. BuildLogQuery being called during the building the query, which takes the log records from the database. In the event catcher, you can access current database object via $this->CI->db.

Arguments: No passed arguments.

12. LogFilterFormRow being called after the last field on the filter log form.

Arguments:

  • $filter contains the array of current filtration parameters.