├── .gitignore ├── phpunit.php ├── cli-config.php ├── phpunit.xml.dist ├── composer.json ├── LICENSE.md ├── README.md ├── ci_instance.php ├── tests └── libraries │ └── DoctrineTest.php └── libraries └── Doctrine.php /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | nbproject/ 3 | 4 | ## Composer 5 | /composer.lock 6 | /vendor/ 7 | -------------------------------------------------------------------------------- /phpunit.php: -------------------------------------------------------------------------------- 1 | 6 | * @license MIT License 7 | * @copyright 2015 Kenji Suzuki 8 | * @link https://github.com/kenjis/codeigniter-doctrine 9 | */ 10 | 11 | error_reporting(E_ALL); 12 | 13 | require __DIR__ . '/vendor/autoload.php'; 14 | 15 | use Doctrine\ORM\Tools\Console\ConsoleRunner; 16 | 17 | define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development'); 18 | define('BASEPATH', __DIR__ . '/vendor/codeigniter/framework/system/'); 19 | define('APPPATH', __DIR__ . '/application/'); 20 | 21 | require APPPATH . 'libraries/Doctrine.php'; 22 | $doctrine = new Doctrine(); 23 | 24 | return ConsoleRunner::createHelperSet($doctrine->em); 25 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | tests 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | vendor/codeigniter/framework/application/libraries 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kenjis/codeigniter-doctrine", 3 | "type": "codeigniter-library", 4 | "description": "A simple Doctrine integration for CodeIgniter 3.x", 5 | "keywords": [ 6 | "codeigniter", 7 | "doctrine" 8 | ], 9 | "license": "MIT", 10 | "authors": [ 11 | { 12 | "name": "Kenji Suzuki", 13 | "homepage": "https://github.com/kenjis/codeigniter-doctrine" 14 | } 15 | ], 16 | "autoload": { 17 | "classmap": [ "libraries/Doctrine.php" ] 18 | }, 19 | "require": { 20 | "php": ">=5.4.0", 21 | "doctrine/orm": "~2.5", 22 | "composer/installers": "~1.0" 23 | }, 24 | "require-dev": { 25 | "codeigniter/framework": "~3.0" 26 | }, 27 | "extra": { 28 | "branch-alias": { 29 | "dev-master": "1.0.x-dev" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2015 Kenji Suzuki 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeIgniter Doctrine 2 | 3 | This package provides simple Doctrine integration for [CodeIgniter](https://github.com/bcit-ci/CodeIgniter) 3.x. 4 | 5 | ## Folder Structure 6 | 7 | ``` 8 | codeigniter/ 9 | └── application/ 10 |     └── libraries/ 11 |         └── codeigniter-doctrine/ 12 |             └── libraries/ 13 |                 └── Doctrine.php 14 | ``` 15 | 16 | ## Requirements 17 | 18 | * PHP 5.4.0 or later 19 | * Composer 20 | 21 | ## Installation 22 | 23 | Install this project with Composer: 24 | 25 | ~~~ 26 | $ cd /path/to/codeigniter/ 27 | $ composer require kenjis/codeigniter-doctrine:1.0.x@dev 28 | ~~~ 29 | 30 | ## Usage 31 | 32 | Load Doctrine library: 33 | 34 | ~~~php 35 | $this->load->library('Doctrine'); 36 | ~~~ 37 | 38 | Use the entity manager: 39 | 40 | ~~~php 41 | $em = $this->doctrine->em; 42 | ~~~ 43 | 44 | Use `doctrine` command: 45 | 46 | ~~~ 47 | $ cd /path/to/codeigniter/ 48 | $ vendor/bin/doctrine 49 | ~~~ 50 | 51 | ### Reference 52 | 53 | * http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/ 54 | 55 | ## Related Projects for CodeIgniter 3.x 56 | 57 | * [CodeIgniter Composer Installer](https://github.com/kenjis/codeigniter-composer-installer) 58 | * [Cli for CodeIgniter 3.0](https://github.com/kenjis/codeigniter-cli) 59 | * [ci-phpunit-test](https://github.com/kenjis/ci-phpunit-test) 60 | * [CodeIgniter Simple and Secure Twig](https://github.com/kenjis/codeigniter-ss-twig) 61 | * [CodeIgniter Deployer](https://github.com/kenjis/codeigniter-deployer) 62 | -------------------------------------------------------------------------------- /ci_instance.php: -------------------------------------------------------------------------------- 1 | 6 | * @license MIT License 7 | * @copyright 2015 Kenji Suzuki 8 | * @link https://github.com/kenjis/codeigniter-doctrine 9 | * 10 | * Based on http://codeinphp.github.io/post/codeigniter-tip-accessing-codeigniter-instance-outside/ 11 | * Thanks! 12 | */ 13 | 14 | define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development'); 15 | 16 | $system_path = 'vendor/codeigniter/framework/system'; 17 | $application_folder = 'vendor/codeigniter/framework/application'; 18 | $doc_root = 'vendor/codeigniter/framework'; 19 | 20 | if (realpath($system_path) !== false) { 21 | $system_path = realpath($system_path) . '/'; 22 | } 23 | $system_path = rtrim($system_path, '/') . '/'; 24 | 25 | define('BASEPATH', str_replace("\\", "/", $system_path)); 26 | define('FCPATH', $doc_root . '/'); 27 | define('APPPATH', $application_folder . '/'); 28 | define('VIEWPATH', $application_folder . '/views/'); 29 | 30 | require(BASEPATH . 'core/Common.php'); 31 | 32 | if (file_exists(APPPATH . 'config/' . ENVIRONMENT . '/constants.php')) { 33 | require(APPPATH . 'config/' . ENVIRONMENT . '/constants.php'); 34 | } else { 35 | require(APPPATH . 'config/constants.php'); 36 | } 37 | 38 | $charset = strtoupper(config_item('charset')); 39 | ini_set('default_charset', $charset); 40 | 41 | if (extension_loaded('mbstring')) { 42 | define('MB_ENABLED', TRUE); 43 | // mbstring.internal_encoding is deprecated starting with PHP 5.6 44 | // and it's usage triggers E_DEPRECATED messages. 45 | @ini_set('mbstring.internal_encoding', $charset); 46 | // This is required for mb_convert_encoding() to strip invalid characters. 47 | // That's utilized by CI_Utf8, but it's also done for consistency with iconv. 48 | mb_substitute_character('none'); 49 | } else { 50 | define('MB_ENABLED', FALSE); 51 | } 52 | 53 | // There's an ICONV_IMPL constant, but the PHP manual says that using 54 | // iconv's predefined constants is "strongly discouraged". 55 | if (extension_loaded('iconv')) { 56 | define('ICONV_ENABLED', TRUE); 57 | // iconv.internal_encoding is deprecated starting with PHP 5.6 58 | // and it's usage triggers E_DEPRECATED messages. 59 | @ini_set('iconv.internal_encoding', $charset); 60 | } else { 61 | define('ICONV_ENABLED', FALSE); 62 | } 63 | 64 | $GLOBALS['CFG'] = & load_class('Config', 'core'); 65 | $GLOBALS['UNI'] = & load_class('Utf8', 'core'); 66 | $GLOBALS['SEC'] = & load_class('Security', 'core'); 67 | 68 | load_class('Loader', 'core'); 69 | load_class('Router', 'core'); 70 | load_class('Input', 'core'); 71 | load_class('Lang', 'core'); 72 | 73 | require(BASEPATH . 'core/Controller.php'); 74 | 75 | function &get_instance() 76 | { 77 | return CI_Controller::get_instance(); 78 | } 79 | 80 | return new CI_Controller(); 81 | -------------------------------------------------------------------------------- /tests/libraries/DoctrineTest.php: -------------------------------------------------------------------------------- 1 | obj = new Doctrine(); 10 | } 11 | 12 | public function test_convertDbConfig_sqlite_pdo_1() 13 | { 14 | $db['default'] = [ 15 | 'dsn' => '', 16 | 'hostname' => 'sqlite:' . APPPATH . 'ci_test.sqlite', 17 | 'username' => '', 18 | 'password' => '', 19 | 'database' => '', 20 | 'dbdriver' => 'pdo', 21 | 'dbprefix' => '', 22 | 'pconnect' => FALSE, 23 | 'db_debug' => TRUE, 24 | 'cache_on' => FALSE, 25 | 'cachedir' => '', 26 | 'char_set' => 'utf8', 27 | 'dbcollat' => 'utf8_general_ci', 28 | 'swap_pre' => '', 29 | 'encrypt' => FALSE, 30 | 'compress' => FALSE, 31 | 'stricton' => FALSE, 32 | 'failover' => array(), 33 | 'save_queries' => TRUE 34 | ]; 35 | 36 | $actual = $this->obj->convertDbConfig($db['default']); 37 | $expected = [ 38 | 'driver' => 'pdo_sqlite', 39 | 'user' => '', 40 | 'password' => '', 41 | 'path' => 'vendor/codeigniter/framework/application/ci_test.sqlite', 42 | ]; 43 | $this->assertEquals($expected, $actual); 44 | } 45 | 46 | public function test_convertDbConfig_sqlite_pdo_2() 47 | { 48 | $db['default'] = [ 49 | 'dsn' => 'sqlite:' . APPPATH . 'ci_test.sqlite', 50 | 'hostname' => 'localhost', 51 | 'username' => 'sqlite', 52 | 'password' => 'sqlite', 53 | 'database' => 'sqlite', 54 | 'dbdriver' => 'pdo', 55 | 'subdriver' => 'sqlite' 56 | ]; 57 | 58 | $actual = $this->obj->convertDbConfig($db['default']); 59 | $expected = [ 60 | 'driver' => 'pdo_sqlite', 61 | 'user' => 'sqlite', 62 | 'password' => 'sqlite', 63 | 'path' => 'vendor/codeigniter/framework/application/ci_test.sqlite', 64 | ]; 65 | $this->assertEquals($expected, $actual); 66 | } 67 | 68 | public function test_convertDbConfig_mysqli() 69 | { 70 | $db['default'] = [ 71 | 'dsn' => '', 72 | 'hostname' => 'localhost', 73 | 'username' => 'username', 74 | 'password' => 'password', 75 | 'database' => 'codeigniter', 76 | 'dbdriver' => 'mysqli', 77 | 'dbprefix' => '', 78 | 'pconnect' => FALSE, 79 | 'db_debug' => TRUE, 80 | 'cache_on' => FALSE, 81 | 'cachedir' => '', 82 | 'char_set' => 'utf8', 83 | 'dbcollat' => 'utf8_general_ci', 84 | 'swap_pre' => '', 85 | 'encrypt' => FALSE, 86 | 'compress' => FALSE, 87 | 'stricton' => FALSE, 88 | 'failover' => array(), 89 | 'save_queries' => TRUE 90 | ]; 91 | 92 | $actual = $this->obj->convertDbConfig($db['default']); 93 | $expected = [ 94 | 'driver' => 'mysqli', 95 | 'user' => 'username', 96 | 'password' => 'password', 97 | 'host' => 'localhost', 98 | 'dbname' => 'codeigniter', 99 | 'charset' => 'utf8' 100 | ]; 101 | $this->assertEquals($expected, $actual); 102 | } 103 | 104 | public function test_convertDbConfig_pdo_mysql() 105 | { 106 | $db['default'] = [ 107 | 'dsn' => 'mysql:host=localhost;dbname=ci_test', 108 | 'hostname' => 'localhost', 109 | 'username' => 'travis', 110 | 'password' => 'password', 111 | 'database' => 'ci_test', 112 | 'char_set' => 'utf8', 113 | 'dbdriver' => 'pdo', 114 | 'subdriver' => 'mysql' 115 | ]; 116 | 117 | $actual = $this->obj->convertDbConfig($db['default']); 118 | $expected = [ 119 | 'driver' => 'pdo_mysql', 120 | 'user' => 'travis', 121 | 'password' => 'password', 122 | 'host' => 'localhost', 123 | 'dbname' => 'ci_test', 124 | 'charset' => 'utf8' 125 | ]; 126 | $this->assertEquals($expected, $actual); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /libraries/Doctrine.php: -------------------------------------------------------------------------------- 1 | 6 | * @license MIT License 7 | * @copyright 2015 Kenji Suzuki 8 | * @link https://github.com/kenjis/codeigniter-doctrine 9 | */ 10 | 11 | /* 12 | * This code is based on http://doctrine-orm.readthedocs.org/en/latest/cookbook/integrating-with-codeigniter.html 13 | */ 14 | 15 | use Doctrine\Common\ClassLoader; 16 | use Doctrine\ORM\Configuration; 17 | use Doctrine\ORM\EntityManager; 18 | use Doctrine\Common\Cache\ArrayCache; 19 | use Doctrine\DBAL\Logging\EchoSQLLogger; 20 | 21 | class Doctrine 22 | { 23 | /** 24 | * @var EntityManager|null 25 | */ 26 | public $em = null; 27 | 28 | /** 29 | * @var int debug level 30 | */ 31 | public $debug = 0; 32 | 33 | public function __construct() 34 | { 35 | // load database configuration from CodeIgniter 36 | if (! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/database.php') 37 | && ! file_exists($file_path = APPPATH.'config/database.php')) { 38 | throw new Exception('The configuration file database.php does not exist.'); 39 | } 40 | require $file_path; 41 | 42 | $entitiesClassLoader = new ClassLoader('models', rtrim(APPPATH, "/")); 43 | $entitiesClassLoader->register(); 44 | $proxiesClassLoader = new ClassLoader('Proxies', APPPATH . 'models/Proxies'); 45 | $proxiesClassLoader->register(); 46 | 47 | // Set up caches 48 | $config = new Configuration; 49 | $cache = new ArrayCache; 50 | $config->setMetadataCacheImpl($cache); 51 | $driverImpl = $config->newDefaultAnnotationDriver(array(APPPATH . 'models/Entities')); 52 | $config->setMetadataDriverImpl($driverImpl); 53 | $config->setQueryCacheImpl($cache); 54 | 55 | $config->setQueryCacheImpl($cache); 56 | 57 | // Proxy configuration 58 | $config->setProxyDir(APPPATH . '/models/Proxies'); 59 | $config->setProxyNamespace('Proxies'); 60 | 61 | // Set up logger 62 | if ($this->debug > 0) { 63 | $logger = new EchoSQLLogger; 64 | $config->setSQLLogger($logger); 65 | } 66 | 67 | $config->setAutoGenerateProxyClasses(true); 68 | 69 | // Database connection information 70 | $connectionOptions = $this->convertDbConfig($db['default']); 71 | 72 | // Create EntityManager 73 | $this->em = EntityManager::create($connectionOptions, $config); 74 | } 75 | 76 | /** 77 | * Convert CodeIgniter database config array to Doctrine's 78 | * 79 | * See http://www.codeigniter.com/user_guide/database/configuration.html 80 | * See http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html 81 | * 82 | * @param array $db 83 | * @return array 84 | * @throws Exception 85 | */ 86 | public function convertDbConfig($db) 87 | { 88 | $connectionOptions = []; 89 | 90 | if ($db['dbdriver'] === 'pdo') { 91 | return $this->convertDbConfigPdo($db); 92 | } elseif ($db['dbdriver'] === 'mysqli') { 93 | $connectionOptions = [ 94 | 'driver' => $db['dbdriver'], 95 | 'user' => $db['username'], 96 | 'password' => $db['password'], 97 | 'host' => $db['hostname'], 98 | 'dbname' => $db['database'], 99 | 'charset' => $db['char_set'], 100 | ]; 101 | } else { 102 | throw new Exception('Your Database Configuration is not confirmed by CodeIgniter Doctrine'); 103 | } 104 | 105 | return $connectionOptions; 106 | } 107 | 108 | protected function convertDbConfigPdo($db) 109 | { 110 | $connectionOptions = []; 111 | 112 | if (substr($db['hostname'], 0, 7) === 'sqlite:') { 113 | $connectionOptions = [ 114 | 'driver' => 'pdo_sqlite', 115 | 'user' => $db['username'], 116 | 'password' => $db['password'], 117 | 'path' => preg_replace('/\Asqlite:/', '', $db['hostname']), 118 | ]; 119 | } elseif (substr($db['dsn'], 0, 7) === 'sqlite:') { 120 | $connectionOptions = [ 121 | 'driver' => 'pdo_sqlite', 122 | 'user' => $db['username'], 123 | 'password' => $db['password'], 124 | 'path' => preg_replace('/\Asqlite:/', '', $db['dsn']), 125 | ]; 126 | } elseif (substr($db['dsn'], 0, 6) === 'mysql:') { 127 | $connectionOptions = [ 128 | 'driver' => 'pdo_mysql', 129 | 'user' => $db['username'], 130 | 'password' => $db['password'], 131 | 'host' => $db['hostname'], 132 | 'dbname' => $db['database'], 133 | 'charset' => $db['char_set'], 134 | ]; 135 | } else { 136 | throw new Exception('Your Database Configuration is not confirmed by CodeIgniter Doctrine'); 137 | } 138 | 139 | return $connectionOptions; 140 | } 141 | } 142 | --------------------------------------------------------------------------------