Completed
Push — master ( d3563c...35773d )
by Christopher
15s queued 10s
created
code/StringTagField.php 1 patch
Indentation   +332 added lines, -332 removed lines patch added patch discarded remove patch
@@ -11,336 +11,336 @@
 block discarded – undo
11 11
  */
12 12
 class StringTagField extends DropdownField
13 13
 {
14
-    /**
15
-     * @var array
16
-     */
17
-    public static $allowed_actions = array(
18
-        'suggest',
19
-    );
20
-
21
-    /**
22
-     * @var bool
23
-     */
24
-    protected $shouldLazyLoad = false;
25
-
26
-    /**
27
-     * @var int
28
-     */
29
-    protected $lazyLoadItemLimit = 10;
30
-
31
-    /**
32
-     * @var null|DataObject
33
-     */
34
-    protected $record;
35
-
36
-    /**
37
-     * @var bool
38
-     */
39
-    protected $isMultiple = true;
40
-
41
-    /**
42
-     * @param string $name
43
-     * @param string $title
44
-     * @param array|SS_List $source
45
-     * @param array|SS_List $value
46
-     */
47
-    public function __construct($name, $title = '', $source = array(), $value = array())
48
-    {
49
-        parent::__construct($name, $title, $source, $value);
50
-    }
51
-
52
-    /**
53
-     * @return bool
54
-     */
55
-    public function getShouldLazyLoad()
56
-    {
57
-        return $this->shouldLazyLoad;
58
-    }
59
-
60
-    /**
61
-     * @param bool $shouldLazyLoad
62
-     *
63
-     * @return static
64
-     */
65
-    public function setShouldLazyLoad($shouldLazyLoad)
66
-    {
67
-        $this->shouldLazyLoad = $shouldLazyLoad;
68
-
69
-        return $this;
70
-    }
71
-
72
-    /**
73
-     * @return int
74
-     */
75
-    public function getLazyLoadItemLimit()
76
-    {
77
-        return $this->lazyLoadItemLimit;
78
-    }
79
-
80
-    /**
81
-     * @param int $lazyLoadItemLimit
82
-     *
83
-     * @return static
84
-     */
85
-    public function setLazyLoadItemLimit($lazyLoadItemLimit)
86
-    {
87
-        $this->lazyLoadItemLimit = $lazyLoadItemLimit;
88
-
89
-        return $this;
90
-    }
91
-
92
-    /**
93
-     * @return bool
94
-     */
95
-    public function getIsMultiple()
96
-    {
97
-        return $this->isMultiple;
98
-    }
99
-
100
-    /**
101
-     * @param bool $isMultiple
102
-     *
103
-     * @return static
104
-     */
105
-    public function setIsMultiple($isMultiple)
106
-    {
107
-        $this->isMultiple = $isMultiple;
108
-
109
-        return $this;
110
-    }
111
-
112
-    /**
113
-     * @return null|DataObject
114
-     */
115
-    public function getRecord()
116
-    {
117
-        if ($this->record) {
118
-            return $this->record;
119
-        }
120
-
121
-        if ($form = $this->getForm()) {
122
-            return $form->getRecord();
123
-        }
124
-
125
-        return null;
126
-    }
127
-
128
-    /**
129
-     * @param DataObject $record
130
-     *
131
-     * @return $this
132
-     */
133
-    public function setRecord(DataObject $record)
134
-    {
135
-        $this->record = $record;
136
-
137
-        return $this;
138
-    }
139
-
140
-    /**
141
-     * {@inheritdoc}
142
-     */
143
-    public function Field($properties = array())
144
-    {
145
-        Requirements::css(TAG_FIELD_DIR . '/css/select2.min.css');
146
-        Requirements::css(TAG_FIELD_DIR . '/css/TagField.css');
147
-
148
-        Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
149
-        Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js');
150
-        Requirements::javascript(TAG_FIELD_DIR . '/js/select2.js');
151
-        Requirements::javascript(TAG_FIELD_DIR . '/js/TagField.js');
152
-
153
-        $this->addExtraClass('ss-tag-field');
154
-
155
-        if ($this->getIsMultiple()) {
156
-            $this->setAttribute('multiple', 'multiple');
157
-        }
158
-
159
-        if ($this->getShouldLazyLoad()) {
160
-            $this->setAttribute('data-ss-tag-field-suggest-url', $this->getSuggestURL());
161
-        } else {
162
-            $properties = array_merge($properties, array(
163
-                'Options' => $this->getOptions()
164
-            ));
165
-        }
166
-
167
-        $this->setAttribute('data-can-create', (int) $this->getCanCreate());
168
-
169
-        return $this
170
-            ->customise($properties)
171
-            ->renderWith(array("templates/TagField"));
172
-    }
173
-
174
-    /**
175
-     * @return string
176
-     */
177
-    protected function getSuggestURL()
178
-    {
179
-        return Controller::join_links($this->Link(), 'suggest');
180
-    }
181
-
182
-    /**
183
-     * @return ArrayList
184
-     */
185
-    protected function getOptions()
186
-    {
187
-        $options = ArrayList::create();
188
-
189
-        $source = $this->getSource();
190
-
191
-        if ($source instanceof Iterator) {
192
-            $source = iterator_to_array($source);
193
-        }
194
-
195
-        $values = $this->Value();
196
-
197
-        foreach ($source as $value) {
198
-            $options->push(
199
-                ArrayData::create(array(
200
-                    'Title' => $value,
201
-                    'Value' => $value,
202
-                    'Selected' => in_array($value, $values),
203
-                ))
204
-            );
205
-        }
206
-
207
-        return $options;
208
-    }
209
-
210
-    /**
211
-     * {@inheritdoc}
212
-     */
213
-    public function setValue($value, $source = null)
214
-    {
215
-        if (is_string($value)) {
216
-            $value = explode(',', $value);
217
-        }
218
-
219
-        if ($source instanceof DataObject) {
220
-            $name = $this->getName();
221
-            $value = explode(',', $source->$name);
222
-        }
223
-
224
-        if ($source instanceof SS_List) {
225
-            $value = $source->column('ID');
226
-        }
227
-
228
-        if (is_null($value)) {
229
-            $value = array();
230
-        }
231
-
232
-        return parent::setValue(array_filter($value));
233
-    }
234
-
235
-    /**
236
-     * {@inheritdoc}
237
-     */
238
-    public function getAttributes()
239
-    {
240
-        return array_merge(
241
-            parent::getAttributes(),
242
-            array('name' => $this->getName() . '[]')
243
-        );
244
-    }
245
-
246
-    /**
247
-     * {@inheritdoc}
248
-     */
249
-    public function saveInto(DataObjectInterface $record)
250
-    {
251
-        parent::saveInto($record);
252
-
253
-        $name = $this->getName();
254
-
255
-        $record->$name = join(',', $this->Value());
256
-        $record->write();
257
-    }
258
-
259
-    /**
260
-     * Returns a JSON string of tags, for lazy loading.
261
-     *
262
-     * @param SS_HTTPRequest $request
263
-     *
264
-     * @return SS_HTTPResponse
265
-     */
266
-    public function suggest(SS_HTTPRequest $request)
267
-    {
268
-        $responseBody = Convert::raw2json(
269
-            array('items' => array())
270
-        );
271
-
272
-        $response = new SS_HTTPResponse();
273
-        $response->addHeader('Content-Type', 'application/json');
274
-
275
-        if ($record = $this->getRecord()) {
276
-            $tags = array();
277
-            $term = $request->getVar('term');
278
-
279
-            if ($record->hasField($this->getName())) {
280
-                $tags = $this->getTags($term);
281
-            }
282
-
283
-            $responseBody = Convert::raw2json(
284
-                array('items' => $tags)
285
-            );
286
-        }
287
-
288
-        $response->setBody($responseBody);
289
-
290
-        return $response;
291
-    }
292
-
293
-    /**
294
-     * Returns array of arrays representing tags.
295
-     *
296
-     * @param string $term
297
-     *
298
-     * @return array
299
-     */
300
-    protected function getTags($term)
301
-    {
302
-        $record = $this->getRecord();
303
-
304
-        if (!$record) {
305
-            return array();
306
-        }
307
-
308
-        $fieldName = $this->getName();
309
-        $className = $record->getClassName();
310
-
311
-        $term = Convert::raw2sql($term);
312
-
313
-        $query = $className::get()
314
-            ->filter($fieldName . ':PartialMatch:nocase', $term)
315
-            ->limit($this->getLazyLoadItemLimit());
316
-
317
-        $items = array();
318
-
319
-        foreach ($query->column($fieldName) as $tags) {
320
-            $tags = explode(',', $tags);
321
-
322
-            foreach ($tags as $i => $tag) {
323
-                if (stripos($tag, $term) !== false && !in_array($tag, $items)) {
324
-                    $items[] = array(
325
-                        'id' => $tag,
326
-                        'text' => $tag
327
-                    );
328
-                }
329
-            }
330
-        }
331
-
332
-        return $items;
333
-    }
334
-
335
-    /**
336
-     * DropdownField assumes value will be a scalar so we must
337
-     * override validate. This only applies to Silverstripe 3.2+
338
-     *
339
-     * @param Validator $validator
340
-     * @return bool
341
-     */
342
-    public function validate($validator)
343
-    {
344
-        return true;
345
-    }
14
+	/**
15
+	 * @var array
16
+	 */
17
+	public static $allowed_actions = array(
18
+		'suggest',
19
+	);
20
+
21
+	/**
22
+	 * @var bool
23
+	 */
24
+	protected $shouldLazyLoad = false;
25
+
26
+	/**
27
+	 * @var int
28
+	 */
29
+	protected $lazyLoadItemLimit = 10;
30
+
31
+	/**
32
+	 * @var null|DataObject
33
+	 */
34
+	protected $record;
35
+
36
+	/**
37
+	 * @var bool
38
+	 */
39
+	protected $isMultiple = true;
40
+
41
+	/**
42
+	 * @param string $name
43
+	 * @param string $title
44
+	 * @param array|SS_List $source
45
+	 * @param array|SS_List $value
46
+	 */
47
+	public function __construct($name, $title = '', $source = array(), $value = array())
48
+	{
49
+		parent::__construct($name, $title, $source, $value);
50
+	}
51
+
52
+	/**
53
+	 * @return bool
54
+	 */
55
+	public function getShouldLazyLoad()
56
+	{
57
+		return $this->shouldLazyLoad;
58
+	}
59
+
60
+	/**
61
+	 * @param bool $shouldLazyLoad
62
+	 *
63
+	 * @return static
64
+	 */
65
+	public function setShouldLazyLoad($shouldLazyLoad)
66
+	{
67
+		$this->shouldLazyLoad = $shouldLazyLoad;
68
+
69
+		return $this;
70
+	}
71
+
72
+	/**
73
+	 * @return int
74
+	 */
75
+	public function getLazyLoadItemLimit()
76
+	{
77
+		return $this->lazyLoadItemLimit;
78
+	}
79
+
80
+	/**
81
+	 * @param int $lazyLoadItemLimit
82
+	 *
83
+	 * @return static
84
+	 */
85
+	public function setLazyLoadItemLimit($lazyLoadItemLimit)
86
+	{
87
+		$this->lazyLoadItemLimit = $lazyLoadItemLimit;
88
+
89
+		return $this;
90
+	}
91
+
92
+	/**
93
+	 * @return bool
94
+	 */
95
+	public function getIsMultiple()
96
+	{
97
+		return $this->isMultiple;
98
+	}
99
+
100
+	/**
101
+	 * @param bool $isMultiple
102
+	 *
103
+	 * @return static
104
+	 */
105
+	public function setIsMultiple($isMultiple)
106
+	{
107
+		$this->isMultiple = $isMultiple;
108
+
109
+		return $this;
110
+	}
111
+
112
+	/**
113
+	 * @return null|DataObject
114
+	 */
115
+	public function getRecord()
116
+	{
117
+		if ($this->record) {
118
+			return $this->record;
119
+		}
120
+
121
+		if ($form = $this->getForm()) {
122
+			return $form->getRecord();
123
+		}
124
+
125
+		return null;
126
+	}
127
+
128
+	/**
129
+	 * @param DataObject $record
130
+	 *
131
+	 * @return $this
132
+	 */
133
+	public function setRecord(DataObject $record)
134
+	{
135
+		$this->record = $record;
136
+
137
+		return $this;
138
+	}
139
+
140
+	/**
141
+	 * {@inheritdoc}
142
+	 */
143
+	public function Field($properties = array())
144
+	{
145
+		Requirements::css(TAG_FIELD_DIR . '/css/select2.min.css');
146
+		Requirements::css(TAG_FIELD_DIR . '/css/TagField.css');
147
+
148
+		Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
149
+		Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js');
150
+		Requirements::javascript(TAG_FIELD_DIR . '/js/select2.js');
151
+		Requirements::javascript(TAG_FIELD_DIR . '/js/TagField.js');
152
+
153
+		$this->addExtraClass('ss-tag-field');
154
+
155
+		if ($this->getIsMultiple()) {
156
+			$this->setAttribute('multiple', 'multiple');
157
+		}
158
+
159
+		if ($this->getShouldLazyLoad()) {
160
+			$this->setAttribute('data-ss-tag-field-suggest-url', $this->getSuggestURL());
161
+		} else {
162
+			$properties = array_merge($properties, array(
163
+				'Options' => $this->getOptions()
164
+			));
165
+		}
166
+
167
+		$this->setAttribute('data-can-create', (int) $this->getCanCreate());
168
+
169
+		return $this
170
+			->customise($properties)
171
+			->renderWith(array("templates/TagField"));
172
+	}
173
+
174
+	/**
175
+	 * @return string
176
+	 */
177
+	protected function getSuggestURL()
178
+	{
179
+		return Controller::join_links($this->Link(), 'suggest');
180
+	}
181
+
182
+	/**
183
+	 * @return ArrayList
184
+	 */
185
+	protected function getOptions()
186
+	{
187
+		$options = ArrayList::create();
188
+
189
+		$source = $this->getSource();
190
+
191
+		if ($source instanceof Iterator) {
192
+			$source = iterator_to_array($source);
193
+		}
194
+
195
+		$values = $this->Value();
196
+
197
+		foreach ($source as $value) {
198
+			$options->push(
199
+				ArrayData::create(array(
200
+					'Title' => $value,
201
+					'Value' => $value,
202
+					'Selected' => in_array($value, $values),
203
+				))
204
+			);
205
+		}
206
+
207
+		return $options;
208
+	}
209
+
210
+	/**
211
+	 * {@inheritdoc}
212
+	 */
213
+	public function setValue($value, $source = null)
214
+	{
215
+		if (is_string($value)) {
216
+			$value = explode(',', $value);
217
+		}
218
+
219
+		if ($source instanceof DataObject) {
220
+			$name = $this->getName();
221
+			$value = explode(',', $source->$name);
222
+		}
223
+
224
+		if ($source instanceof SS_List) {
225
+			$value = $source->column('ID');
226
+		}
227
+
228
+		if (is_null($value)) {
229
+			$value = array();
230
+		}
231
+
232
+		return parent::setValue(array_filter($value));
233
+	}
234
+
235
+	/**
236
+	 * {@inheritdoc}
237
+	 */
238
+	public function getAttributes()
239
+	{
240
+		return array_merge(
241
+			parent::getAttributes(),
242
+			array('name' => $this->getName() . '[]')
243
+		);
244
+	}
245
+
246
+	/**
247
+	 * {@inheritdoc}
248
+	 */
249
+	public function saveInto(DataObjectInterface $record)
250
+	{
251
+		parent::saveInto($record);
252
+
253
+		$name = $this->getName();
254
+
255
+		$record->$name = join(',', $this->Value());
256
+		$record->write();
257
+	}
258
+
259
+	/**
260
+	 * Returns a JSON string of tags, for lazy loading.
261
+	 *
262
+	 * @param SS_HTTPRequest $request
263
+	 *
264
+	 * @return SS_HTTPResponse
265
+	 */
266
+	public function suggest(SS_HTTPRequest $request)
267
+	{
268
+		$responseBody = Convert::raw2json(
269
+			array('items' => array())
270
+		);
271
+
272
+		$response = new SS_HTTPResponse();
273
+		$response->addHeader('Content-Type', 'application/json');
274
+
275
+		if ($record = $this->getRecord()) {
276
+			$tags = array();
277
+			$term = $request->getVar('term');
278
+
279
+			if ($record->hasField($this->getName())) {
280
+				$tags = $this->getTags($term);
281
+			}
282
+
283
+			$responseBody = Convert::raw2json(
284
+				array('items' => $tags)
285
+			);
286
+		}
287
+
288
+		$response->setBody($responseBody);
289
+
290
+		return $response;
291
+	}
292
+
293
+	/**
294
+	 * Returns array of arrays representing tags.
295
+	 *
296
+	 * @param string $term
297
+	 *
298
+	 * @return array
299
+	 */
300
+	protected function getTags($term)
301
+	{
302
+		$record = $this->getRecord();
303
+
304
+		if (!$record) {
305
+			return array();
306
+		}
307
+
308
+		$fieldName = $this->getName();
309
+		$className = $record->getClassName();
310
+
311
+		$term = Convert::raw2sql($term);
312
+
313
+		$query = $className::get()
314
+			->filter($fieldName . ':PartialMatch:nocase', $term)
315
+			->limit($this->getLazyLoadItemLimit());
316
+
317
+		$items = array();
318
+
319
+		foreach ($query->column($fieldName) as $tags) {
320
+			$tags = explode(',', $tags);
321
+
322
+			foreach ($tags as $i => $tag) {
323
+				if (stripos($tag, $term) !== false && !in_array($tag, $items)) {
324
+					$items[] = array(
325
+						'id' => $tag,
326
+						'text' => $tag
327
+					);
328
+				}
329
+			}
330
+		}
331
+
332
+		return $items;
333
+	}
334
+
335
+	/**
336
+	 * DropdownField assumes value will be a scalar so we must
337
+	 * override validate. This only applies to Silverstripe 3.2+
338
+	 *
339
+	 * @param Validator $validator
340
+	 * @return bool
341
+	 */
342
+	public function validate($validator)
343
+	{
344
+		return true;
345
+	}
346 346
 }
Please login to merge, or discard this patch.
code/TagField.php 1 patch
Indentation   +434 added lines, -434 removed lines patch added patch discarded remove patch
@@ -8,418 +8,418 @@  discard block
 block discarded – undo
8 8
  */
9 9
 class TagField extends DropdownField
10 10
 {
11
-    /**
12
-     * @var array
13
-     */
14
-    public static $allowed_actions = array(
15
-        'suggest',
16
-    );
17
-
18
-    /**
19
-     * @var bool
20
-     */
21
-    protected $shouldLazyLoad = false;
22
-
23
-    /**
24
-     * @var int
25
-     */
26
-    protected $lazyLoadItemLimit = 10;
27
-
28
-    /**
29
-     * @var bool
30
-     */
31
-    protected $canCreate = true;
32
-
33
-    /**
34
-     * @var string
35
-     */
36
-    protected $titleField = 'Title';
37
-
38
-    /**
39
-     * @var bool
40
-     */
41
-    protected $isMultiple = true;
42
-
43
-    /**
44
-     * @param string $name
45
-     * @param string $title
46
-     * @param null|DataList $source
47
-     * @param null|DataList $value
48
-     */
49
-    public function __construct($name, $title = '', $source = null, $value = null)
50
-    {
51
-        parent::__construct($name, $title, $source, $value);
52
-    }
53
-
54
-    /**
55
-     * @return bool
56
-     */
57
-    public function getShouldLazyLoad()
58
-    {
59
-        return $this->shouldLazyLoad;
60
-    }
61
-
62
-    /**
63
-     * @param bool $shouldLazyLoad
64
-     *
65
-     * @return static
66
-     */
67
-    public function setShouldLazyLoad($shouldLazyLoad)
68
-    {
69
-        $this->shouldLazyLoad = $shouldLazyLoad;
70
-
71
-        return $this;
72
-    }
73
-
74
-    /**
75
-     * @return int
76
-     */
77
-    public function getLazyLoadItemLimit()
78
-    {
79
-        return $this->lazyLoadItemLimit;
80
-    }
81
-
82
-    /**
83
-     * @param int $lazyLoadItemLimit
84
-     *
85
-     * @return static
86
-     */
87
-    public function setLazyLoadItemLimit($lazyLoadItemLimit)
88
-    {
89
-        $this->lazyLoadItemLimit = $lazyLoadItemLimit;
90
-
91
-        return $this;
92
-    }
93
-
94
-    /**
95
-     * @return bool
96
-     */
97
-    public function getIsMultiple()
98
-    {
99
-        return $this->isMultiple;
100
-    }
101
-
102
-    /**
103
-     * @param bool $isMultiple
104
-     *
105
-     * @return static
106
-     */
107
-    public function setIsMultiple($isMultiple)
108
-    {
109
-        $this->isMultiple = $isMultiple;
110
-
111
-        return $this;
112
-    }
113
-
114
-    /**
115
-     * @return bool
116
-     */
117
-    public function getCanCreate()
118
-    {
119
-        return $this->canCreate;
120
-    }
121
-
122
-    /**
123
-     * @param bool $canCreate
124
-     *
125
-     * @return static
126
-     */
127
-    public function setCanCreate($canCreate)
128
-    {
129
-        $this->canCreate = $canCreate;
130
-
131
-        return $this;
132
-    }
133
-
134
-    /**
135
-     * @return string
136
-     */
137
-    public function getTitleField()
138
-    {
139
-        return $this->titleField;
140
-    }
141
-
142
-    /**
143
-     * @param string $titleField
144
-     *
145
-     * @return $this
146
-     */
147
-    public function setTitleField($titleField)
148
-    {
149
-        $this->titleField = $titleField;
150
-
151
-        return $this;
152
-    }
153
-
154
-    /**
155
-     * {@inheritdoc}
156
-     */
157
-    public function Field($properties = array())
158
-    {
159
-        Requirements::css(TAG_FIELD_DIR . '/css/select2.min.css');
160
-        Requirements::css(TAG_FIELD_DIR . '/css/TagField.css');
161
-
162
-        Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
163
-        Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js');
164
-        Requirements::javascript(TAG_FIELD_DIR . '/js/select2.js');
165
-        Requirements::javascript(TAG_FIELD_DIR . '/js/TagField.js');
166
-
167
-        $this->addExtraClass('ss-tag-field');
168
-
169
-        if ($this->getIsMultiple()) {
170
-            $this->setAttribute('multiple', 'multiple');
171
-        }
172
-
173
-        if ($this->shouldLazyLoad) {
174
-            $this->setAttribute('data-ss-tag-field-suggest-url', $this->getSuggestURL());
175
-        } else {
176
-            $properties = array_merge($properties, array(
177
-                'Options' => $this->getOptions()
178
-            ));
179
-        }
180
-
181
-        $this->setAttribute('data-can-create', (int) $this->getCanCreate());
182
-
183
-        return $this
184
-            ->customise($properties)
185
-            ->renderWith(array("templates/TagField"));
186
-    }
187
-
188
-    /**
189
-     * @return string
190
-     */
191
-    protected function getSuggestURL()
192
-    {
193
-        return Controller::join_links($this->Link(), 'suggest');
194
-    }
195
-
196
-    /**
197
-     * @return ArrayList
198
-     */
199
-    protected function getOptions()
200
-    {
201
-        $options = ArrayList::create();
202
-
203
-        $source = $this->getSource();
204
-
205
-        if (!$source) {
206
-            $source = new ArrayList();
207
-        }
208
-
209
-        $dataClass = $source->dataClass();
210
-
211
-        $values = $this->Value();
212
-
213
-        // Mark selected tags while still returning a full list of possible options
214
-        $ids = array(); // empty fallback array for comparing
215
-        $values = $this->Value();
216
-        if($values){
217
-            // @TODO conversion from array to DataList to array...(?)
218
-            if(is_array($values)) {
219
-                $values = DataList::create($dataClass)->filter('ID', $values);
220
-            }
221
-            $ids = $values->column('ID');
222
-        }
223
-
224
-        $titleField = $this->getTitleField();
225
-
226
-        foreach ($source as $object) {
227
-            $options->push(
228
-                ArrayData::create(array(
229
-                    'Title' => $object->$titleField,
230
-                    'Value' => $object->ID,
231
-                    'Selected' => in_array($object->ID, $ids),
232
-                ))
233
-            );
234
-        }
235
-
236
-        return $options;
237
-    }
238
-
239
-    /**
240
-     * {@inheritdoc}
241
-     */
242
-    public function setValue($value, $source = null)
243
-    {
244
-        if ($source instanceof DataObject) {
245
-            $name = $this->getName();
246
-
247
-            if ($source->hasMethod($name)) {
248
-                $value = $source->$name()->getIDList();
249
-            }
250
-        } elseif ($value instanceof SS_List) {
251
-            $value = $value->column('ID');
252
-        }
253
-
254
-        if (!is_array($value)) {
255
-            return parent::setValue($value);
256
-        }
257
-
258
-        return parent::setValue(array_filter($value));
259
-    }
260
-
261
-    /**
262
-     * {@inheritdoc}
263
-     */
264
-    public function getAttributes()
265
-    {
266
-        return array_merge(
267
-            parent::getAttributes(),
268
-            array('name' => $this->getName() . '[]')
269
-        );
270
-    }
271
-
272
-    /**
273
-     * {@inheritdoc}
274
-     */
275
-    public function saveInto(DataObjectInterface $record)
276
-    {
277
-        parent::saveInto($record);
278
-
279
-        $name = $this->getName();
280
-        $titleField = $this->getTitleField();
281
-
282
-        $source = $this->getSource();
283
-
284
-        $values = $this->Value();
285
-
286
-        if (!$values) {
287
-            $values = array();
288
-        }
289
-
290
-        if (empty($record) || empty($source) || empty($titleField)) {
291
-            return;
292
-        }
293
-
294
-        if (!$record->hasMethod($name)) {
295
-            throw new Exception(
296
-                sprintf("%s does not have a %s method", get_class($record), $name)
297
-            );
298
-        }
299
-
300
-        $relation = $record->$name();
301
-
302
-        foreach ($values as $i => $value) {
303
-            if (!is_numeric($value)) {
304
-                if (!$this->getCanCreate()) {
305
-                    unset($values[$i]);
306
-                    continue;
307
-                }
308
-
309
-                // Get or create record
310
-                $record = $this->getOrCreateTag($value);
311
-                $values[$i] = $record->ID;
312
-            }
313
-        }
314
-
315
-        if ($values instanceof SS_List) {
316
-            $values = iterator_to_array($values);
317
-        }
318
-
319
-        $relation->setByIDList(array_filter($values));
320
-    }
321
-
322
-    /**
323
-     * Get or create tag with the given value
324
-     *
325
-     * @param string $term
326
-     * @return DataObject
327
-     */
328
-    protected function getOrCreateTag($term)
329
-    {
330
-        // Check if existing record can be found
331
-        $source = $this->getSource();
332
-        $titleField = $this->getTitleField();
333
-        $record = $source
334
-            ->filter($titleField, $term)
335
-            ->first();
336
-        if ($record) {
337
-            return $record;
338
-        }
339
-
340
-        // Create new instance if not yet saved
341
-        $dataClass = $source->dataClass();
342
-        $record = Injector::inst()->create($dataClass);
343
-        $record->{$titleField} = $term;
344
-        $record->write();
345
-        return $record;
346
-    }
347
-
348
-    /**
349
-     * Returns a JSON string of tags, for lazy loading.
350
-     *
351
-     * @param SS_HTTPRequest $request
352
-     *
353
-     * @return SS_HTTPResponse
354
-     */
355
-    public function suggest(SS_HTTPRequest $request)
356
-    {
357
-        $tags = $this->getTags($request->getVar('term'));
358
-
359
-        $response = new SS_HTTPResponse();
360
-        $response->addHeader('Content-Type', 'application/json');
361
-        $response->setBody(json_encode(array('items' => $tags)));
362
-
363
-        return $response;
364
-    }
365
-
366
-    /**
367
-     * Returns array of arrays representing tags.
368
-     *
369
-     * @param string $term
370
-     *
371
-     * @return array
372
-     */
373
-    protected function getTags($term)
374
-    {
375
-        /**
376
-         * @var DataList $source
377
-         */
378
-        $source = $this->getSource();
379
-
380
-        $titleField = $this->getTitleField();
381
-
382
-        $query = $source
383
-            ->filter($titleField . ':PartialMatch:nocase', $term)
384
-            ->sort($titleField)
385
-            ->limit($this->getLazyLoadItemLimit());
386
-
387
-        // Map into a distinct list
388
-        $items = array();
389
-        $titleField = $this->getTitleField();
390
-        foreach ($query->map('ID', $titleField) as $id => $title) {
391
-            $items[$title] = array(
392
-                'id' => $id,
393
-                'text' => $title
394
-            );
395
-        }
396
-
397
-        return array_values($items);
398
-    }
399
-
400
-    /**
401
-     * DropdownField assumes value will be a scalar so we must
402
-     * override validate. This only applies to Silverstripe 3.2+
403
-     *
404
-     * @param Validator $validator
405
-     * @return bool
406
-     */
407
-    public function validate($validator)
408
-    {
409
-        return true;
410
-    }
411
-
412
-    /**
413
-     * Converts the field to a readonly variant.
414
-     *
415
-     * @return TagField_Readonly
416
-     */
417
-    public function performReadonlyTransformation()
418
-    {
419
-        $copy = $this->castedCopy('TagField_Readonly');
420
-        $copy->setSource($this->getSource());
421
-        return $copy;
422
-    }
11
+	/**
12
+	 * @var array
13
+	 */
14
+	public static $allowed_actions = array(
15
+		'suggest',
16
+	);
17
+
18
+	/**
19
+	 * @var bool
20
+	 */
21
+	protected $shouldLazyLoad = false;
22
+
23
+	/**
24
+	 * @var int
25
+	 */
26
+	protected $lazyLoadItemLimit = 10;
27
+
28
+	/**
29
+	 * @var bool
30
+	 */
31
+	protected $canCreate = true;
32
+
33
+	/**
34
+	 * @var string
35
+	 */
36
+	protected $titleField = 'Title';
37
+
38
+	/**
39
+	 * @var bool
40
+	 */
41
+	protected $isMultiple = true;
42
+
43
+	/**
44
+	 * @param string $name
45
+	 * @param string $title
46
+	 * @param null|DataList $source
47
+	 * @param null|DataList $value
48
+	 */
49
+	public function __construct($name, $title = '', $source = null, $value = null)
50
+	{
51
+		parent::__construct($name, $title, $source, $value);
52
+	}
53
+
54
+	/**
55
+	 * @return bool
56
+	 */
57
+	public function getShouldLazyLoad()
58
+	{
59
+		return $this->shouldLazyLoad;
60
+	}
61
+
62
+	/**
63
+	 * @param bool $shouldLazyLoad
64
+	 *
65
+	 * @return static
66
+	 */
67
+	public function setShouldLazyLoad($shouldLazyLoad)
68
+	{
69
+		$this->shouldLazyLoad = $shouldLazyLoad;
70
+
71
+		return $this;
72
+	}
73
+
74
+	/**
75
+	 * @return int
76
+	 */
77
+	public function getLazyLoadItemLimit()
78
+	{
79
+		return $this->lazyLoadItemLimit;
80
+	}
81
+
82
+	/**
83
+	 * @param int $lazyLoadItemLimit
84
+	 *
85
+	 * @return static
86
+	 */
87
+	public function setLazyLoadItemLimit($lazyLoadItemLimit)
88
+	{
89
+		$this->lazyLoadItemLimit = $lazyLoadItemLimit;
90
+
91
+		return $this;
92
+	}
93
+
94
+	/**
95
+	 * @return bool
96
+	 */
97
+	public function getIsMultiple()
98
+	{
99
+		return $this->isMultiple;
100
+	}
101
+
102
+	/**
103
+	 * @param bool $isMultiple
104
+	 *
105
+	 * @return static
106
+	 */
107
+	public function setIsMultiple($isMultiple)
108
+	{
109
+		$this->isMultiple = $isMultiple;
110
+
111
+		return $this;
112
+	}
113
+
114
+	/**
115
+	 * @return bool
116
+	 */
117
+	public function getCanCreate()
118
+	{
119
+		return $this->canCreate;
120
+	}
121
+
122
+	/**
123
+	 * @param bool $canCreate
124
+	 *
125
+	 * @return static
126
+	 */
127
+	public function setCanCreate($canCreate)
128
+	{
129
+		$this->canCreate = $canCreate;
130
+
131
+		return $this;
132
+	}
133
+
134
+	/**
135
+	 * @return string
136
+	 */
137
+	public function getTitleField()
138
+	{
139
+		return $this->titleField;
140
+	}
141
+
142
+	/**
143
+	 * @param string $titleField
144
+	 *
145
+	 * @return $this
146
+	 */
147
+	public function setTitleField($titleField)
148
+	{
149
+		$this->titleField = $titleField;
150
+
151
+		return $this;
152
+	}
153
+
154
+	/**
155
+	 * {@inheritdoc}
156
+	 */
157
+	public function Field($properties = array())
158
+	{
159
+		Requirements::css(TAG_FIELD_DIR . '/css/select2.min.css');
160
+		Requirements::css(TAG_FIELD_DIR . '/css/TagField.css');
161
+
162
+		Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
163
+		Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js');
164
+		Requirements::javascript(TAG_FIELD_DIR . '/js/select2.js');
165
+		Requirements::javascript(TAG_FIELD_DIR . '/js/TagField.js');
166
+
167
+		$this->addExtraClass('ss-tag-field');
168
+
169
+		if ($this->getIsMultiple()) {
170
+			$this->setAttribute('multiple', 'multiple');
171
+		}
172
+
173
+		if ($this->shouldLazyLoad) {
174
+			$this->setAttribute('data-ss-tag-field-suggest-url', $this->getSuggestURL());
175
+		} else {
176
+			$properties = array_merge($properties, array(
177
+				'Options' => $this->getOptions()
178
+			));
179
+		}
180
+
181
+		$this->setAttribute('data-can-create', (int) $this->getCanCreate());
182
+
183
+		return $this
184
+			->customise($properties)
185
+			->renderWith(array("templates/TagField"));
186
+	}
187
+
188
+	/**
189
+	 * @return string
190
+	 */
191
+	protected function getSuggestURL()
192
+	{
193
+		return Controller::join_links($this->Link(), 'suggest');
194
+	}
195
+
196
+	/**
197
+	 * @return ArrayList
198
+	 */
199
+	protected function getOptions()
200
+	{
201
+		$options = ArrayList::create();
202
+
203
+		$source = $this->getSource();
204
+
205
+		if (!$source) {
206
+			$source = new ArrayList();
207
+		}
208
+
209
+		$dataClass = $source->dataClass();
210
+
211
+		$values = $this->Value();
212
+
213
+		// Mark selected tags while still returning a full list of possible options
214
+		$ids = array(); // empty fallback array for comparing
215
+		$values = $this->Value();
216
+		if($values){
217
+			// @TODO conversion from array to DataList to array...(?)
218
+			if(is_array($values)) {
219
+				$values = DataList::create($dataClass)->filter('ID', $values);
220
+			}
221
+			$ids = $values->column('ID');
222
+		}
223
+
224
+		$titleField = $this->getTitleField();
225
+
226
+		foreach ($source as $object) {
227
+			$options->push(
228
+				ArrayData::create(array(
229
+					'Title' => $object->$titleField,
230
+					'Value' => $object->ID,
231
+					'Selected' => in_array($object->ID, $ids),
232
+				))
233
+			);
234
+		}
235
+
236
+		return $options;
237
+	}
238
+
239
+	/**
240
+	 * {@inheritdoc}
241
+	 */
242
+	public function setValue($value, $source = null)
243
+	{
244
+		if ($source instanceof DataObject) {
245
+			$name = $this->getName();
246
+
247
+			if ($source->hasMethod($name)) {
248
+				$value = $source->$name()->getIDList();
249
+			}
250
+		} elseif ($value instanceof SS_List) {
251
+			$value = $value->column('ID');
252
+		}
253
+
254
+		if (!is_array($value)) {
255
+			return parent::setValue($value);
256
+		}
257
+
258
+		return parent::setValue(array_filter($value));
259
+	}
260
+
261
+	/**
262
+	 * {@inheritdoc}
263
+	 */
264
+	public function getAttributes()
265
+	{
266
+		return array_merge(
267
+			parent::getAttributes(),
268
+			array('name' => $this->getName() . '[]')
269
+		);
270
+	}
271
+
272
+	/**
273
+	 * {@inheritdoc}
274
+	 */
275
+	public function saveInto(DataObjectInterface $record)
276
+	{
277
+		parent::saveInto($record);
278
+
279
+		$name = $this->getName();
280
+		$titleField = $this->getTitleField();
281
+
282
+		$source = $this->getSource();
283
+
284
+		$values = $this->Value();
285
+
286
+		if (!$values) {
287
+			$values = array();
288
+		}
289
+
290
+		if (empty($record) || empty($source) || empty($titleField)) {
291
+			return;
292
+		}
293
+
294
+		if (!$record->hasMethod($name)) {
295
+			throw new Exception(
296
+				sprintf("%s does not have a %s method", get_class($record), $name)
297
+			);
298
+		}
299
+
300
+		$relation = $record->$name();
301
+
302
+		foreach ($values as $i => $value) {
303
+			if (!is_numeric($value)) {
304
+				if (!$this->getCanCreate()) {
305
+					unset($values[$i]);
306
+					continue;
307
+				}
308
+
309
+				// Get or create record
310
+				$record = $this->getOrCreateTag($value);
311
+				$values[$i] = $record->ID;
312
+			}
313
+		}
314
+
315
+		if ($values instanceof SS_List) {
316
+			$values = iterator_to_array($values);
317
+		}
318
+
319
+		$relation->setByIDList(array_filter($values));
320
+	}
321
+
322
+	/**
323
+	 * Get or create tag with the given value
324
+	 *
325
+	 * @param string $term
326
+	 * @return DataObject
327
+	 */
328
+	protected function getOrCreateTag($term)
329
+	{
330
+		// Check if existing record can be found
331
+		$source = $this->getSource();
332
+		$titleField = $this->getTitleField();
333
+		$record = $source
334
+			->filter($titleField, $term)
335
+			->first();
336
+		if ($record) {
337
+			return $record;
338
+		}
339
+
340
+		// Create new instance if not yet saved
341
+		$dataClass = $source->dataClass();
342
+		$record = Injector::inst()->create($dataClass);
343
+		$record->{$titleField} = $term;
344
+		$record->write();
345
+		return $record;
346
+	}
347
+
348
+	/**
349
+	 * Returns a JSON string of tags, for lazy loading.
350
+	 *
351
+	 * @param SS_HTTPRequest $request
352
+	 *
353
+	 * @return SS_HTTPResponse
354
+	 */
355
+	public function suggest(SS_HTTPRequest $request)
356
+	{
357
+		$tags = $this->getTags($request->getVar('term'));
358
+
359
+		$response = new SS_HTTPResponse();
360
+		$response->addHeader('Content-Type', 'application/json');
361
+		$response->setBody(json_encode(array('items' => $tags)));
362
+
363
+		return $response;
364
+	}
365
+
366
+	/**
367
+	 * Returns array of arrays representing tags.
368
+	 *
369
+	 * @param string $term
370
+	 *
371
+	 * @return array
372
+	 */
373
+	protected function getTags($term)
374
+	{
375
+		/**
376
+		 * @var DataList $source
377
+		 */
378
+		$source = $this->getSource();
379
+
380
+		$titleField = $this->getTitleField();
381
+
382
+		$query = $source
383
+			->filter($titleField . ':PartialMatch:nocase', $term)
384
+			->sort($titleField)
385
+			->limit($this->getLazyLoadItemLimit());
386
+
387
+		// Map into a distinct list
388
+		$items = array();
389
+		$titleField = $this->getTitleField();
390
+		foreach ($query->map('ID', $titleField) as $id => $title) {
391
+			$items[$title] = array(
392
+				'id' => $id,
393
+				'text' => $title
394
+			);
395
+		}
396
+
397
+		return array_values($items);
398
+	}
399
+
400
+	/**
401
+	 * DropdownField assumes value will be a scalar so we must
402
+	 * override validate. This only applies to Silverstripe 3.2+
403
+	 *
404
+	 * @param Validator $validator
405
+	 * @return bool
406
+	 */
407
+	public function validate($validator)
408
+	{
409
+		return true;
410
+	}
411
+
412
+	/**
413
+	 * Converts the field to a readonly variant.
414
+	 *
415
+	 * @return TagField_Readonly
416
+	 */
417
+	public function performReadonlyTransformation()
418
+	{
419
+		$copy = $this->castedCopy('TagField_Readonly');
420
+		$copy->setSource($this->getSource());
421
+		return $copy;
422
+	}
423 423
 }
424 424
 
425 425
 /**
@@ -430,26 +430,26 @@  discard block
 block discarded – undo
430 430
  */
431 431
 class TagField_Readonly extends TagField
432 432
 {
433
-    protected $readonly = true;
434
-
435
-    /**
436
-     * Render the readonly field as HTML.
437
-     *
438
-     * @param array $properties
439
-     * @return HTMLText
440
-     */
441
-    public function Field($properties = array())
442
-    {
443
-        $options = array();
444
-
445
-        foreach ($this->getOptions()->filter('Selected', true) as $option) {
446
-            $options[] = $option->Title;
447
-        }
448
-
449
-        $field = ReadonlyField::create($this->name.'_Readonly', $this->title);
450
-
451
-        $field->setForm($this->form);
452
-        $field->setValue(implode(', ', $options));
453
-        return $field->Field();
454
-    }
433
+	protected $readonly = true;
434
+
435
+	/**
436
+	 * Render the readonly field as HTML.
437
+	 *
438
+	 * @param array $properties
439
+	 * @return HTMLText
440
+	 */
441
+	public function Field($properties = array())
442
+	{
443
+		$options = array();
444
+
445
+		foreach ($this->getOptions()->filter('Selected', true) as $option) {
446
+			$options[] = $option->Title;
447
+		}
448
+
449
+		$field = ReadonlyField::create($this->name.'_Readonly', $this->title);
450
+
451
+		$field->setForm($this->form);
452
+		$field->setValue(implode(', ', $options));
453
+		return $field->Field();
454
+	}
455 455
 }
Please login to merge, or discard this patch.