Completed
Push — master ( 955d75...4d8fb1 )
by Ingo
36:25 queued 24:15
created

FieldGroup::setZebra()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 5
rs 9.4285
1
<?php
2
3
namespace SilverStripe\Forms;
4
5
use InvalidArgumentException;
6
7
/**
8
 * Lets you include a nested group of fields inside a template.
9
 * This control gives you more flexibility over form layout.
10
 *
11
 * Note: the child fields within a field group aren't rendered using FieldHolder().  Instead,
12
 * SmallFieldHolder() is called, which just prefixes $Field with a <label> tag, if the Title is set.
13
 *
14
 * <b>Usage</b>
15
 *
16
 * <code>
17
 * FieldGroup::create(
18
 * 	FieldGroup::create(
19
 * 		HeaderField::create('FieldGroup 1'),
20
 * 		TextField::create('Firstname')
21
 * 	),
22
 * 	FieldGroup::create(
23
 * 		HeaderField::create('FieldGroup 2'),
24
 * 		TextField::create('Surname')
25
 * 	)
26
 * )
27
 * </code>
28
 *
29
 * <b>Adding to existing FieldGroup instances</b>
30
 *
31
 * <code>
32
 * function getCMSFields() {
33
 * 	$fields = parent::getCMSFields();
34
 *
35
 * 	$fields->addFieldToTab(
36
 * 		'Root.Main',
37
 * 		FieldGroup::create(
38
 * 			TimeField::create("StartTime","What's the start time?"),
39
 * 			TimeField::create("EndTime","What's the end time?")
40
 * 		),
41
 * 		'Content'
42
 * 	);
43
 *
44
 * 	return $fields;
45
 *
46
 * }
47
 * </code>
48
 *
49
 * <b>Setting a title to a FieldGroup</b>
50
 *
51
 * <code>
52
 * $fields->addFieldToTab("Root.Main",
53
 * 		FieldGroup::create(
54
 * 			TimeField::create('StartTime','What's the start time?'),
55
 * 			TimeField::create('EndTime', 'What's the end time?')
56
 * 		)->setTitle('Time')
57
 * );
58
 * </code>
59
 */
60
class FieldGroup extends CompositeField {
61
62
	protected $zebra;
63
64
	/**
65
	 * Create a new field group.
66
	 *
67
	 * Accepts any number of arguments.
68
	 *
69
	 * @param mixed $titleOrField Either the field title, list of fields, or first field
70
	 * @param mixed ...$otherFields Subsequent fields or field list (if passing in title to $titleOrField)
71
	 */
72
	public function __construct($titleOrField = null, $otherFields = null) {
73
		$title = null;
74
		if(is_array($titleOrField) || $titleOrField instanceof FieldList) {
75
			$fields = $titleOrField;
76
77
			// This would be discarded otherwise
78
			if($otherFields) {
79
				throw new InvalidArgumentException(
80
					'$otherFields is not accepted if passing in field list to $titleOrField'
81
				);
82
			}
83
84
		} else if(is_array($otherFields) || $otherFields instanceof FieldList) {
85
			$title = $titleOrField;
86
			$fields = $otherFields;
87
88
		} else {
89
			$fields = func_get_args();
90
			if(!is_object(reset($fields))) {
91
				$title = array_shift($fields);
92
			}
93
		}
94
95
		parent::__construct($fields);
96
97
		if($title) {
98
			$this->setTitle($title);
99
		}
100
	}
101
102
	/**
103
	 * Returns the name (ID) for the element.
104
	 * In some cases the FieldGroup doesn't have a title, but we still want
105
	 * the ID / name to be set. This code, generates the ID from the nested children
106
	 *
107
	 * TODO this is temporary, and should be removed when FormTemplateHelper is updated to handle ID
108
	 *  for CompositeFields with no name
109
	 */
110
	public function getName(){
111
		if($this->name) {
112
			return $this->name;
113
		}
114
115
		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...
116
			return parent::getName();
117
		}
118
119
		return preg_replace("/[^a-zA-Z0-9]+/", "", $this->title);
120
	}
121
122
	/**
123
	 * Set an odd/even class
124
	 *
125
	 * @param string $zebra one of odd or even.
126
	 * @return $this
127
	 */
128
	public function setZebra($zebra) {
129
		if($zebra == 'odd' || $zebra == 'even') $this->zebra = $zebra;
130
		else user_error("setZebra passed '$zebra'.  It should be passed 'odd' or 'even'", E_USER_WARNING);
131
		return $this;
132
	}
133
134
	/**
135
	 * @return string
136
	 */
137
	public function getZebra() {
138
		return $this->zebra;
139
	}
140
141
	/**
142
	 * @return string
143
	 */
144
	public function Message() {
145
		$fs = array();
146
		$this->collateDataFields($fs);
147
148
		foreach($fs as $subfield) {
149
			if($m = $subfield->Message()) $message[] = rtrim($m, ".");
0 ignored issues
show
Coding Style Comprehensibility introduced by
$message was never initialized. Although not strictly required by PHP, it is generally a good practice to add $message = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
150
		}
151
152
		return (isset($message)) ? implode(",  ", $message) . "." : "";
153
	}
154
155
	/**
156
	 * @return string
157
	 */
158
	public function MessageType() {
159
		$fs = array();
160
		$this->collateDataFields($fs);
161
162
		foreach($fs as $subfield) {
163
			if($m = $subfield->MessageType()) $MessageType[] = $m;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$MessageType was never initialized. Although not strictly required by PHP, it is generally a good practice to add $MessageType = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
164
		}
165
166
		return (isset($MessageType)) ? implode(".  ", $MessageType) : "";
167
	}
168
}
169