Passed
Push — fix-start-session-without-head... ( b5847f...1b2c5b )
by Sam
08:40 queued 03:56
created

TabSet::getSchemaStateDefaults()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Forms;
4
5
use SilverStripe\Core\Convert;
6
use SilverStripe\ORM\FieldType\DBHTMLText;
7
use SilverStripe\View\Requirements;
8
use InvalidArgumentException;
9
10
/**
11
 * Defines a set of tabs in a form.
12
 * The tabs are build with our standard tabstrip javascript library.
13
 * By default, the HTML is generated using FieldHolder.
14
 *
15
 * <b>Usage</b>
16
 *
17
 * <code>
18
 * new TabSet(
19
 *  $name = "TheTabSetName",
20
 *  new Tab(
21
 *      $title='Tab one',
22
 *      new HeaderField("A header"),
23
 *      new LiteralField("Lipsum","Lorem ipsum dolor sit amet enim.")
24
 *  ),
25
 *  new Tab(
26
 *      $title='Tab two',
27
 *      new HeaderField("A second header"),
28
 *      new LiteralField("Lipsum","Ipsum dolor sit amet enim.")
29
 *  )
30
 * )
31
 * </code>
32
 *
33
 * Caution: The form field does not include any JavaScript or CSS when used outside of the CMS context,
34
 * since the required frontend dependencies are included through CMS bundling.
35
 */
36
class TabSet extends CompositeField
37
{
38
39
    /**
40
     * Use custom react component
41
     *
42
     * @var string
43
     */
44
    protected $schemaComponent = 'Tabs';
45
46
    /**
47
     * @var TabSet
48
     */
49
    protected $tabSet;
50
51
    /**
52
     * @var string
53
     */
54
    protected $id;
55
56
    /**
57
     * @param string $name Identifier
58
     * @param string|Tab|TabSet $titleOrTab Natural language title of the tabset, or first tab.
59
     * If its left out, the class uses {@link FormField::name_to_label()} to produce a title
60
     * from the {@link $name} parameter.
61
     * @param Tab|TabSet ...$tabs All further parameters are inserted as children into the TabSet
62
     */
63
    public function __construct($name, $titleOrTab = null, $tabs = null)
64
    {
65
        if (!is_string($name)) {
66
            throw new InvalidArgumentException('Invalid string parameter for $name');
67
        }
68
69
        // Get following arguments
70
        $tabs = func_get_args();
71
        array_shift($tabs);
72
73
        // Detect title from second argument, if it is a string
74
        if ($titleOrTab && is_string($titleOrTab)) {
75
            $title = $titleOrTab;
76
            array_shift($tabs);
77
        } else {
78
            $title = static::name_to_label($name);
79
        }
80
81
        // Normalise children list
82
        if (count($tabs) === 1 && (is_array($tabs[0]) || $tabs[0] instanceof FieldList)) {
83
            $tabs = $tabs[0];
84
        }
85
86
        // Ensure tabs are assigned to this tabset
87
        if ($tabs) {
88
            foreach ($tabs as $tab) {
89
                if ($tab instanceof Tab || $tab instanceof TabSet) {
90
                    $tab->setTabSet($this);
91
                } else {
92
                    throw new InvalidArgumentException("TabSet can only contain instances of other Tab or Tabsets");
93
                }
94
            }
95
        }
96
97
        parent::__construct($tabs);
98
99
        // Assign name and title (not assigned by parent constructor)
100
        $this->setName($name);
101
        $this->setTitle($title);
102
        $this->setID(Convert::raw2htmlid($name));
103
    }
104
105
    public function ID()
106
    {
107
        if ($this->tabSet) {
108
            return $this->tabSet->ID() . '_' . $this->id . '_set';
109
        } else {
110
            return $this->id;
111
        }
112
    }
113
114
    /**
115
     * Set custom HTML ID to use for this tabset
116
     *
117
     * @param string $id
118
     * @return $this
119
     */
120
    public function setID($id)
121
    {
122
        $this->id = $id;
123
        return $this;
124
    }
125
126
    /**
127
     * Returns a tab-strip and the associated tabs.
128
     * The HTML is a standardised format, containing a &lt;ul;
129
     *
130
     * @param array $properties
131
     * @return DBHTMLText|string
132
     */
133
    public function FieldHolder($properties = array())
134
    {
135
        $obj = $properties ? $this->customise($properties) : $this;
136
137
        return $obj->renderWith($this->getTemplates());
138
    }
139
140
    /**
141
     * Return a set of all this classes tabs
142
     *
143
     * @return FieldList
144
     */
145
    public function Tabs()
146
    {
147
        return $this->children;
148
    }
149
150
    /**
151
     * @param FieldList $children Assign list of tabs
152
     */
153
    public function setTabs($children)
154
    {
155
        $this->children = $children;
156
    }
157
158
    /**
159
     * Assign to a TabSet instance
160
     *
161
     * @param TabSet $val
162
     * @return $this
163
     */
164
    public function setTabSet($val)
165
    {
166
        $this->tabSet = $val;
167
        return $this;
168
    }
169
170
    /**
171
     * Get parent tabset
172
     *
173
     * @return TabSet
174
     */
175
    public function getTabSet()
176
    {
177
        return $this->tabSet;
178
    }
179
180
    public function getAttributes()
181
    {
182
        return array_merge(
183
            $this->attributes,
184
            array(
185
                'id' => $this->ID(),
186
                'class' => $this->extraClass()
187
            )
188
        );
189
    }
190
191
    /**
192
     * Add a new child field to the end of the set.
193
     *
194
     * @param FormField $field
195
     */
196
    public function push(FormField $field)
197
    {
198
        if ($field instanceof Tab || $field instanceof TabSet) {
199
            $field->setTabSet($this);
200
        }
201
        parent::push($field);
202
    }
203
204
    /**
205
     * Add a new child field to the beginning of the set.
206
     *
207
     * @param FormField $field
208
     */
209
    public function unshift(FormField $field)
210
    {
211
        if ($field instanceof Tab || $field instanceof TabSet) {
212
            $field->setTabSet($this);
213
        }
214
        parent::unshift($field);
215
    }
216
217
    /**
218
     * Inserts a field before a particular field in a FieldList.
219
     *
220
     * @param string $insertBefore Name of the field to insert before
221
     * @param FormField $field The form field to insert
222
     * @return FormField|null
223
     */
224
    public function insertBefore($insertBefore, $field)
225
    {
226
        if ($field instanceof Tab || $field instanceof TabSet) {
227
            $field->setTabSet($this);
228
        }
229
        return parent::insertBefore($insertBefore, $field);
0 ignored issues
show
Bug Best Practice introduced by
The expression return parent::insertBefore($insertBefore, $field) could also return false which is incompatible with the documented return type null|SilverStripe\Forms\FormField. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
230
    }
231
232
    /**
233
     * Inserts a field after a particular field in a FieldList.
234
     *
235
     * @param string $insertAfter Name of the field to insert after
236
     * @param FormField $field The form field to insert
237
     * @return FormField|null
238
     */
239
    public function insertAfter($insertAfter, $field)
240
    {
241
        if ($field instanceof Tab || $field instanceof TabSet) {
242
            $field->setTabSet($this);
243
        }
244
        return parent::insertAfter($insertAfter, $field);
0 ignored issues
show
Bug Best Practice introduced by
The expression return parent::insertAfter($insertAfter, $field) could also return false which is incompatible with the documented return type null|SilverStripe\Forms\FormField. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
245
    }
246
247
    /**
248
     * Sets an additional default for $schemaData.
249
     * The existing keys are immutable. HideNav is added in this overriding method to ensure it is not ignored by
250
     * {@link setSchemaData()}
251
     * It allows hiding of the navigation in the Tabs.js React component.
252
     *
253
     * @return array
254
     */
255
    public function getSchemaStateDefaults()
256
    {
257
        $defaults = parent::getSchemaStateDefaults();
258
        $defaults['hideNav'] = false;
259
        return $defaults;
260
    }
261
}
262