PageRenderTime 51ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/vivoManagement/app/Plugin/TwitterBootstrap/View/Helper/BootstrapFormHelper.php

https://bitbucket.org/vsposato/vivo-tools
PHP | 405 lines | 349 code | 56 blank | 0 comment | 61 complexity | d28f1c9c12ee659064ab29c40620eeb0 MD5 | raw file
  1. <?php
  2. App::uses('FormHelper', 'View/Helper');
  3. App::uses('Set', 'Utility');
  4. class BootstrapFormHelper extends FormHelper {
  5. const FORM_SEARCH = 'form-search';
  6. const FORM_INLINE = 'form-inline';
  7. const FORM_HORIZONTAL = 'form-horizontal';
  8. const CLASS_GROUP = 'control-group';
  9. const CLASS_INPUTS = 'controls';
  10. const CLASS_ACTION = 'form-actions';
  11. const CLASS_BUTTON = 'btn';
  12. const CLASS_ERROR = 'error';
  13. public $helpers = array('Html' => array('className' => 'TwitterBootstrap.BootstrapHtml'));
  14. protected $_isHorizontal = false;
  15. protected $_Opts = array();
  16. public function uneditable($fieldName, $options = array(), $before = false) {
  17. if ($before) {
  18. $class = explode(' ', $this->_extractOption('class', $options));
  19. if (in_array('uneditable-input', $class)) {
  20. $this->_Opts[$fieldName] = $options;
  21. $options['type'] = 'uneditable';
  22. }
  23. return $options;
  24. } else {
  25. return $this->Html->tag('span', $options['value'], $options['class']);
  26. }
  27. }
  28. public function addon($fieldName, $options = array(), $before = false) {
  29. if ($before) {
  30. $prepend = $this->_extractOption('prepend', $options);
  31. $append = $this->_extractOption('append', $options);
  32. if ($prepend || $append) {
  33. $this->_Opts[$fieldName] = $options;
  34. $options['type'] = 'addon';
  35. }
  36. return $options;
  37. } else {
  38. $type = $this->_extractOption('type', $this->_Opts[$fieldName]);
  39. $default = array('wrap' => 'span', 'class' => 'add-on');
  40. $divOptions = array();
  41. foreach (array('prepend', 'append') as $addon) {
  42. $$addon = null;
  43. $option = (array)$this->_extractOption($addon, $options);
  44. if ($option) {
  45. if (!is_array($option[0])) {
  46. $option = array($option);
  47. }
  48. foreach ($option as $_option) {
  49. array_push($_option, array());
  50. list($text, $addonOptions) = $_option;
  51. $addonOptions += $default;
  52. $wrap = $addonOptions['wrap'];
  53. unset($addonOptions['wrap']);
  54. $$addon .= $this->Html->tag($wrap, $text, $addonOptions);
  55. }
  56. unset($options[$addon]);
  57. $divOptions = $this->addClass($divOptions, 'input-' . $addon);
  58. }
  59. }
  60. $out = $prepend . $this->{$type}($fieldName, $options) . $append;
  61. return $this->Html->tag('div', $out, $divOptions);
  62. }
  63. }
  64. public function checkbox($fieldName, $options = array()) {
  65. $label = $this->_extractOption('label', $this->_Opts[$fieldName]);
  66. if (!is_array($label)) {
  67. $label = array('text' => $label);
  68. }
  69. $after = $this->_extractOption('after', $this->_Opts[$fieldName]);
  70. if ($this->_isHorizontal) {
  71. $label['text'] = $after;
  72. $label['class'] = null;
  73. }
  74. $label = $this->addClass($label, 'checkbox');
  75. $text = $label['text'];
  76. unset($label['text']);
  77. $out = parent::checkbox($fieldName, $options) . $text;
  78. return $this->label($fieldName, $out, $label);
  79. }
  80. protected function _setOptions($fieldName, $options) {
  81. if ('textarea' === $options['type']) {
  82. $options += array('cols' => false, 'rows' => '3');
  83. }
  84. if ('checkbox' === $options['type']) {
  85. if ($this->_isHorizontal) {
  86. $options['after'] = null;
  87. } else {
  88. $options['label'] = false;
  89. }
  90. }
  91. return $options;
  92. }
  93. public function radio($fieldName, $radioOptions = array(), $options = array()) {
  94. $options['legend'] = false;
  95. $options['separator'] = "\n";
  96. $out = parent::radio($fieldName, $radioOptions, $options);
  97. $out = $this->_restructureLabel($out, array('class' => 'radio'));
  98. return $out;
  99. }
  100. public function select($fieldName, $options = array(), $attributes = array()) {
  101. $multiple = $this->_extractOption('multiple', $attributes);
  102. $checkbox = explode(' ', $multiple);
  103. $attributes['multiple'] = $checkbox[0];
  104. $out = parent::select($fieldName, $options, $attributes);
  105. if ('checkbox' === $checkbox[0]) {
  106. $out = $this->_restructureLabel($out, array('class' => $multiple));
  107. }
  108. return $out;
  109. }
  110. protected function _restructureLabel($out, $options = array()) {
  111. $out = explode("\n", $out);
  112. foreach ($out as $key => &$_out) {
  113. $input = strip_tags($_out, '<input><img>');
  114. if ($input) {
  115. $_out = $this->Html->tag('label', $input, $options);
  116. }
  117. }
  118. return implode("\n", $out);
  119. }
  120. public function create($model = null, $options = array()) {
  121. $class = explode(' ', $this->_extractOption('class', $options));
  122. $inputDefaults = $this->_extractOption('inputDefaults', $options, array());
  123. if (in_array(self::FORM_HORIZONTAL, $class)) {
  124. $this->_isHorizontal = true;
  125. }
  126. if (in_array(self::FORM_SEARCH, $class) || in_array(self::FORM_INLINE, $class)) {
  127. $options['inputDefaults'] = Set::merge($inputDefaults, array('div' => false, 'label' => false));
  128. } else {
  129. $options['inputDefaults'] = Set::merge($inputDefaults, array('div' => self::CLASS_GROUP));
  130. }
  131. return parent::create($model, $options);
  132. }
  133. public function submit($caption = null, $options = array()) {
  134. $default = array(
  135. 'type' => 'submit',
  136. 'class' => self::CLASS_BUTTON,
  137. 'div' => self::CLASS_ACTION,
  138. 'icon' => null,
  139. );
  140. $options = array_merge($default, $this->_inputDefaults, $options);
  141. if ($options['div'] !== false && $this->_isHorizontal) {
  142. $options['div'] = self::CLASS_ACTION;
  143. }
  144. if ($options['icon']) {
  145. $caption = $this->Html->icon($options['icon']) . ' ' . $caption;
  146. unset($options['icon']);
  147. }
  148. $div = $this->_extractOption('div', $options);
  149. $out = $this->button($caption, $options);
  150. return (false === $div) ? $out : $this->Html->div($div, $out);
  151. }
  152. public function input($fieldName, $options = array()) {
  153. $options = array_merge(
  154. array('format' => array('before', 'label', 'between', 'input', 'error', 'after')),
  155. $this->_inputDefaults,
  156. $options
  157. );
  158. $this->_Opts[$fieldName] = $options;
  159. $type = $this->_extractOption('type', $options);
  160. $options = $this->_getType($fieldName, $options);
  161. $hidden = null;
  162. if ('hidden' === $options['type']) {
  163. $options['div'] = false;
  164. $options['label'] = false;
  165. } else {
  166. $options = $this->uneditable($fieldName, $options, true);
  167. $options = $this->addon($fieldName, $options, true);
  168. $options = $this->_setOptions($fieldName, $options);
  169. $options = $this->_controlGroupStates($fieldName, $options);
  170. $options = $this->_buildAfter($options);
  171. $hidden = $this->_hidden($fieldName, $options);
  172. if ($hidden) {
  173. $options['hiddenField'] = false;
  174. }
  175. }
  176. if (is_null($type) && empty($this->_Opts[$fieldName]['type'])) {
  177. unset($options['type']);
  178. }
  179. $disabled = $this->_extractOption('disabled', $options, false);
  180. if ($disabled) {
  181. $options = $this->addClass($options, 'disabled');
  182. }
  183. $div = $this->_extractOption('div', $options);
  184. $options['div'] = false;
  185. $before = $this->_extractOption('before', $options);
  186. $options['before'] = null;
  187. $label = $this->_extractOption('label', $options);
  188. if (false !== $label) {
  189. if (!is_array($label)) {
  190. $label = array('text' => $label);
  191. }
  192. if (false !== $div) {
  193. $class = $this->_extractOption('class', $label, 'control-label');
  194. $label = $this->addClass($label, $class);
  195. }
  196. $text = $label['text'];
  197. unset($label['text']);
  198. $label = $this->label($fieldName, $text, $label);
  199. }
  200. $options['label'] = false;
  201. $between = $this->_extractOption('between', $options);
  202. $options['between'] = null;
  203. $input = parent::input($fieldName, $options);
  204. $divControls = $this->_extractOption('divControls', $options, self::CLASS_INPUTS);
  205. $input = $hidden . ((false === $div) ? $input : $this->Html->div($divControls, $input));
  206. $out = $before . $label . $between . $input;
  207. return (false === $div) ? $out : $this->Html->div($div, $out);
  208. }
  209. protected function _getType($fieldName, $options) {
  210. if (!isset($options['type'])) {
  211. $this->setEntity($fieldName);
  212. $modelKey = $this->model();
  213. $fieldKey = $this->field();
  214. $options['type'] = 'text';
  215. if (isset($options['options'])) {
  216. $options['type'] = 'select';
  217. } elseif (in_array($fieldKey, array('psword', 'passwd', 'password'))) {
  218. $options['type'] = 'password';
  219. } elseif (isset($options['checked'])) {
  220. $options['type'] = 'checkbox';
  221. } elseif ($fieldDef = $this->_introspectModel($modelKey, 'fields', $fieldKey)) {
  222. $type = $fieldDef['type'];
  223. $primaryKey = $this->fieldset[$modelKey]['key'];
  224. }
  225. if (isset($type)) {
  226. $map = array(
  227. 'string' => 'text', 'datetime' => 'datetime',
  228. 'boolean' => 'checkbox', 'timestamp' => 'datetime',
  229. 'text' => 'textarea', 'time' => 'time',
  230. 'date' => 'date', 'float' => 'number',
  231. 'integer' => 'number'
  232. );
  233. if (isset($this->map[$type])) {
  234. $options['type'] = $this->map[$type];
  235. } elseif (isset($map[$type])) {
  236. $options['type'] = $map[$type];
  237. }
  238. if ($fieldKey == $primaryKey) {
  239. $options['type'] = 'hidden';
  240. }
  241. }
  242. if (preg_match('/_id$/', $fieldKey) && $options['type'] !== 'hidden') {
  243. $options['type'] = 'select';
  244. }
  245. if ($modelKey === $fieldKey) {
  246. $options['type'] = 'select';
  247. }
  248. }
  249. return $options;
  250. }
  251. protected function _buildAfter($options) {
  252. $outInline = array();
  253. $inlines = (array)$this->_extractOption('helpInline', $options, array());
  254. if ($inlines) {
  255. unset($options['helpInline']);
  256. }
  257. foreach ($inlines as $inline) {
  258. $outInline[] = $this->help($inline, array('type' => 'inline'));
  259. }
  260. $outInline = implode(' ', $outInline);
  261. $outBlock = array();
  262. $blocks = (array)$this->_extractOption('helpBlock', $options, array());
  263. if ($blocks) {
  264. unset($options['helpBlock']);
  265. }
  266. foreach ($blocks as $block) {
  267. $outBlock[] = $this->help($block, array('type' => 'block'));
  268. }
  269. $outBlock = implode("\n", $outBlock);
  270. $options['after'] = $outInline . "\n" . $outBlock . "\n" . $this->_extractOption('after', $options);
  271. return $options;
  272. }
  273. protected function _controlGroupStates($fieldName, $options) {
  274. $div = $this->_extractOption('div', $options);
  275. if (false !== $div) {
  276. $inlines = (array)$this->_extractOption('helpInline', $options, array());
  277. foreach ($options as $key => $value) {
  278. if (in_array($key, array('warning', 'success'))) {
  279. unset($options[$key]);
  280. array_unshift($inlines, $value);
  281. $options = $this->addClass($options, $key, 'div');
  282. }
  283. }
  284. if ($inlines) {
  285. $options['helpInline'] = $inlines;
  286. }
  287. }
  288. if ($this->error($fieldName)) {
  289. $error = $this->_extractOption('error', $options, array());
  290. $options['error'] = array_merge($error, array(
  291. 'attributes' => array(
  292. 'wrap' => 'span',
  293. 'class' => 'help-inline error-message',
  294. ),
  295. ));
  296. if (false !== $div) {
  297. $options = $this->addClass($options, self::CLASS_ERROR, 'div');
  298. }
  299. }
  300. return $options;
  301. }
  302. protected function _hidden($fieldName, $options) {
  303. $type = $options['type'];
  304. if (!in_array($type, array('checkbox', 'radio', 'select'))) {
  305. return null;
  306. }
  307. $multiple = $this->_extractOption('multiple', $options);
  308. $multiple = current(explode(' ', $multiple));
  309. if ('select' === $type && !$multiple) {
  310. return null;
  311. }
  312. $hiddenField = $this->_extractOption('hiddenField', $options, true);
  313. if (!$hiddenField) {
  314. return null;
  315. }
  316. $out = null;
  317. if ('checkbox' === $type || !isset($options['value']) || $options['value'] === '') {
  318. $options['secure'] = false;
  319. $options = $this->_initInputField($fieldName, $options);
  320. $style = ('select' === $type && 'checkbox' !== $multiple) ? null : '_';
  321. $hiddenOptions = array(
  322. 'id' => $options['id'] . $style,
  323. 'name' => $options['name'],
  324. 'value' => '',
  325. );
  326. if ('checkbox' === $type) {
  327. $hiddenOptions['value'] = ($hiddenField !== true ? $hiddenField : '0');
  328. $hiddenOptions['secure'] = false;
  329. }
  330. if (isset($options['disabled']) && $options['disabled'] == true) {
  331. $hiddenOptions['disabled'] = 'disabled';
  332. }
  333. $out = $this->hidden($fieldName, $hiddenOptions);
  334. }
  335. return $out;
  336. }
  337. public function help($text, $options = array()) {
  338. $classMap = array(
  339. 'inline' => array('wrap' => 'span', 'class' => 'help-inline'),
  340. 'block' => array('wrap' => 'p', 'class' => 'help-block'),
  341. );
  342. $options += array('type' => 'inline');
  343. $options += $this->_extractOption($options['type'], $classMap, array());
  344. unset($options['type']);
  345. $wrap = $options['wrap'];
  346. unset($options['wrap']);
  347. return $this->Html->tag($wrap , $text, $options);
  348. }
  349. }