├── application
├── models
│ ├── grocery_crud_model_mysql.php
│ ├── grocery_crud_model_mysqli.php
│ ├── grocery_crud_model_oci8.php
│ ├── grocery_crud_model_odbc.php
│ ├── grocery_crud_model_cubrid.php
│ ├── grocery_crud_model_ibase.php
│ ├── grocery_crud_model_mssql.php
│ ├── grocery_crud_model_postgre.php
│ ├── grocery_crud_model_sqlite.php
│ ├── grocery_crud_model_sqlite3.php
│ ├── grocery_crud_model_sqlsrv.php
│ ├── grocery_crud_model_pdo.php
│ └── grocery_crud_generic_model.php
└── controllers
│ └── examples.php
├── example_database
└── sqlite_example_database.sqlite
└── README.md
/application/models/grocery_crud_model_mysql.php:
--------------------------------------------------------------------------------
1 | 'mysql:host=localhost;port=3306;dbname=test_database',
14 | 'hostname' => 'localhost',
15 | 'username' => 'root',
16 | 'password' => 'my_password',
17 | 'database' => 'test_database',
18 | 'dbdriver' => 'pdo',
19 | 'dbprefix' => '',
20 | 'pconnect' => TRUE,
21 | 'db_debug' => TRUE,
22 | 'cache_on' => FALSE,
23 | 'cachedir' => '',
24 | 'char_set' => 'utf8',
25 | 'dbcollat' => 'utf8_general_ci',
26 | 'swap_pre' => '',
27 | 'autoinit' => TRUE,
28 | 'encrypt' => FALSE,
29 | 'compress' => FALSE,
30 | 'stricton' => FALSE,
31 | 'failover' => array()
32 | );
33 | ```
34 | If you want to use sqlite, change your dsn into this `'sqlite:'.FCPATH.'example_database/sqlite_example_database.sqlite'`
35 |
--------------------------------------------------------------------------------
/application/models/grocery_crud_model_pdo.php:
--------------------------------------------------------------------------------
1 | subdriver = $this->db->subdriver;
9 | // these drivers doesn't have CONCAT command
10 | if(in_array($this->subdriver, array('sqlite', 'pgsql'))){
11 | $this->CAPABLE_CONCAT = FALSE;
12 | }
13 | }
14 |
15 | function get_primary_key($table_name = null)
16 | {
17 | // let's see what the parent can do
18 | $primary_key = parent::get_primary_key($table_name);
19 | if($primary_key !== FALSE){
20 | return $primary_key;
21 | }
22 |
23 | // set default value for table_name if not set.
24 | if(!isset($table_name)){
25 | $table_name = $this->table_name;
26 | }
27 | // postgre need this
28 | if($this->subdriver=='pgsql'){
29 | $SQL = "SELECT
30 | pg_attribute.attname
31 | FROM pg_index, pg_class, pg_attribute
32 | WHERE
33 | pg_class.oid = '".$table_name."'::regclass AND
34 | indrelid = pg_class.oid AND
35 | pg_attribute.attrelid = pg_class.oid AND
36 | pg_attribute.attnum = any(pg_index.indkey);";
37 | $query = $this->db->query($SQL);
38 | $row = $query->row();
39 | $primary_key = $row->attname;
40 | }
41 |
42 | return $primary_key;
43 | }
44 |
45 | function get_field_types_basic_table()
46 | {
47 | $results = parent::get_field_types_basic_table();
48 | if($this->subdriver == 'pgsql'){
49 | $results = array_reverse($results);
50 | }
51 | return $results;
52 | }
53 |
54 | function build_db_join_relation($related_table, $unique_name, $related_primary_key, $field_name){
55 | if($this->subdriver=='pgsql'){
56 | $this->db->join( $this->protect_identifiers($related_table).' as '.$this->protect_identifiers($unique_name) ,
57 | 'cast('.$this->protect_identifiers($unique_name.'.'.$related_primary_key).' as character varying) = cast('. $this->protect_identifiers($this->table_name.'.'.$field_name).' as character varying)', 'left', FALSE);
58 |
59 | }else{
60 | parent::build_db_join_relation($related_table, $unique_name, $related_primary_key, $field_name);
61 | }
62 | }
63 |
64 | function build_relation_n_n_subquery($field, $selection_table, $relation_table, $primary_key_alias_to_selection_table, $primary_key_selection_table, $primary_key_alias_to_this_table, $field_name){
65 | if($this->subdriver=='pgsql'){
66 | return "(SELECT string_agg(".$this->protect_identifiers($field).", ',') FROM ".$this->protect_identifiers($selection_table)
67 | ." LEFT JOIN ".$this->protect_identifiers($relation_table)." ON ".$this->protect_identifiers($relation_table.".".$primary_key_alias_to_selection_table)." = ".$this->protect_identifiers($selection_table.".".$primary_key_selection_table)
68 | ." WHERE cast(".$this->protect_identifiers($relation_table.".".$primary_key_alias_to_this_table)." as character varying ) = cast(".$this->protect_identifiers($this->table_name.".".$this->get_primary_key())." as character varying ) GROUP BY ".$this->protect_identifiers($relation_table.".".$primary_key_alias_to_this_table).") AS ".$this->protect_identifiers($field_name);
69 | }else{
70 | return parent::build_relation_n_n_subquery($field, $selection_table, $relation_table, $primary_key_alias_to_selection_table, $primary_key_selection_table, $primary_key_alias_to_this_table, $field_name);
71 | }
72 | }
73 |
74 |
75 | }
--------------------------------------------------------------------------------
/application/controllers/examples.php:
--------------------------------------------------------------------------------
1 | load->database();
10 | $this->load->helper('url');
11 | }
12 |
13 | public function new_crud(){
14 | $db_driver = $this->db->platform();
15 | $model_name = 'grocery_crud_model_'.$db_driver;
16 | $model_alias = 'm'.substr(md5(rand()), 0, rand(4,15) );
17 |
18 | unset($this->{$model_name});
19 | $this->load->library('grocery_CRUD');
20 | $crud = new Grocery_CRUD();
21 | if (file_exists(APPPATH.'/models/'.$model_name.'.php')){
22 | $this->load->model('grocery_crud_model');
23 | $this->load->model('grocery_crud_generic_model');
24 | $this->load->model($model_name,$model_alias);
25 | $crud->basic_model = $this->{$model_alias};
26 | }
27 | return $crud;
28 | }
29 |
30 | public function _example_output($output = null)
31 | {
32 | $this->load->view('example.php',$output);
33 | }
34 |
35 | public function offices()
36 | {
37 | $crud = $this->new_crud();
38 | $output = $crud->render();
39 |
40 | $this->_example_output($output);
41 | }
42 |
43 | public function index()
44 | {
45 | $this->_example_output((object)array('output' => '' , 'js_files' => array() , 'css_files' => array()));
46 | }
47 |
48 | public function offices_management()
49 | {
50 | try{
51 | $crud = $this->new_crud();
52 |
53 | $crud->set_theme('datatables');
54 | $crud->set_table('offices');
55 | $crud->set_subject('Office');
56 | $crud->required_fields('city');
57 | $crud->columns('city','country','phone','addressLine1','postalCode');
58 |
59 | $output = $crud->render();
60 |
61 | $this->_example_output($output);
62 |
63 | }catch(Exception $e){
64 | show_error($e->getMessage().' --- '.$e->getTraceAsString());
65 | }
66 | }
67 |
68 | public function employees_management()
69 | {
70 | $crud = $this->new_crud();
71 |
72 | $crud->set_theme('datatables');
73 | $crud->set_table('employees');
74 | $crud->set_relation('officeCode','offices','city');
75 | $crud->display_as('officeCode','Office City');
76 | $crud->set_subject('Employee');
77 |
78 | $crud->required_fields('lastName');
79 |
80 | $crud->set_field_upload('file_url','assets/uploads/files');
81 |
82 | $output = $crud->render();
83 |
84 | $this->_example_output($output);
85 | }
86 |
87 | public function customers_management()
88 | {
89 | $crud = $this->new_crud();
90 |
91 | $crud->set_table('customers');
92 | $crud->columns('customerName','contactLastName','phone','city','country','salesRepEmployeeNumber','creditLimit');
93 | $crud->display_as('salesRepEmployeeNumber','from Employeer')
94 | ->display_as('customerName','Name')
95 | ->display_as('contactLastName','Last Name');
96 | $crud->set_subject('Customer');
97 | $crud->set_relation('salesRepEmployeeNumber','employees','lastName');
98 |
99 | $output = $crud->render();
100 |
101 | $this->_example_output($output);
102 | }
103 |
104 | public function orders_management()
105 | {
106 | $crud = $this->new_crud();
107 |
108 | $crud->set_relation('customerNumber','customers','{contactLastName} {contactFirstName}');
109 | $crud->display_as('customerNumber','Customer');
110 | $crud->set_table('orders');
111 | $crud->set_subject('Order');
112 | $crud->unset_add();
113 | $crud->unset_delete();
114 |
115 | $output = $crud->render();
116 |
117 | $this->_example_output($output);
118 | }
119 |
120 | public function products_management()
121 | {
122 | $crud = $this->new_crud();
123 |
124 | $crud->set_table('products');
125 | $crud->set_subject('Product');
126 | $crud->unset_columns('productDescription');
127 | $crud->callback_column('buyPrice',array($this,'valueToEuro'));
128 |
129 | $output = $crud->render();
130 |
131 | $this->_example_output($output);
132 | }
133 |
134 | public function valueToEuro($value, $row)
135 | {
136 | return $value.' €';
137 | }
138 |
139 | public function film_management()
140 | {
141 | $crud = $this->new_crud();
142 |
143 | $crud->set_table('film');
144 | $crud->set_relation_n_n('actors', 'film_actor', 'actor', 'film_id', 'actor_id', 'fullname','priority');
145 | $crud->set_relation_n_n('category', 'film_category', 'category', 'film_id', 'category_id', 'name');
146 | $crud->unset_columns('special_features','description','actors');
147 |
148 | $crud->fields('title', 'description', 'actors' , 'category' ,'release_year', 'rental_duration', 'rental_rate', 'length', 'replacement_cost', 'rating', 'special_features');
149 |
150 | $output = $crud->render();
151 |
152 | $this->_example_output($output);
153 | }
154 |
155 | public function film_management_twitter_bootstrap()
156 | {
157 | try{
158 | $crud = $this->new_crud();
159 |
160 | $crud->set_theme('twitter-bootstrap');
161 | $crud->set_table('film');
162 | $crud->set_relation_n_n('actors', 'film_actor', 'actor', 'film_id', 'actor_id', 'fullname','priority');
163 | $crud->set_relation_n_n('category', 'film_category', 'category', 'film_id', 'category_id', 'name');
164 | $crud->unset_columns('special_features','description','actors');
165 |
166 | $crud->fields('title', 'description', 'actors' , 'category' ,'release_year', 'rental_duration', 'rental_rate', 'length', 'replacement_cost', 'rating', 'special_features');
167 |
168 | $output = $crud->render();
169 | $this->_example_output($output);
170 |
171 | }catch(Exception $e){
172 | show_error($e->getMessage().' --- '.$e->getTraceAsString());
173 | }
174 | }
175 |
176 | function multigrids()
177 | {
178 | $this->config->load('grocery_crud');
179 | $this->config->set_item('grocery_crud_dialog_forms',true);
180 | $this->config->set_item('grocery_crud_default_per_page',10);
181 |
182 | $output1 = $this->offices_management2();
183 |
184 | $output2 = $this->employees_management2();
185 |
186 | $output3 = $this->customers_management2();
187 |
188 | $js_files = $output1->js_files + $output2->js_files + $output3->js_files;
189 | $css_files = $output1->css_files + $output2->css_files + $output3->css_files;
190 | $output = "
List 1
".$output1->output."List 2
".$output2->output."List 3
".$output3->output;
191 |
192 | $this->_example_output((object)array(
193 | 'js_files' => $js_files,
194 | 'css_files' => $css_files,
195 | 'output' => $output
196 | ));
197 | }
198 |
199 | public function offices_management2()
200 | {
201 | $crud = $this->new_crud();
202 | $crud->set_table('offices');
203 | $crud->set_subject('Office');
204 | $crud->required_fields('city');
205 | $crud->columns('city','country','phone','addressLine1','postalCode');
206 |
207 | $crud->set_crud_url_path(site_url(strtolower(__CLASS__."/".__FUNCTION__)),site_url(strtolower(__CLASS__."/multigrids")));
208 |
209 | $output = $crud->render();
210 |
211 | if($crud->getState() != 'list') {
212 | $this->_example_output($output);
213 | } else {
214 | return $output;
215 | }
216 | }
217 |
218 | public function employees_management2()
219 | {
220 | $crud = $this->new_crud();
221 |
222 | $crud->set_theme('datatables');
223 | $crud->set_table('employees');
224 | $crud->set_relation('officeCode','offices','city');
225 | $crud->display_as('officeCode','Office City');
226 | $crud->set_subject('Employee');
227 |
228 | $crud->required_fields('lastName');
229 |
230 | $crud->set_field_upload('file_url','assets/uploads/files');
231 |
232 | $crud->set_crud_url_path(site_url(strtolower(__CLASS__."/".__FUNCTION__)),site_url(strtolower(__CLASS__."/multigrids")));
233 |
234 | $output = $crud->render();
235 |
236 | if($crud->getState() != 'list') {
237 | $this->_example_output($output);
238 | } else {
239 | return $output;
240 | }
241 | }
242 |
243 | public function customers_management2()
244 | {
245 |
246 | $crud = $this->new_crud();
247 |
248 | $crud->set_table('customers');
249 | $crud->columns('customerName','contactLastName','phone','city','country','salesRepEmployeeNumber','creditLimit');
250 | $crud->display_as('salesRepEmployeeNumber','from Employeer')
251 | ->display_as('customerName','Name')
252 | ->display_as('contactLastName','Last Name');
253 | $crud->set_subject('Customer');
254 | $crud->set_relation('salesRepEmployeeNumber','employees','lastName');
255 |
256 | $crud->set_crud_url_path(site_url(strtolower(__CLASS__."/".__FUNCTION__)),site_url(strtolower(__CLASS__."/multigrids")));
257 |
258 | $output = $crud->render();
259 |
260 | if($crud->getState() != 'list') {
261 | $this->_example_output($output);
262 | } else {
263 | return $output;
264 | }
265 | }
266 |
267 | }
--------------------------------------------------------------------------------
/application/models/grocery_crud_generic_model.php:
--------------------------------------------------------------------------------
1 | protect_identifiers('t');
11 | $first_char = substr($test,0,1);
12 | if($first_char !== 't'){
13 | $this->ESCAPE_CHAR = $first_char;
14 | }
15 | }
16 |
17 | public function protect_identifiers($value)
18 | {
19 | return $this->db->protect_identifiers($value);
20 | }
21 |
22 | // rather than mess around with this everytime, it is better to build a function for this.
23 | public function build_concat_from_template($template, $prefix_replacement='', $suffix_replacement='', $as=NULL){
24 | if($this->CAPABLE_CONCAT){
25 | // if CONCAT is possible in the current driver
26 | $concat_str =
27 | "CONCAT('".
28 | str_replace(
29 | array(
30 | "{",
31 | "}"
32 | ),
33 | array(
34 | "',COALESCE(".$prefix_replacement,
35 | $suffix_replacement.", ''),'"
36 | ),
37 | str_replace("'","\\'",$template)
38 | ).
39 | "')";
40 |
41 | }else{
42 | // if CONCAT is impossible in the current driver, use || instead
43 | $concat_str =
44 | "('".
45 | str_replace(
46 | array(
47 | "{",
48 | "}"
49 | ),
50 | array(
51 | "' || COALESCE(".$replacement,
52 | ", '') || '"
53 | ),
54 | str_replace("'","\\'",$template)
55 | ).
56 | "')";
57 | }
58 | if(isset($as)){
59 | $concat_str .= " as ".$as;
60 | }
61 |
62 | }
63 |
64 | function get_list()
65 | {
66 | if($this->table_name === null)
67 | return false;
68 |
69 | $select = $this->protect_identifiers("{$this->table_name}").".*";
70 |
71 | // this variable is used to save table.column info since postgresql doesn't support "AS 'table.column'" syntax
72 | $additional_fields = array();
73 | //set_relation special queries
74 | if(!empty($this->relation))
75 | {
76 | foreach($this->relation as $relation)
77 | {
78 | list($field_name , $related_table , $related_field_title) = $relation;
79 | $unique_join_name = $this->_unique_join_name($field_name);
80 | $unique_field_name = $this->_unique_field_name($field_name);
81 |
82 | if(strstr($related_field_title,'{'))
83 | {
84 | $related_field_title = str_replace(" "," ",$related_field_title);
85 | $select .= ", ".$this->build_concat_from_template(
86 | $related_field_title,
87 | $this->protect_identifiers($unique_join_name).".".$this->ESCAPE_CHAR,
88 | $this->ESCAPE_CHAR,
89 | $this->protect_identifiers($unique_field_name)
90 | );
91 | //$select .= ", CONCAT('".str_replace(array('{','}'),array("',COALESCE(".$this->protect_identifiers($unique_join_name).".".$this->ESCAPE_CHAR, $this->ESCAPE_CHAR.", ''),'"),str_replace("'","\\'",$related_field_title))."') as ".$this->protect_identifiers($unique_field_name);
92 | }
93 | else
94 | {
95 | $select .= ', ' . $this->protect_identifiers($unique_join_name. '.'. $related_field_title).' AS '. $this->protect_identifiers($unique_field_name);
96 | }
97 |
98 | if($this->field_exists($related_field_title)){
99 | $additional_fields[$this->table_name. '.'. $related_field_title] = $related_field_title;
100 | // this syntax doesn't work on postgresql
101 | //$select .= ', '.$this->protect_identifiers($this->table_name. '.'. $related_field_title).' AS \''.$this->table_name. '.'. $related_field_title.'\'';
102 | }
103 |
104 | }
105 | }
106 |
107 | //set_relation_n_n special queries. We prefer sub queries from a simple join for the relation_n_n as it is faster and more stable on big tables.
108 | if(!empty($this->relation_n_n))
109 | {
110 | $select = $this->relation_n_n_queries($select);
111 | }
112 |
113 | $this->db->select($select, false);
114 |
115 | $results = $this->db->get($this->table_name)->result();
116 |
117 | // add information from additional_fields
118 | for($i=0; $i$real_field){
120 | $results[$i]->{$alias} = $results[$i]->{$real_field};
121 | }
122 | }
123 |
124 | return $results;
125 | }
126 |
127 | protected function relation_n_n_queries($select)
128 | {
129 | $this_table_primary_key = $this->get_primary_key();
130 | foreach($this->relation_n_n as $relation_n_n)
131 | {
132 | list($field_name, $relation_table, $selection_table, $primary_key_alias_to_this_table,
133 | $primary_key_alias_to_selection_table, $title_field_selection_table, $priority_field_relation_table) = array_values((array)$relation_n_n);
134 |
135 | $primary_key_selection_table = $this->get_primary_key($selection_table);
136 |
137 | $field = "";
138 | $use_template = strpos($title_field_selection_table,'{') !== false;
139 | $field_name_hash = $this->_unique_field_name($title_field_selection_table);
140 | if($use_template)
141 | {
142 | $title_field_selection_table = str_replace(" ", " ", $title_field_selection_table);
143 | $field .= $this->build_concat_from_template($this->protect_identifiers($title_field_selection_table));
144 | //$field .= "CONCAT('".str_replace(array('{','}'),array("',COALESCE(",", ''),'"),str_replace("'","\\'",$this->protect_identifiers($title_field_selection_table)))."')";
145 | }
146 | else
147 | {
148 | $field .= $this->protect_identifiers($selection_table.'.'.$title_field_selection_table);
149 | }
150 |
151 | //Sorry Codeigniter but you cannot help me with the subquery!
152 | $select .= ", ".
153 | $this->build_relation_n_n_subquery($field, $selection_table, $relation_table, $primary_key_alias_to_selection_table, $primary_key_selection_table, $primary_key_alias_to_this_table, $field_name);
154 | }
155 |
156 | return $select;
157 | }
158 |
159 | function get_total_results()
160 | {
161 | //set_relation_n_n special queries. We prefer sub queries from a simple join for the relation_n_n as it is faster and more stable on big tables.
162 | if(!empty($this->relation_n_n))
163 | {
164 | $select = $this->protect_identifiers($this->table_name).'.'.'*';
165 | $select = $this->relation_n_n_queries($select);
166 |
167 | $this->db->select($select,false);
168 |
169 | return $this->db->get($this->table_name)->num_rows();
170 | }
171 |
172 | return $this->db->count_all_results($this->table_name);
173 | }
174 |
175 | function join_relation($field_name , $related_table , $related_field_title)
176 | {
177 | $related_primary_key = $this->get_primary_key($related_table);
178 |
179 | if($related_primary_key !== false)
180 | {
181 | $unique_name = $this->_unique_join_name($field_name);
182 | $this->build_db_join_relation($related_table, $unique_name, $related_primary_key, $field_name);
183 |
184 | $this->relation[$field_name] = array($field_name , $related_table , $related_field_title);
185 |
186 | return true;
187 | }
188 |
189 | return false;
190 | }
191 |
192 | function get_relation_array($field_name , $related_table , $related_field_title, $where_clause, $order_by, $limit = null, $search_like = null)
193 | {
194 | $relation_array = array();
195 | $field_name_hash = $this->_unique_field_name($field_name);
196 |
197 | $related_primary_key = $this->get_primary_key($related_table);
198 |
199 | $select = $this->protect_identifiers($related_table).'.'.$this->protect_identifiers($related_primary_key).', ';
200 |
201 | if(strstr($related_field_title,'{'))
202 | {
203 | $related_field_title = str_replace(" ", " ", $related_field_title);
204 | $select .= $this->build_concat_from_template(
205 | $related_field_title,
206 | $this->ESCAPE_CHAR,
207 | $this->ESCAPE_CHAR,
208 | $this->protect_identifiers($field_name_hash)
209 | );
210 | //$select .= "CONCAT('".str_replace(array('{','}'),array("',COALESCE(".$this->ESCAPE_CHAR , $this->ESCAPE_CHAR.", ''),'"),str_replace("'","\\'", $related_field_title))."') as ".$this->protect_identifiers($field_name_hash);
211 | }
212 | else
213 | {
214 | $select .= $this->protect_identifiers($related_table.'.'.$related_field_title).' as '.$this->protect_identifiers($field_name_hash);
215 | }
216 |
217 | $this->db->select($select,false);
218 | if($where_clause !== null)
219 | $this->db->where($where_clause);
220 |
221 | if($where_clause !== null)
222 | $this->db->where($where_clause);
223 |
224 | if($limit !== null)
225 | $this->db->limit($limit);
226 |
227 | if($search_like !== null)
228 | $this->db->having($this->protect_identifiers($field_name_hash)." LIKE '%".$this->db->escape_like_str($search_like)."%'");
229 |
230 | $order_by !== null
231 | ? $this->db->order_by($order_by)
232 | : $this->db->order_by($field_name_hash);
233 |
234 | $results = $this->db->get($related_table)->result();
235 |
236 | foreach($results as $row)
237 | {
238 | $relation_array[$row->$related_primary_key] = $row->$field_name_hash;
239 | }
240 |
241 | return $relation_array;
242 | }
243 |
244 | function get_relation_n_n_selection_array($primary_key_value, $field_info)
245 | {
246 | $select = "";
247 | $related_field_title = $field_info->title_field_selection_table;
248 | $use_template = strpos($related_field_title,'{') !== false;;
249 | $field_name_hash = $this->_unique_field_name($related_field_title);
250 | if($use_template)
251 | {
252 | $related_field_title = str_replace(" ", " ", $related_field_title);
253 | $select .= $this->build_concat_from_template(
254 | $related_field_title,
255 | $this->ESCAPE_CHAR,
256 | $this->ESCAPE_CHAR,
257 | $this->protect_identifiers($field_name_hash)
258 | );
259 | //$select .= "CONCAT('".str_replace(array('{','}'),array("',COALESCE(",", ''),'"),str_replace("'","\\'",$related_field_title))."') as $field_name_hash";
260 | }
261 | else
262 | {
263 | $select .= "$related_field_title as $field_name_hash";
264 | }
265 | $this->db->select('*, '.$select,false);
266 |
267 | $selection_primary_key = $this->get_primary_key($field_info->selection_table);
268 |
269 | if(empty($field_info->priority_field_relation_table))
270 | {
271 | if(!$use_template){
272 | $this->db->order_by("{$field_info->selection_table}.{$field_info->title_field_selection_table}");
273 | }
274 | }
275 | else
276 | {
277 | $this->db->order_by("{$field_info->relation_table}.{$field_info->priority_field_relation_table}");
278 | }
279 | $this->db->where($field_info->primary_key_alias_to_this_table, $primary_key_value);
280 | $this->db->join(
281 | $field_info->selection_table,
282 | "{$field_info->relation_table}.{$field_info->primary_key_alias_to_selection_table} = {$field_info->selection_table}.{$selection_primary_key}"
283 | );
284 | $results = $this->db->get($field_info->relation_table)->result();
285 |
286 | $results_array = array();
287 | foreach($results as $row)
288 | {
289 | $results_array[$row->{$field_info->primary_key_alias_to_selection_table}] = $row->{$field_name_hash};
290 | }
291 |
292 | return $results_array;
293 | }
294 |
295 | function get_relation_n_n_unselected_array($field_info, $selected_values)
296 | {
297 | $use_where_clause = !empty($field_info->where_clause);
298 |
299 | $select = "";
300 | $related_field_title = $field_info->title_field_selection_table;
301 | $use_template = strpos($related_field_title,'{') !== false;
302 | $field_name_hash = $this->_unique_field_name($related_field_title);
303 |
304 | if($use_template)
305 | {
306 | $related_field_title = str_replace(" ", " ", $related_field_title);
307 | $select .= $this->build_concat_from_template(
308 | $related_field_title,
309 | $this->ESCAPE_CHAR,
310 | $this->ESCAPE_CHAR,
311 | $this->protect_identifiers($field_name_hash)
312 | );
313 | //$select .= "CONCAT('".str_replace(array('{','}'),array("',COALESCE(",", ''),'"),str_replace("'","\\'",$related_field_title))."') as $field_name_hash";
314 | }
315 | else
316 | {
317 | $select .= "$related_field_title as $field_name_hash";
318 | }
319 | $this->db->select('*, '.$select,false);
320 |
321 | if($use_where_clause){
322 | $this->db->where($field_info->where_clause);
323 | }
324 |
325 | $selection_primary_key = $this->get_primary_key($field_info->selection_table);
326 | if(!$use_template)
327 | $this->db->order_by("{$field_info->selection_table}.{$field_info->title_field_selection_table}");
328 | $results = $this->db->get($field_info->selection_table)->result();
329 |
330 | $results_array = array();
331 | foreach($results as $row)
332 | {
333 | if(!isset($selected_values[$row->$selection_primary_key]))
334 | $results_array[$row->$selection_primary_key] = $row->{$field_name_hash};
335 | }
336 |
337 | return $results_array;
338 | }
339 |
340 | function get_field_types_basic_table()
341 | {
342 | $db_field_types = array();
343 | foreach($this->get_field_types($this->table_name) as $db_field_type)
344 | {
345 | $db_type = $db_field_type->type;
346 | $length = $db_field_type->max_length;
347 | $db_field_types[$db_field_type->name]['db_max_length'] = $length;
348 | $db_field_types[$db_field_type->name]['db_type'] = $db_type;
349 | $db_field_types[$db_field_type->name]['db_null'] = true;
350 | $db_field_types[$db_field_type->name]['db_extra'] = '';
351 | }
352 |
353 | $results = $this->get_field_types($this->table_name);
354 | foreach($results as $num => $row)
355 | {
356 | $row = (array)$row;
357 | $results[$num] = (object)( array_merge($row, $db_field_types[$row['name']]) );
358 | }
359 | return $results;
360 | }
361 |
362 | function get_field_types($table_name)
363 | {
364 | $results = $this->db->field_data($table_name);
365 | // some driver doesn't provide primary_key information
366 | foreach($results as $num => $row)
367 | {
368 | $row = (array)$row;
369 | if(!array_key_exists('primary_key', $row)){
370 | $results[$num]->primary_key = 0;
371 | }
372 | }
373 | return $results;
374 | }
375 |
376 | function db_insert($post_array)
377 | {
378 | $insert = $this->db->insert($this->table_name,$post_array);
379 | if($insert)
380 | {
381 | $primary_key = $this->get_primary_key();
382 | // if user already define a value for the primary key, then just return it
383 | // postgresql use LASTVAL() to retrieve insert_id which would cause an error if the sequence is not used.
384 | if(array_key_exists($primary_key, $post_array)){
385 | return $post_array[$primary_key];
386 | }
387 | return $this->db->insert_id();
388 | }
389 | return false;
390 | }
391 |
392 | function build_db_join_relation($related_table, $unique_name, $related_primary_key, $field_name){
393 | $this->db->join($this->protect_identifiers($related_table).' as '.$this->protect_identifiers($unique_name) , $this->protect_identifiers($unique_name.'.'.$related_primary_key).' = '. $this->protect_identifiers($this->table_name.'.'.$field_name),'left');
394 | }
395 |
396 | function build_relation_n_n_subquery($field, $selection_table, $relation_table, $primary_key_alias_to_selection_table, $primary_key_selection_table, $primary_key_alias_to_this_table, $field_name){
397 | return "(SELECT GROUP_CONCAT(DISTINCT ".$this->protect_identifiers($field).") FROM ".$this->protect_identifiers($selection_table)
398 | ." LEFT JOIN ".$this->protect_identifiers($relation_table)." ON ".$this->protect_identifiers($relation_table.".".$primary_key_alias_to_selection_table)." = ".$this->protect_identifiers($selection_table.".".$primary_key_selection_table)
399 | ." WHERE ".$this->protect_identifiers($relation_table.".".$primary_key_alias_to_this_table)." = ".$this->protect_identifiers($this->table_name.".".$this->get_primary_key($this->table_name))." GROUP BY ".$this->protect_identifiers($relation_table.".".$primary_key_alias_to_this_table).") AS ".$this->protect_identifiers($field_name);
400 | }
401 |
402 | function db_delete($primary_key_value)
403 | {
404 | $primary_key_field = $this->get_primary_key();
405 |
406 | if($primary_key_field === false)
407 | return false;
408 |
409 | $this->db->delete($this->table_name,array( $primary_key_field => $primary_key_value));
410 | if( $this->db->affected_rows() != 1)
411 | return false;
412 | else
413 | return true;
414 | }
415 |
416 | function field_exists($field,$table_name = null)
417 | {
418 | if(empty($table_name))
419 | {
420 | $table_name = $this->table_name;
421 | }
422 |
423 | // sqlite doesn't support this $this->db->field_exists($field,$table_name)
424 | $field_data_list = $this->db->field_data($table_name);
425 | foreach($field_data_list as $field_data){
426 | if($field_data->name == $field) return TRUE;
427 | }
428 | return FALSE;
429 | }
430 |
431 | function get_edit_values($primary_key_value)
432 | {
433 | $result = parent::get_edit_values($primary_key_value);
434 | // some driver like postgresql doesn't return string
435 | foreach($result as $key => $value) {
436 | $result->$key = (string)$value;
437 | }
438 | return $result;
439 | }
440 |
441 | }
442 |
--------------------------------------------------------------------------------