Passed
Pull Request — master (#4)
by Vincent
05:10
created

FormView::value()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Bdf\Form\Aggregate\View;
4
5
use Bdf\Form\Aggregate\Form;
6
use Bdf\Form\Aggregate\FormInterface;
7
use Bdf\Form\Button\View\ButtonViewInterface;
8
use Bdf\Form\View\ElementViewInterface;
9
use Bdf\Form\View\ElementViewTrait;
10
use Bdf\Form\View\FieldSetViewInterface;
11
use Bdf\Form\View\FieldSetViewTrait;
12
use Bdf\Form\View\FieldViewInterface;
13
use IteratorAggregate;
14
15
/**
16
 * View for a form element
17
 * Works for root and embedded forms
18
 *
19
 * <code>
20
 *  <div><?php echo $form['foo']; ?></div>
21
 *  <div><?php echo $form['bar']; ?></div>
22
 *  <fieldset>
23
 *      <div><?php echo $form['embedded']['a']; ?></div>
24
 *      <div><?php echo $form['embedded']['b']; ?></div>
25
 *  </fieldset>
26
 *  <?php echo $form->button('btn'); ?>
27
 *  <!-- Array access works also for buttons -->
28
 *  <?php echo $form['btn']; ?>
29
 * </code>
30
 *
31
 * @see Form::view()
32
 */
33
final class FormView implements IteratorAggregate, FieldSetViewInterface
34
{
35
    use ElementViewTrait;
36
    use FieldSetViewTrait {
37
        FieldSetViewTrait::hasError insteadof ElementViewTrait;
38
    }
39
40
    /**
41
     * @var ButtonViewInterface[]
42
     */
43
    private $buttons = [];
44
45
    /**
46
     * FormView constructor.
47
     *
48
     * @param string $type
49
     * @param string|null $error
50
     * @param ElementViewInterface[] $elements
51
     */
52 19
    public function __construct(string $type, ?string $error, array $elements)
53
    {
54 19
        $this->type = $type;
55 19
        $this->error = $error;
56 19
        $this->elements = $elements;
57 19
    }
58
59
    /**
60
     * {@inheritdoc}
61
     *
62
     * @return ElementViewInterface|ButtonViewInterface
63
     */
64
    #[\ReturnTypeWillChange]
65 11
    public function offsetGet($offset)
66
    {
67 11
        return $this->elements[$offset] ?? $this->buttons[$offset];
68
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73 4
    public function offsetExists($offset): bool
74
    {
75 4
        return isset($this->elements[$offset]) || isset($this->buttons[$offset]);
76
    }
77
78
    /**
79
     * Get all available buttons
80
     *
81
     * <code>
82
     *  <div class="form-footer">
83
     *      <?php foreach ($view->buttons() as $button): ?>
84
     *          <?php echo $button->class('btn btn-default'); ?>
85
     *      <?php endforeach; ?>
86
     *  </div>
87
     * </code>
88
     *
89
     * @return ButtonViewInterface[]
90
     */
91 1
    public function buttons(): array
92
    {
93 1
        return $this->buttons;
94
    }
95
96
    /**
97
     * Get a button by its name
98
     *
99
     * <code>
100
     * echo $form->button('btn')->inner('Save')->class('btn btn-primary');
101
     * </code>
102
     *
103
     * @param string $name The button name
104
     *
105
     * @return ButtonViewInterface|null
106
     * @see ButtonViewInterface::name()
107
     */
108 1
    public function button(string $name): ?ButtonViewInterface
109
    {
110 1
        return $this->buttons[$name] ?? null;
111
    }
112
113
    /**
114
     * Get HTTP fields and values for all inputs
115
     *
116
     * @return array<string, mixed>
117
     * @see FormInterface::httpValue() This value should be same as calling this method
118
     */
119 1
    public function value(): array
120
    {
121 1
        return self::extractValue($this);
122
    }
123
124
    /**
125
     * Change the form type
126
     * Used internally by CustomForm
127
     *
128
     * @param string $type The form class name
129
     * @internal
130
     */
131 4
    public function setType(string $type): void
132
    {
133 4
        $this->type = $type;
134 4
    }
135
136
    /**
137
     * Set form buttons
138
     *
139
     * @param ButtonViewInterface[] $buttons
140
     * @internal
141
     */
142 6
    public function setButtons(array $buttons): void
143
    {
144 6
        $this->buttons = $buttons;
145 6
    }
146
147 1
    private static function extractValue(FieldSetViewInterface $aggregate): array
148
    {
149 1
        $values = [];
150
151 1
        foreach ($aggregate as $child) {
152 1
            if ($child instanceof FieldViewInterface) {
153 1
                $values[$child->name()] = $child->value();
154 1
            } elseif ($child instanceof FieldSetViewInterface) {
155 1
                $values += self::extractValue($child);
156
            }
157
        }
158
159 1
        return $values;
160
    }
161
}
162