Framework : CodeIgniter 3 (version 3.2.0-dev)
Status : support
Last update : 29/09/2024
======================================================================
INSTRUCTION
-
HOW TO START A NEW PROJECT?
- Download this project
- Rename project folder to any name
- Run command "composer install/update" using CMD/Terminal (make sure to install composer!)
- Run command "npm install/update" using CMD/Terminal (make sure to install Node.js!)
- Configure the .env files for ENVIRONMENT, DATABASE & APP
-
HOW TO INSTALL GRUNT ASSET BUNDLER?
- Make sure node.js already install!
- Open Terminal/Command Prompt (copy & paste code below)
- npm ls -g grunt-cli (To check if grunt already install or not)
- npm install -g grunt-cli
- npm install grunt grunt-contrib-concat grunt-contrib-uglify grunt-contrib-clean grunt-contrib-cssmin grunt-babel @babel/core @babel/preset-env --save-dev
======================================================================
FEATURES
-
SECURITY
- XSS Protection (validate data from malicious code using middleware)
- Google Authenticator (Use for 2FA)
- Google ReCAPTCHA v2 (Reduce DDos Attack)
- Login Attempt (Reduce Brute Force Attack)
- Custom Front-end Validation in JS (Data integrity)
- Custom Route & Middleware (Protect URL & Page) - Thanks Luthier CI for amazing library
- CSRF Token & Cookie (Built in CI3)
- Rate Limiting Trait (API Request limiter using Middleware)
-
SYSTEM
- Custom Model DB Query.
- Job Queue (Worker) - Running in the background (Thanks to Yidas for Queue Worker library)
- Maintenance Mode (With custom page)
- Blade Templating Engine (Increase security & caching) - (Credit to team BladeOne)
- SSL Force redirect (production mode)
- System logger (Log error system in database & files)
- Audit Trail (Log data insert, update, delete in the database)
- CRUD Log (Log data insert, update, delete in files)
- Cron Scheduler - (Credit to Peppeocchi)
-
HELPER
- Front-end
- Call API (POST, GET), Upload API, Delete API wrapper (using Axios)
- Dynamic modal & Form loaded
- Generate datatable (server-side & client-side rendering)
- Print DIV (use printThis library)
- Backend-end
- Array helper
- Data Helper
- Date Helper
- Upload Helper (upload, move, compress image)
- QR Generate Helper (using Endroid library)
- Read/Import Excel (using PHPSpreadsheet library)
- Mailer (using PHPMailer library)
-
SERVICES
- Backup system folder (with exceptions file or folder)
- Backup database (MySQL tested)
- Upload file backup to google drive (need to configure)
-
MODULE BUNDLER
- Concat, uglify JavaScript using Grunt JS (read more Grunt Website)
======================================================================
COMMAND
Command (Terminal / Command Prompt):-
- Cache
- php struck clear view (remove blade cache)
- php struck clear cache (remove ci session cache)
- php struck clear all (remove ci session cache, blade cache & logs file)
- php struck optimize (remove blade cache & logs file)
- Backup (use as an ordinary cron job)
- php struck cron database (backup the database in folder project)
- php struck cron system (backup system folder in folder project)
- php struck cron database upload (backup the database & upload to google drive)
- php struck cron system upload (backup system folder & upload to google drive)
- Jobs (Queue Worker)
- php struck jobs (temporary run until jobs completed)
- php struck jobs:work (temporary run until jobs completed)
- php struck jobs:listen (permanent until services kill) - use in Linux environment
- php struck queue:retry < replace with UUID >
- php struck queue:retry all
- Cron Scheduler (Laravel Task Scheduling)
- php struck schedule:run
- php struck schedule:list
- php struck schedule:work
- php struck schedule:fail
- Module Bundler
- grunt
- grunt watch (keep detecting changes)
======================================================================
CUSTOM COMMAND
This Ci3Based also includes stub files for creating controllers & models. Please change according to the suitability of the project
Notes :
- $fileName is required.
- $tableName is optional & use for model only.
- $type is required & only support for 'model' and 'controller'.
Command to run using terminal or cmd (without $) :
- php struck create $type $fileName $tableName
- php struck structure $fileName $tableName
- php struck generate services $moduleName $fileName $modelName $tableName
Example :
- Model
- php struck create model MasterRoles (will create a basic model)
- php struck create model MasterRoles master_role (will create model with table columns from database)
- Controller
- php struck create controller MasterRoles (will create controller)
- Structure
- php struck structure MasterRoles (will create controller & basic model)
- php struck structure MasterRoles master_role (will create controller & model with table columns from database)
- Services
- php struck generate services core profile usersProfile users_profile
======================================================================
MY_Model_Custom is an extended model class for CodeIgniter 3 that introduces advanced query capabilities, improved relationship handling, fixes the N+1 query issue, and adds security layers for interacting with databases.
MySQL
Click to view model example
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName>_model extends MY_Model
{
// (OPTIONAL) The connection to database based on configuration, default is 'default'
protected $connection = 'default';
// (REQUIRED) The name of the table
public $table = '';
// (REQUIRED) The primary key column name, default is 'id'
public $primaryKey = 'id';
// (REQUIRED) The fields that can be filled by insert/update
public $fillable = [];
// (OPTIONAL) Enable or disable timestamps (created_at & updated_at)
public $timestamps = TRUE;
// (OPTIONAL) The timestamp format to save in database, default is 'Y-m-d H:i:s'
protected $timestamps_format = 'Y-m-d H:i:s';
// (OPTIONAL) The timestamp column that expected to be save
protected $_created_at_field = 'created_at';
protected $_updated_at_field = 'updated_at';
// (OPTIONAL) Will append the query result with new data from a specific function
public $appends = [];
// (OPTIONAL) Will remove specific columns from the query result
public $hidden = [];
// (OPTIONAL) Columns defined here will not be updated or inserted
public $protected = [];
// (OPTIONAL) The validation rules for insert & update
protected $_validation = [];
// (OPTIONAL) The validation rules for insert only, will override the $_validation if exists.
protected $_insertValidation = [];
// (OPTIONAL) The validation rules for update only, will override the $_validation if exists.
protected $_updateValidation = [];
public function __construct()
{
parent::__construct();
}
}| Function | Description |
|---|---|
rawQuery() |
Execute raw SQL queries directly. Useful for complex queries not supported by active record. |
table() |
Specifies the database table for the query. |
select() |
Defines the columns to retrieve in a query. Similar to CodeIgniter’s select(). |
where() |
Adds a basic WHERE clause to the query. Similar to Laravel's where(). |
orWhere() |
Adds an OR WHERE clause. Similar to Laravel's orWhere(). |
whereNull() |
Adds a WHERE clause to check for NULL values. Similar to Laravel's whereNull(). |
orWhereNull() |
Adds an OR WHERE clause to check for NULL values. Similar to Laravel's orWhereNull(). |
whereNotNull() |
Adds a WHERE clause to check for non-NULL values. Similar to Laravel's whereNotNull(). |
orWhereNotNull() |
Adds an OR WHERE clause to check for non-NULL values. Similar to Laravel's orWhereNotNull(). |
whereExists() |
Adds a WHERE EXISTS clause. Similar to Laravel's whereExists(). |
orWhereExists() |
Adds an OR WHERE EXISTS clause. Similar to Laravel's orWhereExists(). |
whereNotExists() |
Adds a WHERE NOT EXISTS clause. Similar to Laravel's whereNotExists(). |
orWhereNotExists() |
Adds an OR WHERE NOT EXISTS clause. Similar to Laravel's orWhereNotExists(). |
whereNot() |
Adds a WHERE NOT clause for negating conditions. Similar to Laravel's whereNot(). |
orWhereNot() |
Adds an OR WHERE NOT clause for negating conditions. Similar to Laravel's orWhereNot(). |
whereTime() |
Adds a WHERE clause for a time comparison. Similar to Laravel's whereTime(). |
orWhereTime() |
Adds an OR WHERE clause for a time comparison. Similar to Laravel's orWhereTime(). |
whereDate() |
Adds a WHERE clause for a date comparison. Similar to Laravel's whereDate(). |
orWhereDate() |
Adds an OR WHERE clause for a date comparison. Similar to Laravel's orWhereDate(). |
whereDay() |
Adds a WHERE clause for a specific day. Similar to Laravel's whereDay(). |
orWhereDay() |
Adds an OR WHERE clause for a specific day. Similar to Laravel's orWhereDay(). |
whereYear() |
Adds a WHERE clause for a specific year. Similar to Laravel's whereYear(). |
orWhereYear() |
Adds an OR WHERE clause for a specific year. Similar to Laravel's orWhereYear(). |
whereMonth() |
Adds a WHERE clause for a specific month. Similar to Laravel's whereMonth(). |
orWhereMonth() |
Adds an OR WHERE clause for a specific month. Similar to Laravel's orWhereMonth(). |
whereIn() |
Adds a WHERE IN clause. Similar to Laravel's whereIn(). |
orWhereIn() |
Adds an OR WHERE IN clause. Similar to Laravel's orWhereIn(). |
whereNotIn() |
Adds a WHERE NOT IN clause. Similar to Laravel's whereNotIn(). |
orWhereNotIn() |
Adds an OR WHERE NOT IN clause. Similar to Laravel's orWhereNotIn(). |
whereBetween() |
Adds a WHERE BETWEEN clause. Similar to Laravel's whereBetween(). |
orWhereBetween() |
Adds an OR WHERE BETWEEN clause. Similar to Laravel's orWhereBetween(). |
whereNotBetween() |
Adds a WHERE NOT BETWEEN clause. Similar to Laravel's whereNotBetween(). |
orWhereNotBetween() |
Adds an OR WHERE NOT BETWEEN clause. Similar to Laravel's orWhereNotBetween(). |
join() |
Adds an INNER JOIN to the query. Similar to CodeIgniter’s join(). |
rightJoin() |
Adds a RIGHT JOIN to the query. Similar to Laravel's rightJoin(). |
leftJoin() |
Adds a LEFT JOIN to the query. Similar to Laravel's leftJoin(). |
innerJoin() |
Adds an INNER JOIN to the query. Same as join(). |
outerJoin() |
Adds an OUTER JOIN to the query. Similar to Laravel's outerJoin(). |
limit() |
Limits the number of records returned. Similar to CodeIgniter's limit(). |
offset() |
Skips a number of records before starting to return records. Similar to CodeIgniter's offset(). |
orderBy() |
Adds an ORDER BY clause. Similar to Laravel's orderBy(). |
groupBy() |
Adds a GROUP BY clause. Similar to Laravel's groupBy(). |
groupByRaw() |
Adds a raw GROUP BY clause. Similar to Laravel's groupByRaw(). |
having() |
Adds a HAVING clause. Similar to Laravel's having(). |
havingRaw() |
Adds a raw HAVING clause. Similar to Laravel's havingRaw(). |
chunk() |
Process data in chunks to handle large datasets efficiently. Similar to Laravel's chunk(). |
get() |
Retrieves all data from the database based on the specified criteria. |
fetch() |
Retrieves a single record from the database based on the specified criteria. |
first() |
Retrieves the first record based on the query. |
last() |
Retrieves the last record based on the query. |
count() |
Counts the number of records matching the specified criteria. |
find() |
Finds a record by its primary key (ID). |
toSql() |
Returns the SQL query string (without eager loading query). |
toSqlPatch() |
Returns the SQL query string for updating data. |
toSqlCreate() |
Returns the SQL query string for inserting data. |
toSqlDestroy() |
Returns the SQL query string for deleting data. |
| Function | Description |
|---|---|
setPaginateFilterColumn() |
Sets the filter conditions for pagination. If not set, all columns from the main table are queried. |
paginate() |
Custom pagination method that works without the datatable library. Allows paginating results based on the specified criteria. |
paginate_ajax() |
Pagination method specifically designed to work with AJAX requests and integrate with datatables. |
Example Usage of setPaginateFilterColumn($key)
Parameters:
$key (array): An array containing the list of column to be used when making the filter conditions in query (only support main table, eager load are not supported).
<?php
# MODEL
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Any_model extends MY_Model
{
public $table = 'anyTable';
public $primaryKey = 'id';
public $fillable = [
'column1',
'column2',
'column3',
'column4'
];
public function __construct()
{
parent::__construct();
}
}
# CONTROLLER
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName> extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('any_model');
}
public function exampleSetPaginateFilter()
{
$paginateData = $this->any_model->whereYear('created_at', '>=', 2024)
->setPaginateFilterColumn(
[
null, // used for count the number
'column1',
'column2'
]
)
->paginate_ajax($_POST);
if (isset($paginateData['data']) && !empty($paginateData['data'])) {
$i = $_POST['start'] + 1;
foreach ($paginateData['data'] as $key => $data) {
$actionArr = [
'<a href="javascript:void(0);" onclick="deleteConfirm(' . $data['id'] . ')" data-id="' . $data['id'] . '"> Delete </a>',
'<a href="javascript:void(0);" onclick="updateRecord(' . $data['id'] . ')" data-id="' . $data['id'] . '"> Edit </a>',
];
// Replace the data with formatted data
$paginateData['data'][$key] = [
$i++,
$member['column1'],
$member['column2']
'<div class="text-center">' . implode('|', $actionArr) . '</div>'
];
}
}
echo json_encode($paginateData);
}
}Example Usage of paginate($pageSize, $currentPage, $searchValue)
Parameters:
$pageSize (string): The size of the data want to display, default is 10. [OPTIONAL]
$currentPage (string): The current page. Will taking from the url ?page= if this value is not provide or null [OPTIONAL]
$searchValue (string): The search value to filter the records [OPTIONAL]
<?php
# MODEL
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Any_model extends MY_Model
{
public $table = 'anyTable';
public $primaryKey = 'id';
public $fillable = [
'column1',
'column2',
'column3',
'column4'
];
public function __construct()
{
parent::__construct();
}
}
# CONTROLLER
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName> extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('any_model');
}
public function examplePaginate()
{
$search = $this->input->post('search', TRUE);
$paginateData = $this->any_model->whereYear('created_at', '>=', 2024)->paginate(30, 19, $search);
if (isset($paginateData['data']) && !empty($paginateData['data'])) {
$i = 1; // Need to change this part
foreach ($paginateData['data'] as $key => $data) {
$actionArr = [
'<a href="javascript:void(0);" onclick="deleteConfirm(' . $data['id'] . ')" data-id="' . $data['id'] . '"> Delete </a>',
'<a href="javascript:void(0);" onclick="updateRecord(' . $data['id'] . ')" data-id="' . $data['id'] . '"> Edit </a>',
];
// Replace the data with formatted data
$paginateData['data'][$key] = [
$i++,
$member['column1'],
$member['column2']
'<div class="text-center">' . implode('|', $actionArr) . '</div>'
];
}
}
echo json_encode($paginateData);
}
}Example Usage of paginate_ajax($dataPost)
Parameters:
$dataPost (array): An array $_POST from the request ajax datatable.
<?php
# MODEL
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Any_model extends MY_Model
{
public $table = 'anyTable';
public $primaryKey = 'id';
public $fillable = [
'column1',
'column2',
'column3',
'column4'
];
public function __construct()
{
parent::__construct();
}
}
# CONTROLLER
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName> extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('any_model');
}
public function examplePaginateAjaxWithoutFilterColumn()
{
$paginateData = $this->any_model->whereYear('created_at', '>=', 2024)->paginate_ajax($_POST);
if (isset($paginateData['data']) && !empty($paginateData['data'])) {
$i = $_POST['start'] + 1;
foreach ($paginateData['data'] as $key => $data) {
$actionArr = [
'<a href="javascript:void(0);" onclick="deleteConfirm(' . $data['id'] . ')" data-id="' . $data['id'] . '"> Delete </a>',
'<a href="javascript:void(0);" onclick="updateRecord(' . $data['id'] . ')" data-id="' . $data['id'] . '"> Edit </a>',
];
// Replace the data with formatted data
$paginateData['data'][$key] = [
$i++,
$member['column1'],
$member['column2']
'<div class="text-center">' . implode('|', $actionArr) . '</div>'
];
}
}
echo json_encode($paginateData);
}
public function examplePaginateAjaxWithFilterColumn()
{
$paginateData = $this->any_model->whereYear('created_at', '>=', 2024)
->setPaginateFilterColumn(
[
null, // used for count the number
'column1',
'column2'
]
)
->paginate_ajax($_POST);
if (isset($paginateData['data']) && !empty($paginateData['data'])) {
$i = $_POST['start'] + 1;
foreach ($paginateData['data'] as $key => $data) {
$actionArr = [
'<a href="javascript:void(0);" onclick="deleteConfirm(' . $data['id'] . ')" data-id="' . $data['id'] . '"> Delete </a>',
'<a href="javascript:void(0);" onclick="updateRecord(' . $data['id'] . ')" data-id="' . $data['id'] . '"> Edit </a>',
];
// Replace the data with formatted data
$paginateData['data'][$key] = [
$i++,
$member['column1'],
$member['column2']
'<div class="text-center">' . implode('|', $actionArr) . '</div>'
];
}
}
echo json_encode($paginateData);
}
}| Function | Description |
|---|---|
hasMany() |
Defines a one-to-many relationship. Similar to Laravel's hasMany(). |
hasOne() |
Defines a one-to-one relationship. Similar to Laravel's hasOne(). |
belongsTo() |
Defines an inverse one-to-many or one-to-one relationship. Similar to Laravel's belongsTo(). |
Example Usage of hasMany($modelName, $foreignKey, $localKey)
Parameters:
$modelName (string): Indicate the model that want to has the relation [REQUIRED]
$foreignKey (string): Indicate the foreign key in related model [REQUIRED]
$localKey (string): Indicate the key in current model, usually will taking from $primaryKey value [OPTIONAL]
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Any_model extends MY_Model
{
public $table = 'anyTable';
public $primaryKey = 'id';
public $fillable = [
'column1',
'column2',
'column3',
'column4'
];
public function __construct()
{
parent::__construct();
}
public function relatedModelWithLocalKey()
{
return $this->hasMany('Related_model', 'foreign_id', 'id');
}
public function relatedModelWithoutLocalKey()
{
return $this->hasMany('Related_model', 'foreign_id');
// Explanation : will use $primaryKey value as the localKey
}
}Example Usage of hasOne($modelName, $foreignKey, $localKey)
Parameters:
$modelName (string): Indicate the model that want to has the relation [REQUIRED]
$foreignKey (string): Indicate the foreign key in related model [REQUIRED]
$localKey (string): Indicate the key in current model, usually will taking from $primaryKey value [OPTIONAL]
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Any_model extends MY_Model
{
public $table = 'anyTable';
public $primaryKey = 'id';
public $fillable = [
'column1',
'column2',
'column3',
'column4'
];
public function __construct()
{
parent::__construct();
}
public function relatedModelWithLocalKey()
{
return $this->hasOne('Related_model', 'foreign_id', 'id');
}
public function relatedModelWithoutLocalKey()
{
return $this->hasOne('Related_model', 'foreign_id');
// Explanation : will use $primaryKey value as the localKey
}
}Example Usage of belongsTo($modelName, $foreignKey, $ownerKey)
Parameters:
$modelName (string): Indicate the model that want to has the relation [REQUIRED]
$foreignKey (string): Indicate the foreign key in related model [REQUIRED]
$ownerKey (string): Indicate the key in current model, usually will taking from $primaryKey value [OPTIONAL]
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Any_model extends MY_Model
{
public $table = 'anyTable';
public $primaryKey = 'id';
public $fillable = [
'column1',
'column2',
'column3',
'column4'
];
public function __construct()
{
parent::__construct();
}
public function relatedModelWithOwnerKey()
{
return $this->belongsTo('Related_model', 'foreign_id', 'id');
}
public function relatedModelWithoutOwnerKey()
{
return $this->belongsTo('Related_model', 'foreign_id');
// Explanation : will use $primaryKey value as the ownerKey
}
}| Function | Description |
|---|---|
with() |
Eager loads related models to avoid the N+1 query issue. Similar to Laravel's with(). |
Example Usage of with($relation)
Parameters:
$relation (array/string/callback): An relation to extends the result with related table.
<?php
# MODEL : MAIN / PARENT
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Any_model extends MY_Model
{
public $table = 'anyTable';
public $primaryKey = 'id';
public $fillable = [
'column1',
'column2',
'column3',
'column4'
];
public function __construct()
{
parent::__construct();
}
public function related1()
{
return $this->hasMany('Related1_model', 'anyPK_id', 'id');
}
}
# MODEL : RELATED / CHILD
class Related1_model extends MY_Model
{
public $table = 'relatedTable';
public $primaryKey = 'id';
public $fillable = [
'columnRelated1',
'columnRelated2',
'columnRelated3',
'columnRelated4',
'anyPK_id'
];
public function __construct()
{
parent::__construct();
}
public function function1()
{
return $this->hasMany('Related2_model', 'anyRelatedPK_id', 'id');
}
public function function2()
{
return $this->hasOne('Related3_model', 'anyRelatedPK_id', 'id');
}
}
# CONTROLLER
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName> extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('any_model');
}
public function simpleEagerLoadUsingParam()
{
return $this->any_model->select('id, column1, column2')
->whereYear('created_at', '>=', '2024')
->orderBy('id', 'DESC')
->with('related1', 'related1.function1', 'related1.function2') // USE PARAMS
->get(); // can used get(), fetch(), paginate(), first(), last().
}
public function simpleEagerLoadUsingArray()
{
return $this->any_model->select('id, column1, column2')
->whereYear('created_at', '>=', '2024')
->orderBy('id', 'DESC')
->with(['related1', 'related1.function1', 'related1.function2']) // USE ARRAY
->fetch(); // can used get(), fetch(), paginate(), first(), last().
}
public function advancedEagerLoadUsingCallback()
{
return $this->model->select('id, name, email, nickname, password, username')
->whereYear('created_at', '>=', '2024')
->orderBy('id', 'DESC')
->with(['related1' => function ($query) {
$query->select('columnRelated1, columnRelated2')->whereMonth('created_at', '>=', 2);
}])
->with(['related1.function1' => function ($query) {
$query->select('columnRelatedFunc1, columnRelatedFunc4');
}])
->with('related1.function2')
->paginate(10, 3); // can used get(), fetch(), paginate(), first(), last().
}
}| Function | Description |
|---|---|
create() |
Inserts a new record in the database based on the provided data. |
patch() |
Updates a specific record by its primary key (ID) set at $primaryKey property in model. |
destroy() |
Deletes a specific record by its primary key (ID) set at $primaryKey property in model. |
insertOrUpdate() |
Determines whether to insert or update a record based on given conditions. Similar to Laravel's updateOrInsert(). |
Example Usage of create($data)
Parameters:
$data (array): An array of data to be inserted to database.
<?php
# MODEL
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Any_model extends MY_Model
{
public $table = 'anyTable';
public $primaryKey = 'id';
public $fillable = [
'column1',
'column2',
'column3',
'column4'
];
public function __construct()
{
parent::__construct();
}
}
# CONTROLLER
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName> extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('any_model');
}
public function exampleCreate()
{
$data = [
'column1' => $this->input->post('column1', TRUE),
'column2' => $this->input->post('column1', TRUE),
'column3' => $this->input->post('column1', TRUE)
];
echo json_encode($this->any_model->create($data)); // return as the json to ajax
}
}Example Usage of patch($data, $id)
Parameters:
$data (array): An array of data to be update.
$id (string): An id (must be a PK set at $primaryKey in model) value to specify which data to be updated.
<?php
# MODEL
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Any_model extends MY_Model
{
public $table = 'anyTable';
public $primaryKey = 'id';
public $fillable = [
'column1',
'column2',
'column3',
'column4'
];
public function __construct()
{
parent::__construct();
}
}
# CONTROLLER
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName> extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('any_model');
}
public function exampleUpdate()
{
$id = $this->input->post('id', TRUE);
$data = [
'column1' => $this->input->post('column1', TRUE),
'column2' => $this->input->post('column1', TRUE),
'column3' => $this->input->post('column1', TRUE)
];
echo json_encode($this->any_model->patch($data, $id)); // return as the json to ajax
}
}Example Usage of destroy($id)
Parameters:
$id (string): An id (must be a PK set at $primaryKey in model) value to specify which data to be deleted.
<?php
# MODEL
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Any_model extends MY_Model
{
public $table = 'anyTable';
public $primaryKey = 'id';
public $fillable = [
'column1',
'column2',
'column3',
'column4'
];
public function __construct()
{
parent::__construct();
}
}
# CONTROLLER
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName> extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('any_model');
}
public function exampleDelete()
{
$id = $this->input->post('id', TRUE);
echo json_encode($this->any_model->destroy($id)); // return as the json to ajax
}
}Example Usage of insertOrUpdate($condition, $data)
Parameters:
$condition (array): An array of data to be use as the condition to determine the records are exist or not in database.
$data (array): An array of data to be insert or update.
<?php
# MODEL
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Any_model extends MY_Model
{
public $table = 'anyTable';
public $primaryKey = 'id';
public $fillable = [
'column1',
'column2',
'column3',
'column4'
];
public function __construct()
{
parent::__construct();
}
}
# CONTROLLER
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName> extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('any_model');
}
public function exampleInsertOrUpdate1()
{
$data = [
'column1' => $this->input->post('column1', TRUE),
'column2' => $this->input->post('column1', TRUE),
'column3' => $this->input->post('column1', TRUE)
];
echo json_encode($this->any_model->insertOrUpdate(['id' => 'value'], $data)); // return as the json to ajax
}
public function exampleInsertOrUpdate2()
{
$condition = ['id' => 'value', 'column4' => 'example']; // this both condition must be fit in database to be updated, otherwise, it will insert a new record.
$data = [
'column1' => $this->input->post('column1', TRUE),
'column2' => $this->input->post('column1', TRUE),
'column3' => $this->input->post('column1', TRUE)
];
echo json_encode($this->any_model->insertOrUpdate($condition, $data)); // return as the json to ajax
}
}| Function | Description |
|---|---|
ignoreValidation() |
Ignores all validation rules for inserts and updates. |
setValidationRules() |
Sets or overrides existing validation rules for the model on the fly. |
setCustomValidationRules() |
Adds or changes existing validation rules that are already set in the model. |
Example Usage of ignoreValidation()
<?php
# MODEL
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Any_model extends MY_Model
{
public $table = 'anyTable';
public $primaryKey = 'id';
public $fillable = [
'column1',
'column2',
'column3',
'column4'
];
protected $_validation = [
'column1' => ['field' => 'column1', 'label' => 'Column 1', 'rules' => 'required'],
'column4' => ['field' => 'column4', 'label' => 'Column 4', 'rules' => 'required|trim']
];
public function __construct()
{
parent::__construct();
}
}
# CONTROLLER
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName> extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('any_model');
}
public function exampleCreate()
{
return $this->any_model->ignoreValidation()->create($dataToInsert);
}
public function exampleUpdate()
{
return $this->any_model->ignoreValidation()->patch($dataToUpdate, $id);
}
}Example Usage of setValidationRules($rules)
Parameters:
$rules (array): An array containing the set of rules.
<?php
# MODEL
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Any_model extends MY_Model
{
public $table = 'anyTable';
public $primaryKey = 'id';
public $fillable = [
'column1',
'column2',
'column3',
'column4'
];
// NO VALIDATION RULES SET HERE
public function __construct()
{
parent::__construct();
}
}
# CONTROLLER
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName> extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('any_model');
}
public function exampleCreate()
{
return $this->any_model
->setValidationRules([
'column1' => ['field' => 'column1', 'label' => 'Column 1', 'rules' => 'required|trim|max_length[255]'], // with required
'column2' => ['field' => 'column2', 'label' => 'Column 2', 'rules' => 'required|trim|valid_email', 'errors' => ['required' => 'Column 2 adalah wajib.']]
])
->create($dataToInsert);
}
public function exampleUpdate()
{
return $this->any_model
->setValidationRules([
'column1' => ['field' => 'column1', 'label' => 'Column 1', 'rules' => 'trim|max_length[255]'], // without required
'column2' => ['field' => 'column2', 'label' => 'Column 2', 'rules' => 'required|trim', 'errors' => ['required' => 'Column 2 adalah wajib.']],
])
->patch($dataToUpdate, $id);
}
}Example Usage of setCustomValidationRules($rules)
Parameters:
$rules (array): An array containing the set of rules to change or add.
<?php
# MODEL
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Any_model extends MY_Model
{
public $table = 'anyTable';
public $primaryKey = 'id';
public $fillable = [
'column1',
'column2',
'column3',
'column4'
];
protected $_validation = [
'column1' => ['field' => 'column1', 'label' => 'Column 1', 'rules' => 'required'], // Only have required
'column4' => ['field' => 'column4', 'label' => 'Column 4', 'rules' => 'required|trim']
];
public function __construct()
{
parent::__construct();
}
}
# CONTROLLER
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName> extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('any_model');
}
public function exampleCreate()
{
return $this->any_model
->setCustomValidationRules([
'column1' => ['field' => 'column1', 'label' => 'Column 1', 'rules' => 'required|trim|max_length[255]'], // will override the existing validation on models.
'column2' => ['field' => 'column2', 'label' => 'Column 2', 'rules' => 'required|trim|valid_email'] // will add new validation for column 2
])
->create($dataToInsert);
}
public function exampleUpdate()
{
return $this->any_model
->setCustomValidationRules([
'column1' => ['field' => 'column1', 'label' => 'Column 1', 'rules' => 'trim|max_length[255]'], // will override the existing validation on models.
'column3' => ['field' => 'column3', 'label' => 'Column 3', 'rules' => 'required|trim|valid_email', 'errors' => ['required' => 'Column 3 adalah wajib.']] // will add new validation for column 3
])
->patch($dataToUpdate, $id);
}
}| Function | Description |
|---|---|
safeOutput() |
Escapes output to prevent XSS attacks. All data, including eager loaded and appended data, will be filtered. |
safeOutputWithException() |
Same as safeOutput(), but allows specific fields to be excluded from escaping. |
Example Usage of safeOutput()
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName> extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('any_model');
}
public function simpleSafeOutput()
{
return $this->any_model->where('column', 'value')->safeOutput()->get();
}
public function exampleEagerLoadSafeOutput()
{
return $this->any_model->where()
->with(['keyRelation' => function ($query) {
$query->safeOutput();
}])
->safeOutput()
->get();
}
}Example Usage of safeOutputWithException($column)
Parameters:
$column (array): An array containing the column to exclude from escaping.
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName> extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('any_model');
}
public function simpleSafeOutputWithException()
{
return $this->any_model->where('column', 'value')->safeOutputWithException(['column1', 'column2'])->get();
}
public function exampleEagerLoadSafeOutputWithException()
{
return $this->any_model->where()
->with(['keyRelation' => function ($query) {
$query->safeOutputWithException(['columnRelation1', 'columnRelation2']);
}])
->safeOutputWithException(['column1', 'column2'])
->get();
}
}| Function | Description |
|---|---|
toArray() |
Converts the result set to an array format (Default). |
toObject() |
Converts the result set to an object format. |
toJson() |
Converts the result set to JSON format. |
showColumnHidden() |
Displays hidden columns by removing the $hidden property temporarily. |
setColumnHidden() |
Dynamically sets columns to be hidden, similar to Laravel's $hidden model property. |
setAppends() |
Dynamically appends custom attributes to the result set, similar to Laravel's $appends model property. |
Example Usage of toArray() / toObject() / toJson()
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName> extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('any_model');
}
public function example returnAsArrayData()
{
return $this->any_model->where('column', 'value')->toArray()->get();
}
public function example returnAsObjectData()
{
return $this->any_model->where('column', 'value')->toObject()->first();
}
public function example returnAsJsonData()
{
echo $this->any_model->where('column', 'value')->toJson()->fetch();
}
}Example Usage of showColumnHidden()
<?php
# MODEL
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Any_model extends MY_Model
{
public $table = 'anyTable';
public $primaryKey = 'id';
public $fillable = [
'column1',
'column2',
'column3',
'column4'
];
protected $hidden = ['column3']; // Removed the column3 from showing in the result
public function __construct()
{
parent::__construct();
}
}
# CONTROLLER
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName> extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('any_model');
}
public function exampleReturnWitColumnHiddenInModel()
{
return $this->any_model->where('column', 'value')->fetch();
// Result : [
// 'column1' => 'value',
// 'column2' => 'value2',
// 'column4' => 'value4',
// ];
// Explanation : column3 is not showing in the result because its already set hidden in the model.
}
public function exampleReturnWithoutColumnHidden()
{
return $this->any_model->where('column', 'value')->showColumnHidden()->fetch();
// Result : [
// 'column1' => 'value',
// 'column2' => 'value2',
// 'column3' => 'value3',
// 'column4' => 'value4'
// ];
// Explanation : Will show all the column.
}
}Example Usage of setColumnHidden($column)
Parameters:
$column (array): An array containing the column to exclude from showing in the result.
<?php
# MODEL
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Any_model extends MY_Model
{
public $table = 'anyTable';
public $primaryKey = 'id';
public $fillable = [
'column1',
'column2',
'column3',
'column4'
];
protected $hidden = ['column3']; // removed the column3 from showing in the result
public function __construct()
{
parent::__construct();
}
}
# CONTROLLER
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName> extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('any_model');
}
public function exampleReturnWithoutColumnHidden()
{
return $this->any_model->where('column', 'value')->fetch();
// Result : [
// 'column1' => 'value',
// 'column2' => 'value2',
// 'column4' => 'value4'
// ];
// Explanation : column3 is not showing in the result because its already set hidden in the model.
}
public function exampleReturnWithColumnHidden()
{
return $this->any_model->where('column', 'value')->setColumnHidden(['column1'])->fetch();
// Result : [
// 'column2' => 'value2',
// 'column3' => 'value3',
// 'column4' => 'value4'
// ];
// Explanation : will override the $hidden in model.
}
public function exampleReturnWithColumnHiddenSetToEmpty()
{
return $this->any_model->where('column', 'value')->setColumnHidden([])->fetch();
// Result : [
// 'column1' => 'value',
// 'column2' => 'value2',
// 'column3' => 'value3',
// 'column4' => 'value4'
// ];
// Explanation : will override the $hidden in model. Showing all the data since no column hidden are being set. Use `showColumnHidden()` instead.
}
}Example Usage of setAppends($key)
Parameters:
$key (array): An array containing the functions to be called in the model. The key will be used to append as the new key in the result data.
Explanation:
- Need to create the function with prefix
getand the suffixAttributein the model. If the key has underscore ('_'), it will be removed and the first later of next text will become uppercase.
Example :
new_datawill becomepublic function getNewDataAttribute()testdatawill becomepublic function getTestdataAttribute()appendNewdatawill becomepublic function getAppendNewdataAttribute()appendNew_datawill becomepublic function getAppendNewDataAttribute()
<?php
# MODEL
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Any_model extends MY_Model
{
public $table = 'anyTable';
public $primaryKey = 'id';
public $fillable = [
'column1',
'column2',
'column3',
'column4'
];
protected $appends = ['new_data']; // If set in the model like this. all the query to this model will be append the new key
public function __construct()
{
parent::__construct();
}
public function getNewDataAppendAttribute()
{
return empty($this->column1) ? 'Will use this value a' : 'Will use this value b';
}
public function getOtherAppendExampleAttribute()
{
return 'Will show this others value';
}
}
# CONTROLLER
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class <ClassName> extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('any_model');
}
public function exampleWithoutAppends()
{
return $this->any_model->where('column1', 'value')->fetch();
// Result : [
// 'column1' => 'value',
// 'column2' => 'value2',
// 'column3' => 'value3',
// 'column4' => 'value4',
// 'new_data' => 'Will use this value b'
// ];
// Explanation : new_data key is a new data key result from the configuration using `$appends` property in the model.
}
public function exampleUsingSingleAppends()
{
return $this->any_model->where('column1', 'value')->setAppends(['other_append_example'])->fetch();
// Result : [
// 'column1' => 'value',
// 'column2' => 'value2',
// 'column3' => 'value3',
// 'column4' => 'value4',
// 'other_append_example' => 'Will show this others value'
// ];
// Explanation : other_append_example key is a new data key result. It will override the `$appends` property in the model.
}
public function exampleUsingBothAppends()
{
return $this->any_model->where('column1', 'value')->setAppends(['new_data', 'other_append_example'])->fetch();
// Result : [
// 'column1' => 'value',
// 'column2' => 'value2',
// 'column3' => 'value3',
// 'column4' => 'value4',
// 'new_data' => 'Will use this value b',
// 'other_append_example' => 'Will show this others value'
// ];
// Explanation : new_data & other_append_example key is a new data key result. It will override the `$appends` property in the model.
}
}