mirror of
https://github.com/silverstripe/silverstripe-tagfield
synced 2024-10-22 09:05:32 +00:00
ENH: Configuration enhancement (search, value sort fields, allow raw data storage).
This commit is contained in:
parent
176da2d434
commit
900938afbf
326
src/TagField.php
326
src/TagField.php
@ -49,10 +49,48 @@ class TagField extends MultiSelectField
|
||||
protected $canCreate = true;
|
||||
|
||||
/**
|
||||
* This is the field that populates the label displayed in the UI
|
||||
* It can be either a DB field or a model method name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $titleField = 'Title';
|
||||
|
||||
/**
|
||||
* This is the field that is used to store selected values
|
||||
* It has to be a DB field or null
|
||||
* Use null for the auto-detection
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $valueField = 'Title';
|
||||
|
||||
/**
|
||||
* This is the field which drives the "suggest" action via text-based search
|
||||
* It has to be a DB field
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $searchField = 'Title';
|
||||
|
||||
/**
|
||||
* This is the field which drives the order of results that appear in the "suggest" action via text-based search
|
||||
* It has to be a DB field or empty string
|
||||
* Use empty string to skip order customisation which will result in whatever order the source list is in
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $sortField = 'Title';
|
||||
|
||||
/**
|
||||
* Allow Raw data to be stored on the matching DB field of the model
|
||||
* Use this to cover cases which don't require form level data serialisation
|
||||
* such as MultiValueField (symbiote/silverstripe-multivaluefield)
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $allowRawValue = false;
|
||||
|
||||
/**
|
||||
* @var DataList
|
||||
*/
|
||||
@ -71,10 +109,29 @@ class TagField extends MultiSelectField
|
||||
* @param null|DataList|array $source
|
||||
* @param null|DataList $value
|
||||
* @param string $titleField
|
||||
* @param string|null $valueField
|
||||
* @param string|null $searchField
|
||||
* @param string|null $sortField
|
||||
* @param bool $allowRawValue
|
||||
*/
|
||||
public function __construct($name, $title = '', $source = [], $value = null, $titleField = 'Title')
|
||||
{
|
||||
$this->setTitleField($titleField);
|
||||
public function __construct(
|
||||
$name,
|
||||
$title = '',
|
||||
$source = [],
|
||||
$value = null,
|
||||
$titleField = 'Title',
|
||||
$valueField = null,
|
||||
$searchField = null,
|
||||
$sortField = null,
|
||||
$allowRawValue = false
|
||||
) {
|
||||
$this
|
||||
->setTitleField($titleField)
|
||||
->initValueField($valueField)
|
||||
->initSearchField($searchField)
|
||||
->initSortField($sortField)
|
||||
->setAllowRawValue($allowRawValue);
|
||||
|
||||
parent::__construct($name, $title, $source, $value);
|
||||
|
||||
$this->addExtraClass('ss-tag-field');
|
||||
@ -180,6 +237,82 @@ class TagField extends MultiSelectField
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $valueField
|
||||
* @return $this
|
||||
*/
|
||||
public function setValueField($valueField)
|
||||
{
|
||||
$this->valueField = $valueField;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValueField()
|
||||
{
|
||||
return $this->valueField;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $searchField
|
||||
* @return $this
|
||||
*/
|
||||
public function setSearchField($searchField)
|
||||
{
|
||||
$this->searchField = $searchField;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSearchField()
|
||||
{
|
||||
return $this->searchField;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fieldName
|
||||
* @return $this
|
||||
*/
|
||||
public function setSortField($fieldName)
|
||||
{
|
||||
$this->sortField = $fieldName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSortField()
|
||||
{
|
||||
return $this->sortField;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $allowRawValue
|
||||
* @return $this
|
||||
*/
|
||||
public function setAllowRawValue($allowRawValue)
|
||||
{
|
||||
$this->allowRawValue = $allowRawValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getAllowRawValue()
|
||||
{
|
||||
return $this->allowRawValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DataList source. The 4.x upgrade for SelectField::setSource starts to convert this to an array.
|
||||
* If empty use getSource() for array version
|
||||
@ -270,7 +403,6 @@ class TagField extends MultiSelectField
|
||||
}
|
||||
|
||||
$dataClass = $source->dataClass();
|
||||
|
||||
$values = $this->getValueArray();
|
||||
|
||||
// If we have no values and we only want selected options we can bail here
|
||||
@ -279,41 +411,33 @@ class TagField extends MultiSelectField
|
||||
}
|
||||
|
||||
$titleField = $this->getTitleField();
|
||||
$valueField = $this->getValueField();
|
||||
|
||||
// Convert an array of values into a datalist of options
|
||||
if (!$values instanceof SS_List) {
|
||||
if (is_array($values) && !empty($values)) {
|
||||
// if values is an array of Ids then we should look up via
|
||||
// ID.
|
||||
if (array_filter($values, 'is_int')) {
|
||||
$queryField = 'ID';
|
||||
} else {
|
||||
$queryField = $titleField;
|
||||
}
|
||||
|
||||
if (is_a($source, DataList::class)) {
|
||||
$values = $source->filterAny([
|
||||
$queryField => $values
|
||||
]);
|
||||
} else {
|
||||
$values = DataList::create($dataClass)
|
||||
$values = is_a($source, DataList::class)
|
||||
? $source->filterAny([
|
||||
$valueField => $values,
|
||||
])
|
||||
: DataList::create($dataClass)
|
||||
->filterAny([
|
||||
$queryField => $values
|
||||
$valueField => $values,
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
$values = ArrayList::create();
|
||||
}
|
||||
}
|
||||
|
||||
// Prep a function to parse a dataobject into an option
|
||||
$addOption = function (DataObject $item) use ($options, $values, $titleField) {
|
||||
$option = $item->$titleField;
|
||||
$addOption = function (DataObject $item) use ($options, $values, $titleField, $valueField) {
|
||||
$title = $item->{$titleField};
|
||||
$value = $item->{$valueField};
|
||||
|
||||
$options->push(ArrayData::create([
|
||||
'Title' => $option,
|
||||
'Value' => $option,
|
||||
'Selected' => (bool) $values->find($titleField, $option)
|
||||
'Title' => $title,
|
||||
'Value' => $value,
|
||||
'Selected' => (bool) $values->find($valueField, $value)
|
||||
]));
|
||||
};
|
||||
|
||||
@ -398,11 +522,11 @@ class TagField extends MultiSelectField
|
||||
}
|
||||
|
||||
if ($values instanceof SS_List) {
|
||||
return $values->column($this->getTitleField());
|
||||
return $values->column($this->getValueField());
|
||||
}
|
||||
|
||||
if ($values instanceof DataObject && $values->exists()) {
|
||||
return [$values->{$this->getTitleField()} ?? $values->ID];
|
||||
return [$values->{$this->getValueField()}];
|
||||
}
|
||||
|
||||
if (is_int($values)) {
|
||||
@ -412,15 +536,37 @@ class TagField extends MultiSelectField
|
||||
return [trim((string) $values)];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DataObjectInterface $record
|
||||
* @return void
|
||||
*/
|
||||
public function loadFrom(DataObjectInterface $record): void
|
||||
{
|
||||
$fieldName = $this->getName();
|
||||
|
||||
if (!$fieldName) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->getAllowRawValue()) {
|
||||
// Load raw value without de-serialisation
|
||||
$this->value = $record->{$fieldName};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
parent::loadFrom($record);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function saveInto(DataObjectInterface $record)
|
||||
{
|
||||
$name = $this->getName();
|
||||
$fieldName = $this->getName();
|
||||
$values = $this->getValueArray();
|
||||
|
||||
// We need to extract IDs as in some cases (Relation) we are unable to use the value field
|
||||
$ids = [];
|
||||
|
||||
if (!$values) {
|
||||
@ -431,37 +577,58 @@ class TagField extends MultiSelectField
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var Relation $relation */
|
||||
$relation = $record->hasMethod($name) ? $record->$name() : null;
|
||||
$valueField = $this->getValueField();
|
||||
$tag = null;
|
||||
$cleanValues = [];
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
foreach ($values as $value) {
|
||||
$tag = $this->getOrCreateTag($value);
|
||||
|
||||
if ($tag) {
|
||||
$ids[] = $tag->ID;
|
||||
$values[$key] = $tag->Title;
|
||||
if (!$tag) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ids[] = $tag->ID;
|
||||
$cleanValues[] = $tag->{$valueField};
|
||||
}
|
||||
|
||||
/** @var Relation $relation */
|
||||
$relation = $record->hasMethod($fieldName)
|
||||
? $record->$fieldName()
|
||||
: null;
|
||||
|
||||
if ($relation instanceof Relation) {
|
||||
// Save ids into relation
|
||||
// Save values into relation
|
||||
$relation->setByIDList(array_filter($ids ?? []));
|
||||
} elseif ($record->hasField($name)) {
|
||||
} elseif ($this->getAllowRawValue()) {
|
||||
// Store raw data without serialisation
|
||||
$record->{$fieldName} = $cleanValues;
|
||||
} elseif ($record->hasField($fieldName)) {
|
||||
if ($this->getIsMultiple()) {
|
||||
if ($record->obj($name) instanceof DBMultiEnum) {
|
||||
$record->{$fieldName} = $record->obj($fieldName) instanceof DBMultiEnum
|
||||
// Save dataValue into field... a CSV for DBMultiEnum
|
||||
$record->$name = $this->csvEncode(array_filter(array_values($values)));
|
||||
} else {
|
||||
? $this->csvEncode(array_filter(array_values($cleanValues)))
|
||||
// ... JSON-encoded string for other fields
|
||||
$record->$name = $this->stringEncode(array_filter(array_values($values)));
|
||||
}
|
||||
: $this->stringEncode(array_filter(array_values($cleanValues)));
|
||||
} else {
|
||||
if (isset($tag) && $tag->ID) {
|
||||
$record->$name = $tag->ID;
|
||||
} else {
|
||||
$record->$name = null;
|
||||
// Detect has one as this case needs ID as opposed to custom value
|
||||
$relations = $record->hasOne();
|
||||
$hasOneDetected = false;
|
||||
|
||||
foreach ($relations as $relationName => $relationTarget) {
|
||||
$foreignKey = $relationName . 'ID';
|
||||
|
||||
if ($foreignKey === $fieldName) {
|
||||
$hasOneDetected = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$targetField = $hasOneDetected ? 'ID' : $valueField;
|
||||
$record->{$fieldName} = $tag && $tag->{$targetField}
|
||||
? $tag->{$targetField}
|
||||
: null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -481,14 +648,14 @@ class TagField extends MultiSelectField
|
||||
|
||||
// Check if existing record can be found
|
||||
$source = $this->getSourceList();
|
||||
$titleField = $this->getTitleField();
|
||||
$valueField = $this->getValueField();
|
||||
|
||||
if (!$source) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$record = $source
|
||||
->filter($titleField, $value)
|
||||
->filter($valueField, $value)
|
||||
->first();
|
||||
|
||||
if ($record) {
|
||||
@ -499,7 +666,7 @@ class TagField extends MultiSelectField
|
||||
if ($this->getCanCreate() && $value) {
|
||||
$dataClass = $source->dataClass();
|
||||
$record = Injector::inst()->create($dataClass);
|
||||
$record->{$titleField} = $value;
|
||||
$record->{$valueField} = $value;
|
||||
$record->write();
|
||||
|
||||
if ($source instanceof SS_List) {
|
||||
@ -538,25 +705,33 @@ class TagField extends MultiSelectField
|
||||
protected function getTags($term)
|
||||
{
|
||||
$source = $this->getSourceList();
|
||||
|
||||
if (!$source) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$titleField = $this->getTitleField();
|
||||
$valueField = $this->getValueField();
|
||||
$searchField = $this->getSearchField();
|
||||
$sortField = $this->getSortField();
|
||||
|
||||
$query = $source
|
||||
->filter($titleField . ':PartialMatch:nocase', $term)
|
||||
->sort($titleField)
|
||||
$list = $source
|
||||
->filter($searchField . ':PartialMatch:nocase', $term)
|
||||
->limit($this->getLazyLoadItemLimit());
|
||||
|
||||
// Optionally apply sort
|
||||
if ($sortField) {
|
||||
$list = $list->sort($searchField);
|
||||
}
|
||||
|
||||
// Map into a distinct list
|
||||
$items = [];
|
||||
$titleField = $this->getTitleField();
|
||||
|
||||
foreach ($query->map('ID', $titleField)->values() as $title) {
|
||||
$items[$title] = [
|
||||
'Title' => $title,
|
||||
'Value' => $title,
|
||||
foreach ($list as $record) {
|
||||
$value = $record->{$valueField};
|
||||
$items[$value] = [
|
||||
'Title' => $record->{$titleField},
|
||||
'Value' => $value,
|
||||
];
|
||||
}
|
||||
|
||||
@ -624,4 +799,43 @@ class TagField extends MultiSelectField
|
||||
|
||||
return self::SCHEMA_DATA_TYPE_SINGLESELECT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a good default for value field
|
||||
*
|
||||
* @param string|null $value
|
||||
* @return $this
|
||||
*/
|
||||
protected function initValueField($value)
|
||||
{
|
||||
$value = $value ?? $this->getTitleField();
|
||||
|
||||
return $this->setValueField($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a good default for search field
|
||||
*
|
||||
* @param string|null $value
|
||||
* @return $this
|
||||
*/
|
||||
protected function initSearchField($value)
|
||||
{
|
||||
$value = $value ?? $this->getTitleField();
|
||||
|
||||
return $this->setSearchField($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a good default for sort field
|
||||
*
|
||||
* @param string|null $value
|
||||
* @return $this
|
||||
*/
|
||||
protected function initSortField($value)
|
||||
{
|
||||
$value = $value ?? $this->getSearchField();
|
||||
|
||||
return $this->setSortField($value);
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,14 @@ namespace SilverStripe\TagField\Tests\Stub;
|
||||
|
||||
use SilverStripe\Dev\TestOnly;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\TagField\Tests\Stub\TagFieldTestBlogTag;
|
||||
use SilverStripe\ORM\ManyManyList;
|
||||
|
||||
/**
|
||||
* @property string $Content
|
||||
* @property int $PrimaryTagID
|
||||
* @method TagFieldTestBlogTag PrimaryTag()
|
||||
* @method ManyManyList|TagFieldTestBlogTag[] Tags()
|
||||
*/
|
||||
class TagFieldTestBlogPost extends DataObject implements TestOnly
|
||||
{
|
||||
private static $table_name = 'TagFieldTestBlogPost';
|
||||
|
@ -4,8 +4,12 @@ namespace SilverStripe\TagField\Tests\Stub;
|
||||
|
||||
use SilverStripe\Dev\TestOnly;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\TagField\Tests\Stub\TagFieldTestBlogPost;
|
||||
use SilverStripe\ORM\ManyManyList;
|
||||
|
||||
/**
|
||||
* @property int Sort
|
||||
* @method ManyManyList|TagFieldTestBlogPost[] BlogPosts()
|
||||
*/
|
||||
class TagFieldTestBlogTag extends DataObject implements TestOnly
|
||||
{
|
||||
private static $table_name = 'TagFieldTestBlogTag';
|
||||
@ -13,10 +17,16 @@ class TagFieldTestBlogTag extends DataObject implements TestOnly
|
||||
private static $default_sort = '"TagFieldTestBlogTag"."ID" ASC';
|
||||
|
||||
private static $db = [
|
||||
'Title' => 'Varchar(200)'
|
||||
'Title' => 'Varchar(200)',
|
||||
'Sort' => 'Int',
|
||||
];
|
||||
|
||||
private static $belongs_many_many = [
|
||||
'BlogPosts' => TagFieldTestBlogPost::class
|
||||
];
|
||||
|
||||
public function getLabel(): string
|
||||
{
|
||||
return 'Label: ' . $this->Title;
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,12 @@
|
||||
|
||||
namespace SilverStripe\TagField\Tests;
|
||||
|
||||
use ReflectionMethod;
|
||||
use SilverStripe\Control\HTTPRequest;
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\Forms\FieldList;
|
||||
use SilverStripe\Forms\Form;
|
||||
use SilverStripe\ORM\ArrayList;
|
||||
use SilverStripe\ORM\DataList;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\TagField\ReadonlyTagField;
|
||||
@ -70,6 +72,104 @@ class TagFieldTest extends SapphireTest
|
||||
$this->assertEquals($tag->ID, $record->PrimaryTagID, 'The tag is saved to a has_one');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider rawValueStoreCasesProvider
|
||||
*/
|
||||
public function testItSavesToRawValue(bool $rawValueEnabled, mixed $values, mixed $expected): void
|
||||
{
|
||||
$record = $this->getNewTagFieldTestBlogPost('BlogPost1');
|
||||
$tag = new TagFieldTestBlogTag();
|
||||
$tag->Title = 'RawValueTest';
|
||||
$tag->write();
|
||||
|
||||
$field = new TagField('InMemoryOnlyProperty', '', new DataList(TagFieldTestBlogTag::class));
|
||||
$field->setAllowRawValue($rawValueEnabled);
|
||||
|
||||
$field->setValue($values);
|
||||
$field->saveInto($record);
|
||||
|
||||
$this->assertEquals($expected, $record->InMemoryOnlyProperty, 'We expect raw value to be stored');
|
||||
}
|
||||
|
||||
public function rawValueStoreCasesProvider(): array
|
||||
{
|
||||
return [
|
||||
'raw value disabled' => [
|
||||
false,
|
||||
'SampleValue1',
|
||||
null,
|
||||
],
|
||||
'raw value enabled (single value)' => [
|
||||
true,
|
||||
'SampleValue1',
|
||||
[
|
||||
'SampleValue1',
|
||||
],
|
||||
],
|
||||
'raw value enabled (multiple values)' => [
|
||||
true,
|
||||
[
|
||||
'SampleValue1',
|
||||
'SampleValue2',
|
||||
],
|
||||
[
|
||||
'SampleValue1',
|
||||
'SampleValue2',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider rawValueLoadCasesProvider
|
||||
*/
|
||||
public function testItLoadsFromRawValue(bool $rawValueEnabled, mixed $values, mixed $expected): void
|
||||
{
|
||||
$record = $this->getNewTagFieldTestBlogPost('BlogPost1');
|
||||
$tag = new TagFieldTestBlogTag();
|
||||
$tag->Title = 'RawValueTest';
|
||||
$tag->write();
|
||||
|
||||
$field = new TagField('InMemoryOnlyProperty', '', new DataList(TagFieldTestBlogTag::class));
|
||||
$field->setAllowRawValue($rawValueEnabled);
|
||||
$record->InMemoryOnlyProperty = $values;
|
||||
|
||||
$field->loadFrom($record);
|
||||
|
||||
$this->assertEquals($expected, $field->Value(), 'We expect raw value to be loaded');
|
||||
}
|
||||
|
||||
public function rawValueLoadCasesProvider(): array
|
||||
{
|
||||
return [
|
||||
'raw value disabled' => [
|
||||
false,
|
||||
null,
|
||||
[],
|
||||
],
|
||||
'raw value enabled (single value)' => [
|
||||
true,
|
||||
[
|
||||
'SampleValue1',
|
||||
],
|
||||
[
|
||||
'SampleValue1',
|
||||
],
|
||||
],
|
||||
'raw value enabled (multiple values)' => [
|
||||
true,
|
||||
[
|
||||
'SampleValue1',
|
||||
'SampleValue2',
|
||||
],
|
||||
[
|
||||
'SampleValue1',
|
||||
'SampleValue2',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
@ -429,6 +529,148 @@ class TagFieldTest extends SapphireTest
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider optionCasesProvider
|
||||
*/
|
||||
public function testGetOptionsWithConfigurableFields(
|
||||
?string $titleField,
|
||||
?string $valueField,
|
||||
array $expected
|
||||
): void {
|
||||
$source = TagFieldTestBlogTag::get();
|
||||
|
||||
$field = new TagField('TestField', null, $source);
|
||||
|
||||
if ($titleField) {
|
||||
$field->setTitleField($titleField);
|
||||
}
|
||||
|
||||
if ($valueField) {
|
||||
$field->setValueField($valueField);
|
||||
}
|
||||
|
||||
/** @see TagField::getOptions() */
|
||||
$getOptionsMethod = new ReflectionMethod($field, 'getOptions');
|
||||
|
||||
/** @var ArrayList $result */
|
||||
$result = $getOptionsMethod->invoke($field);
|
||||
|
||||
$data = $result
|
||||
->map('Title', 'Value')
|
||||
->toArray();
|
||||
$this->assertSame($expected, $data, 'We expect specific fields to be present');
|
||||
}
|
||||
|
||||
public function optionCasesProvider(): array
|
||||
{
|
||||
return [
|
||||
'default fields' => [
|
||||
null,
|
||||
null,
|
||||
[
|
||||
'Tag1' => 'Tag1',
|
||||
'222' => '222'
|
||||
],
|
||||
],
|
||||
'Label > Sort' => [
|
||||
'Label',
|
||||
'Sort',
|
||||
[
|
||||
'Label: Tag1' => 2,
|
||||
'Label: 222' => 1
|
||||
],
|
||||
],
|
||||
'Sort > Title' => [
|
||||
'Sort',
|
||||
'Title',
|
||||
[
|
||||
2 => 'Tag1',
|
||||
1 => '222'
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getTagsCasesProvider
|
||||
*/
|
||||
public function testGetTagsWithConfigurableFields(
|
||||
?string $titleField,
|
||||
?string $valueField,
|
||||
?string $searchField,
|
||||
?string $sortField,
|
||||
string $searchSubject,
|
||||
array $expected
|
||||
): void {
|
||||
$tag3 = TagFieldTestBlogTag::create();
|
||||
$tag3->Title = 'Tag3';
|
||||
$tag3->Sort = 3;
|
||||
$tag3->write();
|
||||
|
||||
$source = TagFieldTestBlogTag::get();
|
||||
|
||||
$field = new TagField('TestField', null, $source);
|
||||
|
||||
if ($titleField) {
|
||||
$field->setTitleField($titleField);
|
||||
}
|
||||
|
||||
if ($valueField) {
|
||||
$field->setValueField($valueField);
|
||||
}
|
||||
|
||||
if ($searchField) {
|
||||
$field->setSearchField($searchField);
|
||||
}
|
||||
|
||||
if ($sortField) {
|
||||
$field->setSortField($sortField);
|
||||
}
|
||||
|
||||
/** @see TagField::getTags() */
|
||||
$getTagsMethod = new ReflectionMethod($field, 'getTags');
|
||||
|
||||
/** @var ArrayList $result */
|
||||
$result = $getTagsMethod->invoke($field, $searchSubject);
|
||||
$data = [];
|
||||
|
||||
foreach ($result as $item) {
|
||||
$title = $item['Title'];
|
||||
$value = $item['Value'];
|
||||
$data[$title] = $value;
|
||||
}
|
||||
|
||||
$this->assertSame($expected, $data, 'We expect specific fields to be present');
|
||||
}
|
||||
|
||||
public function getTagsCasesProvider(): array
|
||||
{
|
||||
return [
|
||||
'default fields' => [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
'Tag',
|
||||
[
|
||||
'Tag1' => 'Tag1',
|
||||
'Tag3' => 'Tag3',
|
||||
],
|
||||
],
|
||||
'custom fields' => [
|
||||
'Label',
|
||||
'Sort',
|
||||
'Title',
|
||||
'Sort',
|
||||
'Tag',
|
||||
[
|
||||
'Label: Tag1' => 2,
|
||||
'Label: Tag3' => 3,
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function testGetSchemaDataDefaults()
|
||||
{
|
||||
$form = new Form(null, 'Form', new FieldList(), new FieldList());
|
||||
|
@ -1,11 +1,13 @@
|
||||
SilverStripe\TagField\Tests\Stub\TagFieldTestBlogTag:
|
||||
Tag1:
|
||||
Title: Tag1
|
||||
Title: 'Tag1'
|
||||
Sort: 2
|
||||
Tag2:
|
||||
Title: 222
|
||||
Title: '222'
|
||||
Sort: 1
|
||||
SilverStripe\TagField\Tests\Stub\TagFieldTestBlogPost:
|
||||
BlogPost1:
|
||||
Title: BlogPost1
|
||||
Title: 'BlogPost1'
|
||||
BlogPost2:
|
||||
Title: BlogPost2
|
||||
Title: 'BlogPost2'
|
||||
Tags: =>SilverStripe\TagField\Tests\Stub\TagFieldTestBlogTag.Tag1,=>SilverStripe\TagField\Tests\Stub\TagFieldTestBlogTag.Tag2
|
||||
|
Loading…
x
Reference in New Issue
Block a user