Welcome Guest, Not a member yet? Register   Sign In
Drop-in PHP Doctrine plugin
#1

[eluser]Nick Husher[/eluser]
CI-Doctrine - built for Doctrine 1.0 (included in package)

A colleague of mine recently turned me on to Doctrine, an Object-Relational Mapper for PHP5. There are plenty of great resources that explain exactly what using an ORM gets you, but for me it boils down to being able to transparently serialize objects into my database in a human-understandable way.

The problem is that Doctrine didn't really have CodeIgniter in mind when it was developed, so it can be a little difficult and confusing to install it in such a way as to be maintainable and comfortable to use for a CI developer. I read the Wiki article, which is a little dated (for version 0.1 rather that version 1.0), and requires hacking of core CodeIgniter files. I also found a helpful blog entry, which migrates any core hacking out into a hook, but it still required some configuration and couldn't be selectively disabled on some pages (not every page needs that kind of page overhead). I want drop-in-and-go ease, and flexibility.

So, I developed my own solution in the form of a CI plugin. It grabs information from the database.php configuration file, just like the hook, but is as simple as dropping it into your CI plugins directory and writing your schema file.

The Readme file follows:
#2

[eluser]Nick Husher[/eluser]
Requirements:
* A database supported by Doctrine
* CodeIgniter (tested on v1.7)
* PHP5
* A working PDO library for your database of choice

Installation:
1. Drop this extracted directory into the plugins folder of your CI system directory.
2. Create a directory within your application folder called "doctrine"
2a. Create three directories within this doctrine directory named "fixtures", "models", and "schema". Make sure the "models" directory has full write access (chmod 777)
4. Configure your database connection as you would for CodeIgniter

The schema directory will be where the Doctrine plugin will look for your yaml schema files as per the Doctrine manual. Models generated from those yaml files will be saved in the models directory (which is why the directory must have full write access). The fixtures directory contains any fixture data you may want to include: this data will be inserted into the database whenever the doctrine_populate_database method is called (more on that below).


Configuration:
The Doctrine plugin uses the database information as it exists in the database configuration file (/system/application/config/database.php). It should require zero configuration to install properly.

Using Doctrine:
To use Doctrine, you must first load the plugin into CodeIgniter. This can be done with "$this->load->plugin('doctrine')". From there, you gain access to the the full doctrine API, which should behave very much like a typical PHP project. In addition, there are some useful convenience functions added to the plugin file that make development (particularly developing schema and fixture information) more expedient.

The primary ones are doctrine_install, doctrine_uninstall, and doctrine_reinstall. The install function will generate model files from the schema yaml, then instantiate the database using the CI configuration files, then insert the fixture data. Uninstall will do just the opposite: it will drop all the tables that were created by Doctrine and delete all the model files.

You can control the order in which these things take place with a set of utility functions:

doctrine_create_database: Creates the database from the doctrine model files it finds in the models directory. If there are no models in this directory, it will run doctrine_create_models before generating the database.

doctrine_populate_database: Populates the database with data defined in your fixtures directory. Requires an installed database and generated models. It does not generate these things automatically.

doctrine_destroy_database: Drops all tables created by Doctrine. Any tables that were not created or maintained by Doctrine will not be deleted.

doctrine_create_models: Generates model files from the schema files found in the schema directory.

doctrine_destroy_models: Deletes all files in the doctrine models directory.

Troubleshooting:
If you are unable to run the install function successfully, and are running Mac OS X, check if there is a .DS_Store file in your doctrine models directory. If so, delete it.
#3

[eluser]Muser[/eluser]
Thank you for your contribution!

I started with doctrine 3 days ago and I'm a really newbie... Sad
I am using the implementation of the blog post that you say.

Using this->load->plugin('doctrine') PHP IDE like NetBeans or Eclipse PDT have autocompletion?

Now I'm learning DQL language from the Doctrine documentation (the getting started and how to guides from Doctine project official page ara excellent). Doctrine documentation.

Do you alternate doctrine querys and ci-db queries or Do you only are using doctrine?
Libraries like CI_Session, or authentication libraries of the community are using ci-db database library... Are you recoding this libraries for use with Doctrine?
#4

[eluser]Nick Husher[/eluser]
You can use Active Record, raw SQL, and Doctrine interchangably. The goal was to integrate Doctrine as quickly as possible without damaging any core CI functionality or hobbling Doctrine unnecessarily.

If you're looking for something like CodeIgniter with a built-in ORM mapper, check out Kohana.
#5

[eluser]GSV Sleeper Service[/eluser]
nice one, thanks Nick
#6

[eluser]acpbl[/eluser]
Many thanks for this.

Any idea on whether version 1.1 can be adapted in a similar fashion?

In general what are your experiences with doctrine? Is it stable enough for a production environment? What about performance? I understand ofcourse there will be opportunities for optimising specific heavy queries with custom code. But for the standard things is there any significant impact on performance?
#7

[eluser]RedLeader[/eluser]
First off, thanks for a great plugin.

I currently have an issue with autoloading "conservative" and "aggressive" and I wanted to see if you could help me.

I was reading the Doctrine 1.0 manual about Autoloading here:
http://www.doctrine-project.org/document...ing-models

I want to lazy load my classes (conservative) because there is a slight performance boost because not all the classes get loaded everytime:
Code:
[FILE: doctrine_pi.php]
Doctrine_Manager::getInstance()->setAttribute('model_loading', Doctrine::MODEL_LOADING_CONSERVATIVE);

However, when I try this I get an error in the browser.
Here's the error:
Code:
Fatal error: Uncaught exception 'Doctrine_Table_Exception' with message 'Unknown method Doctrine_Table::getCreatedToday' in C:\Projects\www\projectx\system\plugins\doctrine\Doctrine\Table.php:2283
Stack trace:
#0 [internal function]: Doctrine_Table->__call('getCreatedToday', Array)
#1 C:\Projects\www\projectx\system\application\controllers\backend.php(288): Doctrine_Table->getCreatedToday()
#2 [internal function]: Backend->categories()
#3 C:\Projects\www\projectx\system\codeigniter\CodeIgniter.php(232): call_user_func_array(Array, Array)
#4 C:\Projects\www\projectx\www\index.php(116): require_once('C:\Projects\www...')
#5 {main} thrown in C:\Projects\www\projectx\system\plugins\doctrine\Doctrine\Table.php on line 2283

It appears the function getCreatedToday() isn't being recognised as a method of my CategoryTable class. Strange because it is there in my class:
Code:
<?php

/**
* This class has been auto-generated by the Doctrine ORM Framework
*/
class CategoryTable extends Doctrine_Table
{

    public function getCreatedToday()
    {
        return 'yo!';
    }
}

As you can see I have only built a test method called getCreatedToday() which doesn't do much. However, that's not the point as the method itself isn't being found.

Note that this error doesn't occur when I autoload aggressively (which is the default but I will state this line of code for clarity):
Code:
Doctrine_Manager::getInstance()->setAttribute('model_loading', Doctrine::MODEL_LOADING_AGGRESSIVE);


Can anyone please tell me why it's not finding my method when "conservative" autoloading?

Thanks for any help with this!
#8

[eluser]GSV Sleeper Service[/eluser]
can you post line 288 of your 'backend' controller? I've had no problems with conservative loading
#9

[eluser]RedLeader[/eluser]
[quote author="GSV Sleeper Service" date="1237926061"]can you post line 288 of your 'backend' controller? I've had no problems with conservative loading[/quote]

Sure, it's just the call to the method:
Code:
public function categories()
{
    $categoryTable = Doctrine::getTable('Category');
    $categories = $categoryTable->getCreatedToday(); // line 288
    $this->load_template_view('backend/categories', $data);
}
#10

[eluser]GSV Sleeper Service[/eluser]
most odd, these are my doctrine autoload settings, they're probably out of date, I've been using these since Doctrine 1.0.1, but they're still working with 1.1
Code:
Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_MODEL_LOADING, Doctrine::MODEL_LOADING_CONSERVATIVE);
Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES, TRUE);




Theme © iAndrew 2016 - Forum software by © MyBB