What's new? | Help | Directory | Sign in
Google
pluf
Pluf - PHP5 webapp development framework
  
  
    
Search
for
Updated Nov 17, 2007 by diaeresis
Labels: Featured
DatabaseOrm  
Object Relational Mapping

At the core of Plume is the Active Record ORM. This ORM enables rapid development of extensions without the need to deal with the SQL needed to store the data into the database. It is built to support different database engines.

Presentation

The ORM is based on the Active Record pattern. To create your own model you need to extend the Pluf_Model class and overwrite the init() method with the details of your model. You can of course add custom methods. See the Pluf_User model for example. The Pluf_Model is very close to the Django model.

A given class model is associated to a table in the database. Each item is saved as one row in the table.

Here is a short example using the models of the test application. In this example we create a todo list and add 2 todo items in the list.

// Create a list
$list = new Todo_List();
$list->name = 'My todo list';
$list->create();
// Create a todo item
$item = new Todo_Item();
$item->item = 'Improve the documentation';
$item->completed = true;
$item->list = $list;
$item->create();
// Create another todo item
$item = new Todo_Item();
$item->item = 'Improve the website';
$item->completed = false;
$item->list = $list;
$item->create();
// Get the list of all the items in the list
$items = $list->get_todo_item_list();

As you can see, you do not have to think about SQL, all the work is done for you by the ORM.

Basic definition of a model

Here is a presentation of how you should define a model extending Pluf_Model.

class MyApp_MyModel extends Pluf_Model
{
    function init()
    { 
        // The table in the database where your
        // model is stored.
        $this->_a['table'] = 'myapp_mymodels';
        // The name of your model
        $this->_a['model'] = 'MyApp_MyModel';

        // Here the core with the definition of the
        // fields.
        $this->_a['cols'] = array(
           // The id field of type sequence is mandatory
           // for each model
           'id' =>
           array(
             'type' => 'Pluf_DB_Field_Sequence',
             'blank' => true,//It is automatically added.
             ),
           // Here we have string for the title
           // it must not be empty
           'title' => 
           array(
             'type' => 'Pluf_DB_Field_Varchar',
             'blank' => false,
             'size' => 100,
             ),
           // But the description can be empty.
           'description' => 
           array(
              'type' => 'Pluf_DB_Field_Text',
              'blank' => true,
              ),
        );
        // It is mandatory to call the parent init function.
        parent::init();  
    }
} 

The definition of the fields is an associative array with the key being the name of the field and the value being another associative array of parameters. The most important parameters are:

Each type of field has different extra parameters.

Now you can use this model the following way:

$model = new MyApp_MyModel();
$model->title = 'Hello world!';
$model->description = 'What first program says.';
$model->create();
$model->description = 'What your first program says.';
$model->update();

Very simple, right?

Overview of the available fields

Pluf_DB_Field_File

The file is stored on the file system and the database only stores the subdirectory of the upload_root folder and the filename.

Parameters for the field:

TODO: Put the parameters.

Relations between models

If you cannot have relations between models, there is no fun. A relation is of two types: Many To One or Many To Many. The many to one relation is defined by a Pluf_DB_Field_Foreignkey field and the many to many by a Pluf_DB_Field_Manytomany.

The many to one relation

In our first example with the todo item and the todo list we can easily see that many items relate to one list. That means that an item will have a Pluf_DB_Field_Foreignkey to the list.

If you look at the definition of the Todo_Item you will see in the init() method the following code:

TODO: Add link to the definition on the subversion repository

'list' => 
array(
  'type' => 'Pluf_DB_Field_Foreignkey',
  'blank' => false,
  'model' => 'Todo_List',
  'verbose' => __('in list'),
  'help_text' => __('To easily ... in lists.'),
 ),

It means that the list field of the Todo_Item is a link to a Todo_List list. What it means is that you can relate an item to a list. From that you automatically have some goodies.

Automatically available methods

As you relate a Todo_Item to a Todo_List the natural thing is that you want to get the list in which is the item or the list of items in the list. It is very easy.

From the item you can get the list that way:

$list_id = = $item->list;
$list = $item->get_list();

You can see that list corresponds to the name of the field. If you just request the list property of the item you get the id of the list, but to get the real object Todo_List you need to call the corresponding get_xxx() method.

From the list you can get a list of items:

$items = $list->get_todo_item_list();

This method is a little bit magic, because nowhere in the definition of the todo list you can find a reference to the todo item. This is done through the definition of the Todo/relations.php file. This file is explained later. The convention for the name of the method is:

get_ + lower case name of the related model + _list

The name of this method can be changed through the use of the relate_name parameter of the foreign key. For example the definition of the list field would have had 'relate_name'=>'items_in' you could have done the following:

$items = $list->get_items_in_list();

The many to many relation

The many to many relation is used when you want one item to belongs to many others non exclusively. For example you want to have an Article model to be in many Category models. But a Category should be able to have many Article model in it.

The many to many relation must be defined only in one of the two models. You should try to use the most logical. Here it is easier to say that an Article is part of many Category(s) so the many to many relation should be defined at the Article level.

This would be done the following way:

 'categories' => 
 array(
  'type' => 'Pluf_DB_Field_Manytomany',
  'blank' => false,
  'model' => 'Category',
  'verbose' => __('in categories'),
 ),

Automatically available methods

As the both a Category has many Article(s) and an Article many Category(s) only list() methods are available. These methods are:

$article->get_categories_list();
$category->get_article_list();

The name of the method on the article is get_categories_list() with a plural form for category because this is the name of the field. On the category it is get_article_list() with a singular for article because this is the lowercase name of the Article model. As for the many to one relation, it is possible to change this name by using the relate_name parameter.

If you want to associate an article to a category you have the following methods available:

$article->setAssoc($category);
$category->setAssoc($article);

You can see that a many to many relation is symetric. To remove an association you simply use the delAssoc() method:

$article->delAssoc($category);
$category->delAssoc($article);

Registration of a model

Or the MyApp/relations.php file. To be able to dynamically have a method to list the Todo_Item in a Todo_List the relations between the models has to be defined. It is technically possible to load all the models and go through the definition of each model and from that build the relation map. Technically possible but not very efficient.

As presented, when you use the Plume Framework you create a folder for your application which is in fact the name of the application. In the case of the test application, the name is Todo. The content of the Todo folder. You will see a relations.php file. The content is very simple:

$m = array();
$m['Todo_Item'] = array('relate_to' => array('Todo_List'));
return $m;

What it says is that the Todo_Item relate to the Todo_List. If an item could have been part of many lists through a many to many relation the definition would have been:

$m = array();
$m['Todo_Item'] = array('relate_to_many' => array('Todo_List'));
return $m;

It is very important to define this file correctly. This file is used at the initialization of Pluf when calling:

Pluf::start('./configuration.php');

Pluf will automatically look at the installed_apps configuration variable and load all the corresponding relations.php files. For example the test app configuration contains:

$cfg['installed_apps'] = array('Pluf', 'Todo');

It means that the Todo/relations.php file will be loaded and the relations between the Todo_Item and the Todo_List will be found. For a more complex example you can see the relations of the core models of Pluf in Pluf/relations.php.


Comment by amarnath.sureddy, Apr 13, 2008

code for how to add a field into list in php


Sign in to add a comment