PageRenderTime 47ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/application/third_party/gas/classes/extension/html.php

https://bitbucket.org/hugobraulio/dosxtremos
PHP | 589 lines | 310 code | 74 blank | 205 comment | 41 complexity | 1f8d3073def9bc4d21f644e1b66591cc MD5 | raw file
  1. <?php namespace Gas\Extension;
  2. /**
  3. * CodeIgniter Gas ORM Packages
  4. *
  5. * A lighweight and easy-to-use ORM for CodeIgniter
  6. *
  7. * This packages intend to use as semi-native ORM for CI,
  8. * based on the ActiveRecord pattern. This ORM uses CI stan-
  9. * dard DB utility packages also validation class.
  10. *
  11. * @package Gas ORM
  12. * @category ORM
  13. * @version 2.1.1
  14. * @author Taufan Aditya A.K.A Toopay
  15. * @link http://gasorm-doc.taufanaditya.com/
  16. * @license BSD
  17. *
  18. * =================================================================================================
  19. * =================================================================================================
  20. * Copyright 2011 Taufan Aditya a.k.a toopay. All rights reserved.
  21. *
  22. * Redistribution and use in source and binary forms, with or without modification, are
  23. * permitted provided that the following conditions are met:
  24. *
  25. * 1. Redistributions of source code must retain the above copyright notice, this list of
  26. * conditions and the following disclaimer.
  27. *
  28. * 2. Redistributions in binary form must reproduce the above copyright notice, this list
  29. * of conditions and the following disclaimer in the documentation and/or other materials
  30. * provided with the distribution.
  31. *
  32. * THIS SOFTWARE IS PROVIDED BY Taufan Aditya a.k.a toopay ‘’AS IS’’ AND ANY EXPRESS OR IMPLIED
  33. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  34. * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Taufan Aditya a.k.a toopay OR
  35. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  36. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  37. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  38. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  39. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  40. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  41. *
  42. * The views and conclusions contained in the software and documentation are those of the
  43. * authors and should not be interpreted as representing official policies, either expressed
  44. * or implied, of Taufan Aditya a.k.a toopay.
  45. * =================================================================================================
  46. * =================================================================================================
  47. */
  48. /**
  49. * Gas\Extension\Html Class.
  50. *
  51. * @package Gas ORM
  52. * @since 2.1.0
  53. */
  54. use \Gas\Extension;
  55. class Html implements Extension {
  56. /**
  57. * @var mixed Gas instance(s)
  58. */
  59. public $gas;
  60. /**
  61. * @var array Table headings holder
  62. */
  63. public $table_headings;
  64. /**
  65. * @var array Table template holder
  66. */
  67. public $table_template;
  68. /**
  69. * @var array Table records holder
  70. */
  71. public $table_records;
  72. /**
  73. * @var array Form labels holder
  74. */
  75. public $form_labels;
  76. /**
  77. * @var array Form definitions holder
  78. */
  79. public $form_definitions;
  80. /**
  81. * @var string Form separator holder
  82. */
  83. public $form_separator = '';
  84. /**
  85. * @var string Form prefix tag
  86. */
  87. public $form_entity_prefix = '<p>';
  88. /**
  89. * @var string Form suffix tag
  90. */
  91. public $form_entity_suffix = '</p>';
  92. /**
  93. * @var array Form submit url
  94. */
  95. public $form_submit = '';
  96. /**
  97. * @var array Hidden keys holder
  98. */
  99. public $hidden_keys = array();
  100. /**
  101. * Extension initialization method
  102. *
  103. * @param object
  104. * @return void
  105. */
  106. function __init($gas)
  107. {
  108. // Here, Gas will transport your instance
  109. $this->gas = $gas;
  110. return $this;
  111. }
  112. /**
  113. * Hide keys for next operation
  114. *
  115. * @param mixed
  116. * @return void
  117. */
  118. public function hide($keys)
  119. {
  120. // Parse if the argument was string
  121. if (is_string($keys))
  122. {
  123. $keys = explode(',', $keys);
  124. }
  125. if ( ! empty($keys)) $this->hidden_keys = $keys;
  126. return $this;
  127. }
  128. /**
  129. * Set table templates
  130. *
  131. * @param array
  132. * @return void
  133. */
  134. public function template($tmpl = array())
  135. {
  136. $this->table_template = $tmpl;
  137. return $this;
  138. }
  139. /**
  140. * Set table heading
  141. *
  142. * @param array
  143. * @return void
  144. */
  145. public function heading($headings = null)
  146. {
  147. if (is_null($headings))
  148. {
  149. // Get all collumns name, and filter for avoid keys which declared before final method
  150. $list_fields = $this->all_collumns();
  151. $headings = array_filter($list_fields, get_class($this).'::avoid_keys');
  152. array_walk_recursive($headings, get_class($this).'::human_name');
  153. }
  154. $this->table_headings = $headings;
  155. return $this;
  156. }
  157. /**
  158. * Generate HTML table
  159. *
  160. * @return string
  161. */
  162. public function table()
  163. {
  164. $CI =& get_instance();
  165. if ( ! class_exists('CI_Table')) $CI->load->library('table');
  166. if (is_null($this->table_headings)) $this->heading();
  167. $CI->table->set_heading($this->table_headings);
  168. $CI->table->set_template($this->table_template);
  169. // Validate the records
  170. if (is_object($this->gas))
  171. {
  172. $records = $this->gas->record->get();
  173. }
  174. elseif (is_array($this->gas) && ! empty($this->gas))
  175. {
  176. $records = $this->gas;
  177. }
  178. else
  179. {
  180. $records = array();
  181. }
  182. // Fill the table rows
  183. foreach ($records as $record)
  184. {
  185. $record = (is_object($record)) ? $record->record->get('data') : $record;
  186. $CI->table->add_row($record);
  187. }
  188. // Do we need to hide some collumn?
  189. $raw_rows = $CI->table->rows;
  190. $CI->table->rows = array();
  191. foreach ($raw_rows as $raw_row)
  192. {
  193. $row = array_shift($raw_row);
  194. if ( ! empty($this->hidden_keys))
  195. {
  196. foreach ($this->hidden_keys as $hidden_key)
  197. {
  198. if (isset($row[$hidden_key])) unset($row[$hidden_key]);
  199. }
  200. }
  201. $CI->table->add_row(array_values($row));
  202. }
  203. // Generate the table
  204. $table = $CI->table->generate();
  205. $CI->table->clear();
  206. return $table;
  207. }
  208. /**
  209. * Set form fields entity definition
  210. *
  211. * @param array
  212. * @return void
  213. */
  214. public function definition($args = array())
  215. {
  216. $this->validate_form();
  217. $collumns = $this->all_collumns();
  218. if (empty($args)) $args = $collumns;
  219. // Validate the records
  220. if (is_object($this->gas))
  221. {
  222. $gas_records = $this->gas->record->get();
  223. if (empty($gas_records))
  224. {
  225. $records[] = array_combine($collumns, array_fill(0, count($collumns), ''));
  226. }
  227. else
  228. {
  229. $records = $gas_records;
  230. }
  231. }
  232. elseif (is_array($this->gas) && ! empty($this->gas))
  233. {
  234. $records = $this->gas;
  235. }
  236. else
  237. {
  238. $records[] = array_combine($collumns, array_fill(0, count($collumns), ''));
  239. }
  240. // Initial form definition
  241. $form_entities = array();
  242. $custom = FALSE;
  243. // Loop over the record(s)
  244. foreach ($records as $record)
  245. {
  246. $record = (is_object($record)) ? $record->record->get('data') : $record;
  247. if ( ! $args)
  248. {
  249. // This came from multiple instance, which not allowed (yet)
  250. throw new \InvalidArgumentException('[definition]Form method(s) can not handle multiple instances');
  251. }
  252. foreach ($args as $key => $arg)
  253. {
  254. if (is_numeric($key))
  255. {
  256. // No custom definition has been set
  257. $value = isset($record[$arg]) ? $record[$arg] : '';
  258. $option = array('name' => $arg, 'value' => $value);
  259. $form_entities[$arg] = call_user_func('form_input', $option);
  260. }
  261. else
  262. {
  263. // Mark the custom flag
  264. if ($custom == FALSE)
  265. {
  266. $this->definition();
  267. $custom = TRUE;
  268. }
  269. // Here we must handle custom form definition(s)
  270. $type = key($arg);
  271. $value = isset($record[$key]) ? $record[$key] : '';
  272. $option = $arg[$type];
  273. $needed = array('dropdown', 'multiselect', 'checkbox', 'radio');
  274. if ( ! is_array($option) && in_array($type, $needed))
  275. {
  276. // Not valid argument for further usage
  277. throw new \InvalidArgumentException('[definition]'.$type.' should contain valid option');
  278. }
  279. // Determine the type of form entity, then generate decent entity definition
  280. if ($type == 'dropdown' or $type == 'multiselect')
  281. {
  282. if ($type == 'dropdown')
  283. {
  284. $form_entities[$key] = form_dropdown($key, $option, $value);
  285. }
  286. else
  287. {
  288. $form_entities[$key] = form_multiselect($key.'[]', $option, $value);
  289. }
  290. }
  291. elseif ($type == 'checkbox' or $type == 'radio')
  292. {
  293. $checked = ! empty($value);
  294. $option = array_merge($option, array('name' => $key, 'checked' => $checked));
  295. $form_entities[$key] = call_user_func('form_'.$type, $option);
  296. }
  297. else
  298. {
  299. // Determine how we handle the option
  300. if (is_string($option))
  301. {
  302. // This mean, option contain direct value.
  303. // Now, we need to know whether corresponding value exists or not
  304. if (empty($value))
  305. {
  306. // No related value found, use this option
  307. $option = array('name' => $key, 'value' => $option);
  308. }
  309. else
  310. {
  311. // Related value found, overide this option
  312. $option = array('name' => $key, 'value' => $value);
  313. }
  314. }
  315. elseif (is_array($option))
  316. {
  317. // Option already contain both 'name' and 'value',
  318. // merge it with our model instance entity
  319. $option = array_merge($option, array('name' => $key, 'value' => $value));
  320. }
  321. if ($type == 'hidden')
  322. {
  323. $name = $option['name'];
  324. $val = $option['value'];
  325. $form_entities[':hidden:'.$key] = form_hidden($name, $val);
  326. }
  327. else
  328. {
  329. if ( ! function_exists('form_'.$type))
  330. {
  331. throw new \BadMethodCallException('[definition]Unknown form method within CI Form helper');
  332. }
  333. $form_entities[$key] = call_user_func('form_'.$type, $option);
  334. }
  335. }
  336. }
  337. }
  338. // Finalize the form definitions
  339. if ($custom == TRUE)
  340. {
  341. $this->form_definitions = array_merge($this->form_definitions, $form_entities);
  342. }
  343. else
  344. {
  345. $this->form_definitions = $form_entities;
  346. }
  347. return $this;
  348. }
  349. }
  350. /**
  351. * Set form separator
  352. *
  353. * @param string
  354. * @return void
  355. */
  356. public function separator($separator = '')
  357. {
  358. $this->form_separator = $separator;
  359. return $this;
  360. }
  361. /**
  362. * Set Entity prefix or/and suffix
  363. *
  364. * @param string
  365. * @param string
  366. * @return void
  367. */
  368. public function entity($prefix = '<p>', $suffix = '</p>')
  369. {
  370. $this->form_entity_prefix = $prefix;
  371. $this->form_entity_suffix = $suffix;
  372. return $this;
  373. }
  374. /**
  375. * Set form submit
  376. *
  377. * @param string
  378. * @param string
  379. * @return void
  380. */
  381. public function submit($arg = 'submit', $content = 'Submit')
  382. {
  383. $this->validate_form();
  384. $this->form_submit = is_array($arg) ? form_submit($arg) : form_submit($arg, $content);
  385. return $this;
  386. }
  387. /**
  388. * Generate HTML form
  389. *
  390. * @param string
  391. * @param array
  392. * @param bool
  393. * @param bool
  394. * @return string
  395. */
  396. public function form($url = '', $attributes = array(), $multipart = FALSE, $as_array = FALSE)
  397. {
  398. $this->validate_form();
  399. if (is_null($this->form_definitions)) $this->definition();
  400. // Prepare all needed information
  401. $entities = array();
  402. $method = array('method' => 'POST');
  403. $attributes = empty($attributes) ? $method : array_merge($attributes, $method);
  404. $open_tag = ($multipart) ? form_open_multipart($url, $attributes) : form_open($url, $attributes);
  405. // Build the form entities
  406. foreach ($this->form_definitions as $label => $entity)
  407. {
  408. if ( ! in_array($label, $this->hidden_keys))
  409. {
  410. if (strpos($entity, ':hidden:') === 0)
  411. {
  412. $entity = str_replace(':hidden:', '', $entity);
  413. $entities[] = $this->form_entity_prefix.$entity.$this->form_entity_suffix;
  414. }
  415. else
  416. {
  417. // Do we need to hide some label?
  418. if (strpos($label, ':hidden:') === 0)
  419. {
  420. $entities[] = $this->form_entity_prefix.$entity.$this->form_entity_suffix;
  421. }
  422. else
  423. {
  424. $formatted_label = form_label(ucfirst(str_replace(array('-', '_'), ' ', $label)));
  425. $entities[] = $this->form_entity_prefix.$formatted_label.$entity.$this->form_entity_suffix;
  426. }
  427. }
  428. }
  429. }
  430. if (empty($this->form_submit)) $this->submit();
  431. $close_tag = form_close();
  432. // Finalize the form
  433. if ($as_array)
  434. {
  435. $form = array(
  436. 'open_tag' => $open_tag,
  437. 'entities' => $entities,
  438. 'submit' => $this->form_submit,
  439. 'close_tag' => $close_tag,
  440. );
  441. }
  442. else
  443. {
  444. $form = $open_tag
  445. .implode($this->form_separator, $entities)
  446. .$this->form_separator
  447. .$this->form_submit
  448. .$close_tag;
  449. }
  450. return $form;
  451. }
  452. /**
  453. * Check form helper state
  454. *
  455. * @return void
  456. */
  457. protected function validate_form()
  458. {
  459. // Load the form helper
  460. if ( ! function_exists('form_open'))
  461. {
  462. $CI =& get_instance();
  463. $CI->load->helper('form');
  464. }
  465. return;
  466. }
  467. /**
  468. * Return table collumns name
  469. *
  470. * @return array
  471. */
  472. protected function all_collumns()
  473. {
  474. // Determine whether gas property was a single instance or
  475. // a collection of instance(s)
  476. if (is_object($this->gas))
  477. {
  478. $collumns = $this->gas->meta->get('collumns');
  479. }
  480. elseif (is_array($this->gas))
  481. {
  482. $sample = $this->gas;
  483. $gas = array_shift($sample);
  484. $collumns = $gas->meta->get('collumns');
  485. }
  486. else
  487. {
  488. // Null instance is not allowed
  489. throw new \BadMethodCallException('[html]Extension should receive a valid Gas Model instance');
  490. }
  491. return $collumns;
  492. }
  493. /**
  494. * Generate label portion
  495. *
  496. * @param mixed
  497. * @param mixed
  498. * @return void
  499. */
  500. protected function human_name(&$v, $k)
  501. {
  502. $v = ucfirst(str_replace('_', '', $v));
  503. }
  504. /**
  505. * Sorting keys for hidden keys
  506. *
  507. * @param mixed
  508. * @param mixed
  509. * @return void
  510. */
  511. protected function avoid_keys($v)
  512. {
  513. return( ! in_array($v, $this->hidden_keys));
  514. }
  515. }