How to create a module

In this section of the documentation described how to create a module for DIAFAN.CMS. At first glance, it's easy, but, as elsewhere, has its own peculiarities. Appendix to this section – the module frame, which can be downloaded at this link.

Module – a set of files in the folder modules/module_name. For more information about the module structure.

In our example, the module will be called example. All module files will be stored in the folder modules/example.

To connect our crude module o DIAFAN.CMS, you must make entries in the tables {modules} and {admin}. To do this, in the file example.install.php prescribes:

Example:

// record in the table {modules}
public $modules = array(
    array(
        
"name" => "example",
        
"admin" => true,
        
"site" => true,
        
"site_page" => true,
    ),
);

// admin menu
public $admin = array(
    array(
        
"name" => "Module name",
        
"rewrite" => "example",
        
"group_id" => "1",
        
"sort" => 5,
        
"act" => true,
        
"children" => array(
            array(
                
"name" => "Settings",
                
"rewrite" => "example/config",
            ),
        )
    ),
);

Now the module will appear in the list of modules to be installed in the "Modules and DB" – "Installing modules." Install the module.

The next step is to add our module on any page of the site. We go to the admin panel, create a plain text page, and in the tab "Additional properties" attach to it our new module.

All module is ready for use!

The truth is it does not do anything, so let's make it functional.

Let's make a module that will allow to place ads on the site.

Attention!

Everything you read below is not strict step by step instructions and perform actions in the order, which is done here is not necessary. Every programmer their approach to the task and must be able to think for themselves, that all worked.

Create a table in the database

To start to define the tasks to be performed by the module:

  • allow registered users to add ad;
  • allow administrators to edit ad;
  • allow administrators to publish ad;

Advertisements will be placed in a database table YOUR_PREFIX_example, and we need to develop its structure.

Attention!

The default prefix – diafan_. You can rename it when you install DIAFAN.CMS, therefore, create a table in the likeness of other tables in the database.

To use the database, you can use phpMyAdmin, which usually have hosted.

Table structure

  • user_id – id of our registered user, who added ad
  • created – created time
  • text – ad text

A table with information about the users we already have, this module is the default "Users", so we will use that information. We only need to store the user ID in the field user_id our new table.

The table below describes in the file example.install.php, so you can use the module again.

Example:

public $tables = array(
    array(
        
"name" => "example",
        
"fields" => array(
            array(
                
"name" => "id",
                
"type" => "INT(11) UNSIGNED NOT NULL AUTO_INCREMENT",
            ),
            array(
                
"name" => "user_id",
                
"type" => "INT(11) UNSIGNED NOT NULL DEFAULT '0'",
            ),
            array(
                
"name" => "created",
                
"type" => "INT(10) UNSIGNED NOT NULL DEFAULT '0'",
            ),
            array(
                
"name" => "text",
                
"type" => "text NOT NULL DEFAULT ''",
            ),
        ),
        
"keys" => array(
            
"PRIMARY KEY (id)",
        ),
    ),
);

Administration panel

Let's start with the development of our admin module, before that do not forget to enable "development mode" in the site settings to see the log of our possible errors.

Attention!

Be sure to turn development mode and turn off caching in the site settings for any revisions of any modules.

If you open the admin panel of our new module, we will not see anything because we did not describe. When the administrative part DIAFAN.CMS connects the module administration, the core of the system automatically connects directly for information management module all actions. The module for the beginning simply describe what and how to display and edit that.

Open the file example.admin.php and describe the class Example_admin:

Example:

class Example_admin extends Frame_admin
{
    
// name of the database table on which the list will be formed
    
public $table = 'example';

    
// description of table fields
    
public $variables = array (
        
'main' => array (
            
'created' => array(
                
'type' => 'datetime',
                
'name' => 'Date of creation',
            ),
            
'user_id' => array(
                
'type' => 'select',
                
'name' => 'Author',
            ),
            
'text' => array(
                
'type' => 'editor',
                
'name' => 'Ad text',
            ),
        ),
    );

    
// description of the fields in the list
    
public $variables_list = array (
        
'checkbox' => '',
        
'name' => array(
            
'name' => 'Ad text',
        ),
    );

    
// link to add new ads
    
public function show_add()
    {
        
$this->diafan->addnew_init('Add an ad');
    }

    
// function, which determines that the output modules when opening
    
public function show()
    {
        
// ads list
        
$this->diafan->list_row();
    }
}

Property classes $table specifies which table to store our ads. Array $variables describes each field of the table. Array $variables_list describes which fields and how they will be displayed in the list, the function show() list of ads.

Describing the field, we show DIAFAN.CMS, that we want to edit, and in what form. Note that the order of the items is repeated on the page in the admin area. To edit the user more convenient to do drop-down list, which would be registered usernames. To do this, we specify additional attribute select_db, which indicates what the database table and what data to take.

Example:

// description of table fields
public $variables = array (
    
'main' => array (
        
'created' => array(
            
'type' => 'datetime',
            
'name' => 'Date of creation',
        ),
        
'user_id' => array(
            
'type' => 'select',
            
'name' => 'Author',
            
'select_db' => array(
                
'table' => 'users',
                
'name' => 'fio',
                
'where' => "trash='1'",
            ),
        ),
        
'text' => array(
            
'type' => 'editor',
            
'name' => 'Ad text',
        ),
    ),
);

We now describe how it will look all the ads. To do this, you need to add them to the array $variables_list.

Example:

// description of the fields in the list
public $variables_list = array (
    
'checkbox' => '',
    
'created' => array(
        
'name' => 'Date and time',
        
'type' => 'datetime',
        
'sql' => true,
    ),
    
'name' => array(
        
'name' => 'Ad text',
    ),
    
'user_id' => array(
        
'name' => 'User',
        
'type' => 'string',
        
'sql' => true,
    ),
    
'actions' => array(
        
'del' => true,
    ),
);

We've added two fields from the database (attribute sql means that it will take the data from the database). And indicate the format in which outputting data. And added the action "Remove".

And the last. We must point out that the main field we have called the text (default name):

Example:

'name' => array(
    
'name' => 'Ad text',
    
'variable' => 'text',
),

All this is enough to display all the ads, add, edit, and save them.

Hooray, now we have the list of ads displayed, and the addition of a user id.

List of ads

As you can see, the function list_row displays fields from the database in the form in which they are written in it, but it can be easy to fix!

Let's write a simple function to override the system display. Function name format is as follows: list_variable_field($row). Here $row – an array of values for the current element:

Example:

public function list_variable_user_id($row)
{
    return
'<div>'.DB::query_result("SELECT fio FROM {users} WHERE id=%d", $row['user_id']).'</div>';
}

That is, if DIAFAN.CMS detect these features with the name of the mask list_variable_*, she realizes that the field user_id you want to display as described in this function.

List of ads with user names

Attention! The example shows how to use function list_variable_(). Optimal for this task, use the type *select as described in the $variables attribute select_db.

Come on. We extend the functionality of our module to our ads sort, delete and activate at our behest.

The database field to add to cart remove, and sort of activity:

Table structure

And mount settings $variables_list.

Example:

// description of the fields in the list
public $variables_list = array (
    
'checkbox' => '',
    
'sort' => array(
        
'name' => 'Sorting',
        
'type' => 'numtext',
        
'desc' => true,
        
'sql' => true,
        
'fast_edit' => true,
    ),
    
'created' => array(
        
'name' => 'Date and time',
        
'type' => 'datetime',
        
'sql' => true,
    ),
    
'name' => array(
        
'name' => 'Ad text',
    ),
    
'user_id' => array(
        
'name' => 'User',
        
'type' => 'string',
        
'sql' => true,
    ),
    
'actions' => array(
        
'act' => true,
        
'trash' => true,
    ),
);

We now have in the list of ads will delete icons, activity, and they can be sorted.

Attention!

Also do not forget about the variable $variables_filter, which allows us to add your own parameters in the filter.

Let's use it to organize for example a filter ads by user name.

Example:

public $variables_filter = array (
    
'user_id' => array(
        
'type' => 'select',
        
'name' => 'Search by user',
    ),
);

Values for the list take from the database. Database tables take from the attribute select_db in the array $variables.

In general, the form of presentation of the administrative unit depends only on your imagination. No one forces you to use function list_row, you can write all your own handler.

Attention!

A powerful tool for functional expansion module is the type function.

It allows you to define custom functions for editing and saving field. Let's do so that when editing user_id username we did not have a drop-down list, and selected using AJAX-query:

Reassign $variable, we point to user_id type is not select and function.

Example:

public $variables = array (
    
'main' => array (
        ...
        
'user_id' => array(
            
'type' => 'function',
            
'name' => 'Author',
        ),
        ...
    ),
);

And we declare two functions

Example:

public function edit_variable_user_id(){}

public function
save_variable_user_id(){}

Let us modify the visual field mapping user_id and will edit function edit_variable_user_id.

Example:

public function edit_variable_user_id()
{
    echo
'<div class="unit">
        <div class="infofield">Click</div>
        <div class="user_id" rel="'
.$this->diafan->value.'"><b>here</b></div>
    </div>'
;
}

Let's write a simple jQuery handler that sends Ajax-request. To do this, create a file modules/example/admin/js/example.admin.edit.js. This JS-file to connect to edit forms automatically. The created file will be as follows:

Example:

$(".user_id").click(function(){
    var
user_id = $(this).attr('rel');
    
diafan_ajax.init({
        
data:{
            
action: "user",
            
module: "example",
            
user_id: user_id
        
},
        
success: function(response) {
            
alert(response.name);
        }
    });
});

Handler on clicking an element with the class user_id sent to current page AJAX-request with parameters module, action and user_id. Ajax-requests are sent through the handler diafan_ajax, were added to the identification and verification of the hash.

Now we need to write example.admin.action.php.

Example:

class Example_admin_action extends Action_admin
{
    public function
init()
    {
        if (! empty(
$_POST['user_id']))
        {
            
$this->result["name"] = DB::query_result("SELECT fio FROM {users} WHERE id=%d", $_POST['user_id']);
        }
        else
        {
            
$this->result["name"] = 'error';
        }
    }
}

File example.admin.action.php connected only when both variables action and module are sent POST. The value of the variable module must match the name of our module. Under these conditions, connect function init(), which should be described in the request processing. The data stored in the variable $this->result will be automatically sent back to the JSON-formatted.

Now, we modify the function save_variable_user_id, in which the preservation of the field occurs. Here you can insert data into another table, to handle their own variables $_POST, double counted to infinity.

In order to write data into table {example}, which uses our module, can make this trick:

Example:

public function save_variable_user_id()
{
    
$this->diafan->set_query("user_id=%d");
    
$this->diafan->set_value(1);
}

Thus, we have added a field to a SQL UPDATE request user_id with the value 1.

The current sample from the database can be accessed through the function $this->diafan->values(). For example, $this->diafan->values('site_id') return value of the field site_id.

As you can see for yourself, function provides a tremendous opportunity to expand functionality of the administrative module, all depends on your imagination and the right hand to the body attachment.

Yet there is a remarkable type in $variablesmodule. It means that you need to connect to third-party editing module.

How it works.

Where you need to connect the module example, for example, when news editing in the file modules/news/admin/news.admin.php to $variables prescribe.

Example:

public $variables = array(
    
'main' => array(
        
'example' => 'module',
        

    
),
    

);

When editing news DIAFAN.CMS will look file modules/example/admin/example.admin.inc.php, which describes the functions edit() and save().

This works almost as well as the type function, only between the modules.

The tabs for the module and settings

In DIAFAN.CMS administrative part of the module can be further complemented by various extensions, tabs (subsections of the module). Look in the folder modules/shop/admin.

Here's how: create a file example.admin.bolt.php and it is initialized class

class Example_admin_bolt extends Frame_admin

Then we go to http://site.com/admin/admin/ and add our module to subsection with semantic URL example/bolt. The number of expansion modules that depend only on your imagination.

There is a special type of extensions – settings.

It is registered it in the same way as usual extension: in http://site.com/admin/admin/ add subsection "Settings" with semantic URL example/config.

Its main distinguishing feature is the setting in $config.

public $config = array('config');

If it is set, it is not the preservation of the table specified in $table, and in the table {config}. For access to which a special function configmodules, which can be called from anywhere.

Public part

If we connect the module to the page of the site, then when you open it from the controller example.php is called function init().

As can be seen from the example, when the module is connected model initialization. The result of execution is recorded in a variable $this->result. Once connected, the specified template in $this->result["view"]. In the example $this->result["view"] = 'show'. It means connect file modules/example/views/example.view.show.php.

If the module to be used explanatory variables inherent in the link, to indicate that they should be in an array rewrite_variable_names.

Example:

public $rewrite_variable_names = array('page', 'show');

Our unit is still damp. When you visit a page with an attached module, we do not see anything. Let's make a list of ads, divided into pages. By clicking on the ad it will open in a separate window in which you can enter a comment.

It's not hard, do not be alarmed :)

Example:

public function show()
{
    
// data will be cached
    
$cache_meta = array(
    
"name" => "list", // cache tag
    
"page" => $this->diafan->page > 1 ? $this->diafan->page : 1,
    );

    
// if there is no data in the cache is listed them
    
if (!$this->result = $this->diafan->_cache->get($cache_meta, 'example'))
    {
        
$this->result = array();

        
////navigation//
        
$this->diafan->_paginator->nen = DB::query_result("SELECT COUNT(id) FROM {example} WHERE act='1' AND trash='0'");
        
$this->result["paginator"] = $this->diafan->_paginator->get();
        
////navigation///

        
$rows = DB::query_range_fetch_all("SELECT id, created, text FROM {example} WHERE act='1' AND trash='0' ORDER BY created DESC, id DESC",
            
$this->diafan->_paginator->polog, $this->diafan->_paginator->nastr);

        foreach(
$rows as $row)
        {
            
$row['created'] = $this->format_date($row['created'], 'example');
            
$row['link'] = $this->diafan->_route->link($this->diafan->_site->id, $row["id"], 'example');

            
$this->result['rows'][] = $row;
        }
        
//cache saving
        
$this->diafan->_cache->save($this->result, $cache_meta, 'example');
    }

    
$this->result["paginator"] = $this->diafan->_tpl->get('get', 'paginator', $this->result["paginator"]);
    
$this->result['view'] = 'show';
}

As you can see the code here, we used cash. This is necessary if you want to reduce the load on the database and reduce the time display of the page.

During development, we always recommend that you disable the cache in Site Settings because the default cache is cleared only if the item is changed in the admin panel, you have all of your manipulation of the database in the file *.model.php with caching enabled, you can not see immediately.

We distribute a small example to make it clearer

Example:

$cache_meta = array(
    
"name" => "trololo", // cache tag
    
"language" => _LANG,
    
"page" => $this->diafan->page > 1 ? $this->diafan->page : 1,
    
"site_id" => $this->diafan->_site->id,
);
// if the cache is stored, he will be in $ data if not then condition
$data = array();
if(!
$data = $this->diafan->_cache->get($cache_meta, $this->diafan->module))
{
    
$data = array('first', 'black');
    
//cache saving
    
$this->diafan->_cache->save($data, $cache_meta, $this->diafan->module);
}

About paginated read more here.

Function format_date() formats the date in accordance with the settings of the module, it inherits from the class Model. Read more about it you can read here.

Let's add our module to the settings other than the number of ads on the page and even the date format.

Create settings file modules/example/admin/example.admin.config.php and fill it:

Example:

public $variables = array (
    
'base' => array (
        
'nastr' => array(
            
'type' => 'numtext',
            
'name' => 'Number of items per page',
        ),
        
'format_date' => array(
            
'type' => 'select',
            
'name' => 'Date format',
            
'select' => array(
                
0 => '01.05.2016',
                
6 => '01.05.2016 14:45',
                
1 => '1 may 2016',
                
2 => '1 may',
                
3 => '1 may 2016, monday',
                
5 => 'yesterday 15:30',
                
4 => 'do not show',
            ),
        ),
     )
);

public
$config = array('config');

The result was as much a function module with two variable settings and caching.

You can also create a separate template tag for the module. This is a separate lesson "How to add the template tag".

The source code example of the module.