Welcome Guest, Not a member yet? Register   Sign In
Doctrine integration
#1

(This post was last modified: 11-16-2019, 08:31 PM by ScientiFist.)

Hi,
I'm trying to integrate doctrine 2.6.4 with CI 4.

Doctrine was installed via composer.

App/Libraries/Doctrine.php
Code:
<?php

include_once dirname(__DIR__, 2) . '/vendor/autoload.php';

use Doctrine\Common\ClassLoader;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\Mapping\Driver\YamlDriver;


class Doctrine
{

    public $em;

    public function __construct()
    {


        $connection_options = array(
            'driver'        => 'pdo_mysql',
            'user'            => 'root',
            'password'    => 'password',
            'host'            => 'localhost',
            'dbname'        => 'project',
            'charset'        => 'utf8',
            'driverOptions'    => array(
                'charset'    => 'utf8',
            ),
        );

        $models_namespace = 'Entities';
        $models_path = APPPATH . 'Models';
        $proxies_dir = APPPATH . 'Models/Proxies';
        $metadata_paths = array(APPPATH . 'Models/Entities');

        $dev_mode = true;
        $cache = null;
        $useSimpleAnnotationReader = false;
        $config = Setup::createAnnotationMetadataConfiguration($metadata_paths, $dev_mode, $proxies_dir, $cache, $useSimpleAnnotationReader);
        $this->em = EntityManager::create($connection_options, $config);

        //YAML
        $yamlDriver = new YamlDriver(APPPATH . 'Models/Mappings');
        $config->setMetadataDriverImpl($yamlDriver);
        $loader = new ClassLoader($models_namespace, $models_path);
        $loader->register();
    }

}

App/Doctrine.php
Code:
<?php


define('APPPATH', dirname(__FILE__) . '/');
define('ENVIRONMENT', 'development');

chdir(APPPATH);

require __DIR__ . '/Libraries/Doctrine.php';

foreach ($GLOBALS as $helperSetCandidate) {
    if ($helperSetCandidate instanceof \Symfony\Component\Console\Helper\HelperSet) {
        $helperSet = $helperSetCandidate;
        break;
    }
}

$doctrine = new Doctrine;
$em = $doctrine->em;

$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
    'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
    'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
));

\Doctrine\ORM\Tools\Console\ConsoleRunner::run($helperSet);

Everything is working with the console i can render Entities via YML Mappings so everything is connected to my db and so on

Then i'm just calling doctrine in the Base controller in CI 3 i was using the load->library

Quote:require APPPATH.'/Libraries/Doctrine.php';

And here is the problem i can't initiate the entityManager i tried in different way but im all the time getting a undefined property or undefinedclass :

PHP Code:
<?php namespace App\Controllers;

class 
Home extends BaseController
{


    public function 
index()
    {

         //TEST 1
         $em $this->doctrine->getEntityManager();

         //TEST 2 with the name of my entities
         $test= new DebugTest();

        return 
view('welcome_message');
    }





I know it's maybe complicated or me who's missing something but would be amazing any kind of help, a lot of users of CI are using doctrine as an orm and would really help me for my future project
Reply
#2

(This post was last modified: 11-17-2019, 04:41 AM by MGatner.)

THere's probably going to be a lot of collision that will have to be handled. I haven't ever used Doctrine, but from your example above it looks like Doctrine might need its own APPPATH? That would cause problems with the framework for sure. I would recommend looking into Composer integration for starters, as that will handle the autoloading. Also read up on namespaces and how CI4 is different than CI3 when it comes to loading and the super object (e.g. you can't use $this->doctrine):
https://codeigniter4.github.io/CodeIgnit...dules.html

I guess I should add that I have a module to help with adding relationship loading to CI4. I'm not a fan of ORM but this might get at some of the eager/lazy loading and easy access that ORMs provide:
https://github.com/tattersoftware/codeig...-relations
Note that there's a major release in the works on branch develop, so the current stable release will differ some.
Reply
#3

Did you read the documentation?

You need to create an instance of the Entity Manager before you can use it.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#4

Also to mention this package which hasn’t been touched in a while but is the best CodeIgniter 4 style ORM I have seen worked on
https://github.com/hlohrenz/CI4-Relation...ry-Builder
Reply
#5

(This post was last modified: 11-17-2019, 06:03 PM by ScientiFist.)

(11-17-2019, 04:50 AM)InsiteFX Wrote: Did you read the documentation?

You need to create an instance of the Entity Manager before you can use it.
Here was the problem i didn't create the instance...

I added the namespace for my Doctrine.php in libraries

PHP Code:
<?php
namespace App\Libraries;

include_once 
dirname(__DIR__2) . '/vendor/autoload.php'

Thank you MGatner ! I didn't saw this way to load a library
PHP Code:
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        
// Do Not Edit This Line
        
parent::initController($request$response$logger);

        
//--------------------------------------------------------------------
        // Preload any models, libraries, etc, here.
        //--------------------------------------------------------------------
        // E.g.:
        // $this->session = \Config\Services::session();

        
$doctrine = new \App\Libraries\Doctrine;
        
$em $doctrine->em;

        
$test $em->getRepository('Entities\DebugTable')->findAll();
        
var_dump($test);
    } 
I'm getting back the data so it's perfect. Big Grin 


Last question my Home controller extend from this BaseController. 
So how i can get my back my $em object in my controllers from this initController?
Reply
#6

Since it seems like Doctrine already works very nicely with namespaces, and supplies a singular reference and object, I would recommend writing a service definition for it. That time you can load it anywhere you want with `service(‘doctrine’)` and the services will take care of continuity for you.
Reply
#7

(11-18-2019, 05:31 AM)MGatner Wrote: Since it seems like Doctrine already works very nicely with namespaces, and supplies a singular reference and object, I would recommend writing a service definition for it. That time you can load it anywhere you want with `service(‘doctrine’)` and the services will take care of continuity for you.

Amazing thank you a lot, everything is working  Big Grin

So i added doctrine as a service 
PHP Code:
class Services extends CoreServices
{

  //DOCTRINE SERVICE CLASS
  public static function doctrine(){
    // INITIATE
    $doctrine = new \App\Libraries\Doctrine;
    // SHORTCUT ENTITY MANAGER
    $em $doctrine->em;
    // RETURN ENTITY MANAGER
    return $em;
  }



and then im calling it like this in my Home controller
PHP Code:
    public function index()
    {
        
// CALLING THE SERVICE WAY 1
        
$em = \Config\Services::doctrine();
        
// CALLING THE SERVICE WAY 2
    
  //    $em = service('doctrine');

        
$test $em->getRepository('Entities\DebugTable')->findAll();
        
var_dump($test);
        return 
view('welcome_message');
    } 

 Just small question there is not a way to call this service for all my controllers instead of calling it each time i want to use it? 

Quote:Ps: I will send all the files and the explanation how i got doctrine working with code igniter after i received some PM about it
Reply
#8

That’s a good start! I’d recommend adding a getShared clause, as this is what helps your service save resources by returning a common instance. If I’m understanding Doctrine correctly, you don’t want to load a fresh instance on every call. Check out Lonnie’s examples in his auth library:
https://github.com/lonnieezell/myth-auth...rvices.php

There should be no need to carry around the $em object, but if you really find yourself needing it all the time in controllers you can load it in BaseController ($this->em = $em) and then extend that.
Reply
#9

Here is it with the getshared: (Hope is working like that) 
PHP Code:
class Services extends CoreServices
{

  //DOCTRINE SERVICE CLASS
    public static function doctrine($getShared false)
    {
      if (! $getShared)
       {
        // INITIATE
        $doctrine = new \App\Libraries\Doctrine;
        // SHORTCUT ENTITY MANAGER
        $em $doctrine->em;
        // RETURN ENTITY MANAGER
        return $em;
      }
      return static::getSharedInstance('doctrine');
    }
    


But i didn't get what do you meant with the '$em' ?
Reply
#10

(11-18-2019, 10:34 AM)ScientiFist Wrote:
(11-18-2019, 05:31 AM)MGatner Wrote: Since it seems like Doctrine already works very nicely with namespaces, and supplies a singular reference and object, I would recommend writing a service definition for it. That time you can load it anywhere you want with `service(‘doctrine’)` and the services will take care of continuity for you.

Amazing thank you a lot, everything is working  Big Grin

So i added doctrine as a service 
PHP Code:
class Services extends CoreServices
{

  //DOCTRINE SERVICE CLASS
  public static function doctrine(){
    // INITIATE
    $doctrine = new \App\Libraries\Doctrine;
    // SHORTCUT ENTITY MANAGER
    $em $doctrine->em;
    // RETURN ENTITY MANAGER
    return $em;
  }



and then im calling it like this in my Home controller
PHP Code:
    public function index()
    {
        
// CALLING THE SERVICE WAY 1
        
$em = \Config\Services::doctrine();
        
// CALLING THE SERVICE WAY 2
    
  //    $em = service('doctrine');

        
$test $em->getRepository('Entities\DebugTable')->findAll();
        
var_dump($test);
        return 
view('welcome_message');
    } 

 Just small question there is not a way to call this service for all my controllers instead of calling it each time i want to use it? 

Quote:Ps: I will send all the files and the explanation how i got doctrine working with code igniter after i received some PM about it


Hello ScientiFist,

Would you be willing to post instructions for using your Doctrine implementation?
I am interested in trying it out!

I've noticed the CodeIgniter4 Playground has Doctrine installed in the vendor directory after performing a
Code:
composer update
, but it lacks any Doctrine implementation example.

Best regards,

Jason Ziegler

(Using CodeIgniter since 1.x)
Reply




Theme © iAndrew 2016 - Forum software by © MyBB