PageRenderTime 62ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/application/libraries/grocery_crud.php

https://bitbucket.org/masangga/laperbanget
PHP | 4906 lines | 3642 code | 719 blank | 545 comment | 494 complexity | cf270da4489c18f3567ffe13db15cfbe MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * PHP grocery CRUD
  4. *
  5. * A Codeigniter library that creates a CRUD automatically with just few lines of code.
  6. *
  7. * Copyright (C) 2010 - 2012 John Skoumbourdis.
  8. *
  9. * LICENSE
  10. *
  11. * Grocery CRUD is released with dual licensing, using the GPL v3 (license-gpl3.txt) and the MIT license (license-mit.txt).
  12. * You don't have to do anything special to choose one license or the other and you don't have to notify anyone which license you are using.
  13. * Please see the corresponding license file for details of these licenses.
  14. * You are free to use, modify and distribute this software, but all copyright information must remain.
  15. *
  16. * @package grocery CRUD
  17. * @copyright Copyright (c) 2010 through 2012, John Skoumbourdis
  18. * @license https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
  19. * @version 1.3
  20. * @author John Skoumbourdis <scoumbourdisj@gmail.com>
  21. */
  22. // ------------------------------------------------------------------------
  23. /**
  24. * grocery Field Types
  25. *
  26. * The types of the fields and the default reactions
  27. *
  28. * @package grocery CRUD
  29. * @author John Skoumbourdis <scoumbourdisj@gmail.com>
  30. * @license https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
  31. * @link http://www.grocerycrud.com/documentation
  32. */
  33. class grocery_CRUD_Field_Types
  34. {
  35. /**
  36. * Gets the field types of the main table.
  37. * @return array
  38. */
  39. public function get_field_types()
  40. {
  41. if($this->field_types !== null)
  42. return $this->field_types;
  43. $types = array();
  44. foreach($this->basic_model->get_field_types_basic_table() as $field_info)
  45. {
  46. $field_info->required = !empty($this->required_fields) && in_array($field_info->name,$this->required_fields) ? true : false;
  47. $field_info->display_as =
  48. isset($this->display_as[$field_info->name]) ?
  49. $this->display_as[$field_info->name] :
  50. ucfirst(str_replace("_"," ",$field_info->name));
  51. if($this->change_field_type !== null && isset($this->change_field_type[$field_info->name]))
  52. {
  53. $field_type = $this->change_field_type[$field_info->name];
  54. $field_info->crud_type = $field_type->type;
  55. $field_info->extras = $field_type->extras;
  56. $real_type = $field_info->crud_type;
  57. }
  58. elseif(isset($this->relation[$field_info->name]))
  59. {
  60. $real_type = 'relation';
  61. $field_info->crud_type = 'relation';
  62. }
  63. elseif(isset($this->upload_fields[$field_info->name]))
  64. {
  65. $real_type = 'upload_file';
  66. $field_info->crud_type = 'upload_file';
  67. }
  68. else
  69. {
  70. $real_type = $this->get_type($field_info);
  71. $field_info->crud_type = $real_type;
  72. }
  73. switch ($real_type) {
  74. case 'text':
  75. if(!empty($this->unset_texteditor) && in_array($field_info->name,$this->unset_texteditor))
  76. $field_info->extras = false;
  77. else
  78. $field_info->extras = 'text_editor';
  79. break;
  80. case 'relation':
  81. $field_info->extras = $this->relation[$field_info->name];
  82. break;
  83. case 'upload_file':
  84. $field_info->extras = $this->upload_fields[$field_info->name];
  85. break;
  86. default:
  87. if(empty($field_info->extras))
  88. $field_info->extras = false;
  89. break;
  90. }
  91. $types[$field_info->name] = $field_info;
  92. }
  93. if(!empty($this->relation_n_n))
  94. {
  95. foreach($this->relation_n_n as $field_name => $field_extras)
  96. {
  97. $field_info = (object)array();
  98. $field_info->name = $field_name;
  99. $field_info->crud_type = 'relation_n_n';
  100. $field_info->extras = $field_extras;
  101. $field_info->required = !empty($this->required_fields) && in_array($field_name,$this->required_fields) ? true : false;;
  102. $field_info->display_as =
  103. isset($this->display_as[$field_name]) ?
  104. $this->display_as[$field_name] :
  105. ucfirst(str_replace("_"," ",$field_name));
  106. $types[$field_name] = $field_info;
  107. }
  108. }
  109. if(!empty($this->add_fields))
  110. foreach($this->add_fields as $field_object)
  111. {
  112. $field_name = isset($field_object->field_name) ? $field_object->field_name : $field_object;
  113. if(!isset($types[$field_name]))
  114. {
  115. $field_info = (object)array(
  116. 'name' => $field_name,
  117. 'crud_type' => $this->change_field_type !== null && isset($this->change_field_type[$field_name]) ?
  118. $this->change_field_type[$field_name]->type :
  119. 'string',
  120. 'display_as' => isset($this->display_as[$field_name]) ?
  121. $this->display_as[$field_name] :
  122. ucfirst(str_replace("_"," ",$field_name)),
  123. 'required' => in_array($field_name,$this->required_fields) ? true : false
  124. );
  125. $types[$field_name] = $field_info;
  126. }
  127. }
  128. if(!empty($this->edit_fields))
  129. foreach($this->edit_fields as $field_object)
  130. {
  131. $field_name = isset($field_object->field_name) ? $field_object->field_name : $field_object;
  132. if(!isset($types[$field_name]))
  133. {
  134. $field_info = (object)array(
  135. 'name' => $field_name,
  136. 'crud_type' => $this->change_field_type !== null && isset($this->change_field_type[$field_name]) ?
  137. $this->change_field_type[$field_name]->type :
  138. 'string',
  139. 'display_as' => isset($this->display_as[$field_name]) ?
  140. $this->display_as[$field_name] :
  141. ucfirst(str_replace("_"," ",$field_name)),
  142. 'required' => in_array($field_name,$this->required_fields) ? true : false
  143. );
  144. $types[$field_name] = $field_info;
  145. }
  146. }
  147. $this->field_types = $types;
  148. return $this->field_types;
  149. }
  150. public function get_primary_key()
  151. {
  152. return $this->basic_model->get_primary_key();
  153. }
  154. /**
  155. * Get the html input for the specific field with the
  156. * current value
  157. *
  158. * @param object $field_info
  159. * @param string $value
  160. * @return object
  161. */
  162. protected function get_field_input($field_info, $value = null)
  163. {
  164. $real_type = $field_info->crud_type;
  165. $types_array = array(
  166. 'integer',
  167. 'text',
  168. 'true_false',
  169. 'string',
  170. 'date',
  171. 'datetime',
  172. 'enum',
  173. 'set',
  174. 'relation',
  175. 'relation_n_n',
  176. 'upload_file',
  177. 'hidden',
  178. 'password',
  179. 'readonly',
  180. 'dropdown',
  181. 'multiselect'
  182. );
  183. if (in_array($real_type,$types_array)) {
  184. /* A quick way to go to an internal method of type $this->get_{type}_input .
  185. * For example if the real type is integer then we will use the method
  186. * $this->get_integer_input
  187. * */
  188. $field_info->input = $this->{"get_".$real_type."_input"}($field_info,$value);
  189. }
  190. else
  191. {
  192. $field_info->input = $this->get_string_input($field_info,$value);
  193. }
  194. return $field_info;
  195. }
  196. protected function change_list_value($field_info, $value = null)
  197. {
  198. $real_type = $field_info->crud_type;
  199. switch ($real_type) {
  200. case 'hidden':
  201. case 'invisible':
  202. case 'integer':
  203. break;
  204. case 'true_false':
  205. if(isset($this->default_true_false_text[$value]))
  206. $value = $this->default_true_false_text[$value];
  207. break;
  208. case 'string':
  209. $value = $this->character_limiter($value,$this->character_limiter,"...");
  210. break;
  211. case 'text':
  212. $value = $this->character_limiter(strip_tags($value),$this->character_limiter,"...");
  213. break;
  214. case 'date':
  215. if(!empty($value) && $value != '0000-00-00' && $value != '1970-01-01')
  216. {
  217. list($year,$month,$day) = explode("-",$value);
  218. $value = date($this->php_date_format, mktime (0, 0, 0, (int)$month , (int)$day , (int)$year));
  219. }
  220. else
  221. {
  222. $value = '';
  223. }
  224. break;
  225. case 'datetime':
  226. if(!empty($value) && $value != '0000-00-00 00:00:00' && $value != '1970-01-01 00:00:00')
  227. {
  228. list($year,$month,$day) = explode("-",$value);
  229. list($hours,$minutes) = explode(":",substr($value,11));
  230. $value = date($this->php_date_format." - H:i", mktime ((int)$hours , (int)$minutes , 0, (int)$month , (int)$day ,(int)$year));
  231. }
  232. else
  233. {
  234. $value = '';
  235. }
  236. break;
  237. case 'enum':
  238. $value = $this->character_limiter($value,$this->character_limiter,"...");
  239. break;
  240. case 'multiselect':
  241. $value_as_array = array();
  242. foreach(explode(",",$value) as $row_value)
  243. {
  244. $value_as_array[] = array_key_exists($row_value,$field_info->extras) ? $field_info->extras[$row_value] : $row_value;
  245. }
  246. $value = implode(",",$value_as_array);
  247. break;
  248. case 'relation_n_n':
  249. $value = $this->character_limiter(str_replace(',',', ',$value),$this->character_limiter,"...");
  250. break;
  251. case 'password':
  252. $value = '******';
  253. break;
  254. case 'dropdown':
  255. $value = array_key_exists($value,$field_info->extras) ? $field_info->extras[$value] : $value;
  256. break;
  257. case 'upload_file':
  258. if(empty($value))
  259. {
  260. $value = "";
  261. }
  262. else
  263. {
  264. $is_image = !empty($value) &&
  265. ( substr($value,-4) == '.jpg'
  266. || substr($value,-4) == '.png'
  267. || substr($value,-5) == '.jpeg'
  268. || substr($value,-4) == '.gif'
  269. || substr($value,-5) == '.tiff')
  270. ? true : false;
  271. $file_url = base_url().$field_info->extras->upload_path."/$value";
  272. $file_url_anchor = '<a href="'.$file_url.'"';
  273. if($is_image)
  274. {
  275. $file_url_anchor .= ' class="image-thumbnail"><img src="'.$file_url.'" height="50px">';
  276. }
  277. else
  278. {
  279. $file_url_anchor .= ' target="_blank">'.$this->character_limiter($value,$this->character_limiter,'...',true);
  280. }
  281. $file_url_anchor .= '</a>';
  282. $value = $file_url_anchor;
  283. }
  284. break;
  285. default:
  286. $value = $this->character_limiter($value,$this->character_limiter,"...");
  287. break;
  288. }
  289. return $value;
  290. }
  291. /**
  292. * Character Limiter of codeigniter (I just don't want to load the helper )
  293. *
  294. * Limits the string based on the character count. Preserves complete words
  295. * so the character count may not be exactly as specified.
  296. *
  297. * @access public
  298. * @param string
  299. * @param integer
  300. * @param string the end character. Usually an ellipsis
  301. * @return string
  302. */
  303. function character_limiter($str, $n = 500, $end_char = '&#8230;')
  304. {
  305. if (strlen($str) < $n)
  306. {
  307. return $str;
  308. }
  309. // a bit complicated, but faster than preg_replace with \s+
  310. $str = preg_replace('/ {2,}/', ' ', str_replace(array("\r", "\n", "\t", "\x0B", "\x0C"), ' ', $str));
  311. if (strlen($str) <= $n)
  312. {
  313. return $str;
  314. }
  315. $out = '';
  316. foreach (explode(' ', trim($str)) as $val)
  317. {
  318. $out .= $val.' ';
  319. if (strlen($out) >= $n)
  320. {
  321. $out = trim($out);
  322. return (strlen($out) === strlen($str)) ? $out : $out.$end_char;
  323. }
  324. }
  325. }
  326. protected function get_type($db_type)
  327. {
  328. $type = false;
  329. if(!empty($db_type->type))
  330. {
  331. switch ($db_type->type) {
  332. case '1':
  333. case '3':
  334. case 'int':
  335. case 'tinyint':
  336. case 'mediumint':
  337. case 'longint':
  338. if( $db_type->db_type == 'tinyint' && $db_type->db_max_length == 1)
  339. $type = 'true_false';
  340. else
  341. $type = 'integer';
  342. break;
  343. case '254':
  344. case 'string':
  345. case 'enum':
  346. if($db_type->db_type != 'enum')
  347. $type = 'string';
  348. else
  349. $type = 'enum';
  350. break;
  351. case 'set':
  352. if($db_type->db_type != 'set')
  353. $type = 'string';
  354. else
  355. $type = 'set';
  356. break;
  357. case '252':
  358. case 'blob':
  359. case 'text':
  360. case 'mediumtext':
  361. case 'longtext':
  362. $type = 'text';
  363. break;
  364. case '10':
  365. case 'date':
  366. $type = 'date';
  367. break;
  368. case '12':
  369. case 'datetime':
  370. case 'timestamp':
  371. $type = 'datetime';
  372. break;
  373. }
  374. }
  375. return $type;
  376. }
  377. }
  378. // ------------------------------------------------------------------------
  379. /**
  380. * Grocery Model Driver
  381. *
  382. * Drives the model - I'ts so easy like you drive a bicycle :-)
  383. *
  384. * @package grocery CRUD
  385. * @author John Skoumbourdis <scoumbourdisj@gmail.com>
  386. * @version 1.3
  387. * @link http://www.grocerycrud.com/documentation
  388. */
  389. class grocery_CRUD_Model_Driver extends grocery_CRUD_Field_Types
  390. {
  391. /**
  392. * @var grocery_CRUD_Model
  393. */
  394. public $basic_model = null;
  395. protected function set_default_Model()
  396. {
  397. $ci = &get_instance();
  398. $ci->load->model('grocery_CRUD_Model');
  399. $this->basic_model = $ci->grocery_CRUD_Model;
  400. }
  401. protected function get_total_results()
  402. {
  403. if(!empty($this->where))
  404. foreach($this->where as $where)
  405. $this->basic_model->where($where[0],$where[1],$where[2]);
  406. if(!empty($this->or_where))
  407. foreach($this->or_where as $or_where)
  408. $this->basic_model->or_where($or_where[0],$or_where[1],$or_where[2]);
  409. if(!empty($this->like))
  410. foreach($this->like as $like)
  411. $this->basic_model->like($like[0],$like[1],$like[2]);
  412. if(!empty($this->or_like))
  413. foreach($this->or_like as $or_like)
  414. $this->basic_model->or_like($or_like[0],$or_like[1],$or_like[2]);
  415. if(!empty($this->having))
  416. foreach($this->having as $having)
  417. $this->basic_model->having($having[0],$having[1],$having[2]);
  418. if(!empty($this->or_having))
  419. foreach($this->or_having as $or_having)
  420. $this->basic_model->or_having($or_having[0],$or_having[1],$or_having[2]);
  421. if(!empty($this->relation))
  422. foreach($this->relation as $relation)
  423. $this->basic_model->join_relation($relation[0],$relation[1],$relation[2]);
  424. if(!empty($this->relation_n_n))
  425. {
  426. $columns = $this->get_columns();
  427. foreach($columns as $column)
  428. {
  429. //Use the relation_n_n ONLY if the column is called . The set_relation_n_n are slow and it will make the table slower without any reason as we don't need those queries.
  430. if(isset($this->relation_n_n[$column->field_name]))
  431. {
  432. $this->basic_model->set_relation_n_n_field($this->relation_n_n[$column->field_name]);
  433. }
  434. }
  435. }
  436. return $this->basic_model->get_total_results();
  437. }
  438. public function set_model($model_name)
  439. {
  440. $ci = &get_instance();
  441. $ci->load->model('grocery_CRUD_Model');
  442. $ci->load->model($model_name);
  443. $temp = explode('/',$model_name);
  444. krsort($temp);
  445. foreach($temp as $t)
  446. {
  447. $real_model_name = $t;
  448. break;
  449. }
  450. $this->basic_model = $ci->$real_model_name;
  451. }
  452. protected function set_ajax_list_queries($state_info = null)
  453. {
  454. if(!empty($state_info->per_page))
  455. {
  456. if(empty($state_info->page) || !is_numeric($state_info->page) )
  457. $this->limit($state_info->per_page);
  458. else
  459. {
  460. $limit_page = ( ($state_info->page-1) * $state_info->per_page );
  461. $this->limit($state_info->per_page, $limit_page);
  462. }
  463. }
  464. if(!empty($state_info->order_by))
  465. {
  466. $this->order_by($state_info->order_by[0],$state_info->order_by[1]);
  467. }
  468. if(!empty($state_info->search))
  469. {
  470. if(!empty($this->relation))
  471. foreach($this->relation as $relation_name => $relation_values)
  472. $temp_relation[$this->_unique_field_name($relation_name)] = $this->_get_field_names_to_search($relation_values);
  473. if($state_info->search->field !== null)
  474. {
  475. if(isset($temp_relation[$state_info->search->field]))
  476. {
  477. if(is_array($temp_relation[$state_info->search->field]))
  478. foreach($temp_relation[$state_info->search->field] as $search_field)
  479. $this->or_like($search_field , $state_info->search->text);
  480. else
  481. $this->like($temp_relation[$state_info->search->field] , $state_info->search->text);
  482. }
  483. elseif(isset($this->relation_n_n[$state_info->search->field]))
  484. {
  485. $escaped_text = $this->basic_model->escape_str($state_info->search->text);
  486. $this->having($state_info->search->field." LIKE '%".$escaped_text."%'");
  487. }
  488. else
  489. {
  490. $this->like($state_info->search->field , $state_info->search->text);
  491. }
  492. }
  493. else
  494. {
  495. $columns = $this->get_columns();
  496. $search_text = $state_info->search->text;
  497. if(!empty($this->where))
  498. foreach($this->where as $where)
  499. $this->basic_model->having($where[0],$where[1],$where[2]);
  500. foreach($columns as $column)
  501. {
  502. if(isset($temp_relation[$column->field_name]))
  503. {
  504. if(is_array($temp_relation[$column->field_name]))
  505. {
  506. foreach($temp_relation[$column->field_name] as $search_field)
  507. {
  508. $this->or_like($search_field, $search_text);
  509. }
  510. }
  511. else
  512. {
  513. $this->or_like($temp_relation[$column->field_name], $search_text);
  514. }
  515. }
  516. elseif(isset($this->relation_n_n[$column->field_name]))
  517. {
  518. //@todo have a where for the relation_n_n statement
  519. }
  520. else
  521. {
  522. $this->or_like($column->field_name, $search_text);
  523. }
  524. }
  525. }
  526. }
  527. }
  528. protected function table_exists($table_name = null)
  529. {
  530. if($this->basic_model->db_table_exists($table_name))
  531. return true;
  532. return false;
  533. }
  534. protected function get_relation_array($relation_info, $primary_key_value = null, $limit = null)
  535. {
  536. list($field_name , $related_table , $related_field_title, $where_clause, $order_by) = $relation_info;
  537. if($primary_key_value !== null)
  538. {
  539. $primary_key = $this->basic_model->get_primary_key($related_table);
  540. //A where clause with the primary key is enough to take the selected key row
  541. $where_clause = array($primary_key => $primary_key_value);
  542. }
  543. $relation_array = $this->basic_model->get_relation_array($field_name , $related_table , $related_field_title, $where_clause, $order_by, $limit);
  544. return $relation_array;
  545. }
  546. protected function get_relation_total_rows($relation_info)
  547. {
  548. list($field_name , $related_table , $related_field_title, $where_clause) = $relation_info;
  549. $relation_array = $this->basic_model->get_relation_total_rows($field_name , $related_table , $related_field_title, $where_clause);
  550. return $relation_array;
  551. }
  552. protected function db_insert_validation()
  553. {
  554. $validation_result = (object)array('success'=>false);
  555. $field_types = $this->get_field_types();
  556. $required_fields = $this->required_fields;
  557. $add_fields = $this->get_add_fields();
  558. if(!empty($required_fields))
  559. {
  560. foreach($add_fields as $add_field)
  561. {
  562. $field_name = $add_field->field_name;
  563. if(!isset($this->validation_rules[$field_name]) && in_array( $field_name, $required_fields) )
  564. {
  565. $this->set_rules( $field_name, $field_types[$field_name]->display_as, 'required');
  566. }
  567. }
  568. }
  569. if(!empty($this->validation_rules))
  570. {
  571. $form_validation = $this->form_validation();
  572. $add_fields = $this->get_add_fields();
  573. foreach($add_fields as $add_field)
  574. {
  575. $field_name = $add_field->field_name;
  576. if(isset($this->validation_rules[$field_name]))
  577. {
  578. $rule = $this->validation_rules[$field_name];
  579. $form_validation->set_rules($rule['field'],$rule['label'],$rule['rules']);
  580. }
  581. }
  582. if($form_validation->run())
  583. {
  584. $validation_result->success = true;
  585. }
  586. else
  587. {
  588. $validation_result->error_message = $form_validation->error_string();
  589. $validation_result->error_fields = $form_validation->_error_array;
  590. }
  591. }
  592. else
  593. {
  594. $validation_result->success = true;
  595. }
  596. return $validation_result;
  597. }
  598. protected function form_validation()
  599. {
  600. if($this->form_validation === null)
  601. {
  602. $this->form_validation = new grocery_CRUD_Form_validation();
  603. $ci = &get_instance();
  604. $ci->load->library('form_validation');
  605. $ci->form_validation = $this->form_validation;
  606. }
  607. return $this->form_validation;
  608. }
  609. protected function db_update_validation()
  610. {
  611. $validation_result = (object)array('success'=>false);
  612. $field_types = $this->get_field_types();
  613. $required_fields = $this->required_fields;
  614. $edit_fields = $this->get_edit_fields();
  615. if(!empty($required_fields))
  616. {
  617. foreach($edit_fields as $edit_field)
  618. {
  619. $field_name = $edit_field->field_name;
  620. if(!isset($this->validation_rules[$field_name]) && in_array( $field_name, $required_fields) )
  621. {
  622. $this->set_rules( $field_name, $field_types[$field_name]->display_as, 'required');
  623. }
  624. }
  625. }
  626. if(!empty($this->validation_rules))
  627. {
  628. $form_validation = $this->form_validation();
  629. $edit_fields = $this->get_edit_fields();
  630. foreach($edit_fields as $edit_field)
  631. {
  632. $field_name = $edit_field->field_name;
  633. if(isset($this->validation_rules[$field_name]))
  634. {
  635. $rule = $this->validation_rules[$field_name];
  636. $form_validation->set_rules($rule['field'],$rule['label'],$rule['rules']);
  637. }
  638. }
  639. if($form_validation->run())
  640. {
  641. $validation_result->success = true;
  642. }
  643. else
  644. {
  645. $validation_result->error_message = $form_validation->error_string();
  646. $validation_result->error_fields = $form_validation->_error_array;
  647. }
  648. }
  649. else
  650. {
  651. $validation_result->success = true;
  652. }
  653. return $validation_result;
  654. }
  655. protected function db_insert($state_info)
  656. {
  657. $validation_result = $this->db_insert_validation();
  658. if($validation_result->success)
  659. {
  660. $post_data = $state_info->unwrapped_data;
  661. $add_fields = $this->get_add_fields();
  662. if($this->callback_insert === null)
  663. {
  664. if($this->callback_before_insert !== null)
  665. {
  666. $callback_return = call_user_func($this->callback_before_insert, $post_data);
  667. if(!empty($callback_return) && is_array($callback_return))
  668. $post_data = $callback_return;
  669. elseif($callback_return === false)
  670. return false;
  671. }
  672. $insert_data = array();
  673. $types = $this->get_field_types();
  674. foreach($add_fields as $num_row => $field)
  675. {
  676. /* If the multiselect or the set is empty then the browser doesn't send an empty array. Instead it sends nothing */
  677. if(isset($types[$field->field_name]->crud_type) && ($types[$field->field_name]->crud_type == 'set' || $types[$field->field_name]->crud_type == 'multiselect') && !isset($post_data[$field->field_name]))
  678. {
  679. $post_data[$field->field_name] = array();
  680. }
  681. if(isset($post_data[$field->field_name]) && !isset($this->relation_n_n[$field->field_name]))
  682. {
  683. if(isset($types[$field->field_name]->db_null) && $types[$field->field_name]->db_null && is_array($post_data[$field->field_name]) && empty($post_data[$field->field_name]))
  684. {
  685. $insert_data[$field->field_name] = null;
  686. }
  687. elseif(isset($types[$field->field_name]->db_null) && $types[$field->field_name]->db_null && $post_data[$field->field_name] === '')
  688. {
  689. $insert_data[$field->field_name] = null;
  690. }
  691. elseif(isset($types[$field->field_name]->crud_type) && $types[$field->field_name]->crud_type == 'date')
  692. {
  693. $insert_data[$field->field_name] = $this->_convert_date_to_sql_date($post_data[$field->field_name]);
  694. }
  695. elseif(isset($types[$field->field_name]->crud_type) && $types[$field->field_name]->crud_type == 'readonly')
  696. {
  697. //This empty if statement is to make sure that a readonly field will never inserted/updated
  698. }
  699. elseif(isset($types[$field->field_name]->crud_type) && ($types[$field->field_name]->crud_type == 'set' || $types[$field->field_name]->crud_type == 'multiselect'))
  700. {
  701. $insert_data[$field->field_name] = !empty($post_data[$field->field_name]) ? implode(',',$post_data[$field->field_name]) : '';
  702. }
  703. elseif(isset($types[$field->field_name]->crud_type) && $types[$field->field_name]->crud_type == 'datetime'){
  704. $insert_data[$field->field_name] = $this->_convert_date_to_sql_date(substr($post_data[$field->field_name],0,10)).
  705. substr($post_data[$field->field_name],10);
  706. }
  707. else
  708. {
  709. $insert_data[$field->field_name] = $post_data[$field->field_name];
  710. }
  711. }
  712. }
  713. $insert_result = $this->basic_model->db_insert($insert_data);
  714. if($insert_result !== false)
  715. {
  716. $insert_primary_key = $insert_result;
  717. }
  718. else
  719. {
  720. return false;
  721. }
  722. if(!empty($this->relation_n_n))
  723. {
  724. foreach($this->relation_n_n as $field_name => $field_info)
  725. {
  726. $relation_data = isset( $post_data[$field_name] ) ? $post_data[$field_name] : array() ;
  727. $this->db_relation_n_n_update($field_info, $relation_data ,$insert_primary_key);
  728. }
  729. }
  730. if($this->callback_after_insert !== null)
  731. {
  732. $callback_return = call_user_func($this->callback_after_insert, $post_data, $insert_primary_key);
  733. if($callback_return === false)
  734. {
  735. return false;
  736. }
  737. }
  738. }else
  739. {
  740. $callback_return = call_user_func($this->callback_insert, $post_data);
  741. if($callback_return === false)
  742. {
  743. return false;
  744. }
  745. }
  746. if(isset($insert_primary_key))
  747. return $insert_primary_key;
  748. else
  749. return true;
  750. }
  751. return false;
  752. }
  753. protected function db_update($state_info)
  754. {
  755. $validation_result = $this->db_update_validation();
  756. $edit_fields = $this->get_edit_fields();
  757. if($validation_result->success)
  758. {
  759. $post_data = $state_info->unwrapped_data;
  760. $primary_key = $state_info->primary_key;
  761. if($this->callback_update === null)
  762. {
  763. if($this->callback_before_update !== null)
  764. {
  765. $callback_return = call_user_func($this->callback_before_update, $post_data, $primary_key);
  766. if(!empty($callback_return) && is_array($callback_return))
  767. {
  768. $post_data = $callback_return;
  769. }
  770. elseif($callback_return === false)
  771. {
  772. return false;
  773. }
  774. }
  775. $update_data = array();
  776. $types = $this->get_field_types();
  777. foreach($edit_fields as $num_row => $field)
  778. {
  779. /* If the multiselect or the set is empty then the browser doesn't send an empty array. Instead it sends nothing */
  780. if(isset($types[$field->field_name]->crud_type) && ($types[$field->field_name]->crud_type == 'set' || $types[$field->field_name]->crud_type == 'multiselect') && !isset($post_data[$field->field_name]))
  781. {
  782. $post_data[$field->field_name] = array();
  783. }
  784. if(isset($post_data[$field->field_name]) && !isset($this->relation_n_n[$field->field_name]))
  785. {
  786. if(isset($types[$field->field_name]->db_null) && $types[$field->field_name]->db_null && is_array($post_data[$field->field_name]) && empty($post_data[$field->field_name]))
  787. {
  788. $update_data[$field->field_name] = null;
  789. }
  790. elseif(isset($types[$field->field_name]->db_null) && $types[$field->field_name]->db_null && $post_data[$field->field_name] === '')
  791. {
  792. $update_data[$field->field_name] = null;
  793. }
  794. elseif(isset($types[$field->field_name]->crud_type) && $types[$field->field_name]->crud_type == 'date')
  795. {
  796. $update_data[$field->field_name] = $this->_convert_date_to_sql_date($post_data[$field->field_name]);
  797. }
  798. elseif(isset($types[$field->field_name]->crud_type) && $types[$field->field_name]->crud_type == 'readonly')
  799. {
  800. //This empty if statement is to make sure that a readonly field will never inserted/updated
  801. }
  802. elseif(isset($types[$field->field_name]->crud_type) && ($types[$field->field_name]->crud_type == 'set' || $types[$field->field_name]->crud_type == 'multiselect'))
  803. {
  804. $update_data[$field->field_name] = !empty($post_data[$field->field_name]) ? implode(',',$post_data[$field->field_name]) : '';
  805. }
  806. elseif(isset($types[$field->field_name]->crud_type) && $types[$field->field_name]->crud_type == 'datetime'){
  807. $update_data[$field->field_name] = $this->_convert_date_to_sql_date(substr($post_data[$field->field_name],0,10)).
  808. substr($post_data[$field->field_name],10);
  809. }
  810. else
  811. {
  812. $update_data[$field->field_name] = $post_data[$field->field_name];
  813. }
  814. }
  815. }
  816. if($this->basic_model->db_update($update_data, $primary_key) === false)
  817. {
  818. return false;
  819. }
  820. if(!empty($this->relation_n_n))
  821. {
  822. foreach($this->relation_n_n as $field_name => $field_info)
  823. {
  824. if ( $this->unset_edit_fields !== null
  825. && is_array($this->unset_edit_fields)
  826. && in_array($field_name,$this->unset_edit_fields)
  827. ) {
  828. continue;
  829. }
  830. $relation_data = isset( $post_data[$field_name] ) ? $post_data[$field_name] : array() ;
  831. $this->db_relation_n_n_update($field_info, $relation_data ,$primary_key);
  832. }
  833. }
  834. if($this->callback_after_update !== null)
  835. {
  836. $callback_return = call_user_func($this->callback_after_update, $post_data, $primary_key);
  837. if($callback_return === false)
  838. {
  839. return false;
  840. }
  841. }
  842. }
  843. else
  844. {
  845. $callback_return = call_user_func($this->callback_update, $post_data, $primary_key);
  846. if($callback_return === false)
  847. {
  848. return false;
  849. }
  850. }
  851. return true;
  852. }
  853. else
  854. {
  855. return false;
  856. }
  857. }
  858. protected function _convert_date_to_sql_date($date)
  859. {
  860. $date = substr($date,0,10);
  861. if(preg_match('/\d{4}-\d{2}-\d{2}/',$date))
  862. {
  863. //If it's already a sql-date don't convert it!
  864. return $date;
  865. }elseif(empty($date))
  866. {
  867. return '';
  868. }
  869. $date_array = preg_split( '/[-\.\/ ]/', $date);
  870. if($this->php_date_format == 'd/m/Y')
  871. {
  872. $sql_date = date('Y-m-d',mktime(0,0,0,$date_array[1],$date_array[0],$date_array[2]));
  873. }
  874. elseif($this->php_date_format == 'm/d/Y')
  875. {
  876. $sql_date = date('Y-m-d',mktime(0,0,0,$date_array[0],$date_array[1],$date_array[2]));
  877. }
  878. else
  879. {
  880. $sql_date = $date;
  881. }
  882. return $sql_date;
  883. }
  884. protected function _get_field_names_to_search(array $relation_values)
  885. {
  886. if(!strstr($relation_values[2],'{'))
  887. return $this->_unique_join_name($relation_values[0]).'.'.$relation_values[2];
  888. else
  889. {
  890. $relation_values[2] = ' '.$relation_values[2].' ';
  891. $temp1 = explode('{',$relation_values[2]);
  892. unset($temp1[0]);
  893. $field_names_array = array();
  894. foreach($temp1 as $field)
  895. list($field_names_array[]) = explode('}',$field);
  896. return $field_names_array;
  897. }
  898. }
  899. protected function _unique_join_name($field_name)
  900. {
  901. return 'j'.substr(md5($field_name),0,8); //This j is because is better for a string to begin with a letter and not a number
  902. }
  903. protected function _unique_field_name($field_name)
  904. {
  905. return 's'.substr(md5($field_name),0,8); //This s is because is better for a string to begin with a letter and not a number
  906. }
  907. protected function db_delete($state_info)
  908. {
  909. $primary_key = $state_info->primary_key;
  910. if($this->callback_delete === null)
  911. {
  912. if($this->callback_before_delete !== null)
  913. {
  914. $callback_return = call_user_func($this->callback_before_delete, $primary_key);
  915. if($callback_return === false)
  916. {
  917. return false;
  918. }
  919. }
  920. if(!empty($this->relation_n_n))
  921. {
  922. foreach($this->relation_n_n as $field_name => $field_info)
  923. {
  924. $this->db_relation_n_n_delete( $field_info, $primary_key );
  925. }
  926. }
  927. $delete_result = $this->basic_model->db_delete($primary_key);
  928. if($delete_result === false)
  929. {
  930. return false;
  931. }
  932. if($this->callback_after_delete !== null)
  933. {
  934. $callback_return = call_user_func($this->callback_after_delete, $primary_key);
  935. if($callback_return === false)
  936. {
  937. return false;
  938. }
  939. }
  940. }
  941. else
  942. {
  943. $callback_return = call_user_func($this->callback_delete, $primary_key);
  944. if($callback_return === false)
  945. {
  946. return false;
  947. }
  948. }
  949. return true;
  950. }
  951. protected function db_relation_n_n_update($field_info, $post_data , $primary_key_value)
  952. {
  953. $this->basic_model->db_relation_n_n_update($field_info, $post_data , $primary_key_value);
  954. }
  955. protected function db_relation_n_n_delete($field_info, $primary_key_value)
  956. {
  957. $this->basic_model->db_relation_n_n_delete($field_info, $primary_key_value);
  958. }
  959. protected function get_list()
  960. {
  961. if(!empty($this->order_by))
  962. $this->basic_model->order_by($this->order_by[0],$this->order_by[1]);
  963. if(!empty($this->where))
  964. foreach($this->where as $where)
  965. $this->basic_model->where($where[0],$where[1],$where[2]);
  966. if(!empty($this->or_where))
  967. foreach($this->or_where as $or_where)
  968. $this->basic_model->or_where($or_where[0],$or_where[1],$or_where[2]);
  969. if(!empty($this->like))
  970. foreach($this->like as $like)
  971. $this->basic_model->like($like[0],$like[1],$like[2]);
  972. if(!empty($this->or_like))
  973. foreach($this->or_like as $or_like)
  974. $this->basic_model->or_like($or_like[0],$or_like[1],$or_like[2]);
  975. if(!empty($this->having))
  976. foreach($this->having as $having)
  977. $this->basic_model->having($having[0],$having[1],$having[2]);
  978. if(!empty($this->or_having))
  979. foreach($this->or_having as $or_having)
  980. $this->basic_model->or_having($or_having[0],$or_having[1],$or_having[2]);
  981. if(!empty($this->relation))
  982. foreach($this->relation as $relation)
  983. $this->basic_model->join_relation($relation[0],$relation[1],$relation[2]);
  984. if(!empty($this->relation_n_n))
  985. {
  986. $columns = $this->get_columns();
  987. foreach($columns as $column)
  988. {
  989. //Use the relation_n_n ONLY if the column is called . The set_relation_n_n are slow and it will make the table slower without any reason as we don't need those queries.
  990. if(isset($this->relation_n_n[$column->field_name]))
  991. {
  992. $this->basic_model->set_relation_n_n_field($this->relation_n_n[$column->field_name]);
  993. }
  994. }
  995. }
  996. if($this->theme_config['crud_paging'] === true)
  997. {
  998. if($this->limit === null)
  999. {
  1000. $default_per_page = $this->config->default_per_page;
  1001. if(is_numeric($default_per_page) && $default_per_page >1)
  1002. {
  1003. $this->basic_model->limit($default_per_page);
  1004. }
  1005. else
  1006. {
  1007. $this->basic_model->limit(10);
  1008. }
  1009. }
  1010. else
  1011. {
  1012. $this->basic_model->limit($this->limit[0],$this->limit[1]);
  1013. }
  1014. }
  1015. $results = $this->basic_model->get_list();
  1016. return $results;
  1017. }
  1018. protected function get_edit_values($primary_key_value)
  1019. {
  1020. $values = $this->basic_model->get_edit_values($primary_key_value);
  1021. if(!empty($this->relation_n_n))
  1022. {
  1023. foreach($this->relation_n_n as $field_name => $field_info)
  1024. {
  1025. $values->$field_name = $this->get_relation_n_n_selection_array($primary_key_value, $field_info);
  1026. }
  1027. }
  1028. return $values;
  1029. }
  1030. protected function get_relation_n_n_selection_array($primary_key_value, $field_info)
  1031. {
  1032. return $this->basic_model->get_relation_n_n_selection_array($primary_key_value, $field_info);
  1033. }
  1034. protected function get_relation_n_n_unselected_array($field_info, $selected_values)
  1035. {
  1036. return $this->basic_model->get_relation_n_n_unselected_array($field_info, $selected_values);
  1037. }
  1038. protected function set_basic_db_table($table_name = null)
  1039. {
  1040. $this->basic_model->set_basic_table($table_name);
  1041. }
  1042. protected function upload_file($state_info)
  1043. {
  1044. if(isset($this->upload_fields[$state_info->field_name]) )
  1045. {
  1046. if($this->callback_upload === null)
  1047. {
  1048. if($this->callback_before_upload !== null)
  1049. {
  1050. $callback_before_upload_response = call_user_func($this->callback_before_upload, $_FILES, $this->upload_fields[$state_info->field_name]);
  1051. if($callback_before_upload_response === false)
  1052. return false;
  1053. elseif(is_string($callback_before_upload_response))
  1054. return $callback_before_upload_response;
  1055. }
  1056. $upload_info = $this->upload_fields[$state_info->field_name];
  1057. header('Pragma: no-cache');
  1058. header('Cache-Control: private, no-cache');
  1059. header('Content-Disposition: inline; filename="files.json"');
  1060. header('X-Content-Type-Options: nosniff');
  1061. header('Access-Control-Allow-Origin: *');
  1062. header('Access-Control-Allow-Methods: OPTIONS, HEAD, GET, POST, PUT, DELETE');
  1063. header('Access-Control-Allow-Headers: X-File-Name, X-File-Type, X-File-Size');
  1064. $allowed_files = $this->config->file_upload_allow_file_types;
  1065. $reg_exp = '/(\\.|\\/)('.$allowed_files.')$/i';
  1066. $max_file_size_ui = $this->config->file_upload_max_file_size;
  1067. $max_file_size_bytes = $this->_convert_bytes_ui_to_bytes($max_file_size_ui);
  1068. $options = array(
  1069. 'upload_dir' => $upload_info->upload_path.'/',
  1070. 'param_name' => $this->_unique_field_name($state_info->field_name),
  1071. 'upload_url' => base_url().$upload_info->upload_path.'/',
  1072. 'accept_file_types' => $reg_exp,
  1073. 'max_file_size' => $max_file_size_bytes
  1074. );
  1075. $upload_handler = new UploadHandler($options);
  1076. $upload_handler->default_config_path = $this->default_config_path;
  1077. $uploader_response = $upload_handler->post();
  1078. if(is_array($uploader_response))
  1079. {
  1080. foreach($uploader_response as &$response)
  1081. {
  1082. unset($response->delete_url);
  1083. unset($response->delete_type);
  1084. }
  1085. }
  1086. if($this->callback_after_upload !== null)
  1087. {
  1088. $callback_after_upload_response = call_user_func($this->callback_after_upload, $uploader_response , $this->upload_fields[$state_info->field_name] , $_FILES );
  1089. if($callback_after_upload_response === false)
  1090. return false;
  1091. elseif(is_string($callback_after_upload_response))
  1092. return $callback_after_upload_response;
  1093. elseif(is_array($callback_after_upload_response))
  1094. $uploader_response = $callback_after_upload_response;
  1095. }
  1096. return $uploader_response;
  1097. }
  1098. else
  1099. {
  1100. $upload_response = call_user_func($this->callback_upload, $_FILES, $this->upload_fields[$state_info->field_name] );
  1101. if($upload_response === false)
  1102. {
  1103. return false;
  1104. }
  1105. else
  1106. {
  1107. return $upload_response;
  1108. }
  1109. }
  1110. }
  1111. else
  1112. {
  1113. return false;
  1114. }
  1115. }
  1116. protected function delete_file($state_info)
  1117. {
  1118. if(isset($state_info->field_name) && isset($this->upload_fields[$state_info->field_name]))
  1119. {
  1120. $upload_info = $this->upload_fields[$state_info->field_name];
  1121. if(file_exists("{$upload_info->upload_path}/{$state_info->file_name}"))
  1122. {
  1123. if( unlink("{$upload_info->upload_path}/{$state_info->file_name}") )
  1124. {
  1125. $this->basic_model->db_file_delete($state_info->field_name, $state_info->file_name);
  1126. return true;
  1127. }
  1128. else
  1129. {
  1130. return false;
  1131. }
  1132. }
  1133. else
  1134. {
  1135. $this->basic_model->db_file_delete($state_info->field_name, $state_info->file_name);
  1136. return true;
  1137. }
  1138. }
  1139. else
  1140. {
  1141. return false;
  1142. }
  1143. }
  1144. protected function ajax_relation($state_info)
  1145. {
  1146. if(!isset($this->relation[$state_info->field_name]))
  1147. return false;
  1148. list($field_name, $related_table, $related_field_title, $where_clause, $order_by) = $this->relation[$state_info->field_name];
  1149. return $this->basic_model->get_ajax_relation_array($state_info->search, $field_name, $related_table, $related_field_title, $where_clause, $order_by);
  1150. }
  1151. }
  1152. /**
  1153. * PHP grocery CRUD
  1154. *
  1155. * LICENSE
  1156. *
  1157. * Grocery CRUD is released with dual licensing, using the GPL v3 (license-gpl3.txt) and the MIT license (license-mit.txt).
  1158. * You don't have to do anything special to choose one license or the other and you don't have to notify anyone which license you are using.
  1159. * Please see the corresponding license file for details of these licenses.
  1160. * You are free to use, modify and distribute this software, but all copyright information must remain.
  1161. *
  1162. * @package grocery CRUD
  1163. * @copyright Copyright (c) 2010 through 2012, John Skoumbourdis
  1164. * @license https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
  1165. * @author John Skoumbourdis <scoumbourdisj@gmail.com>
  1166. */
  1167. // ------------------------------------------------------------------------
  1168. /**
  1169. * PHP grocery Layout
  1170. *
  1171. * Here you manage all the HTML Layout
  1172. *
  1173. * @package grocery CRUD
  1174. * @author John Skoumbourdis <scoumbourdisj@gmail.com>
  1175. * @version 1.3
  1176. */
  1177. class grocery_CRUD_Layout extends grocery_CRUD_Model_Driver
  1178. {
  1179. private $theme_path = null;
  1180. private $views_as_string = '';
  1181. private $echo_and_die = false;
  1182. protected $theme = null;
  1183. protected $default_true_false_text = array('inactive' , 'active');
  1184. protected $css_files = array();
  1185. protected $js_files = array();
  1186. protected function set_basic_Layout()
  1187. {
  1188. if(!file_exists($this->theme_path.$this->theme.'/views/list_template.php'))
  1189. {
  1190. throw new Exception('The template does not exist. Please check your files and try again.', 12);
  1191. die();
  1192. }
  1193. }
  1194. protected function showList($ajax = false, $state_info = null)
  1195. {
  1196. $data = $this->get_common_data();
  1197. $data->order_by = $this->order_by;
  1198. $data->types = $this->get_field_types();
  1199. $data->list = $this->get_list();
  1200. $data->list = $this->change_list($data->list , $data->types);
  1201. $data->list = $this->change_list_add_actions($data->list);
  1202. $data->total_results = $this->get_total_results();
  1203. $data->columns = $this->get_columns();
  1204. $data->success_message = $this->get_success_message_at_list($state_info);
  1205. $data->primary_key = $this->get_primary_key();
  1206. $data->add_url = $this->getAddUrl();
  1207. $data->edit_url = $this->getEditUrl();
  1208. $data->delete_url = $this->getDeleteUrl();
  1209. $data->ajax_list_url = $this->getAjaxListUrl();
  1210. $data->ajax_list_info_url = $this->getAjaxListInfoUrl();
  1211. $data->export_url = $this->getExportToExcelUrl();
  1212. $data->print_url = $this->getPrintUrl();
  1213. $data->actions = $this->actions;
  1214. $data->unique_hash = $this->get_method_hash();
  1215. $data->order_by = $this->order_by;
  1216. $data->unset_add = $this->unset_add;
  1217. $data->unset_edit = $this->unset_edit;
  1218. $data->unset_delete = $this->unset_delete;
  1219. $data->unset_export = $this->unset_export;
  1220. $data->unset_print = $this->unset_print;
  1221. $default_per_page = $this->config->default_per_page;
  1222. $data->paging_options = array('10','25','50','100');
  1223. $data->default_per_page = is_numeric($default_per_page) && $default_per_page >1 && in_array($default_per_page,$data->paging_options)? $default_per_page : 25;
  1224. if($data->list === false)
  1225. {
  1226. throw new Exception('It is impossible to get data. Please check your model and try again.', 13);
  1227. $data->list = array();
  1228. }
  1229. foreach($data->list as $num_row => $row)
  1230. {
  1231. $data->list[$num_row]->edit_url = $data->edit_url.'/'.$row->{$data->primary_key};
  1232. $data->list[$num_row]->delete_url = $data->delete_url.'/'.$row->{$data->primary_key};
  1233. }
  1234. if(!$ajax)
  1235. {
  1236. $data->list_view = $this->_theme_view('list.php',$data,true);
  1237. $this->_theme_view('list_template.php',$data);
  1238. }
  1239. else
  1240. {
  1241. $this->set_echo_and_die();
  1242. $this->_theme_view('list.php',$data);
  1243. }
  1244. }
  1245. protected function exportToExcel($state_info = null)
  1246. {
  1247. $data = $this->get_common_data();
  1248. $data->order_by = $this->order_by;
  1249. $data->types = $this->get_field_types();
  1250. $data->list = $this->get_list();
  1251. $data->list = $this->change_list($data->list , $data->types);
  1252. $data->list = $this->change_list_add_actions($data->list);
  1253. $data->total_results = $this->get_total_results();
  1254. $data->columns = $this->get_columns();
  1255. $data->primary_key = $this->get_primary_key();
  1256. @ob_end_clean();
  1257. $this->_export_to_excel($data);
  1258. }
  1259. protected function _export_to_excel($data)
  1260. {
  1261. /**
  1262. * No need to use an external library here. The only bad thing without using external library is that Microsoft Excel is complaining
  1263. * that the file is in a different format than specified by the file extension. If you press "Yes" everything will be just fine.
  1264. * */
  1265. $string_to_export = "";
  1266. foreach($data->columns as $column){
  1267. $string_to_export .= $column->display_as."\t";
  1268. }
  1269. $string_to_export .= "\n";
  1270. foreach($data->list as $num_row => $row){
  1271. foreach($data->columns as $column){
  1272. $string_to_export .= $this->_trim_export_string($row->{$column->field_name})."\t";
  1273. }
  1274. $string_to_export .= "\n";
  1275. }
  1276. // Convert to UTF-16LE and Prepend BOM
  1277. $string_to_export = "\xFF\xFE" .mb_convert_encoding($string_to_export, 'UTF-16LE', 'UTF-8');
  1278. $filename = "export-".date("Y-m-d_H:i:s").".xls";
  1279. header('Content-type: application/vnd.ms-excel;charset=UTF-16LE');
  1280. header('Content-Disposition: attachment; filename='.$filename);
  1281. header("Cache-Control: no-cache");
  1282. echo $string_to_export;
  1283. die();
  1284. }
  1285. protected function print_webpage($state_info = null)
  1286. {
  1287. $data = $this->get_common_data();
  1288. $data->order_by = $this->order_by;
  1289. $data->types = $this->get_field_types();
  1290. $data->list = $this->get_list();
  1291. $data->list = $this->change_list($data->list , $data->types);
  1292. $data->list = $this->change_list_add_actions($data->list);
  1293. $data->total_results = $this->get_total_results();
  1294. $data->columns = $this->get_columns();
  1295. $data->primary_key = $this->get_primary_key();
  1296. @ob_end_clean();
  1297. $this->_print_webpage($data);
  1298. }
  1299. protected function _print_webpage($data)
  1300. {
  1301. $string_to_print = "<meta charset=\"utf-8\" /><style type=\"text/css\" >
  1302. #print-table{ color: #000; background: #fff; font-family: Verdana,Tahoma,Helvetica,sans-serif; font-size: 13px;}
  1303. #print-table table tr td, #print-table table tr th{ border: 1px solid black; border-bottom: none; border-right: none; padding: 4px 8px 4px 4px}
  1304. #print-table table{ border-bottom: 1px solid black; border-right: 1px solid black}
  1305. #print-table table tr th{text-align: left;background: #ddd}
  1306. #print-table table tr:nth-child(odd){background: #eee}
  1307. </style>";
  1308. $string_to_print .= "<div id='print-table'>";
  1309. $string_to_print .= '<table width="100%" cellpadding="0" cellspacing="0" ><tr>';
  1310. foreach($data->columns as $column){
  1311. $string_to_print .= "<th>".$column->display_as."</th>";
  1312. }
  1313. $string_to_print .= "</tr>";
  1314. foreach($data->list as $num_row => $row){
  1315. $string_to_print .= "<tr>";
  1316. foreach($data->columns as $column){
  1317. $string_to_print .= "<td>".$this->_trim_print_string($row->{$column->field_name})."</td>";
  1318. }
  1319. $string_to_print .= "</tr>";
  1320. }
  1321. $string_to_print .= "</table></div>";
  1322. echo $string_to_print;
  1323. die();
  1324. }
  1325. protected function _trim_export_string($value)
  1326. {
  1327. $value = str_replace(array("&nbsp;","&amp;","&gt;","&lt;"),array(" ","&",">","<"),$value);
  1328. return strip_tags(str_replace(array("\t","\n","\r"),"",$value));
  1329. }
  1330. protected function _trim_print_string($value)
  1331. {
  1332. $value = str_replace(array("&nbsp;","&amp;","&gt;","&lt;"),array(" ","&",">","<"),$value);
  1333. //If the value has only spaces and nothing more then add the whitespace html character
  1334. if(str_replace(" ","",$value) == "")
  1335. $value = "&nbsp;";
  1336. return strip_tags($value);
  1337. }
  1338. protected function set_echo_and_die()
  1339. {
  1340. $this->echo_and_die = true;
  1341. }
  1342. protected function unset_echo_and_die()
  1343. {
  1344. $this->echo_and_die = false;
  1345. }
  1346. protected function showListInfo()
  1347. {
  1348. $this->set_echo_and_die();
  1349. $total_results = (int)$this->get_total_results();
  1350. @ob_end_clean();
  1351. echo json_encode(array('total_results' => $total_results));
  1352. die();
  1353. }
  1354. protected function change_list_add_actions($list)
  1355. {
  1356. if(empty($this->actions))
  1357. return $list;
  1358. $primary_key = $this->get_primary_key();
  1359. foreach($list as $num_row => $row)
  1360. {
  1361. $actions_urls = array();
  1362. foreach($this->actions as $unique_id => $action)
  1363. {
  1364. if(!empty($action->url_callback))
  1365. {
  1366. $actions_urls[$unique_id] = call_user_func($action->url_callback, $row->$primary_key, $row);
  1367. }
  1368. else
  1369. {
  1370. $actions_urls[$unique_id] =
  1371. $action->url_has_http ?
  1372. $action->link_url.$row->$primary_key :
  1373. site_url($action->link_url.'/'.$row->$primary_key);
  1374. }
  1375. }
  1376. $row->action_urls = $actions_urls;
  1377. }
  1378. return $list;
  1379. }
  1380. protected function change_list($list,$types)
  1381. {
  1382. $primary_key = $this->get_primary_key();
  1383. $has_callbacks = !empty($this->callback_column) ? true : false;
  1384. $output_columns = $this->get_columns();
  1385. foreach($list as $num_row => $row)
  1386. {
  1387. foreach($output_columns as $column)
  1388. {
  1389. $field_name = $column->field_name;
  1390. $field_value = isset( $row->{$column->field_name} ) ? $row->{$column->field_name} : null;
  1391. if( $has_callbacks && isset($this->callback_column[$field_name]) )
  1392. $list[$num_row]->$field_name = call_user_func($this->callback_column[$field_name], $field_value, $row);
  1393. elseif(isset($types[$field_name]))
  1394. $list[$num_row]->$field_name = $this->change_list_value($types[$field_name] , $field_value);
  1395. else
  1396. $list[$num_row]->$field_name = $field_value;
  1397. }
  1398. }
  1399. return $list;
  1400. }
  1401. protected function showAddForm()
  1402. {
  1403. $this->set_js($this->default_javascript_path.'/'.grocery_CRUD::JQUERY);
  1404. $data = $this->get_common_data();
  1405. $data->types = $this->get_field_types();
  1406. $data->list_url = $this->getListUrl();
  1407. $data->insert_url = $this->getInsertUrl();
  1408. $data->validation_url = $this->getValidationInsertUrl();
  1409. $data->input_fields = $this->get_add_input_fields();
  1410. $data->fields = $this->get_add_fields();
  1411. $data->hidden_fields = $this->get_add_hidden_fields();
  1412. $data->unset_back_to_list = $this->unset_back_to_list;
  1413. $this->_theme_view('add.php',$data);
  1414. $this->_inline_js("var js_date_format = '".$this->js_date_format."';");
  1415. }
  1416. protected function showEditForm($state_info)
  1417. {
  1418. $this->set_js($this->default_javascript_path.'/'.grocery_CRUD::JQUERY);
  1419. $data = $this->get_common_data();
  1420. $data->types = $this->get_field_types();
  1421. $data->field_values = $this->get_edit_values($state_info->primary_key);
  1422. $data->add_url = $this->getAddUrl();
  1423. $data->list_url = $this->getListUrl();
  1424. $data->update_url = $this->getUpdateUrl($state_info);
  1425. $data->delete_url = $this->getDeleteUrl($state_info);
  1426. $data->input_fields = $this->get_edit_input_fields($data->field_values);
  1427. $data->fields = $this->get_edit_fields();
  1428. $data->hidden_fields = $this->get_edit_hidden_fields();
  1429. $data->unset_back_to_list = $this->unset_back_to_list;
  1430. $data->validation_url = $this->getValidationUpdateUrl($state_info->primary_key);
  1431. $this->_theme_view('edit.php',$data);
  1432. $this->_inline_js("var js_date_format = '".$this->js_date_format."';");
  1433. }
  1434. protected function delete_layout($delete_result = true)
  1435. {
  1436. @ob_end_clean();
  1437. if($delete_result === false)
  1438. {
  1439. $error_message = '<p>'.$this->l('delete_error_message').

Large files files are truncated, but you can click here to view the full file