jueves, 23 de abril de 2015

Utilizar Doctrine en CodeIgniter

Veamos cómo integrar Doctrine en codeigniter 3.0.0; este ejemplo esta basado
en el siguiente post:  http://codesamplez.com/development/using-doctrine-with-codeigniter

1. descargamos CodeIgniter 3.0.0, lo descomprimimos y lo renombramos como:  ci_doctrine.

2. creamos una base de tatos con el nombre de: ci_doctrine; dentramos a esta y ejecutamos el siguiente codigo en la pestaña SQL


CREATE TABLE IF NOT EXISTS `entradas` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `titulo` varchar(150) NOT NULL,
  `contenido` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

--
-- Dumping data for table `entradas`
--

INSERT INTO `entradas` (`id`, `titulo`, `contenido`) VALUES
(1, 'Entrada 1', 'Contenido 1'),
(2, 'Entrada 2', 'Contenido 2'),
(3, 'Entrada 3', 'Contenido 3');  
3. descargamos: Doctrine  versión 2.3.3; descrompimos el archivo y dentro de esta sacamos la carpeta Doctrine y la colocamos en: ci_doctrine/application/third_party

4. configuramos la url del proyecto en: ci_doctrine/application/config/config.php

$config['base_url'] = 'http://localhost/ci_doctrine/';
 5. en ci_doctrine/application/config/autload.php cargamos las librerias

$autoload['libraries'] = array('database', 'doctrine');
6. en ci_doctrine/application/config/routes.php cambiamos el controlador por posts
$route['default_controller'] = 'posts';
7. configuramos el acceso a la base de datos: ci_doctrine/application/config/database.php
    $db['default']['hostname'] = 'localhost';
    $db['default']['username'] = 'root';
    $db['default']['password'] = '';
    $db['default']['database'] = 'ci_doctrine';
5. creamos un archivo llamado Doctrine.php en: ci_doctrine/application/libraries; colocamos el siguiente código:

 <?php
use Doctrine\Common\ClassLoader,
    Doctrine\ORM\Configuration,
    Doctrine\ORM\EntityManager,
    Doctrine\Common\Cache\ArrayCache,
    //Doctrine\DBAL\Logging\EchoSQLLogger,
    Doctrine\ORM\Mapping\Driver\DatabaseDriver,
    Doctrine\ORM\Tools\DisconnectedClassMetadataFactory,
    Doctrine\ORM\Tools\EntityGenerator;

/**
 * CodeIgniter Smarty Class
 *
 * initializes basic doctrine settings and act as doctrine object
 *
 * @final   Doctrine
 * @category    Libraries
 * @author  Md. Ali Ahsan Rana
 * @link    http://codesamplez.com/
 */
class Doctrine {

  /**
   * @var EntityManager $em
   */
    public $em = null;

  /**
   * constructor
   */
  public function __construct()
  {
    // load database configuration from CodeIgniter
    require APPPATH.'config/database.php';
    
    // Set up class loading. You could use different autoloaders, provided by your favorite framework,
    // if you want to.
    require_once APPPATH.'third_party/Doctrine/Common/ClassLoader.php';

    $doctrineClassLoader = new ClassLoader('Doctrine',  APPPATH.'third_party');
    $doctrineClassLoader->register();
    $entitiesClassLoader = new ClassLoader('models', rtrim(APPPATH, "/" ));
    $entitiesClassLoader->register();
    $proxiesClassLoader = new ClassLoader('proxies', APPPATH.'models');
    $proxiesClassLoader->register();

    // Set up caches
    $config = new Configuration;
    $cache = new ArrayCache;
    $config->setMetadataCacheImpl($cache);
    $driverImpl = $config->newDefaultAnnotationDriver(array(APPPATH.'models/Entidades'));
    $config->setMetadataDriverImpl($driverImpl);
    $config->setQueryCacheImpl($cache);

    // Proxy configuration
    $config->setProxyDir(APPPATH.'models/proxies');
    $config->setProxyNamespace('Proxies');

    // Set up logger
    //$logger = new EchoSQLLogger;
    //$config->setSQLLogger($logger);

    $config->setAutoGenerateProxyClasses( TRUE ); 
    // Database connection information
    $connectionOptions = array(
        'driver' => 'pdo_mysql',
        'user' =>     $db['default']['username'],
        'password' => $db['default']['password'],
        'host' =>     $db['default']['hostname'],
        'dbname' =>   $db['default']['database']
    );

    // Create EntityManager
    $this->em = EntityManager::create($connectionOptions, $config);     
    
  }

  //------------------------------------------
 
/**
   * generate entity objects automatically from mysql db tables
   * @return none
   */ 
 
    function generate_classes(){   
          
        $this->em->getConfiguration()
                 ->setMetadataDriverImpl(
                    new DatabaseDriver(
                            $this->em->getConnection()->getSchemaManager()
                    )
        );
   
        $cmf = new DisconnectedClassMetadataFactory();
        $cmf->setEntityManager($this->em);
        $metadata = $cmf->getAllMetadata();   
        $generator = new EntityGenerator();
        
        $generator->setUpdateEntityIfExists(true);
        $generator->setGenerateStubMethods(true);
        $generator->setGenerateAnnotations(true);
        $generator->generate($metadata, APPPATH."models/Entidades");
        
      }
   
    //------------------------------------------ 
         

}
6. vamos a: ci_doctrine/application/controllers y creamos un controlador llamado: Posts.php y colocamos el siguiente codigo:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');


class Posts extends CI_Controller {

    public function __construct(){
        parent::__construct();        
            $this->load->model('Entradas_model');       
    }
   
    //--------------------------------

    public function index()
    {       
        $data['titulo'] = 'CodeIgniter 3 + Doctrine 2.3.3 ';       
        $data['entradas'] = $this->Entradas_model->get_entradas();
       
        $this->load->view('entradas_view', $data);        
    }
   
    //--------------------------------------
   
    public function crear_entidades()
    { 
        // Después de crear las entidades comentamos
        $this->doctrine->generate_classes();  
    }
   

}
 7. vamos a: ci_doctrine/application/models, creamos un modelo con el nombre de: Entradas_model.php  y copiamos:
<?php

require_once(APPPATH."models/Entidades/Entradas.php");

class Entradas_model extends CI_Model {

    var $em;
    
    public function __construct() {
        parent::__construct();
        $this->em = $this->doctrine->em;
    }
   
  //--------------------------------   
       
  function get_entradas(){   
     return $this->em->getRepository('Entradas')->findAll();   
  }   
 
  //------------------------------
 
}
8. vamos al modelo(Entradas_model) y comentamos por un momento las linea 3; cuando se hallan creado las entidades las descomentamos, si ya existieran y fueramos a actulizar no necesitariomos comentar. visitamos la siguiente ulr: http://ci_doctrine/index.php/posts/crear_entidades, de este modo creamos la entidades, luego ya podemos comentar la linea(26 controlador) y descomentar en el modelo las lineas 3 que llama al método de la clase Doctrine.php(libraries); cuando necesitemos actualizar o crear nuevas entidades de la BD descomentamos y repetimos este paso.  la carpeta models debe tener permiso de escritura(usuarios linux).

9. Si dejaramos así la entidad creada nos daría un error; entoncres abrimos este archivo y quitamos de las anotaciones donde diga: ORM\ Si estamos en NetBeans o SublimeText buscamos con ctrl+f y reemplazamos en blanco con ctrl+h; en Aptana automaticamente tenemos la opción de reemplzar.

10. creamos una vista en: ci_doctrine/application/views con el nombre de entradas_view.php; así solo es ir a localhost/ci_doctrine y debería funcionar.
    <!DOCTYPE html>
    <html lang="en">
    <head>
            <meta charset="utf-8">
            <title><?php echo $titulo ?></title>
    </head>
    <body>

    <h3><?php echo $titulo; ?></h3>
    <?php

        foreach($entradas as $entrada){
                    echo '<b>'.$entrada->getTitulo().'</b>: '.$entrada->getContenido().'</br>';
        }
    ?>

    </body>
    </html>
Descargar ejemplo