PageRenderTime 26ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/anahkiasen/former/src/Former/Framework/TwitterBootstrap3.php

https://gitlab.com/hatemdigify/digifyblog
PHP | 449 lines | 188 code | 51 blank | 210 comment | 14 complexity | 838e4b89ae247241bfb8038e1bb51735 MD5 | raw file
  1. <?php
  2. namespace Former\Framework;
  3. use Former\Interfaces\FrameworkInterface;
  4. use Former\Traits\Field;
  5. use Former\Traits\Framework;
  6. use HtmlObject\Element;
  7. use Illuminate\Container\Container;
  8. use Illuminate\Support\Str;
  9. /**
  10. * The Twitter Bootstrap form framework
  11. */
  12. class TwitterBootstrap3 extends Framework implements FrameworkInterface
  13. {
  14. /**
  15. * Form types that trigger special styling for this Framework
  16. *
  17. * @var array
  18. */
  19. protected $availableTypes = array('horizontal', 'vertical', 'inline');
  20. /**
  21. * The button types available
  22. *
  23. * @var array
  24. */
  25. private $buttons = array(
  26. 'lg',
  27. 'sm',
  28. 'xs',
  29. 'block',
  30. 'link',
  31. 'default',
  32. 'primary',
  33. 'warning',
  34. 'danger',
  35. 'success',
  36. 'info',
  37. );
  38. /**
  39. * The field sizes available
  40. *
  41. * @var array
  42. */
  43. private $fields = array(
  44. 'lg',
  45. 'sm',
  46. // 'col-xs-1', 'col-xs-2', 'col-xs-3', 'col-xs-4', 'col-xs-5', 'col-xs-6',
  47. // 'col-xs-7', 'col-xs-8', 'col-xs-9', 'col-xs-10', 'col-xs-11', 'col-xs-12',
  48. // 'col-sm-1', 'col-sm-2', 'col-sm-3', 'col-sm-4', 'col-sm-5', 'col-sm-6',
  49. // 'col-sm-7', 'col-sm-8', 'col-sm-9', 'col-sm-10', 'col-sm-11', 'col-sm-12',
  50. // 'col-md-1', 'col-md-2', 'col-md-3', 'col-md-4', 'col-md-5', 'col-md-6',
  51. // 'col-md-7', 'col-md-8', 'col-md-9', 'col-md-10', 'col-md-11', 'col-md-12',
  52. // 'col-lg-1', 'col-lg-2', 'col-lg-3', 'col-lg-4', 'col-lg-5', 'col-lg-6',
  53. // 'col-lg-7', 'col-lg-8', 'col-lg-9', 'col-lg-10', 'col-lg-11', 'col-lg-12',
  54. );
  55. /**
  56. * The field states available
  57. *
  58. * @var array
  59. */
  60. protected $states = array(
  61. 'has-warning',
  62. 'has-error',
  63. 'has-success',
  64. );
  65. /**
  66. * The default HTML tag used for icons
  67. *
  68. * @var string
  69. */
  70. protected $iconTag = 'span';
  71. /**
  72. * The default set for icon fonts
  73. * By default Bootstrap 3 offers only 'glyphicon'
  74. * See Former docs to use 'social' and 'filetypes' sets for specific icons.
  75. *
  76. * @var string
  77. */
  78. protected $iconSet = 'glyphicon';
  79. /**
  80. * The default prefix icon names
  81. * "icon" works for Bootstrap 2 and Font-awesome
  82. *
  83. * @var string
  84. */
  85. protected $iconPrefix = 'glyphicon';
  86. /**
  87. * Create a new TwitterBootstrap instance
  88. *
  89. * @param \Illuminate\Container\Container $app
  90. */
  91. public function __construct(Container $app)
  92. {
  93. $this->app = $app;
  94. $this->setFrameworkDefaults();
  95. }
  96. ////////////////////////////////////////////////////////////////////
  97. /////////////////////////// FILTER ARRAYS //////////////////////////
  98. ////////////////////////////////////////////////////////////////////
  99. /**
  100. * Filter buttons classes
  101. *
  102. * @param array $classes An array of classes
  103. *
  104. * @return string[] A filtered array
  105. */
  106. public function filterButtonClasses($classes)
  107. {
  108. // Filter classes
  109. // $classes = array_intersect($classes, $this->buttons);
  110. // Prepend button type
  111. $classes = $this->prependWith($classes, 'btn-');
  112. $classes[] = 'btn';
  113. return $classes;
  114. }
  115. /**
  116. * Filter field classes
  117. *
  118. * @param array $classes An array of classes
  119. *
  120. * @return array A filtered array
  121. */
  122. public function filterFieldClasses($classes)
  123. {
  124. // Filter classes
  125. $classes = array_intersect($classes, $this->fields);
  126. // Prepend field type
  127. $classes = array_map(function ($class) {
  128. return Str::startsWith($class, 'col') ? $class : 'input-'.$class;
  129. }, $classes);
  130. return $classes;
  131. }
  132. ////////////////////////////////////////////////////////////////////
  133. ///////////////////// EXPOSE FRAMEWORK SPECIFICS ///////////////////
  134. ////////////////////////////////////////////////////////////////////
  135. /**
  136. * Framework error state
  137. *
  138. * @return string
  139. */
  140. public function errorState()
  141. {
  142. return 'has-error';
  143. }
  144. /**
  145. * Returns corresponding inline class of a field
  146. *
  147. * @param Field $field
  148. *
  149. * @return string
  150. */
  151. public function getInlineLabelClass($field)
  152. {
  153. $inlineClass = parent::getInlineLabelClass($field);
  154. if ($field->isOfType('checkbox', 'checkboxes')) {
  155. $inlineClass = 'checkbox-'.$inlineClass;
  156. } elseif ($field->isOfType('radio', 'radios')) {
  157. $inlineClass = 'radio-'.$inlineClass;
  158. }
  159. return $inlineClass;
  160. }
  161. /**
  162. * Set the fields width from a label width
  163. *
  164. * @param array $labelWidths
  165. */
  166. protected function setFieldWidths($labelWidths)
  167. {
  168. $labelWidthClass = $fieldWidthClass = $fieldOffsetClass = '';
  169. $viewports = $this->getFrameworkOption('viewports');
  170. foreach ($labelWidths as $viewport => $columns) {
  171. if ($viewport) {
  172. $labelWidthClass .= " col-$viewports[$viewport]-$columns";
  173. $fieldWidthClass .= " col-$viewports[$viewport]-".(12 - $columns);
  174. $fieldOffsetClass .= " col-$viewports[$viewport]-offset-$columns";
  175. }
  176. }
  177. $this->labelWidth = ltrim($labelWidthClass);
  178. $this->fieldWidth = ltrim($fieldWidthClass);
  179. $this->fieldOffset = ltrim($fieldOffsetClass);
  180. }
  181. ////////////////////////////////////////////////////////////////////
  182. ///////////////////////////// ADD CLASSES //////////////////////////
  183. ////////////////////////////////////////////////////////////////////
  184. /**
  185. * Add classes to a field
  186. *
  187. * @param Field $field
  188. * @param array $classes The possible classes to add
  189. *
  190. * @return Field
  191. */
  192. public function getFieldClasses(Field $field, $classes)
  193. {
  194. // Add inline class for checkables
  195. if ($field->isCheckable() and in_array('inline', $classes)) {
  196. $field->inline();
  197. }
  198. // Filter classes according to field type
  199. if ($field->isButton()) {
  200. $classes = $this->filterButtonClasses($classes);
  201. } else {
  202. $classes = $this->filterFieldClasses($classes);
  203. }
  204. // Add form-control class for text-type, textarea and select fields
  205. // As text-type is open-ended we instead exclude those that shouldn't receive the class
  206. if (!$field->isCheckable() and !$field->isButton() and !in_array($field->getType(), array(
  207. 'file',
  208. 'plaintext',
  209. )) and !in_array('form-control', $classes)
  210. ) {
  211. $classes[] = 'form-control';
  212. }
  213. return $this->addClassesToField($field, $classes);
  214. }
  215. /**
  216. * Add group classes
  217. *
  218. * @return string A list of group classes
  219. */
  220. public function getGroupClasses()
  221. {
  222. return 'form-group';
  223. }
  224. /**
  225. * Add label classes
  226. *
  227. * @return string[] An array of attributes with the label class
  228. */
  229. public function getLabelClasses()
  230. {
  231. if ($this->app['former.form']->isOfType('horizontal')) {
  232. return array('control-label', $this->labelWidth);
  233. } elseif ($this->app['former.form']->isOfType('inline')) {
  234. return array('sr-only');
  235. } else {
  236. return array('control-label');
  237. }
  238. }
  239. /**
  240. * Add uneditable field classes
  241. *
  242. * @return string An array of attributes with the uneditable class
  243. */
  244. public function getUneditableClasses()
  245. {
  246. return '';
  247. }
  248. /**
  249. * Add plain text field classes
  250. *
  251. * @return string An array of attributes with the plain text class
  252. */
  253. public function getPlainTextClasses()
  254. {
  255. return 'form-control-static';
  256. }
  257. /**
  258. * Add form class
  259. *
  260. * @param string $type The type of form to add
  261. *
  262. * @return string|null
  263. */
  264. public function getFormClasses($type)
  265. {
  266. return $type ? 'form-'.$type : null;
  267. }
  268. /**
  269. * Add actions block class
  270. *
  271. * @return string|null
  272. */
  273. public function getActionClasses()
  274. {
  275. if ($this->app['former.form']->isOfType('horizontal') || $this->app['former.form']->isOfType('inline')) {
  276. return 'form-group';
  277. }
  278. return null;
  279. }
  280. ////////////////////////////////////////////////////////////////////
  281. //////////////////////////// RENDER BLOCKS /////////////////////////
  282. ////////////////////////////////////////////////////////////////////
  283. /**
  284. * Render an help text
  285. *
  286. * @param string $text
  287. * @param array $attributes
  288. *
  289. * @return Element
  290. */
  291. public function createHelp($text, $attributes = array())
  292. {
  293. return Element::create('span', $text, $attributes)->addClass('help-block');
  294. }
  295. /**
  296. * Render an help text
  297. *
  298. * @param string $text
  299. * @param array $attributes
  300. *
  301. * @return Element
  302. */
  303. public function createBlockHelp($text, $attributes = array())
  304. {
  305. return Element::create('p', $text, $attributes)->addClass('help-block');
  306. }
  307. /**
  308. * Render a disabled field
  309. *
  310. * @param Field $field
  311. *
  312. * @return Element
  313. */
  314. public function createDisabledField(Field $field)
  315. {
  316. return Element::create('span', $field->getValue(), $field->getAttributes());
  317. }
  318. /**
  319. * Render a plain text field
  320. *
  321. * @param Field $field
  322. *
  323. * @return Element
  324. */
  325. public function createPlainTextField(Field $field)
  326. {
  327. $label = $field->getLabel();
  328. if ($label) {
  329. $label->for('');
  330. }
  331. return Element::create('div', $field->getValue(), $field->getAttributes());
  332. }
  333. ////////////////////////////////////////////////////////////////////
  334. //////////////////////////// WRAP BLOCKS ///////////////////////////
  335. ////////////////////////////////////////////////////////////////////
  336. /**
  337. * Wrap an item to be prepended or appended to the current field
  338. *
  339. * @return Element A wrapped item
  340. */
  341. public function placeAround($item)
  342. {
  343. // Render object
  344. if (is_object($item) and method_exists($item, '__toString')) {
  345. $item = $item->__toString();
  346. }
  347. // Get class to use
  348. $class = (strpos($item, '<button') !== false) ? 'btn' : 'addon';
  349. return Element::create('span', $item)->addClass('input-group-'.$class);
  350. }
  351. /**
  352. * Wrap a field with prepended and appended items
  353. *
  354. * @param Field $field
  355. * @param array $prepend
  356. * @param array $append
  357. *
  358. * @return string A field concatented with prepended and/or appended items
  359. */
  360. public function prependAppend($field, $prepend, $append)
  361. {
  362. $return = '<div class="input-group">';
  363. $return .= join(null, $prepend);
  364. $return .= $field->render();
  365. $return .= join(null, $append);
  366. $return .= '</div>';
  367. return $return;
  368. }
  369. /**
  370. * Wrap a field with potential additional tags
  371. *
  372. * @param Field $field
  373. *
  374. * @return Element A wrapped field
  375. */
  376. public function wrapField($field)
  377. {
  378. if ($this->app['former.form']->isOfType('horizontal')) {
  379. return Element::create('div', $field)->addClass($this->fieldWidth);
  380. }
  381. return $field;
  382. }
  383. /**
  384. * Wrap actions block with potential additional tags
  385. *
  386. * @param Actions $actions
  387. *
  388. * @return string A wrapped actions block
  389. */
  390. public function wrapActions($actions)
  391. {
  392. // For horizontal forms, we wrap the actions in a div
  393. if ($this->app['former.form']->isOfType('horizontal')) {
  394. return Element::create('div', $actions)->addClass(array($this->fieldOffset, $this->fieldWidth));
  395. }
  396. return $actions;
  397. }
  398. }