Completed
Push — master ( f39c4d...b2e354 )
by Sam
03:35 queued 03:17
created

FieldGroup::getMessageCast()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Forms;
4
5
use InvalidArgumentException;
6
use SilverStripe\ORM\ValidationResult;
7
8
/**
9
 * Lets you include a nested group of fields inside a template.
10
 * This control gives you more flexibility over form layout.
11
 *
12
 * Note: the child fields within a field group aren't rendered using FieldHolder().  Instead,
13
 * SmallFieldHolder() is called, which just prefixes $Field with a <label> tag, if the Title is set.
14
 *
15
 * <b>Usage</b>
16
 *
17
 * <code>
18
 * FieldGroup::create(
19
 *  FieldGroup::create(
20
 *      HeaderField::create('FieldGroup 1'),
21
 *      TextField::create('Firstname')
22
 *  ),
23
 *  FieldGroup::create(
24
 *      HeaderField::create('FieldGroup 2'),
25
 *      TextField::create('Surname')
26
 *  )
27
 * )
28
 * </code>
29
 *
30
 * <b>Adding to existing FieldGroup instances</b>
31
 *
32
 * <code>
33
 * function getCMSFields() {
34
 *  $fields = parent::getCMSFields();
35
 *
36
 *  $fields->addFieldToTab(
37
 *      'Root.Main',
38
 *      FieldGroup::create(
39
 *          TimeField::create("StartTime","What's the start time?"),
40
 *          TimeField::create("EndTime","What's the end time?")
41
 *      ),
42
 *      'Content'
43
 *  );
44
 *
45
 *  return $fields;
46
 *
47
 * }
48
 * </code>
49
 *
50
 * <b>Setting a title to a FieldGroup</b>
51
 *
52
 * <code>
53
 * $fields->addFieldToTab("Root.Main",
54
 *      FieldGroup::create(
55
 *          TimeField::create('StartTime','What's the start time?'),
56
 *          TimeField::create('EndTime', 'What's the end time?')
57
 *      )->setTitle('Time')
58
 * );
59
 * </code>
60
 */
61
class FieldGroup extends CompositeField
62
{
63
64
    protected $zebra;
65
66
    /**
67
     * Create a new field group.
68
     *
69
     * Accepts any number of arguments.
70
     *
71
     * @param mixed $titleOrField Either the field title, list of fields, or first field
72
     * @param mixed ...$otherFields Subsequent fields or field list (if passing in title to $titleOrField)
73
     */
74
    public function __construct($titleOrField = null, $otherFields = null)
75
    {
76
        $title = null;
77
        if (is_array($titleOrField) || $titleOrField instanceof FieldList) {
78
            $fields = $titleOrField;
79
80
            // This would be discarded otherwise
81
            if ($otherFields) {
82
                throw new InvalidArgumentException(
83
                    '$otherFields is not accepted if passing in field list to $titleOrField'
84
                );
85
            }
86
        } elseif (is_array($otherFields) || $otherFields instanceof FieldList) {
87
            $title = $titleOrField;
88
            $fields = $otherFields;
89
        } else {
90
            $fields = func_get_args();
91
            if (!is_object(reset($fields))) {
92
                $title = array_shift($fields);
93
            }
94
        }
95
96
        parent::__construct($fields);
97
98
        if ($title) {
99
            $this->setTitle($title);
100
        }
101
    }
102
103
    /**
104
     * Returns the name (ID) for the element.
105
     * In some cases the FieldGroup doesn't have a title, but we still want
106
     * the ID / name to be set. This code, generates the ID from the nested children
107
     *
108
     * TODO this is temporary, and should be removed when FormTemplateHelper is updated to handle ID
109
     *  for CompositeFields with no name
110
     */
111
    public function getName()
112
    {
113
        if ($this->name) {
114
            return $this->name;
115
        }
116
117
        if (!$this->title) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->title of type null|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
118
            return parent::getName();
119
        }
120
121
        return preg_replace("/[^a-zA-Z0-9]+/", "", $this->title);
122
    }
123
124
    /**
125
     * Set an odd/even class
126
     *
127
     * @param string $zebra one of odd or even.
128
     * @return $this
129
     */
130
    public function setZebra($zebra)
131
    {
132
        if ($zebra == 'odd' || $zebra == 'even') {
133
            $this->zebra = $zebra;
134
        } else {
135
            user_error("setZebra passed '$zebra'.  It should be passed 'odd' or 'even'", E_USER_WARNING);
136
        }
137
        return $this;
138
    }
139
140
    /**
141
     * @return string
142
     */
143
    public function getZebra()
144
    {
145
        return $this->zebra;
146
    }
147
148
    /**
149
     * @return string
150
     */
151
    public function getMessage()
152
    {
153
        $dataFields = array();
154
        $this->collateDataFields($dataFields);
155
156
        /** @var FormField $subfield */
157
        $messages = [];
158
        foreach ($dataFields as $subfield) {
159
            $message = $subfield->obj('Message')->forTemplate();
160
            if ($message) {
161
                $messages[] = rtrim($message, ".");
162
            }
163
        }
164
165
        if (!$messages) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $messages of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
166
            return null;
167
        }
168
169
        return implode(", ", $messages) . ".";
170
    }
171
172
    /**
173
     * @return string
174
     */
175
    public function getMessageType()
176
    {
177
        $dataFields = array();
178
        $this->collateDataFields($dataFields);
179
180
        /** @var FormField $subfield */
181
        foreach ($dataFields as $subfield) {
182
            $type = $subfield->getMessageType();
183
            if ($type) {
184
                return $type;
185
            }
186
        }
187
188
        return null;
189
    }
190
191
    public function getMessageCast()
192
    {
193
        return ValidationResult::CAST_HTML;
194
    }
195
}
196