mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge branch '4.6' into 4
This commit is contained in:
commit
015ea8cfc8
@ -2,16 +2,17 @@
|
|||||||
|
|
||||||
namespace SilverStripe\Forms;
|
namespace SilverStripe\Forms;
|
||||||
|
|
||||||
use SilverStripe\Core\Convert;
|
|
||||||
use SilverStripe\Control\Controller;
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Core\Convert;
|
||||||
use SilverStripe\ORM\ArrayList;
|
use SilverStripe\ORM\ArrayList;
|
||||||
use SilverStripe\ORM\DataList;
|
use SilverStripe\ORM\DataList;
|
||||||
use SilverStripe\ORM\DataObject;
|
use SilverStripe\ORM\DataObject;
|
||||||
use SilverStripe\ORM\DataObjectInterface;
|
use SilverStripe\ORM\DataObjectInterface;
|
||||||
use SilverStripe\ORM\FieldType\DBHTMLText;
|
use SilverStripe\ORM\FieldType\DBHTMLText;
|
||||||
|
use SilverStripe\ORM\Relation;
|
||||||
|
use SilverStripe\ORM\SS_List;
|
||||||
use SilverStripe\Security\Group;
|
use SilverStripe\Security\Group;
|
||||||
use SilverStripe\View\ViewableData;
|
use SilverStripe\View\ViewableData;
|
||||||
use stdClass;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This formfield represents many-many joins using a tree selector shown in a dropdown styled element
|
* This formfield represents many-many joins using a tree selector shown in a dropdown styled element
|
||||||
@ -119,48 +120,72 @@ class TreeMultiselectField extends TreeDropdownField
|
|||||||
*/
|
*/
|
||||||
public function getItems()
|
public function getItems()
|
||||||
{
|
{
|
||||||
$items = new ArrayList();
|
$value = $this->Value();
|
||||||
|
|
||||||
// If the value has been set, use that
|
// If unchanged, load from record
|
||||||
if ($this->value != 'unchanged') {
|
if ($value === 'unchanged') {
|
||||||
$sourceObject = $this->getSourceObject();
|
// Verify a form exists
|
||||||
if (is_array($sourceObject)) {
|
$form = $this->getForm();
|
||||||
$values = is_array($this->value) ? $this->value : preg_split('/ *, */', trim($this->value));
|
if (!$form) {
|
||||||
|
return ArrayList::create();
|
||||||
foreach ($values as $value) {
|
|
||||||
$item = new stdClass;
|
|
||||||
$item->ID = $value;
|
|
||||||
$item->Title = $sourceObject[$value];
|
|
||||||
$items->push($item);
|
|
||||||
}
|
|
||||||
return $items;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, look data up from the linked relation
|
// Verify this form has an attached record with the necessary relation
|
||||||
if (is_string($this->value)) {
|
$fieldName = $this->getName();
|
||||||
$ids = explode(',', $this->value);
|
$record = $form->getRecord();
|
||||||
foreach ($ids as $id) {
|
if ($record instanceof DataObject && $record->hasMethod($fieldName)) {
|
||||||
if (!is_numeric($id)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$item = DataObject::get_by_id($sourceObject, $id);
|
|
||||||
if ($item) {
|
|
||||||
$items->push($item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $items;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->form) {
|
|
||||||
$fieldName = $this->name;
|
|
||||||
$record = $this->form->getRecord();
|
|
||||||
if (is_object($record) && $record->hasMethod($fieldName)) {
|
|
||||||
return $record->$fieldName();
|
return $record->$fieldName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No relation on parent record found
|
||||||
|
return ArrayList::create();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $items;
|
// Value is a list
|
||||||
|
if ($value instanceof SS_List) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse ids from value string / array
|
||||||
|
$ids = [];
|
||||||
|
if (is_string($value)) {
|
||||||
|
$ids = preg_split("#\s*,\s*#", trim($value));
|
||||||
|
} elseif (is_array($value)) {
|
||||||
|
$ids = array_values($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// No value
|
||||||
|
if (empty($ids)) {
|
||||||
|
return ArrayList::create();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query source records by value field
|
||||||
|
return DataObject::get($this->getSourceObject())
|
||||||
|
->filter($this->getKeyField(), $ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setValue($value, $source = null)
|
||||||
|
{
|
||||||
|
// If loading from a dataobject, get items by relation
|
||||||
|
if ($source instanceof DataObject) {
|
||||||
|
$name = $this->getName();
|
||||||
|
if ($source->hasMethod($name)) {
|
||||||
|
$value = $source->$name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle legacy value; form-submitted `unchanged` implies empty set.
|
||||||
|
// See TreeDropdownField.js
|
||||||
|
if ($value === 'unchanged') {
|
||||||
|
$value = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::setValue($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataValue()
|
||||||
|
{
|
||||||
|
return $this->getItems()->column($this->getKeyField());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -221,10 +246,10 @@ class TreeMultiselectField extends TreeDropdownField
|
|||||||
*/
|
*/
|
||||||
public function saveInto(DataObjectInterface $record)
|
public function saveInto(DataObjectInterface $record)
|
||||||
{
|
{
|
||||||
$items = [];
|
$fieldName = $this->getName();
|
||||||
$fieldName = $this->name;
|
|
||||||
$saveDest = $record->$fieldName();
|
|
||||||
|
|
||||||
|
/** @var Relation $saveDest */
|
||||||
|
$saveDest = $record->$fieldName();
|
||||||
if (!$saveDest) {
|
if (!$saveDest) {
|
||||||
$recordClass = get_class($record);
|
$recordClass = get_class($record);
|
||||||
user_error(
|
user_error(
|
||||||
@ -234,24 +259,17 @@ class TreeMultiselectField extends TreeDropdownField
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect whether this field has actually been updated
|
$itemIDs = $this->getItems()->column('ID');
|
||||||
if ($this->value !== 'unchanged') {
|
|
||||||
if (is_array($this->value)) {
|
|
||||||
$items = $this->value;
|
|
||||||
} elseif ($this->value) {
|
|
||||||
$items = preg_split("/ *, */", trim($this->value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allows you to modify the items on your object before save
|
// Allows you to modify the itemIDs on your object before save
|
||||||
$funcName = "onChange$fieldName";
|
$funcName = "onChange$fieldName";
|
||||||
if ($record->hasMethod($funcName)) {
|
if ($record->hasMethod($funcName)) {
|
||||||
$result = $record->$funcName($items);
|
$result = $record->$funcName($itemIDs);
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$saveDest->setByIDList($items);
|
$saveDest->setByIDList($itemIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -96,11 +96,10 @@ class DBForeignKey extends DBInt
|
|||||||
// Remove distinct. Applying distinct shouldn't be required provided relations are not applied.
|
// Remove distinct. Applying distinct shouldn't be required provided relations are not applied.
|
||||||
$dataQuery->setDistinct(false);
|
$dataQuery->setDistinct(false);
|
||||||
|
|
||||||
$dataQuery->setSelect(['over_threshold' => 'count(*) > ' . (int) $threshold]);
|
$dataQuery->setSelect(['over_threshold' => '(CASE WHEN count(*) > ' . (int)$threshold . ' THEN 1 ELSE 0 END)']);
|
||||||
$result = $dataQuery->execute()->column('over_threshold');
|
$result = $dataQuery->execute()->column('over_threshold');
|
||||||
|
|
||||||
// Checking for 't' supports PostgreSQL before silverstripe/postgresql@2.2
|
$overThreshold = !empty($result) && ((int) $result[0] === 1);
|
||||||
$overThreshold = !empty($result) && ($result[0] === 't' || (int) $result[0] === 1);
|
|
||||||
|
|
||||||
static::$foreignListCache[$hasOneClass] = [
|
static::$foreignListCache[$hasOneClass] = [
|
||||||
'overThreshold' => $overThreshold,
|
'overThreshold' => $overThreshold,
|
||||||
|
@ -301,4 +301,44 @@ class TreeMultiselectFieldTest extends SapphireTest
|
|||||||
$this->assertContains($field->ID(), $html);
|
$this->assertContains($field->ID(), $html);
|
||||||
$this->assertContains($this->fieldValue, $html);
|
$this->assertContains($this->fieldValue, $html);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetItems()
|
||||||
|
{
|
||||||
|
// Default items scaffolded from 'unchanged' value (empty)
|
||||||
|
$field = $this->field;
|
||||||
|
$this->assertListEquals(
|
||||||
|
[],
|
||||||
|
$field->getItems()
|
||||||
|
);
|
||||||
|
|
||||||
|
$expectedItem = array_map(
|
||||||
|
function ($folder) {
|
||||||
|
return [
|
||||||
|
'Filename' => $folder->Filename,
|
||||||
|
];
|
||||||
|
},
|
||||||
|
$this->loadFolders()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set list of items by array of ids
|
||||||
|
$field->setValue($this->folderIds);
|
||||||
|
$this->assertListEquals(
|
||||||
|
$expectedItem,
|
||||||
|
$field->getItems()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set list of items by comma separated ids
|
||||||
|
$field->setValue($this->fieldValue);
|
||||||
|
$this->assertListEquals(
|
||||||
|
$expectedItem,
|
||||||
|
$field->getItems()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Handle legacy empty value (form submits 'unchanged')
|
||||||
|
$field->setValue('unchanged');
|
||||||
|
$this->assertListEquals(
|
||||||
|
[],
|
||||||
|
$field->getItems()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user