Integrates Doctrine ORM to Codeigniter 3 with minimal effort.
Credo is a wrapper package of Doctrine ORM for Codeigniter 3. Its implementation was created based on the official integration for Codeigniter 3 to the Doctrine ORM
package.
Install Credo
via Composer:
$ composer require rougin/credo
Create a sample database table first to be used in this example (e.g., users
):
-- Import this script to a SQLite database
CREATE TABLE user (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
name TEXT NOT NULL,
age INTEGER NOT NULL,
gender TEXT NOT NULL
);
INSERT INTO user (name, age, gender) VALUES ('Rougin', 20, 'male');
INSERT INTO user (name, age, gender) VALUES ('Royce', 18, 'male');
INSERT INTO user (name, age, gender) VALUES ('Mei', 19, 'female');
Then configure the composer_autoload
option in config.php
:
// ciacme/application/config/config.php
/*
|--------------------------------------------------------------------------
| Composer auto-loading
|--------------------------------------------------------------------------
|
| Enabling this setting will tell CodeIgniter to look for a Composer
| package auto-loader script in application/vendor/autoload.php.
|
| $config['composer_autoload'] = TRUE;
|
| Or if you have your vendor/ directory located somewhere else, you
| can opt to set a specific path as well:
|
| $config['composer_autoload'] = '/path/to/vendor/autoload.php';
|
| For more information about Composer, please visit http://getcomposer.org/
|
| Note: This will NOT disable or override the CodeIgniter-specific
| autoloading (application/config/autoload.php)
*/
$config['composer_autoload'] = __DIR__ . '/../../vendor/autoload.php';
[!NOTE] The value of
composer_autoload
should be thevendor
directory (e.g.,ciacme/vendor/autoload.php
).
Next is to create an entity that conforms to the documentation of Doctrine ORM
(e.g., User
):
// ciacme/application/models/User.php
/**
* @Entity
* @Table(name="user")
*/
class User extends CI_Model
{
/**
* @Id @GeneratedValue
* @Column(name="id", type="integer", length=10, nullable=FALSE, unique=FALSE)
* @var integer
*/
protected $_id;
// ...
}
Once the entity is created, it can now be used to perform operations using the Credo::getRepository
:
// ciacme/application/controllers/Welcome.php
use Rougin\Credo\Credo;
$this->load->model('user');
$this->load->database();
$credo = new Credo($this->db);
// Snake-case versions of the EntityManager ---
// methods are also available in the class ----
/** @var \Doctrine\ORM\EntityRepository */
$repository = $credo->get_repository('User');
// --------------------------------------------
/** @var \User[] */
$user = $repository->findBy(array());
Rougin\Credo\Repository
To enable this package on a Codeigniter 3
project, create a MY_Loader
class first in the core
directory then extend the newly created class to Rougin\Credo\Loader
:
// ciacme/application/core/MY_Loader.php
use Rougin\Credo\Loader;
class MY_Loader extends Loader
{
}
Next is create a custom entity repository with a _repository
suffix in the class name (e.g., User_repository
):
// ciacme/application/repositories/User_repository.php
use Rougin\Credo\Repository;
class User_repository extends Repository
{
public function find_by_something()
{
// ...
}
}
Once the custom repository is created (e.g., User_repository
), add the repositoryClass
property inside the @Entity
annotation of the specified entity to attach the said custom repository:
// ciacme/application/models/User.php
/**
* @Entity(repositoryClass="User_repository")
*
* @Table(name="user")
*/
class User extends CI_Model
{
// ...
}
Then load the specified repository using $this->load->repository
:
// ciacme/application/controllers/Welcome.php
use Rougin\Credo\Credo;
// Load the model and its repository ---
$this->load->model('user');
$this->load->repository('user');
$this->load->database();
// -------------------------------------
$credo = new Credo($this->db);
// The said repository can now be used ------
/** @var \User_repository */
$repository = $credo->get_repository('User');
// ------------------------------------------
$users = $repository->find_by_something();
[!NOTE] It is encouraged to check the documentation about
Doctrine ORM
first for more information about its design pattern and its various usage on existing projects.
~3.0
version of Doctrine ORM
Credo
should be able to support the latest version of Doctrine ORM
(~3.0
). To use the latest version, the code must be slightly updated:
// ciacme/application/controllers/Welcome.php
use Rougin\Credo\Credo;
// ...
// $this->db must not be included as it ----
// will create an EntityManager instance ---
// based from the given Database object ----
$credo = new Credo;
// -----------------------------------------
// Create an implementation of EntityManager ---
$manager = /** sample implementation */;
// ---------------------------------------------
// Then attach it to the Credo instance ---
$credo->setManager($manager);
// ----------------------------------------
// ...
/** @var \User[] */
$users = $this->user->get();
Using this approach allows to use the latest improvements provided by Doctrine ORM
like using the native attributes introduced in PHP v8.1
:
// ciacme/application/models/User.php
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ORM\Table(name: 'users')]
class User
{
#[ORM\Id]
#[ORM\Column(type: 'integer')]
#[ORM\GeneratedValue]
private int|null $id = null;
#[ORM\Column(type: 'string')]
private string $name;
// ...
}
[!TIP] Please see the Getting Started documentation of
Doctrine ORM
on how to initialize anEntityManager
in the latest version.
Rougin\Credo\Model
The Model
class enables the specified entity to perform CRUD operations without relying on a repository:
// ciacme/application/models/User.php
use Rougin\Credo\Model;
/**
* @Entity
* @Table(name="user")
*/
class User extends Model
{
/**
* @Id @GeneratedValue
* @Column(name="id", type="integer", length=10, nullable=FALSE, unique=FALSE)
* @var integer
*/
protected $_id;
// ...
}
// ciacme/application/controllers/Welcome.php
use Rougin\Credo\Credo;
$this->load->model('user');
// Credo is not needed as it will try to ---
// create an instance based on $this->db ---
// $credo = new Credo($this->db);
// $this->user->credo($credo);
// -----------------------------------------
/** @var \User[] */
$users = $this->user->get();
The Model
class contains methods for performing CRUD operations which are based both on the Query Builder
class of Codeigniter 3
and the EntityManager
of Doctrine ORM
.
[!WARNING] This may be used for getting started to use the models directly without a repository. However, this will be against the principle of
Unit of Work
pattern byDoctrine ORM
(e.g., using the entity class instead of an array in updating its data). With this, using an entity repository is highly encouraged.
Credo
provides traits that are based from the libraries of Codeigniter 3
such as Form Validation
and Pagination Class
. They are used to easily attach the specified functionalities of Codeigniter 3
to a model.
PaginateTrait
The PaginateTrait
is used to easily create pagination links within the model:
// ciacme/application/models/User.php
use Rougin\Credo\Model;
use Rougin\Credo\Traits\PaginateTrait;
class User extends Model
{
use PaginateTrait;
// ...
}
// ciacme/application/controllers/Welcome.php
// Create a pagination links with 10 as the limit and
// 100 as the total number of items from the result.
$result = $this->user->paginate(10, 100);
$data = array('links' => $result[1]);
$offset = $result[0];
// The offset can now be used for filter results
// from the specified table (e.g., "users").
$items = $this->user->get(10, $offset);
The $result[0]
returns the computed offset while $result[1]
returns the generated pagination links:
// ciacme/application/views/users/index.php
<?php echo $links; ?>
To configure the pagination library, the $pagee
property must be defined in the Model
:
// ciacme/application/models/User.php
use Rougin\Credo\Model;
use Rougin\Credo\Traits\PaginateTrait;
class User extends Model
{
use PaginateTrait;
// ...
/**
* Additional configuration to Pagination Class.
*
* @link https://codeigniter.com/userguide3/libraries/pagination.html#customizing-the-pagination
*
* @var array<string, mixed>
*/
protected $pagee = array(
'page_query_string' => true,
'use_page_numbers' => true,
'query_string_segment' => 'p',
'reuse_query_string' => true,
);
}
[!NOTE] Please see the documentation of Pagination Class to get the list of its available configuration.
ValidateTrait
This trait is used to simplify the specifying of validation rules to a model:
// ciacme/application/models/User.php
use Rougin\Credo\Model;
use Rougin\Credo\Traits\ValidateTrait;
class User extends Model
{
use ValidateTrait;
// ...
}
When used, the $rules
property of the model must be defined with validation rules that conforms to the Form Validation
specification:
// ciacme/application/models/User.php
use Rougin\Credo\Model;
use Rougin\Credo\Traits\ValidateTrait;
class User extends Model
{
use ValidateTrait;
// ...
/**
* List of validation rules.
*
* @link https://codeigniter.com/userguide3/libraries/form_validation.html#setting-rules-using-an-array
*
* @var array<string, string>[]
*/
protected $rules = array(
array('field' => 'name', 'label' => 'Name', 'rules' => 'required'),
array('field' => 'email', 'label' => 'Email', 'rules' => 'required'),
);
}
[!NOTE] Kindly check its documentation for the available rules that can be used to the
$rules
property.
To do a form validation, the validate
method must be called from the model:
// ciacme/application/controllers/Welcome.php
/** @var array<string, mixed> */
$input = $this->input->post(null, true);
$valid = $this->user->validate($input);
If executed with a view, the validation errors can be automatically be returned to the view using the form_error
helper:
// ciacme/application/views/users/create.php
<?= form_open('users/create') ?>
<div>
<!-- ... -->
<?= form_error('name') ?>
</div>
<div>
<!-- ... -->
<?= form_error('email') ?>
</div>
<!-- ... -->
<?= form_close() ?>
v0.5.0
releaseThe new release for v0.5.0
will be having a backward compatibility break (BC break). With this, some functionalities from the earlier versions might not be working after upgrading. This was done to increase the maintainability of the project while also adhering to the functionalities for both Codeigniter 3
and Doctrine ORM
. Please see the UPGRADING page for the said breaking changes.
[!TIP] If still using the
v0.4.0
release, kindly click its documentation below: https://github.com/rougin/credo/blob/v0.4.0/README.md