Overview

Namespaces

  • Charcoal
    • Ui
      • Dashboard
      • Form
      • FormGroup
      • FormInput
      • Layout
      • Menu
      • MenuItem
      • ServiceProvider

Classes

  • Charcoal\Ui\AbstractUiItem
  • Charcoal\Ui\Dashboard\AbstractDashboard
  • Charcoal\Ui\Dashboard\DashboardBuilder
  • Charcoal\Ui\Dashboard\DashboardConfig
  • Charcoal\Ui\Dashboard\FormInputConfig
  • Charcoal\Ui\Dashboard\GenericDashboard
  • Charcoal\Ui\Form\AbstractForm
  • Charcoal\Ui\Form\FormBuilder
  • Charcoal\Ui\Form\FormConfig
  • Charcoal\Ui\Form\GenericForm
  • Charcoal\Ui\FormGroup\AbstractFormGroup
  • Charcoal\Ui\FormGroup\FormGroupConfig
  • Charcoal\Ui\FormGroup\GenericFormGroup
  • Charcoal\Ui\FormInput\AbstractFormInput
  • Charcoal\Ui\FormInput\FormInputBuilder
  • Charcoal\Ui\FormInput\GenericFormInput
  • Charcoal\Ui\Layout\AbstractLayout
  • Charcoal\Ui\Layout\GenericLayout
  • Charcoal\Ui\Layout\LayoutBuilder
  • Charcoal\Ui\Layout\LayoutConfig
  • Charcoal\Ui\Layout\LayoutFactory
  • Charcoal\Ui\Menu\AbstractMenu
  • Charcoal\Ui\Menu\GenericMenu
  • Charcoal\Ui\Menu\MenuBuilder
  • Charcoal\Ui\Menu\MenuConfig
  • Charcoal\Ui\Menu\MenuFactory
  • Charcoal\Ui\MenuItem\AbstractMenuItem
  • Charcoal\Ui\MenuItem\GenericMenuItem
  • Charcoal\Ui\MenuItem\MenuItemBuilder
  • Charcoal\Ui\MenuItem\MenuItemConfig
  • Charcoal\Ui\MenuItem\MenuItemFactory
  • Charcoal\Ui\ServiceProvider\DashboardServiceProvider
  • Charcoal\Ui\ServiceProvider\FormServiceProvider
  • Charcoal\Ui\ServiceProvider\LayoutServiceProvider
  • Charcoal\Ui\ServiceProvider\MenuServiceProvider
  • Charcoal\Ui\ServiceProvider\UiServiceProvider
  • Charcoal\Ui\UiItemConfig

Interfaces

  • Charcoal\Ui\Dashboard\DashboardInterface
  • Charcoal\Ui\Form\FormInterface
  • Charcoal\Ui\FormGroup\FormGroupInterface
  • Charcoal\Ui\FormInput\FormInputInterface
  • Charcoal\Ui\Layout\LayoutAwareInterface
  • Charcoal\Ui\Layout\LayoutInterface
  • Charcoal\Ui\Menu\MenuInterface
  • Charcoal\Ui\MenuItem\MenuItemInterface
  • Charcoal\Ui\UiGroupingInterface
  • Charcoal\Ui\UiItemInterface

Traits

  • Charcoal\Ui\Dashboard\DashboardTrait
  • Charcoal\Ui\Form\FormTrait
  • Charcoal\Ui\FormGroup\FormGroupTrait
  • Charcoal\Ui\Layout\LayoutAwareTrait
  • Charcoal\Ui\Layout\LayoutTrait
  • Charcoal\Ui\UiGroupingTrait
  • Charcoal\Ui\UiItemTrait
  • Overview
  • Namespace
  • Class
  1: <?php
  2: 
  3: namespace Charcoal\Ui\Form;
  4: 
  5: use \Exception;
  6: use \InvalidArgumentException;
  7: 
  8: // From 'charcoal-factory'
  9: use \Charcoal\Factory\FactoryInterface;
 10: 
 11: // From 'charcoal-ui'
 12: use \Charcoal\Ui\Form\FormInterface;
 13: use \Charcoal\Ui\FormGroup\FormGroupInterface;
 14: 
 15: /**
 16:  * Provides an implementation of {@see FormInterface}.
 17:  */
 18: trait FormTrait
 19: {
 20:     /**
 21:      * The URI of a program that processes the form information.
 22:      *
 23:      * @var string
 24:      */
 25:     private $action = '';
 26: 
 27:     /**
 28:      * The HTTP method that the browser uses to submit the form.
 29:      *
 30:      * @var string
 31:      */
 32:     private $method = 'post';
 33: 
 34:     /**
 35:      * The form's display mode for multilingual fields.
 36:      *
 37:      * @var string
 38:      */
 39:     private $l10nMode = 'loop_inputs';
 40: 
 41:     /**
 42:      * The form's display mode for groups.
 43:      *
 44:      * @var string
 45:      */
 46:     protected $groupDisplayMode;
 47: 
 48:     /**
 49:      * The form's field groups.
 50:      *
 51:      * @var FormGroupInterface[]
 52:      */
 53:     protected $groups = [];
 54: 
 55:     /**
 56:      * The form's predefined data.
 57:      *
 58:      * @var array $formData
 59:      */
 60:     private $formData = [];
 61: 
 62:     /**
 63:      * Store the form's metadata instance.
 64:      *
 65:      * @var MetadataInterface
 66:      */
 67:     private $metadata;
 68: 
 69:     /**
 70:      * Store the form's group factory instance.
 71:      *
 72:      * @var FactoryInterface
 73:      */
 74:     protected $formGroupFactory;
 75: 
 76:     /**
 77:      * Store the form's group callback.
 78:      *
 79:      * @var callable
 80:      */
 81:     private $groupCallback;
 82: 
 83:     /**
 84:      * @param FactoryInterface $factory A factory, to create customized form gorup objects.
 85:      * @return FormInterface Chainable
 86:      */
 87:     public function setFormGroupFactory(FactoryInterface $factory)
 88:     {
 89:         $this->formGroupFactory = $factory;
 90: 
 91:         return $this;
 92:     }
 93: 
 94:     /**
 95:      * @throws Exception If the form group factory object was not set / injected.
 96:      * @return FormInterface Chainable
 97:      */
 98:     protected function formGroupFactory()
 99:     {
100:         if ($this->formGroupFactory === null) {
101:             throw new Exception(
102:                 'Form group factory was not set.'
103:             );
104:         }
105: 
106:         return $this->formGroupFactory;
107:     }
108: 
109:     /**
110:      * @param callable $cb The group callback.
111:      * @return FormInterface Chainable
112:      */
113:     public function setGroupCallback(callable $cb)
114:     {
115:         $this->groupCallback = $cb;
116: 
117:         return $this;
118:     }
119: 
120:     /**
121:      * @param string $action The "action" value, typically a URL.
122:      * @throws InvalidArgumentException If the action argument is not a string.
123:      * @return FormInterface Chainable
124:      */
125:     public function setAction($action)
126:     {
127:         if (!is_string($action)) {
128:             throw new InvalidArgumentException(
129:                 'Action must be a string'
130:             );
131:         }
132:         $this->action = $action;
133: 
134:         return $this;
135:     }
136: 
137:     /**
138:      * @return string
139:      */
140:     public function action()
141:     {
142:         return $this->action;
143:     }
144: 
145:     /**
146:      * Set the method (forcing lowercase) to "post" or "get".
147:      *
148:      * @param string $method Either "post" or "get".
149:      * @throws InvalidArgumentException If the method is not post or get.
150:      * @return FormInterface Chainable
151:      */
152:     public function setMethod($method)
153:     {
154:         $method = strtolower($method);
155:         if (!in_array($method, ['post', 'get'])) {
156:             throw new InvalidArgumentException(
157:                 'Method must be "post" or "get"'
158:             );
159:         }
160:         $this->method = $method;
161: 
162:         return $this;
163:     }
164: 
165:     /**
166:      * @return string Either "post" or "get".
167:      */
168:     public function method()
169:     {
170:         return $this->method;
171:     }
172: 
173:     /**
174:      * @param string $mode The l10n mode.
175:      * @return FormInterface Chainable
176:      */
177:     public function setL10nMode($mode)
178:     {
179:         $this->l10nMode = $mode;
180: 
181:         return $this;
182:     }
183: 
184:     /**
185:      * @return string
186:      */
187:     public function l10nMode()
188:     {
189:         return $this->l10nMode;
190:     }
191: 
192:     /**
193:      * Set the object's form groups.
194:      *
195:      * @param array $groups A collection of group structures.
196:      * @return FormInterface Chainable
197:      */
198:     public function setGroups(array $groups)
199:     {
200:         $this->groups = [];
201: 
202:         foreach ($groups as $groupIdent => $group) {
203:             $this->addGroup($groupIdent, $group);
204:         }
205: 
206:         return $this;
207:     }
208: 
209:     /**
210:      * Add a form group.
211:      *
212:      * @param  string                   $groupIdent The group identifier.
213:      * @param  array|FormGroupInterface $group      The group object or structure.
214:      * @throws InvalidArgumentException If the identifier is not a string or the group is invalid.
215:      * @return FormInterface Chainable
216:      */
217:     public function addGroup($groupIdent, $group)
218:     {
219:         if ($group === false || $group === null) {
220:             return $this;
221:         }
222: 
223:         if (!is_string($groupIdent)) {
224:             throw new InvalidArgumentException(
225:                 'Group identifier must be a string'
226:             );
227:         }
228: 
229:         if ($group instanceof FormGroupInterface) {
230:             $group = $this->updateFormGroup($group, null, $groupIdent);
231:         } elseif (is_array($group)) {
232:             $data = $group;
233: 
234:             if (isset($data['ident'])) {
235:                 $groupIdent = $data['ident'];
236:             } else {
237:                 $data['ident'] = $groupIdent;
238:             }
239: 
240:             $group = $this->createFormGroup($data);
241:         } else {
242:             throw new InvalidArgumentException(sprintf(
243:                 'Group must be an instance of %s or an array of form group options, received %s',
244:                 'FormGroupInterface',
245:                 (is_object($group) ? get_class($group) : gettype($group))
246:             ));
247:         }
248: 
249:         $this->groups[$groupIdent] = $group;
250: 
251:         return $this;
252:     }
253: 
254:     /**
255:      * Create a new form group widget.
256:      *
257:      * @param  array|null $data Optional. The form group data to set.
258:      * @return FormGroupInterface
259:      */
260:     protected function createFormGroup(array $data = null)
261:     {
262:         if (isset($data['type'])) {
263:             $type = $data['type'];
264:         } else {
265:             $type = $this->defaultGroupType();
266:         }
267: 
268:         $group = $this->formGroupFactory()->create($type);
269:         $group->setForm($this);
270: 
271:         if ($data !== null) {
272:             $group->setData($data);
273:         }
274: 
275:         return $group;
276:     }
277: 
278:     /**
279:      * Update the given form group widget.
280:      *
281:      * @param  FormGroupInterface $group      The form group to update.
282:      * @param  array|null         $groupData  Optional. The new group data to apply.
283:      * @param  string|null        $groupIdent Optional. The new group identifier.
284:      * @return FormGroupInterface
285:      */
286:     protected function updateFormGroup(
287:         FormGroupInterface $group,
288:         array $groupData = null,
289:         $groupIdent = null
290:     ) {
291:         $group->setForm($this);
292: 
293:         if ($groupData !== null) {
294:             $group->setData($groupData);
295:         }
296: 
297:         if ($groupIdent !== null) {
298:             $group->setIdent($groupIdent);
299:         }
300: 
301:         return $group;
302:     }
303: 
304:     /**
305:      * Retrieve the default form group class name.
306:      *
307:      * @return string
308:      */
309:     public function defaultGroupType()
310:     {
311:         return 'charcoal/ui/form-group/generic';
312:     }
313: 
314:     /**
315:      * Retrieve the form groups.
316:      *
317:      * @param callable $groupCallback Optional callback applied to each form group.
318:      * @return FormGroupInterface[]|Generator
319:      */
320:     public function groups(callable $groupCallback = null)
321:     {
322:         $groups = $this->groups;
323:         uasort($groups, [$this, 'sortGroupsByPriority']);
324: 
325:         $groupCallback = (isset($groupCallback) ? $groupCallback : $this->groupCallback);
326: 
327:         $i = 1;
328:         foreach ($groups as $group) {
329:             if (!$group->active()) {
330:                 continue;
331:             }
332: 
333:             // Test formGroup vs. ACL roles
334:             if ($group->isAuthorized() === false) {
335:                 continue;
336:             }
337: 
338:             if (!$group->l10nMode()) {
339:                 $group->setL10nMode($this->l10nMode());
340:             }
341: 
342:             if ($groupCallback) {
343:                 $groupCallback($group);
344:             }
345: 
346:             $GLOBALS['widget_template'] = $group->template();
347: 
348:             if ($this->isTabbable() && $i > 1) {
349:                 $group->isHidden = true;
350:             }
351:             $i++;
352: 
353:             yield $group;
354: 
355:             $GLOBALS['widget_template'] = '';
356:         }
357:     }
358: 
359:     /**
360:      * Determine if the form has any groups.
361:      *
362:      * @return boolean
363:      */
364:     public function hasGroups()
365:     {
366:         return (count($this->groups) > 0);
367:     }
368: 
369:     /**
370:      * Determine if the form has a given group.
371:      *
372:      * @param string $groupIdent The group identifier to look up.
373:      * @throws InvalidArgumentException If the group identifier is invalid.
374:      * @return boolean
375:      */
376:     public function hasGroup($groupIdent)
377:     {
378:         if (!is_string($groupIdent)) {
379:             throw new InvalidArgumentException(
380:                 'Group identifier must be a string'
381:             );
382:         }
383: 
384:         return isset($this->groups[$groupIdent]);
385:     }
386: 
387:     /**
388:      * Count the number of form groups.
389:      *
390:      * @return integer
391:      */
392:     public function numGroups()
393:     {
394:         return count($this->groups);
395:     }
396: 
397:     /**
398:      * Set the widget's content group display mode.
399:      *
400:      * Currently only supports "tab".
401:      *
402:      * @param string $mode Group display mode.
403:      * @throws InvalidArgumentException If the display mode is not a string.
404:      * @return ObjectFormWidget Chainable.
405:      */
406:     public function setGroupDisplayMode($mode)
407:     {
408:         if (!is_string($mode)) {
409:             throw new InvalidArgumentException(
410:                 'Display mode must be a string'
411:             );
412:         }
413: 
414:         if ($mode === 'tabs') {
415:             $mode = 'tab';
416:         }
417: 
418:         $this->groupDisplayMode = $mode;
419: 
420:         return $this;
421:     }
422: 
423:     /**
424:      * Retrieve the widget's content group display mode.
425:      *
426:      * @return string Group display mode.
427:      */
428:     public function groupDisplayMode()
429:     {
430:         return $this->groupDisplayMode;
431:     }
432: 
433:     /**
434:      * Determine if content groups are to be displayed as tabbable panes.
435:      *
436:      * @return boolean
437:      */
438:     public function isTabbable()
439:     {
440:         return ($this->groupDisplayMode() === 'tab');
441:     }
442: 
443:     /**
444:      * @param array $formData The (pre-populated) form data, as [$key=>$val] array.
445:      * @return FormInterface Chainable
446:      */
447:     public function setFormData(array $formData)
448:     {
449:         $this->formData = $formData;
450: 
451:         return $this;
452:     }
453: 
454:     /**
455:      * @param string $key The form data key, or poperty identifier.
456:      * @param mixed  $val The form data value, for a given key.
457:      * @throws InvalidArgumentException If the key argument is not a string.
458:      * @return FormInterface Chainable
459:      */
460:     public function addFormData($key, $val)
461:     {
462:         if (!is_string($key)) {
463:             throw new InvalidArgumentException(
464:                 'Can not add form data: Data key must be a string'
465:             );
466:         }
467:         $this->formData[$key] = $val;
468: 
469:         return $this;
470:     }
471: 
472:     /**
473:      * @return array
474:      */
475:     public function formData()
476:     {
477:         return $this->formData;
478:     }
479: 
480:     /**
481:      * Static comparison function used by {@see uasort()}.
482:      *
483:      * @param  FormGroupInterface $a Form Group A.
484:      * @param  FormGroupInterface $b Form Group B.
485:      * @return integer Sorting value: -1 or 1
486:      */
487:     protected static function sortGroupsByPriority(
488:         FormGroupInterface $a,
489:         FormGroupInterface $b
490:     ) {
491:         $a = $a->priority();
492:         $b = $b->priority();
493: 
494:         return ($a < $b) ? (-1) : 1;
495:     }
496: }
497: 
API documentation generated by ApiGen