Passed
Pull Request — master (#120)
by Guy
05:56
created
src/TagField.php 2 patches
Indentation   +482 added lines, -482 removed lines patch added patch discarded remove patch
@@ -23,489 +23,489 @@
 block discarded – undo
23 23
  */
24 24
 class TagField extends MultiSelectField
25 25
 {
26
-    /**
27
-     * @var array
28
-     */
29
-    private static $allowed_actions = [
30
-        'suggest',
31
-    ];
32
-
33
-    /**
34
-     * @var bool
35
-     */
36
-    protected $shouldLazyLoad = false;
37
-
38
-    /**
39
-     * @var int
40
-     */
41
-    protected $lazyLoadItemLimit = 10;
42
-
43
-    /**
44
-     * @var bool
45
-     */
46
-    protected $canCreate = true;
47
-
48
-    /**
49
-     * @var string
50
-     */
51
-    protected $titleField = 'Title';
52
-
53
-    /**
54
-     * @var DataList
55
-     */
56
-    protected $sourceList;
57
-
58
-    /**
59
-     * @var bool
60
-     */
61
-    protected $isMultiple = true;
62
-
63
-    /** @skipUpgrade */
64
-    protected $schemaComponent = 'TagField';
65
-
66
-    /**
67
-     * @param string $name
68
-     * @param string $title
69
-     * @param null|DataList $source
70
-     * @param null|DataList $value
71
-     * @param string $titleField
72
-     */
73
-    public function __construct($name, $title = '', $source = [], $value = null, $titleField = 'Title')
74
-    {
75
-        $this->setSourceList($source);
76
-        $this->setTitleField($titleField);
77
-        parent::__construct($name, $title, $source, $value);
78
-
79
-        $this->addExtraClass('ss-tag-field');
80
-    }
81
-
82
-    /**
83
-     * @return bool
84
-     */
85
-    public function getShouldLazyLoad()
86
-    {
87
-        return $this->shouldLazyLoad;
88
-    }
89
-
90
-    /**
91
-     * @param bool $shouldLazyLoad
92
-     *
93
-     * @return static
94
-     */
95
-    public function setShouldLazyLoad($shouldLazyLoad)
96
-    {
97
-        $this->shouldLazyLoad = $shouldLazyLoad;
98
-
99
-        return $this;
100
-    }
101
-
102
-    /**
103
-     * @return int
104
-     */
105
-    public function getLazyLoadItemLimit()
106
-    {
107
-        return $this->lazyLoadItemLimit;
108
-    }
109
-
110
-    /**
111
-     * @param int $lazyLoadItemLimit
112
-     *
113
-     * @return static
114
-     */
115
-    public function setLazyLoadItemLimit($lazyLoadItemLimit)
116
-    {
117
-        $this->lazyLoadItemLimit = $lazyLoadItemLimit;
118
-
119
-        return $this;
120
-    }
121
-
122
-    /**
123
-     * @return bool
124
-     */
125
-    public function getIsMultiple()
126
-    {
127
-        return $this->isMultiple;
128
-    }
129
-
130
-    /**
131
-     * @param bool $isMultiple
132
-     *
133
-     * @return static
134
-     */
135
-    public function setIsMultiple($isMultiple)
136
-    {
137
-        $this->isMultiple = $isMultiple;
138
-
139
-        return $this;
140
-    }
141
-
142
-    /**
143
-     * @return bool
144
-     */
145
-    public function getCanCreate()
146
-    {
147
-        return $this->canCreate;
148
-    }
149
-
150
-    /**
151
-     * @param bool $canCreate
152
-     *
153
-     * @return static
154
-     */
155
-    public function setCanCreate($canCreate)
156
-    {
157
-        $this->canCreate = $canCreate;
158
-
159
-        return $this;
160
-    }
161
-
162
-    /**
163
-     * @return string
164
-     */
165
-    public function getTitleField()
166
-    {
167
-        return $this->titleField;
168
-    }
169
-
170
-    /**
171
-     * @param string $titleField
172
-     *
173
-     * @return $this
174
-     */
175
-    public function setTitleField($titleField)
176
-    {
177
-        $this->titleField = $titleField;
178
-
179
-        return $this;
180
-    }
181
-
182
-    /**
183
-     * Get the DataList source. The 4.x upgrade for SelectField::setSource starts to convert this to an array
184
-     * @return DataList
185
-     */
186
-    public function getSourceList()
187
-    {
188
-        return $this->sourceList;
189
-    }
190
-
191
-    /**
192
-     * Set the model class name for tags
193
-     * @param  DataList $className
194
-     * @return self
195
-     */
196
-    public function setSourceList($sourceList)
197
-    {
198
-        $this->sourceList = $sourceList;
199
-        return $this;
200
-    }
201
-
202
-    /**
203
-     * {@inheritdoc}
204
-     */
205
-    public function Field($properties = [])
206
-    {
207
-        $this->addExtraClass('entwine');
208
-
209
-        return $this->customise($properties)->renderWith(self::class);
210
-    }
211
-
212
-    /**
213
-     * Provide TagField data to the JSON schema for the frontend component
214
-     *
215
-     * @return array
216
-     */
217
-    public function getSchemaDataDefaults()
218
-    {
219
-        $options = $this->getOptions(true);
220
-        $schema = array_merge(
221
-            parent::getSchemaDataDefaults(),
222
-            [
223
-                'name' => $this->getName() . '[]',
224
-                'lazyLoad' => $this->getShouldLazyLoad(),
225
-                'creatable' => $this->getCanCreate(),
226
-                'multi' => $this->getIsMultiple(),
227
-                'value' => $options->count() ? $options->toNestedArray() : null,
228
-                'disabled' => $this->isDisabled() || $this->isReadonly(),
229
-            ]
230
-        );
231
-
232
-        if (!$this->getShouldLazyLoad()) {
233
-            $schema['options'] = array_values($this->getOptions()->toNestedArray());
234
-        } else {
235
-            $schema['optionUrl'] = $this->getSuggestURL();
236
-        }
237
-        $this->setAttribute('data-schema', json_encode($schema));
238
-
239
-        return $schema;
240
-    }
241
-
242
-    /**
243
-     * @return string
244
-     */
245
-    protected function getSuggestURL()
246
-    {
247
-        return Controller::join_links($this->Link(), 'suggest');
248
-    }
249
-
250
-    /**
251
-     * @return ArrayList
252
-     */
253
-    protected function getOptions($onlySelected = false)
254
-    {
255
-        $options = ArrayList::create();
256
-        $source = $this->getSourceList();
257
-
258
-        // No source means we have no options
259
-        if (!$source) {
260
-            return ArrayList::create();
261
-        }
262
-
263
-        $dataClass = $source->dataClass();
264
-
265
-        $values = $this->Value();
266
-
267
-        // If we have no values and we only want selected options we can bail here
268
-        if (empty($values) && $onlySelected) {
269
-            return ArrayList::create();
270
-        }
271
-
272
-        // Convert an array of values into a datalist of options
273
-        if (is_array($values) && !empty($values)) {
274
-            $values = DataList::create($dataClass)
275
-                ->filter($this->getTitleField(), $values);
276
-        } else {
277
-            $values = ArrayList::create();
278
-        }
279
-
280
-        // Prep a function to parse a dataobject into an option
281
-        $addOption = function (DataObject $item) use ($options, $values) {
282
-            $titleField = $this->getTitleField();
283
-            $options->push(ArrayData::create([
284
-                'Title' => $item->$titleField,
285
-                'Value' => $item->ID,
286
-                'Selected' => (bool) $values->find('ID', $item->ID)
287
-            ]));
288
-        };
289
-
290
-        // Only parse the values if we only want the selected items in the values list (this is for lazy-loading)
291
-        if ($onlySelected) {
292
-            $values->each($addOption);
293
-            return $options;
294
-        }
295
-
296
-        $source->each($addOption);
297
-        return $options;
298
-    }
299
-
300
-    /**
301
-     * {@inheritdoc}
302
-     */
303
-    public function setValue($value, $source = null)
304
-    {
305
-        if ($source instanceof DataObject) {
306
-            $name = $this->getName();
307
-
308
-            if ($source->hasMethod($name)) {
309
-                $value = $source->$name()->column($this->getTitleField());
310
-            }
311
-        }
312
-
313
-        if (!is_array($value)) {
314
-            return parent::setValue($value);
315
-        }
316
-
317
-        return parent::setValue(array_filter($value));
318
-    }
319
-
320
-    public function getValueAsOptions()
321
-    {
322
-        $value = $this->Value();
26
+	/**
27
+	 * @var array
28
+	 */
29
+	private static $allowed_actions = [
30
+		'suggest',
31
+	];
32
+
33
+	/**
34
+	 * @var bool
35
+	 */
36
+	protected $shouldLazyLoad = false;
37
+
38
+	/**
39
+	 * @var int
40
+	 */
41
+	protected $lazyLoadItemLimit = 10;
42
+
43
+	/**
44
+	 * @var bool
45
+	 */
46
+	protected $canCreate = true;
47
+
48
+	/**
49
+	 * @var string
50
+	 */
51
+	protected $titleField = 'Title';
52
+
53
+	/**
54
+	 * @var DataList
55
+	 */
56
+	protected $sourceList;
57
+
58
+	/**
59
+	 * @var bool
60
+	 */
61
+	protected $isMultiple = true;
62
+
63
+	/** @skipUpgrade */
64
+	protected $schemaComponent = 'TagField';
65
+
66
+	/**
67
+	 * @param string $name
68
+	 * @param string $title
69
+	 * @param null|DataList $source
70
+	 * @param null|DataList $value
71
+	 * @param string $titleField
72
+	 */
73
+	public function __construct($name, $title = '', $source = [], $value = null, $titleField = 'Title')
74
+	{
75
+		$this->setSourceList($source);
76
+		$this->setTitleField($titleField);
77
+		parent::__construct($name, $title, $source, $value);
78
+
79
+		$this->addExtraClass('ss-tag-field');
80
+	}
81
+
82
+	/**
83
+	 * @return bool
84
+	 */
85
+	public function getShouldLazyLoad()
86
+	{
87
+		return $this->shouldLazyLoad;
88
+	}
89
+
90
+	/**
91
+	 * @param bool $shouldLazyLoad
92
+	 *
93
+	 * @return static
94
+	 */
95
+	public function setShouldLazyLoad($shouldLazyLoad)
96
+	{
97
+		$this->shouldLazyLoad = $shouldLazyLoad;
98
+
99
+		return $this;
100
+	}
101
+
102
+	/**
103
+	 * @return int
104
+	 */
105
+	public function getLazyLoadItemLimit()
106
+	{
107
+		return $this->lazyLoadItemLimit;
108
+	}
109
+
110
+	/**
111
+	 * @param int $lazyLoadItemLimit
112
+	 *
113
+	 * @return static
114
+	 */
115
+	public function setLazyLoadItemLimit($lazyLoadItemLimit)
116
+	{
117
+		$this->lazyLoadItemLimit = $lazyLoadItemLimit;
118
+
119
+		return $this;
120
+	}
121
+
122
+	/**
123
+	 * @return bool
124
+	 */
125
+	public function getIsMultiple()
126
+	{
127
+		return $this->isMultiple;
128
+	}
129
+
130
+	/**
131
+	 * @param bool $isMultiple
132
+	 *
133
+	 * @return static
134
+	 */
135
+	public function setIsMultiple($isMultiple)
136
+	{
137
+		$this->isMultiple = $isMultiple;
138
+
139
+		return $this;
140
+	}
141
+
142
+	/**
143
+	 * @return bool
144
+	 */
145
+	public function getCanCreate()
146
+	{
147
+		return $this->canCreate;
148
+	}
149
+
150
+	/**
151
+	 * @param bool $canCreate
152
+	 *
153
+	 * @return static
154
+	 */
155
+	public function setCanCreate($canCreate)
156
+	{
157
+		$this->canCreate = $canCreate;
158
+
159
+		return $this;
160
+	}
161
+
162
+	/**
163
+	 * @return string
164
+	 */
165
+	public function getTitleField()
166
+	{
167
+		return $this->titleField;
168
+	}
169
+
170
+	/**
171
+	 * @param string $titleField
172
+	 *
173
+	 * @return $this
174
+	 */
175
+	public function setTitleField($titleField)
176
+	{
177
+		$this->titleField = $titleField;
178
+
179
+		return $this;
180
+	}
181
+
182
+	/**
183
+	 * Get the DataList source. The 4.x upgrade for SelectField::setSource starts to convert this to an array
184
+	 * @return DataList
185
+	 */
186
+	public function getSourceList()
187
+	{
188
+		return $this->sourceList;
189
+	}
190
+
191
+	/**
192
+	 * Set the model class name for tags
193
+	 * @param  DataList $className
194
+	 * @return self
195
+	 */
196
+	public function setSourceList($sourceList)
197
+	{
198
+		$this->sourceList = $sourceList;
199
+		return $this;
200
+	}
201
+
202
+	/**
203
+	 * {@inheritdoc}
204
+	 */
205
+	public function Field($properties = [])
206
+	{
207
+		$this->addExtraClass('entwine');
208
+
209
+		return $this->customise($properties)->renderWith(self::class);
210
+	}
211
+
212
+	/**
213
+	 * Provide TagField data to the JSON schema for the frontend component
214
+	 *
215
+	 * @return array
216
+	 */
217
+	public function getSchemaDataDefaults()
218
+	{
219
+		$options = $this->getOptions(true);
220
+		$schema = array_merge(
221
+			parent::getSchemaDataDefaults(),
222
+			[
223
+				'name' => $this->getName() . '[]',
224
+				'lazyLoad' => $this->getShouldLazyLoad(),
225
+				'creatable' => $this->getCanCreate(),
226
+				'multi' => $this->getIsMultiple(),
227
+				'value' => $options->count() ? $options->toNestedArray() : null,
228
+				'disabled' => $this->isDisabled() || $this->isReadonly(),
229
+			]
230
+		);
231
+
232
+		if (!$this->getShouldLazyLoad()) {
233
+			$schema['options'] = array_values($this->getOptions()->toNestedArray());
234
+		} else {
235
+			$schema['optionUrl'] = $this->getSuggestURL();
236
+		}
237
+		$this->setAttribute('data-schema', json_encode($schema));
238
+
239
+		return $schema;
240
+	}
241
+
242
+	/**
243
+	 * @return string
244
+	 */
245
+	protected function getSuggestURL()
246
+	{
247
+		return Controller::join_links($this->Link(), 'suggest');
248
+	}
249
+
250
+	/**
251
+	 * @return ArrayList
252
+	 */
253
+	protected function getOptions($onlySelected = false)
254
+	{
255
+		$options = ArrayList::create();
256
+		$source = $this->getSourceList();
257
+
258
+		// No source means we have no options
259
+		if (!$source) {
260
+			return ArrayList::create();
261
+		}
262
+
263
+		$dataClass = $source->dataClass();
264
+
265
+		$values = $this->Value();
266
+
267
+		// If we have no values and we only want selected options we can bail here
268
+		if (empty($values) && $onlySelected) {
269
+			return ArrayList::create();
270
+		}
271
+
272
+		// Convert an array of values into a datalist of options
273
+		if (is_array($values) && !empty($values)) {
274
+			$values = DataList::create($dataClass)
275
+				->filter($this->getTitleField(), $values);
276
+		} else {
277
+			$values = ArrayList::create();
278
+		}
279
+
280
+		// Prep a function to parse a dataobject into an option
281
+		$addOption = function (DataObject $item) use ($options, $values) {
282
+			$titleField = $this->getTitleField();
283
+			$options->push(ArrayData::create([
284
+				'Title' => $item->$titleField,
285
+				'Value' => $item->ID,
286
+				'Selected' => (bool) $values->find('ID', $item->ID)
287
+			]));
288
+		};
289
+
290
+		// Only parse the values if we only want the selected items in the values list (this is for lazy-loading)
291
+		if ($onlySelected) {
292
+			$values->each($addOption);
293
+			return $options;
294
+		}
295
+
296
+		$source->each($addOption);
297
+		return $options;
298
+	}
299
+
300
+	/**
301
+	 * {@inheritdoc}
302
+	 */
303
+	public function setValue($value, $source = null)
304
+	{
305
+		if ($source instanceof DataObject) {
306
+			$name = $this->getName();
307
+
308
+			if ($source->hasMethod($name)) {
309
+				$value = $source->$name()->column($this->getTitleField());
310
+			}
311
+		}
312
+
313
+		if (!is_array($value)) {
314
+			return parent::setValue($value);
315
+		}
316
+
317
+		return parent::setValue(array_filter($value));
318
+	}
319
+
320
+	public function getValueAsOptions()
321
+	{
322
+		$value = $this->Value();
323 323
 
324 324
 //        return $this->getOptions()
325
-    }
326
-
327
-    /**
328
-     * {@inheritdoc}
329
-     */
330
-    public function getAttributes()
331
-    {
332
-        return array_merge(
333
-            parent::getAttributes(),
334
-            [
335
-                'name' => $this->getName() . '[]',
336
-                'style' => 'width: 100%',
337
-                'data-schema' => json_encode($this->getSchemaData()),
338
-            ]
339
-        );
340
-    }
341
-
342
-    /**
343
-     * {@inheritdoc}
344
-     */
345
-    public function saveInto(DataObjectInterface $record)
346
-    {
347
-        $name = $this->getName();
348
-        $titleField = $this->getTitleField();
349
-        $values = $this->Value();
350
-        $relation = $record->$name();
351
-        $ids = [];
352
-
353
-        if (!$values) {
354
-            $values = [];
355
-        }
356
-
357
-        if (empty($record) || empty($titleField)) {
358
-            return;
359
-        }
360
-
361
-        if (!$record->hasMethod($name)) {
362
-            throw new Exception(
363
-                sprintf("%s does not have a %s method", get_class($record), $name)
364
-            );
365
-        }
366
-
367
-        foreach ($values as $key => $value) {
368
-            // Get or create record
369
-            $record = $this->getOrCreateTag($value);
370
-            if ($record) {
371
-                $ids[] = $record->ID;
372
-                $values[$key] = $record->Title;
373
-            }
374
-        }
375
-
376
-        $relation->setByIDList(array_filter($ids));
377
-    }
378
-
379
-    /**
380
-     * Get or create tag with the given value
381
-     *
382
-     * @param  string $term
383
-     * @return DataObject|bool
384
-     */
385
-    protected function getOrCreateTag($term)
386
-    {
387
-        // Check if existing record can be found
388
-        $source = $this->getSourceList();
389
-        $titleField = $this->getTitleField();
390
-        $record = $source
391
-            ->filter($titleField, $term)
392
-            ->first();
393
-        if ($record) {
394
-            return $record;
395
-        }
396
-
397
-        // Create new instance if not yet saved
398
-        if ($this->getCanCreate()) {
399
-            $dataClass = $source->dataClass();
400
-            $record = Injector::inst()->create($dataClass);
401
-
402
-            if (is_array($term)) {
403
-                $term = $term['Value'];
404
-            }
405
-
406
-            $record->{$titleField} = $term;
407
-            $record->write();
408
-            return $record;
409
-        }
410
-
411
-        return false;
412
-    }
413
-
414
-    /**
415
-     * Returns a JSON string of tags, for lazy loading.
416
-     *
417
-     * @param  HTTPRequest $request
418
-     * @return HTTPResponse
419
-     */
420
-    public function suggest(HTTPRequest $request)
421
-    {
422
-        $tags = $this->getTags($request->getVar('term'));
423
-
424
-        $response = HTTPResponse::create();
425
-        $response->addHeader('Content-Type', 'application/json');
426
-        $response->setBody(json_encode(['items' => $tags]));
427
-
428
-        return $response;
429
-    }
430
-
431
-    /**
432
-     * Returns array of arrays representing tags.
433
-     *
434
-     * @param  string $term
435
-     * @return array
436
-     */
437
-    protected function getTags($term)
438
-    {
439
-        $source = $this->getSourceList();
440
-
441
-        $titleField = $this->getTitleField();
442
-
443
-        $query = $source
444
-            ->filter($titleField . ':PartialMatch:nocase', $term)
445
-            ->sort($titleField)
446
-            ->limit($this->getLazyLoadItemLimit());
447
-
448
-        // Map into a distinct list
449
-        $items = [];
450
-        $titleField = $this->getTitleField();
451
-        foreach ($query->map('ID', $titleField) as $id => $title) {
452
-            $items[$title] = [
453
-                'Title' => $title,
454
-                'Value' => $id,
455
-            ];
456
-        }
457
-
458
-        return array_values($items);
459
-    }
460
-
461
-    /**
462
-     * DropdownField assumes value will be a scalar so we must
463
-     * override validate. This only applies to Silverstripe 3.2+
464
-     *
465
-     * @param Validator $validator
466
-     * @return bool
467
-     */
468
-    public function validate($validator)
469
-    {
470
-        return true;
471
-    }
472
-
473
-    /**
474
-     * Converts the field to a readonly variant.
475
-     *
476
-     * @return ReadonlyTagField
477
-     */
478
-    public function performReadonlyTransformation()
479
-    {
480
-        /** @var ReadonlyTagField $copy */
481
-        $copy = $this->castedCopy(ReadonlyTagField::class);
482
-        $copy->setSourceList($this->getSourceList());
483
-        return $copy;
484
-    }
485
-
486
-    /**
487
-     * Prevent the default, which would return "tag"
488
-     *
489
-     * @return string
490
-     */
491
-    public function Type()
492
-    {
493
-        return '';
494
-    }
495
-
496
-    public function getSchemaStateDefaults()
497
-    {
498
-        $data = parent::getSchemaStateDefaults();
499
-
500
-        // Add options to 'data'
501
-        $data['lazyLoad'] = $this->getShouldLazyLoad();
502
-        $data['multi'] = $this->getIsMultiple();
503
-        $data['optionUrl'] = $this->getSuggestURL();
504
-        $data['creatable'] = $this->getCanCreate();
505
-        $options = $this->getOptions(true);
506
-        $data['value'] = $options->count() ? $options->toNestedArray() : null;
507
-
508
-        return $data;
509
-    }
325
+	}
326
+
327
+	/**
328
+	 * {@inheritdoc}
329
+	 */
330
+	public function getAttributes()
331
+	{
332
+		return array_merge(
333
+			parent::getAttributes(),
334
+			[
335
+				'name' => $this->getName() . '[]',
336
+				'style' => 'width: 100%',
337
+				'data-schema' => json_encode($this->getSchemaData()),
338
+			]
339
+		);
340
+	}
341
+
342
+	/**
343
+	 * {@inheritdoc}
344
+	 */
345
+	public function saveInto(DataObjectInterface $record)
346
+	{
347
+		$name = $this->getName();
348
+		$titleField = $this->getTitleField();
349
+		$values = $this->Value();
350
+		$relation = $record->$name();
351
+		$ids = [];
352
+
353
+		if (!$values) {
354
+			$values = [];
355
+		}
356
+
357
+		if (empty($record) || empty($titleField)) {
358
+			return;
359
+		}
360
+
361
+		if (!$record->hasMethod($name)) {
362
+			throw new Exception(
363
+				sprintf("%s does not have a %s method", get_class($record), $name)
364
+			);
365
+		}
366
+
367
+		foreach ($values as $key => $value) {
368
+			// Get or create record
369
+			$record = $this->getOrCreateTag($value);
370
+			if ($record) {
371
+				$ids[] = $record->ID;
372
+				$values[$key] = $record->Title;
373
+			}
374
+		}
375
+
376
+		$relation->setByIDList(array_filter($ids));
377
+	}
378
+
379
+	/**
380
+	 * Get or create tag with the given value
381
+	 *
382
+	 * @param  string $term
383
+	 * @return DataObject|bool
384
+	 */
385
+	protected function getOrCreateTag($term)
386
+	{
387
+		// Check if existing record can be found
388
+		$source = $this->getSourceList();
389
+		$titleField = $this->getTitleField();
390
+		$record = $source
391
+			->filter($titleField, $term)
392
+			->first();
393
+		if ($record) {
394
+			return $record;
395
+		}
396
+
397
+		// Create new instance if not yet saved
398
+		if ($this->getCanCreate()) {
399
+			$dataClass = $source->dataClass();
400
+			$record = Injector::inst()->create($dataClass);
401
+
402
+			if (is_array($term)) {
403
+				$term = $term['Value'];
404
+			}
405
+
406
+			$record->{$titleField} = $term;
407
+			$record->write();
408
+			return $record;
409
+		}
410
+
411
+		return false;
412
+	}
413
+
414
+	/**
415
+	 * Returns a JSON string of tags, for lazy loading.
416
+	 *
417
+	 * @param  HTTPRequest $request
418
+	 * @return HTTPResponse
419
+	 */
420
+	public function suggest(HTTPRequest $request)
421
+	{
422
+		$tags = $this->getTags($request->getVar('term'));
423
+
424
+		$response = HTTPResponse::create();
425
+		$response->addHeader('Content-Type', 'application/json');
426
+		$response->setBody(json_encode(['items' => $tags]));
427
+
428
+		return $response;
429
+	}
430
+
431
+	/**
432
+	 * Returns array of arrays representing tags.
433
+	 *
434
+	 * @param  string $term
435
+	 * @return array
436
+	 */
437
+	protected function getTags($term)
438
+	{
439
+		$source = $this->getSourceList();
440
+
441
+		$titleField = $this->getTitleField();
442
+
443
+		$query = $source
444
+			->filter($titleField . ':PartialMatch:nocase', $term)
445
+			->sort($titleField)
446
+			->limit($this->getLazyLoadItemLimit());
447
+
448
+		// Map into a distinct list
449
+		$items = [];
450
+		$titleField = $this->getTitleField();
451
+		foreach ($query->map('ID', $titleField) as $id => $title) {
452
+			$items[$title] = [
453
+				'Title' => $title,
454
+				'Value' => $id,
455
+			];
456
+		}
457
+
458
+		return array_values($items);
459
+	}
460
+
461
+	/**
462
+	 * DropdownField assumes value will be a scalar so we must
463
+	 * override validate. This only applies to Silverstripe 3.2+
464
+	 *
465
+	 * @param Validator $validator
466
+	 * @return bool
467
+	 */
468
+	public function validate($validator)
469
+	{
470
+		return true;
471
+	}
472
+
473
+	/**
474
+	 * Converts the field to a readonly variant.
475
+	 *
476
+	 * @return ReadonlyTagField
477
+	 */
478
+	public function performReadonlyTransformation()
479
+	{
480
+		/** @var ReadonlyTagField $copy */
481
+		$copy = $this->castedCopy(ReadonlyTagField::class);
482
+		$copy->setSourceList($this->getSourceList());
483
+		return $copy;
484
+	}
485
+
486
+	/**
487
+	 * Prevent the default, which would return "tag"
488
+	 *
489
+	 * @return string
490
+	 */
491
+	public function Type()
492
+	{
493
+		return '';
494
+	}
495
+
496
+	public function getSchemaStateDefaults()
497
+	{
498
+		$data = parent::getSchemaStateDefaults();
499
+
500
+		// Add options to 'data'
501
+		$data['lazyLoad'] = $this->getShouldLazyLoad();
502
+		$data['multi'] = $this->getIsMultiple();
503
+		$data['optionUrl'] = $this->getSuggestURL();
504
+		$data['creatable'] = $this->getCanCreate();
505
+		$options = $this->getOptions(true);
506
+		$data['value'] = $options->count() ? $options->toNestedArray() : null;
507
+
508
+		return $data;
509
+	}
510 510
 }
511 511
 
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -220,7 +220,7 @@  discard block
 block discarded – undo
220 220
         $schema = array_merge(
221 221
             parent::getSchemaDataDefaults(),
222 222
             [
223
-                'name' => $this->getName() . '[]',
223
+                'name' => $this->getName().'[]',
224 224
                 'lazyLoad' => $this->getShouldLazyLoad(),
225 225
                 'creatable' => $this->getCanCreate(),
226 226
                 'multi' => $this->getIsMultiple(),
@@ -278,7 +278,7 @@  discard block
 block discarded – undo
278 278
         }
279 279
 
280 280
         // Prep a function to parse a dataobject into an option
281
-        $addOption = function (DataObject $item) use ($options, $values) {
281
+        $addOption = function(DataObject $item) use ($options, $values) {
282 282
             $titleField = $this->getTitleField();
283 283
             $options->push(ArrayData::create([
284 284
                 'Title' => $item->$titleField,
@@ -332,7 +332,7 @@  discard block
 block discarded – undo
332 332
         return array_merge(
333 333
             parent::getAttributes(),
334 334
             [
335
-                'name' => $this->getName() . '[]',
335
+                'name' => $this->getName().'[]',
336 336
                 'style' => 'width: 100%',
337 337
                 'data-schema' => json_encode($this->getSchemaData()),
338 338
             ]
@@ -441,7 +441,7 @@  discard block
 block discarded – undo
441 441
         $titleField = $this->getTitleField();
442 442
 
443 443
         $query = $source
444
-            ->filter($titleField . ':PartialMatch:nocase', $term)
444
+            ->filter($titleField.':PartialMatch:nocase', $term)
445 445
             ->sort($titleField)
446 446
             ->limit($this->getLazyLoadItemLimit());
447 447
 
Please login to merge, or discard this patch.