├── .gitignore ├── src ├── Column.php ├── Helper.php ├── Request.php ├── DataTable.php ├── DataTableQuery.php └── DataTableColumnDefs.php ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── composer.json ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | -------------------------------------------------------------------------------- /src/Column.php: -------------------------------------------------------------------------------- 1 | isPublic()) 12 | return $object->$varName; 13 | else 14 | { 15 | $rp->setAccessible(TRUE); 16 | return $rp->getValue($object); 17 | } 18 | 19 | } 20 | 21 | } // End of Helper Library Class. 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Your code** 14 | Please write the code that makes the bug appear (PHP and JS) 15 | 16 | **Screenshots** 17 | If applicable, add screenshots to help explain your problem. 18 | 19 | **Version (please complete the following information):** 20 | - PHP Version: 21 | - CodeIgniter version: 22 | - Library version: 23 | -------------------------------------------------------------------------------- /src/Request.php: -------------------------------------------------------------------------------- 1 | getGetPost($requestName); 22 | 23 | return (Object) ((strtolower($request->getMethod()) == 'get') ? $request->getGet() : $request->getPost()); 24 | 25 | } 26 | 27 | 28 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hermawan/codeigniter4-datatables", 3 | "description": "Serverside Datatables library for CodeIgniter4", 4 | "type": "library", 5 | "require": { 6 | "php": ">=7.3", 7 | "codeigniter4/framework": "^4", 8 | "greenlion/php-sql-parser": ">=4.5" 9 | }, 10 | "license": "MIT", 11 | "authors": [ 12 | { 13 | "name": "Hermawan Ramadhan", 14 | "email": "hermawanramadhan@gmail.com" 15 | } 16 | ], 17 | "autoload": { 18 | "psr-4": { 19 | "Hermawan\\DataTables\\": "src/" 20 | } 21 | }, 22 | "minimum-stability": "dev" 23 | } 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Hermawan Ramadhan 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 all 13 | 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 THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeIgniter4 DataTables Library 2 | [![Donate](https://img.shields.io/badge/donate-paypal-blue.svg)](https://www.paypal.me/mbahcoding) 3 | [![Total Downloads](https://poser.pugx.org/hermawan/codeigniter4-datatables/downloads)](https://packagist.org/packages/hermawan/codeigniter4-datatables) 4 | ![GitHub repo size](https://img.shields.io/github/repo-size/hermawanramadhan/CodeIgniter4-DataTables?label=size) 5 | ![GitHub](https://img.shields.io/github/license/hermawanramadhan/CodeIgniter4-DataTables) 6 | 7 | Server-side Datatables library for CodeIgniter4 PHP framework 8 | CodeIgniter4-DataTables is CodeIgniter4 Library to handle server-side processing of DataTables jQuery Plugin via AJAX option by using Query Builder CodeIgniter 4 9 | 10 | # Documentation 11 | For more complete example and demo please visit [Documentation here](https://codeigniter4-datatables.hermawan.dev/welcome) 12 | 13 | 14 | 15 | ## Requirements 16 | * Codeigniter 4.x 17 | * jQuery DataTables v1.10.x 18 | 19 | ## Installing 20 | 21 | ### Using composer 22 | Use composer to install CodeIgniter4-DataTables into your project : 23 | 24 | > composer require hermawan/codeigniter4-datatables 25 | 26 | 27 | ## Simple Initializing 28 | 29 | ### Using CodeIgniter Query Builder 30 | This is simple basic code just write `DataTable::of($builder)` call method `toJson()` for output 31 | 32 | `$builder` is CodeIgniter build-in Query Builder object. 33 | 34 | **Controller :** 35 | ```php 36 | use \Hermawan\DataTables\DataTable; 37 | 38 | public function ajaxDatatable() 39 | { 40 | $db = db_connect(); 41 | $builder = $db->table('customers')->select('customerNumber, customerName, phone, city, country, postalCode'); 42 | 43 | return DataTable::of($builder)->toJson(); 44 | } 45 | ``` 46 | 47 | ### Using CodeIgniter Model 48 | You can initialize using `Model` instead `Query Builder` 49 | This is simple example basic code 50 | 51 | **Controller :** 52 | ```php 53 | use \Hermawan\DataTables\DataTable; 54 | use \App\Models\CustomerModel; 55 | 56 | public function ajaxDatatable() 57 | { 58 | $customerModel = new CustomerModel(); 59 | $customerModel->select('customerNumber, customerName, phone, city, country, postalCode'); 60 | 61 | return DataTable::of($customerModel)->toJson(); 62 | } 63 | ``` 64 | 65 | **Javascript :** 66 | ```javascript 67 | $(document).ready(function() { 68 | $('#table').DataTable({ 69 | processing: true, 70 | serverSide: true, 71 | ajax: '' 72 | }); 73 | }); 74 | ``` 75 | 76 | 77 | 78 | For more complete example and demo please visit [Documentation here](https://codeigniter4-datatables.hermawan.dev/welcome) 79 | -------------------------------------------------------------------------------- /src/DataTable.php: -------------------------------------------------------------------------------- 1 | builder(); 33 | } 34 | $this->query = new DataTableQuery($builder); 35 | $this->columnDefs = new DataTableColumnDefs($builder); 36 | } 37 | 38 | /** 39 | * Make a DataTable instance from builder. 40 | * 41 | * Builder from CodeIgniter Query Builder 42 | * @param \CodeIgniter\Database\BaseBuilder| \CodeIgniter\BaseModel $builder 43 | */ 44 | public static function of($builder): DataTable 45 | { 46 | return new self($builder); 47 | } 48 | 49 | /** 50 | * postQuery 51 | * @param Closure $postQuery 52 | */ 53 | public function postQuery($postQuery) 54 | { 55 | $this->query->postQuery($postQuery); 56 | return $this; 57 | } 58 | 59 | /** 60 | * custom Filter 61 | * @param Closure function 62 | */ 63 | public function filter($filterFunction) 64 | { 65 | $this->query->filter($filterFunction); 66 | return $this; 67 | } 68 | 69 | 70 | /** 71 | * Add numbering to first column 72 | * @param string $column 73 | */ 74 | public function addNumbering($column = NULL) 75 | { 76 | $this->columnDefs->addNumbering($column); 77 | return $this; 78 | } 79 | 80 | 81 | /** 82 | * Add extra column 83 | * 84 | * @param string $column 85 | * @param Closure $callback 86 | * @param string|int $position 87 | */ 88 | public function add($column, $callback, $position = 'last') 89 | { 90 | $this->columnDefs->add($column, $callback, $position); 91 | return $this; 92 | } 93 | 94 | /** 95 | * Edit column 96 | * 97 | * @param string $column 98 | * @param Closure $callback 99 | */ 100 | public function edit($column, $callback) 101 | { 102 | $this->columnDefs->edit($column, $callback); 103 | return $this; 104 | } 105 | 106 | /** 107 | * Format column 108 | * 109 | * @param string $column 110 | * @param Closure $callback 111 | */ 112 | public function format($column, $callback) 113 | { 114 | $this->columnDefs->format($column, $callback); 115 | return $this; 116 | } 117 | 118 | /** 119 | * Hide column 120 | * 121 | * @param string $column 122 | */ 123 | public function hide($column) 124 | { 125 | $this->columnDefs->remove($column); 126 | return $this; 127 | } 128 | 129 | /** 130 | * Escape column 131 | * 132 | * @param string $column 133 | * @param bool $escape 134 | */ 135 | public function escape($column, $escape = TRUE) 136 | { 137 | $this->columnDefs->escape($column, $escape); 138 | return $this; 139 | } 140 | 141 | /** 142 | * Set Searchable columns 143 | * @param string|array 144 | */ 145 | public function setSearchableColumns($columns) 146 | { 147 | $this->columnDefs->setSearchable($columns); 148 | return $this; 149 | } 150 | 151 | /** 152 | * Add Searchable columns 153 | * @param string|array 154 | */ 155 | public function addSearchableColumns($columns) 156 | { 157 | $this->columnDefs->addSearchable($columns); 158 | return $this; 159 | } 160 | 161 | 162 | 163 | /** 164 | * Return JSON output 165 | * 166 | * @param bool $returnAsObject 167 | * @return \CodeIgniter\HTTP\ResponseInterface 168 | */ 169 | public function toJson($returnAsObject = NULL) 170 | { 171 | 172 | if (!Request::get('draw')) { 173 | return self::throwError('no datatable request detected'); 174 | } 175 | 176 | if ($returnAsObject !== NULL) 177 | $this->columnDefs->returnAsObject($returnAsObject); 178 | 179 | $this->query->setColumnDefs($this->columnDefs); 180 | 181 | $response = Services::response(); 182 | 183 | return $response->setJSON([ 184 | 'draw' => Request::get('draw'), 185 | 'recordsTotal' => $this->query->countAll(), 186 | 'recordsFiltered' => $this->query->countFiltered(), 187 | 'data' => $this->query->getDataResult(), 188 | 189 | ]); 190 | } 191 | 192 | 193 | /** 194 | * Throw Error 195 | * 196 | * @param string $message 197 | * @return \CodeIgniter\HTTP\ResponseInterface 198 | */ 199 | public static function throwError($message) 200 | { 201 | $response = Services::response(); 202 | return $response->setJSON([ 203 | 'error' => $message, 204 | 205 | ]); 206 | } 207 | 208 | 209 | 210 | } // End of DataTables Library Class. 211 | -------------------------------------------------------------------------------- /src/DataTableQuery.php: -------------------------------------------------------------------------------- 1 | builder = $builder; 28 | } 29 | 30 | public function setColumnDefs($columnDefs) 31 | { 32 | $this->columnDefs = $columnDefs; 33 | return $this; 34 | } 35 | 36 | public function postQuery($postQuery) 37 | { 38 | $this->postQuery = $postQuery; 39 | } 40 | 41 | public function filter($filter) 42 | { 43 | $this->filter = $filter; 44 | } 45 | 46 | 47 | /* End Modified column */ 48 | 49 | 50 | /* Generating result */ 51 | 52 | 53 | public function countAll() 54 | { 55 | $builder = clone $this->builder; 56 | 57 | $this->countResult = $this->countResult !== NULL ? $this->countResult : $builder->countAllResults(); 58 | return $this->countResult; 59 | } 60 | 61 | public function countFiltered() 62 | { 63 | $builder = clone $this->builder; 64 | 65 | $this->queryFilterSearch($builder); 66 | 67 | $this->countResult = ($this->countResult !== NULL && ! $this->doQueryFilter) ? $this->countResult : $builder->countAllResults(); 68 | 69 | return $this->countResult; 70 | } 71 | 72 | public function getDataResult() 73 | { 74 | $queryResult = $this->queryResult(); 75 | $result = []; 76 | 77 | foreach ($queryResult as $row) 78 | { 79 | $data = []; 80 | $columns = $this->columnDefs->getColumns(); 81 | 82 | foreach ($columns as $index => $column) 83 | { 84 | if($column->escape) 85 | $row->{$column->alias} = esc($row->{$column->alias}); 86 | switch ($column->type) { 87 | case 'numbering': 88 | $value = $this->columnDefs->getNumbering(); 89 | break; 90 | 91 | case 'add': 92 | $callback = $column->callback; 93 | $value = $callback($row); 94 | break; 95 | 96 | case 'edit': 97 | $callback = $column->callback; 98 | 99 | $value = $callback($row, [ 100 | 'index' => $index, 101 | 'key' => $column->key, 102 | 'alias' => $column->alias, 103 | 'searchable' => $column->searchable, 104 | 'orderable' => $column->orderable, 105 | ]); 106 | break; 107 | 108 | case 'format': 109 | $callback = $column->callback; 110 | $value = $callback($row->{$column->alias}, [ 111 | 'index' => $index, 112 | 'key' => $column->key, 113 | 'alias' => $column->alias, 114 | 'searchable' => $column->searchable, 115 | 'orderable' => $column->orderable, 116 | ]); 117 | break; 118 | 119 | default: 120 | $value = $row->{$column->alias}; 121 | break; 122 | } 123 | 124 | if($this->columnDefs->returnAsObject) 125 | $data[$column->alias] = $value; 126 | else 127 | $data[] = $value; 128 | 129 | } 130 | 131 | $result[] = $data; 132 | } 133 | 134 | return $result; 135 | } 136 | 137 | /* End Generating result */ 138 | 139 | 140 | 141 | /* Querying */ 142 | 143 | private function queryOrder($builder) 144 | { 145 | 146 | $orderables = $this->columnDefs->getOrderables(); 147 | $oderColumnRequests = Request::get('order'); 148 | 149 | if($oderColumnRequests) 150 | { 151 | foreach ($oderColumnRequests as $request) 152 | { 153 | $dir = ($request['dir'] == 'desc') ? 'desc' : 'asc'; 154 | $column = $orderables[$request['column']] ?? NULL; 155 | 156 | if( $column !== NULL) 157 | $builder->orderBy($column, $dir); 158 | } 159 | } 160 | 161 | } 162 | 163 | private function queryFilterSearch($builder) 164 | { 165 | 166 | //individual column search (multi column search) 167 | $columnRequests = Request::get('columns'); 168 | foreach ($columnRequests as $index => $request) 169 | { 170 | 171 | if($request['search']['value'] != '') 172 | { 173 | $column = $this->columnDefs->getSearchRequest($index, $request); 174 | $this->doQueryFilter = TRUE; 175 | 176 | $builder->like($column, $request['search']['value']); 177 | } 178 | } 179 | 180 | //global search 181 | $searchRequest = Request::get('search'); 182 | 183 | if($searchRequest['value'] != '') 184 | { 185 | $searchable = $this->columnDefs->getSearchable(); 186 | 187 | if(! empty($searchable)) 188 | { 189 | $this->doQueryFilter = TRUE; 190 | 191 | $builder->groupStart(); 192 | foreach ($searchable as $column) 193 | $builder->orLike(trim($column), $searchRequest['value']); 194 | 195 | $builder->groupEnd(); 196 | } 197 | 198 | } 199 | 200 | $this->queryFilter($builder); 201 | } 202 | 203 | private function queryFilter($builder) 204 | { 205 | if($this->filter !== NULL) 206 | { 207 | $testBuilder = clone $builder; 208 | 209 | $callback = $this->filter; 210 | $callback($builder, Request::get()); 211 | 212 | if($testBuilder != $builder) 213 | $this->doQueryFilter = TRUE; 214 | } 215 | } 216 | 217 | private function queryResult() 218 | { 219 | $builder = clone $this->builder; 220 | 221 | $this->queryOrder($builder); 222 | 223 | if(Request::get('length') != -1) 224 | $builder->limit(Request::get('length'), Request::get('start')); 225 | 226 | $this->queryFilterSearch($builder); 227 | 228 | if($this->postQuery !== NULL) 229 | { 230 | $callback = $this->postQuery; 231 | $callback($builder); 232 | } 233 | 234 | return $builder->get()->getResult(); 235 | } 236 | 237 | /* End Querying */ 238 | 239 | 240 | } // End of DataTableQuery Class. 241 | -------------------------------------------------------------------------------- /src/DataTableColumnDefs.php: -------------------------------------------------------------------------------- 1 | initFromBuilder($builder); 18 | } 19 | 20 | public function returnAsObject($returnAsObject) 21 | { 22 | $this->returnAsObject = $returnAsObject; 23 | return $this; 24 | } 25 | 26 | 27 | public function addNumbering($key) 28 | { 29 | $column = new Column(); 30 | 31 | $column->key = $key; 32 | $column->alias = $key; 33 | $column->type = 'numbering'; 34 | $column->searchable = FALSE; 35 | $column->orderable = FALSE; 36 | $column->escape = FALSE; 37 | 38 | array_unshift($this->columns, $column); 39 | 40 | } 41 | 42 | public function add($key, $callback, $position) 43 | { 44 | $column = new Column(); 45 | 46 | $column->key = $key; 47 | $column->alias = $key; 48 | $column->type = 'add'; 49 | $column->searchable = FALSE; 50 | $column->orderable = FALSE; 51 | $column->callback = $callback; 52 | $column->escape = FALSE; 53 | 54 | switch ($position) { 55 | 56 | case 'first': 57 | array_unshift($this->columns, $column); 58 | break; 59 | 60 | case 'last': 61 | $this->columns[] = $column; 62 | break; 63 | 64 | default: 65 | array_splice( $this->columns, $position, 0, $column); 66 | break; 67 | } 68 | 69 | 70 | } 71 | 72 | public function edit($alias, $callback) 73 | { 74 | if($alias) 75 | { 76 | $column = $this->getColumnBy('alias', $alias); 77 | if(is_object($column)) 78 | { 79 | $column->type = 'edit'; 80 | $column->callback = $callback; 81 | } 82 | 83 | } 84 | 85 | } 86 | 87 | public function format($alias, $callback) 88 | { 89 | if($alias) 90 | { 91 | $column = $this->getColumnBy('alias', $alias); 92 | if(is_object($column)) 93 | { 94 | $column->type = 'format'; 95 | $column->callback = $callback; 96 | } 97 | 98 | } 99 | 100 | } 101 | 102 | public function escape($alias, $escape = TRUE) 103 | { 104 | if($alias) 105 | { 106 | $column = $this->getColumnBy('alias', $alias); 107 | if(is_object($column)) 108 | { 109 | $column->escape = $escape; 110 | } 111 | 112 | } 113 | 114 | } 115 | 116 | public function remove($alias) 117 | { 118 | if(! is_array($alias)) 119 | $aliases = [$alias]; 120 | 121 | foreach ($this->columns as $index => $column) 122 | { 123 | if(in_array($column->alias, $aliases)) 124 | { 125 | unset($this->columns[$index]); 126 | } 127 | } 128 | 129 | $this->columns = array_values($this->columns); 130 | } 131 | 132 | public function setSearchable($searchable) 133 | { 134 | $this->searchableColumns = $searchable; 135 | return $this; 136 | } 137 | 138 | public function addSearchable($searchable) 139 | { 140 | if(is_array($searchable)) 141 | $this->searchableColumns = array_merge($this->searchableColumns, $searchable); 142 | else 143 | $this->searchableColumns[] = $searchable; 144 | } 145 | 146 | public function getColumns() 147 | { 148 | return $this->columns; 149 | } 150 | 151 | public function getOrderables() 152 | { 153 | $orderableColumns = []; 154 | 155 | if($this->returnAsObject) 156 | { 157 | foreach (Request::get('columns') as $columnRequest) 158 | { 159 | if($columnRequest['name']) 160 | $orderableColumns[] = $columnRequest['name']; 161 | 162 | elseif($column = $this->getColumnBy('alias', $columnRequest['data'])) 163 | $orderableColumns[] = $column->alias; 164 | 165 | else 166 | $orderableColumns[] = $columnRequest['data']; 167 | 168 | } 169 | 170 | } 171 | else 172 | { 173 | foreach ($this->columns as $column) 174 | $orderableColumns[] = $column->orderable ? $column->alias : NULL; 175 | } 176 | 177 | return $orderableColumns; 178 | 179 | } 180 | 181 | public function getSearchRequest($index, $request) 182 | { 183 | 184 | if($this->returnAsObject) 185 | { 186 | if($request['name']) 187 | return trim($request['name']); 188 | 189 | elseif($column = $this->getColumnBy('alias', $request['data'])) 190 | return $column->key; 191 | 192 | else 193 | return $request['data']; 194 | } 195 | else 196 | { 197 | return $this->columns[$index]->key; 198 | } 199 | } 200 | 201 | public function getSearchable() 202 | { 203 | if($this->searchableColumns !== NULL) 204 | { 205 | return $this->searchableColumns; 206 | } 207 | else 208 | { 209 | $searchableColumns = []; 210 | 211 | foreach (Request::get('columns') as $index => $request) 212 | { 213 | if($request['searchable'] == 'true') 214 | { 215 | if($this->returnAsObject) 216 | { 217 | if($request['name']) 218 | $searchableColumns[] = trim($request['name']); 219 | 220 | elseif($column = $this->getColumnBy('alias', $request['data'])) 221 | { 222 | if($column->searchable) 223 | $searchableColumns[] = $column->key; 224 | } 225 | 226 | else 227 | $searchableColumns[] = $request['data']; 228 | } 229 | else 230 | { 231 | $column = $this->columns[$index]; 232 | if($column->searchable) 233 | $searchableColumns[] = $column->key; 234 | 235 | } 236 | 237 | } 238 | } 239 | 240 | return $searchableColumns; 241 | 242 | } 243 | 244 | 245 | } 246 | 247 | public function getNumbering() 248 | { 249 | $this->number = $this->number === NULL ? Request::get('start')+1 : $this->number+1; 250 | return $this->number; 251 | } 252 | 253 | 254 | public function initFromBuilder($baseBuilder) 255 | { 256 | $builder = clone $baseBuilder; 257 | $QBSelect = Helper::getObjectPropertyValue($builder, 'QBSelect'); 258 | 259 | if( ! empty($QBSelect) ) 260 | { 261 | $baseSQL = $builder->getCompiledSelect(false); 262 | $parser = new \PHPSQLParser\PHPSQLParser(); 263 | $sqlParsed = $parser->parse($baseSQL); 264 | 265 | foreach ($sqlParsed['SELECT'] as $index => $selectParsed) 266 | { 267 | 268 | $column = new Column(); 269 | 270 | // if select column 271 | if ($selectParsed['expr_type'] == 'colref') 272 | { 273 | 274 | //if have select all (*) query 275 | if(strpos($selectParsed['base_expr'], '*') !== FALSE) 276 | { 277 | $fieldData = $builder->db()->getFieldData($selectParsed['no_quotes']['parts'][0]); 278 | foreach ($fieldData as $field) 279 | { 280 | 281 | $key = $selectParsed['no_quotes']['parts'][0].'.'.$field->name; 282 | $alias = $field->name; 283 | 284 | } 285 | 286 | } 287 | else 288 | { 289 | 290 | $alias = ! empty($selectParsed['alias']) ? end($selectParsed['alias']['no_quotes']['parts']) : end($selectParsed['no_quotes']['parts']); 291 | 292 | $key = count($selectParsed['no_quotes']['parts']) == 2 ? 293 | $selectParsed['no_quotes']['parts'][0].'.'.$selectParsed['no_quotes']['parts'][1] : 294 | $selectParsed['no_quotes']['parts'][0]; 295 | 296 | 297 | } 298 | 299 | } 300 | elseif ($selectParsed['expr_type'] == 'function') 301 | { 302 | 303 | $key = $selectParsed['base_expr']; 304 | $key .= '('; 305 | 306 | $arrayKey = []; 307 | 308 | foreach ($selectParsed['sub_tree'] as $sub_tree) 309 | $arrayKey[] = $sub_tree['base_expr']; 310 | 311 | $key .= implode($selectParsed['delim'].' ', $arrayKey); 312 | $key .= ')'; 313 | 314 | $alias = ! empty($selectParsed['alias']) ? end($selectParsed['alias']['no_quotes']['parts']) : $key; 315 | 316 | 317 | } 318 | else 319 | { 320 | 321 | if( ! empty($selectParsed['alias']) ) 322 | { 323 | $key = substr($QBSelect[$index], 0,-1*(strlen($selectParsed['alias']['base_expr']))); 324 | $alias = end($selectParsed['alias']['no_quotes']['parts']); 325 | } 326 | else 327 | { 328 | $key = $QBSelect[$index]; 329 | $alias = $key; 330 | 331 | } 332 | 333 | } 334 | 335 | $column->key = $key; 336 | $column->alias = $alias; 337 | $this->columns[] = $column; 338 | 339 | } 340 | 341 | } 342 | else 343 | { 344 | 345 | $QBFrom = Helper::getObjectPropertyValue($builder, 'QBFrom'); 346 | $QBJoin = Helper::getObjectPropertyValue($builder, 'QBJoin'); 347 | 348 | foreach ($QBFrom as $table) 349 | { 350 | $fieldData = $builder->db()->getFieldData($table); 351 | foreach ($fieldData as $field) 352 | { 353 | 354 | $column = new Column(); 355 | 356 | $column->key = $table.'.'.$field->name; 357 | $column->alias = $field->name; 358 | 359 | $this->columns[] = $column; 360 | 361 | } 362 | } 363 | 364 | foreach ($QBJoin as $table) 365 | { 366 | $fieldData = $builder->db()->getFieldData($table); 367 | foreach ($fieldData as $field) 368 | { 369 | $column = new Column(); 370 | 371 | $column->key = $table.'.'.$field->name; 372 | $column->alias = $field->name; 373 | 374 | $this->columns[] = $column; 375 | } 376 | } 377 | 378 | } 379 | 380 | return $this; 381 | } 382 | 383 | public function getColumnBy($by, $value) 384 | { 385 | foreach ($this->columns as $column) 386 | { 387 | if($column->$by == $value) 388 | return $column; 389 | } 390 | return NULL; 391 | } 392 | 393 | 394 | } // End of DataTableColumnDefs Class. 395 | --------------------------------------------------------------------------------