Skip to content

Commit

Permalink
Merge pull request #11049 from creative-commoners/pulls/5/gridfield-w…
Browse files Browse the repository at this point in the history
…ith-viewabledata

Make GridField components work with ViewableData where possible
  • Loading branch information
Maxime Rainville authored Dec 19, 2023
2 parents e7775a6 + 7073246 commit 6c69d32
Show file tree
Hide file tree
Showing 42 changed files with 1,456 additions and 146 deletions.
17 changes: 8 additions & 9 deletions src/Forms/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
use SilverStripe\Control\Session;
use SilverStripe\Core\ClassInfo;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\ORM\FieldType\DBHTMLText;
use SilverStripe\ORM\ValidationResult;
Expand Down Expand Up @@ -136,7 +135,7 @@ class Form extends ViewableData implements HasRequestHandler
/**
* Populated by {@link loadDataFrom()}.
*
* @var DataObject|null
* @var ViewableData|null
*/
protected $record;

Expand Down Expand Up @@ -1223,10 +1222,10 @@ public function sessionFieldError($message, $fieldName, $type = ValidationResult
}

/**
* Returns the DataObject that has given this form its data
* Returns the record that has given this form its data
* through {@link loadDataFrom()}.
*
* @return DataObject
* @return ViewableData
*/
public function getRecord()
{
Expand Down Expand Up @@ -1285,7 +1284,7 @@ public function validationResult()
const MERGE_AS_SUBMITTED_VALUE = 0b1000;

/**
* Load data from the given DataObject or array.
* Load data from the given record or array.
*
* It will call $object->MyField to get the value of MyField.
* If you passed an array, it will call $object[MyField].
Expand All @@ -1306,7 +1305,7 @@ public function validationResult()
* @uses FormField::setSubmittedValue()
* @uses FormField::setValue()
*
* @param array|DataObject $data
* @param array|ViewableData $data
* @param int $mergeStrategy
* For every field, {@link $data} is interrogated whether it contains a relevant property/key, and
* what that property/key's value is.
Expand Down Expand Up @@ -1351,7 +1350,7 @@ public function loadDataFrom($data, $mergeStrategy = 0, $fieldList = null)

// If an object is passed, save it for historical reference through {@link getRecord()}
// Also use this to determine if we are loading a submitted form, or loading
// from a dataobject
// from a record
$submitted = true;
if (is_object($data)) {
$this->record = $data;
Expand Down Expand Up @@ -1480,7 +1479,7 @@ public function loadDataFrom($data, $mergeStrategy = 0, $fieldList = null)
* Save the contents of this form into the given data object.
* It will make use of setCastedField() to do this.
*
* @param DataObjectInterface $dataObject The object to save data into
* @param ViewableData&DataObjectInterface $dataObject The object to save data into
* @param FieldList $fieldList An optional list of fields to process. This can be useful when you have a
* form that has some fields that save to one object, and some that save to another.
*/
Expand Down Expand Up @@ -1523,7 +1522,7 @@ public function saveInto(DataObjectInterface $dataObject, $fieldList = null)
* {@link FieldList->dataFields()}, which filters out
* any form-specific data like form-actions.
* Calls {@link FormField->dataValue()} on each field,
* which returns a value suitable for insertion into a DataObject
* which returns a value suitable for insertion into a record
* property.
*
* @return array
Expand Down
10 changes: 5 additions & 5 deletions src/Forms/FormField.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
use SilverStripe\Control\RequestHandler;
use SilverStripe\Core\ClassInfo;
use SilverStripe\Core\Convert;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\ORM\FieldType\DBHTMLText;
use SilverStripe\ORM\ValidationResult;
use SilverStripe\View\AttributesHTML;
use SilverStripe\View\SSViewer;
use SilverStripe\View\ViewableData;

/**
* Represents a field in a form.
Expand Down Expand Up @@ -454,11 +454,11 @@ public function Value()
}

/**
* Method to save this form field into the given {@link DataObject}.
* Method to save this form field into the given record.
*
* By default, makes use of $this->dataValue()
*
* @param DataObject|DataObjectInterface $record DataObject to save data into
* @param ViewableData|DataObjectInterface $record Record to save data into
*/
public function saveInto(DataObjectInterface $record)
{
Expand Down Expand Up @@ -697,7 +697,7 @@ public function attrValue()
* or a submitted form value they should override setSubmittedValue() instead.
*
* @param mixed $value Either the parent object, or array of source data being loaded
* @param array|DataObject $data {@see Form::loadDataFrom}
* @param array|ViewableData $data {@see Form::loadDataFrom}
* @return $this
*/
public function setValue($value, $data = null)
Expand All @@ -712,7 +712,7 @@ public function setValue($value, $data = null)
* data formats.
*
* @param mixed $value
* @param array|DataObject $data
* @param array|ViewableData $data
* @return $this
*/
public function setSubmittedValue($value, $data = null)
Expand Down
33 changes: 18 additions & 15 deletions src/Forms/GridField/GridField.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@
use SilverStripe\Forms\GridField\FormAction\StateStore;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\ORM\Filterable;
use SilverStripe\ORM\Limitable;
use SilverStripe\ORM\Sortable;
use SilverStripe\ORM\SS_List;
use SilverStripe\View\HTML;
use SilverStripe\View\ViewableData;

/**
* Displays a {@link SS_List} in a grid format.
Expand Down Expand Up @@ -83,12 +86,12 @@ class GridField extends FormField
/**
* Data source.
*
* @var SS_List
* @var SS_List&Filterable&Sortable&Limitable
*/
protected $list = null;

/**
* Class name of the DataObject that the GridField will display.
* Class name of the records that the GridField will display.
*
* Defaults to the value of $this->list->dataClass.
*
Expand Down Expand Up @@ -205,7 +208,7 @@ public function setModelClass($modelClassName)
}

/**
* Returns a data class that is a DataObject type that this GridField should look like.
* Returns the class name of the record type that this GridField should contain.
*
* @return string
*
Expand Down Expand Up @@ -374,7 +377,7 @@ public function getCastedValue($value, $castingDefinition)
/**
* Set the data source.
*
* @param SS_List $list
* @param SS_List&Filterable&Sortable&Limitable $list
*
* @return $this
*/
Expand All @@ -388,7 +391,7 @@ public function setList(SS_List $list)
/**
* Get the data source.
*
* @return SS_List
* @return SS_List&Filterable&Sortable&Limitable
*/
public function getList()
{
Expand All @@ -398,7 +401,7 @@ public function getList()
/**
* Get the data source after applying every {@link GridField_DataManipulator} to it.
*
* @return SS_List
* @return SS_List&Filterable&Sortable&Limitable
*/
public function getManipulatedList()
{
Expand Down Expand Up @@ -461,7 +464,7 @@ private function addStateFromRequest(): void
if (($request instanceof NullHTTPRequest) && Controller::has_curr()) {
$request = Controller::curr()->getRequest();
}

$stateStr = $this->getStateManager()->getStateFromRequest($this, $request);
if ($stateStr) {
$oldState = $this->getState(false);
Expand Down Expand Up @@ -744,7 +747,7 @@ public function FieldHolder($properties = [])
/**
* @param int $total
* @param int $index
* @param DataObject $record
* @param ViewableData $record
* @param array $attributes
* @param string $content
*
Expand All @@ -762,7 +765,7 @@ protected function newCell($total, $index, $record, $attributes, $content)
/**
* @param int $total
* @param int $index
* @param DataObject $record
* @param ViewableData $record
* @param array $attributes
* @param string $content
*
Expand All @@ -780,7 +783,7 @@ protected function newRow($total, $index, $record, $attributes, $content)
/**
* @param int $total
* @param int $index
* @param DataObject $record
* @param ViewableData $record
*
* @return array
*/
Expand All @@ -798,7 +801,7 @@ protected function getRowAttributes($total, $index, $record)
/**
* @param int $total
* @param int $index
* @param DataObject $record
* @param ViewableData $record
*
* @return array
*/
Expand Down Expand Up @@ -869,7 +872,7 @@ public function getColumns()
/**
* Get the value from a column.
*
* @param DataObject $record
* @param ViewableData $record
* @param string $column
*
* @return string
Expand Down Expand Up @@ -922,7 +925,7 @@ public function addDataFields($fields)
* Use of this method ensures that any special rules around the data for this gridfield are
* followed.
*
* @param DataObject $record
* @param ViewableData $record
* @param string $fieldName
*
* @return mixed
Expand All @@ -949,7 +952,7 @@ public function getDataFieldValue($record, $fieldName)
/**
* Get extra columns attributes used as HTML attributes.
*
* @param DataObject $record
* @param ViewableData $record
* @param string $column
*
* @return array
Expand Down
26 changes: 25 additions & 1 deletion src/Forms/GridField/GridFieldAddExistingAutocompleter.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
*
* For easier setup, have a look at a sample configuration in
* {@link GridFieldConfig_RelationEditor}.
*
* The modelClass of the GridField this component is in must be a DataObject subclass.
*/
class GridFieldAddExistingAutocompleter extends AbstractGridFieldComponent implements GridField_HTMLProvider, GridField_ActionProvider, GridField_DataManipulator, GridField_URLHandler
{
Expand Down Expand Up @@ -106,6 +108,10 @@ public function getHTMLFragments($gridField)
{
$dataClass = $gridField->getModelClass();

if (!is_a($dataClass, DataObject::class, true)) {
throw new LogicException(__CLASS__ . " must be used with DataObject subclasses. Found '$dataClass'");
}

$forTemplate = new ArrayData([]);
$forTemplate->Fields = new FieldList();

Expand Down Expand Up @@ -191,11 +197,17 @@ public function handleAction(GridField $gridField, $actionName, $arguments, $dat
*/
public function getManipulatedData(GridField $gridField, SS_List $dataList)
{
$dataClass = $gridField->getModelClass();

if (!is_a($dataClass, DataObject::class, true)) {
throw new LogicException(__CLASS__ . " must be used with DataObject subclasses. Found '$dataClass'");
}

$objectID = $gridField->State->GridFieldAddRelation(null);
if (empty($objectID)) {
return $dataList;
}
$object = DataObject::get_by_id($gridField->getModelClass(), $objectID);
$object = DataObject::get_by_id($dataClass, $objectID);
if ($object) {
$dataList->add($object);
}
Expand Down Expand Up @@ -227,6 +239,10 @@ public function doSearch($gridField, $request)
$searchStr = $request->getVar('gridfield_relationsearch');
$dataClass = $gridField->getModelClass();

if (!is_a($dataClass, DataObject::class, true)) {
throw new LogicException(__CLASS__ . " must be used with DataObject subclasses. Found '$dataClass'");
}

$searchFields = ($this->getSearchFields())
? $this->getSearchFields()
: $this->scaffoldSearchFields($dataClass);
Expand Down Expand Up @@ -337,6 +353,10 @@ public function getSearchFields()
*/
public function scaffoldSearchFields($dataClass)
{
if (!is_a($dataClass, DataObject::class, true)) {
throw new LogicException(__CLASS__ . " must be used with DataObject subclasses. Found '$dataClass'");
}

$obj = DataObject::singleton($dataClass);
$fields = null;
if ($fieldSpecs = $obj->searchableFields()) {
Expand Down Expand Up @@ -387,6 +407,10 @@ public function scaffoldSearchFields($dataClass)
*/
public function getPlaceholderText($dataClass)
{
if (!is_a($dataClass, DataObject::class, true)) {
throw new LogicException(__CLASS__ . " must be used with DataObject subclasses. Found '$dataClass'");
}

$searchFields = ($this->getSearchFields())
? $this->getSearchFields()
: $this->scaffoldSearchFields($dataClass);
Expand Down
18 changes: 14 additions & 4 deletions src/Forms/GridField/GridFieldAddNewButton.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace SilverStripe\Forms\GridField;

use LogicException;
use SilverStripe\Control\Controller;
use SilverStripe\Core\ClassInfo;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\RelationList;
use SilverStripe\View\ArrayData;
Expand All @@ -12,8 +14,7 @@
* This component provides a button for opening the add new form provided by
* {@link GridFieldDetailForm}.
*
* Only returns a button if {@link DataObject->canCreate()} for this record
* returns true.
* Only returns a button if canCreate() for this record returns true.
*/
class GridFieldAddNewButton extends AbstractGridFieldComponent implements GridField_HTMLProvider
{
Expand All @@ -36,7 +37,16 @@ public function __construct($targetFragment = 'before')

public function getHTMLFragments($gridField)
{
$singleton = singleton($gridField->getModelClass());
$modelClass = $gridField->getModelClass();
$singleton = singleton($modelClass);

if (!$singleton->hasMethod('canCreate')) {
throw new LogicException(
__CLASS__ . ' cannot be used with models that do not implement canCreate().'
. " Remove this component from your GridField or implement canCreate() on $modelClass"
);
}

$context = [];
if ($gridField->getList() instanceof RelationList) {
$record = $gridField->getForm()->getRecord();
Expand All @@ -51,7 +61,7 @@ public function getHTMLFragments($gridField)

if (!$this->buttonName) {
// provide a default button name, can be changed by calling {@link setButtonName()} on this component
$objectName = $singleton->i18n_singular_name();
$objectName = $singleton->hasMethod('i18n_singular_name') ? $singleton->i18n_singular_name() : ClassInfo::shortName($singleton);
$this->buttonName = _t('SilverStripe\\Forms\\GridField\\GridField.Add', 'Add {name}', ['name' => $objectName]);
}

Expand Down
Loading

0 comments on commit 6c69d32

Please sign in to comment.