Last visit was: It is currently Fri Sep 03, 2010 7:50 pm


All times are UTC




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: Quick start with CodeIgniter
PostPosted: Thu Dec 17, 2009 10:43 pm 
Site Admin

Joined: Sun Dec 13, 2009 10:46 pm
Posts: 62
Here is a quick example on how to use RapidDataMapper with CodeIgniter:

What I'm going to do is the following:

An article viewer on which people can comment.
Currently there is no admin for it where you can remove comments and create/update/delete pages, that I will do tomorrow.

Installation

Follow the installation instructions provided in the manual, the CI specific installation instructions

The database tables

Code:
CREATE TABLE `articles` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) DEFAULT NULL,
  `slug` varchar(255) DEFAULT NULL,
  `content` text,
  PRIMARY KEY (`id`)
);

CREATE TABLE `comments` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `author` varchar(255) DEFAULT NULL,
  `content` text,
  `article_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

INSERT INTO `articles` (`id`,`title`,`slug`,`content`)
VALUES
   (1,'Index','index','Content');


The data objects

Create the file application/data_model/article.php and enter this:
Code:
<?php

class Article
{
    public $id;
    public $title;
    public $slug;
    public $content;

    public $comments = array();
}


Create the file application/data_model/comment.php and add this:
Code:
<?php

class Comment
{
    public $id;
    public $author;
    public $content;
    public $article_id;

    public $article = null;
}


The descriptors, describing how they map to the database

Create application/data_model/articledescriptor.php:
Code:
<?php

class ArticleDescriptor extends Db_Descriptor
{
    function __construct()
    {
        $this->setClass('Article');

        $this->add($this->newPrimaryKey('id'));
        $this->add($this->newColumn('title'));
        $this->add($this->newColumn('slug'));
        $this->add($this->newColumn('content'));

        $this->add($this->newRelation('comments'));

        // Use the Sluggable behaviour to automate slug generation
        $this->applyPlugin(new Db_Plugin_Sluggable(array('title' => 'slug')));
    }
}


Create the application/data_model/commentdescriptor.php:
Code:
<?php

class CommentDescriptor extends Db_Descriptor
{
    function __construct()
    {
        $this->setClass('Comment');

        $this->add($this->newPrimaryKey('id'));
        $this->add($this->newColumn('author'));
        $this->add($this->newColumn('content'));
        $this->add($this->newColumn('article_id'));

        $this->add($this->newRelation('article'));
    }
}


Controller

Because this is a very small application, I won't create a model for it, instead I add all the database interaction in the controller:
Code:
<?php

class Page extends Controller
{
    function __construct()
    {
        parent::__construct();
        $this->load->database();
        $this->load->helper('form');
    }

    function _remap($page_title = 'index')
    {
        $p = Db::find('article')->related('comments')->where('slug', $page_title)->getOne();

        if( ! $p)
        {
            show_404();
        }

        // Because this is an example, I'm going to use $_POST directly
        if( ! empty($_POST['content']) && ! empty($_POST['author']))
        {
            $c = new Comment();

            $c->content = $_POST['content'];
            $c->author = $_POST['author'];

            // Add the comment
            $p->comments[] = $c;

            Db::save($p);
        }

        $this->load->view('article', array('page' => $p));
    }
}


View:

And the matching view:
Code:
<h1><?php echo $page->title; ?></h1>

<p>
   <?php echo $page->content ?>
</p>

<?php foreach($page->comments as $comment): ?>
<p>
   <strong><?php echo $comment->author ?></strong>: <?php echo $comment->content ?>
</p>
<?php endforeach; ?>

<?php echo form_open('/page/'.$page->slug); ?>

<?php echo form_input('author'); ?>
<?php echo form_input('content'); ?>

<?php echo form_submit('', 'Add') ?>

<?php echo form_close(); ?>


Usage:

Point your browser to /page/index and start commenting! :)

Hope this clears some of the confusion around the complexity of RapidDataMapper.

I know RapidDataMapper can be complex, but the complexity comes when you want to do complex things ;)


Top
Offline Profile  
 
 Post subject: Re: Quick start with CodeIgniter
PostPosted: Fri Dec 18, 2009 1:52 pm 
Site Admin

Joined: Sun Dec 13, 2009 10:46 pm
Posts: 62
Here comes the second part of this little quick start guide:

The admin controller

application/controllers/admin.php:
Code:
<?php

class Admin extends Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->database();
        $this->load->helper(array('url', 'form'));
    }
    public function index()
    {
        $this->show_list();
    }
    public function show_list($offset = 0)
    {
        // Get all pages
        $page_count = Db::find('article')->count();
       
        $this->load->library('pagination');
       
        $config['base_url'] = site_url('/admin/show_list');
        $config['total_rows'] = $page_count;
        $config['per_page'] = 10;
        $config['uri_segment'] = 3;

        $this->pagination->initialize($config);
       
        $pages = Db::find('article')->orderBy('article.id', 'desc')->offset($offset)->limit(10)->get();

        $this->load->view('article_admin', array('pages' => $pages, 'pagination' => $this->pagination->create_links()));
    }
    public function create()
    {
        if( ! empty($_POST['title']) && ! empty($_POST['content']))
        {
            $a = new Article();
           
            $a->title = $_POST['title'];
            $a->content = $_POST['content'];
           
            Db::save($a);
           
            redirect('/admin');
        }
        else
        {
            $this->load->view('article_new');
        }
    }
    public function edit($id)
    {
        if( ! $p = Db::find('article', $id))
        {
            echo "<p>Page not found</p>";
           
            $this->show_list();
            return;
        }
       
        if( ! empty($_POST['title']) && ! empty($_POST['content']))
        {
            $p->title = $_POST['title'];
            $p->content = $_POST['content'];
        }
       
        if(Db::isChanged($p))
        {
            Db::save($p);
           
            redirect('admin');
        }
       
        $this->load->view('article_edit', array('page' => $p));
    }
    public function delete($id)
    {
        // In this case we're just going to use a simple query:
        if($this->db->delete('articles', array('id' => $id)))
        {
            // Delete the comments too;
            $this->db->delete('comments', array('article_id' => $id));
           
            echo "<p>Successful delete</p>";
        }
        else
        {
            echo "<p>Delete failed</p>";
        }
       
        $this->show_list();
    }
}


The views

application/views/article_admin.php
Code:
<?php echo anchor('/admin/create', 'Create new page'); ?>

<?php foreach($pages as $page): ?>
<div>
   <strong><?php echo $page->title ?></strong>
   <?php echo anchor('/admin/edit/'.$page->id, 'Edit'); ?>
   <?php echo anchor('/admin/delete/'.$page->id, 'Delete'); ?>
   <?php echo anchor('/page/'.$page->slug, 'Link'); ?>
</div>
<?php endforeach;
echo $pagination;?>


application/views/article_new.php
Code:
<h2>Create new article</h2>

<?php echo form_open('admin/create'); ?>

<?php echo form_input('title'); ?>
<?php echo form_input('content'); ?>

<?php echo form_submit('', 'Save'); ?>

<?php echo form_close(); ?>


application/views/article_edit.php
Code:
<h2>Create new article</h2>

<?php echo form_open('admin/edit/'.$page->id); ?>

<?php echo form_input('title', $page->title); ?>
<?php echo form_input('content', $page->content); ?>

<?php echo form_submit('', 'Save'); ?>

<?php echo form_close(); ?>


To now use the new admin controller, point your browser to /admin


Top
Offline Profile  
 
 Post subject: Re: Quick start with CodeIgniter
PostPosted: Sat Dec 19, 2009 4:16 pm 

Joined: Sat Dec 19, 2009 4:12 pm
Posts: 3
m4rw3r, thank you for this module. I have just started with CI, and after checking several options here I come ^_^

I have used Cake for a while, and coming from Cake it makes me a bit lazy. With Cake, I only have to specify the table name (actually, I dont even have to if the table name and the model name follow the convention), and Cake will automatically figure out the column names for me as well. I wonder if that should be possible here?

Also, it seems a bit redundant and can be a source of problem to have data_model/ with 2 new files for each table/model? Can't we put the new information into model/?

say for example in my model I already have article.php which contains my model class (for CI), can't I just simply add new variables, methods etc here?


Top
Offline Profile  
 
 Post subject: Re: Quick start with CodeIgniter
PostPosted: Mon Dec 21, 2009 1:55 pm 
Site Admin

Joined: Sun Dec 13, 2009 10:46 pm
Posts: 62
Well, you can add variables there, but then RDM will create several instances of it because the DataMapper pattern manages objects, not only a single main instance as ActiveRecord allows.
So I recommend you to have a separate data object, which you can store in the model dir or with the model class (but then you'd have to load that before querying the database).

You can also create the descriptor there too, by creating a new instance of Db_Descriptor and configuring it as you see fit. But that will require you to load the model before you start to query the database (which is definitely feasible).
To do that with good performance, I suggest you to look into Chapter 11: Alternatives To the Db_Descriptor in the RDM manual (describes how you can hook a method which will create the appropriate descriptor only when needed).

About figuring things out, I have planned a "Create files from database" feature which will automatically create the files for you.

The reason I have chosen to have the files like that is because of two reasons: firstly *you* have more control over the database mapping and secondly you get better performance when you don't have to load the database descriptor when you already have the generated result cached.


Top
Offline Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
RapidDataMapper is copyright © Martin Wernståhl