From 9421e854836987a61804f8e4ef13ef2f21fd3ae0 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Fri, 15 Sep 2017 16:01:32 +1200 Subject: [PATCH] BUG Fix inline editing / sortable --- src/GridFieldAddNewInlineButton.php | 28 +++++++++++++++++-------- src/GridFieldAddNewMultiClass.php | 26 ++++++++++++++++++++--- src/GridFieldEditableColumns.php | 32 ++++++++++++++++++++++------- 3 files changed, 68 insertions(+), 18 deletions(-) diff --git a/src/GridFieldAddNewInlineButton.php b/src/GridFieldAddNewInlineButton.php index 7887cfba..6e7d6e62 100755 --- a/src/GridFieldAddNewInlineButton.php +++ b/src/GridFieldAddNewInlineButton.php @@ -8,7 +8,9 @@ use SilverStripe\Forms\GridField\GridField_HTMLProvider; use SilverStripe\Forms\GridField\GridField_SaveHandler; use SilverStripe\ORM\ArrayList; +use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObjectInterface; +use SilverStripe\ORM\FieldType\DBField; use SilverStripe\ORM\ManyManyList; use SilverStripe\View\ArrayData; use SilverStripe\Core\Injector\Injector; @@ -20,6 +22,10 @@ */ class GridFieldAddNewInlineButton implements GridField_HTMLProvider, GridField_SaveHandler { + /** + * @skipUpgrade + */ + const POST_KEY = 'GridFieldAddNewInlineButton'; private $fragment; @@ -86,7 +92,9 @@ public function getHTMLFragments($grid) $fragment = $this->getFragment(); - if (!$editable = $grid->getConfig()->getComponentByType(GridFieldEditableColumns::class)) { + /** @var GridFieldEditableColumns $editable */ + $editable = $grid->getConfig()->getComponentByType(GridFieldEditableColumns::class); + if (!$editable) { throw new Exception('Inline adding requires the editable columns component'); } @@ -122,7 +130,7 @@ private function getRowTemplate(GridField $grid, GridFieldEditableColumns $edita $field->setName(sprintf( '%s[%s][{%%=o.num%%}][%s]', $grid->getName(), - __CLASS__, + self::POST_KEY, $field->getName() )); @@ -132,10 +140,13 @@ private function getRowTemplate(GridField $grid, GridFieldEditableColumns $edita // Convert GridFieldEditableColumns to the template format $content = str_replace( - '[GridFieldEditableColumns][0]', - '[GridFieldAddNewInlineButton][{%=o.num%}]', + sprintf('[%s][0]', GridFieldEditableColumns::POST_KEY), + sprintf('[%s][{%%=o.num%%}]', self::POST_KEY), $content ); + + // Cast content as HTML + $content = DBField::create_field('HTMLFragment', $content); } $attrs = ''; @@ -159,22 +170,23 @@ public function handleSave(GridField $grid, DataObjectInterface $record) $list = $grid->getList(); $value = $grid->Value(); - if (!isset($value[__CLASS__]) || !is_array($value[__CLASS__])) { + if (!isset($value[self::POST_KEY]) || !is_array($value[self::POST_KEY])) { return; } $class = $grid->getModelClass(); /** @var GridFieldEditableColumns $editable */ - $editable = $grid->getConfig()->getComponentByType('Symbiote\\GridFieldExtensions\\GridFieldEditableColumns'); + $editable = $grid->getConfig()->getComponentByType(GridFieldEditableColumns::class); /** @var GridFieldOrderableRows $sortable */ - $sortable = $grid->getConfig()->getComponentByType('Symbiote\\GridFieldExtensions\\GridFieldOrderableRows'); + $sortable = $grid->getConfig()->getComponentByType(GridFieldOrderableRows::class); $form = $editable->getForm($grid, $record); if (!singleton($class)->canCreate()) { return; } - foreach ($value[__CLASS__] as $fields) { + foreach ($value[self::POST_KEY] as $fields) { + /** @var DataObject $item */ $item = $class::create(); $extra = array(); diff --git a/src/GridFieldAddNewMultiClass.php b/src/GridFieldAddNewMultiClass.php index 38ce6c96..ad2f4906 100755 --- a/src/GridFieldAddNewMultiClass.php +++ b/src/GridFieldAddNewMultiClass.php @@ -3,6 +3,7 @@ namespace Symbiote\GridFieldExtensions; use SilverStripe\Control\Controller; +use SilverStripe\Control\HTTPRequest; use SilverStripe\Control\HTTPResponse_Exception; use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Config\Config; @@ -11,6 +12,7 @@ use SilverStripe\Forms\GridField\GridField; use SilverStripe\Forms\GridField\GridField_HTMLProvider; use SilverStripe\Forms\GridField\GridField_URLHandler; +use SilverStripe\Forms\GridField\GridFieldDetailForm; use SilverStripe\View\ArrayData; use ReflectionClass; use Exception; @@ -23,6 +25,10 @@ */ class GridFieldAddNewMultiClass implements GridField_HTMLProvider, GridField_URLHandler { + /** + * @skipUpgrade + */ + const POST_KEY = 'GridFieldAddNewMultiClass'; private static $allowed_actions = array( 'handleAdd' @@ -35,8 +41,14 @@ class GridFieldAddNewMultiClass implements GridField_HTMLProvider, GridField_URL private $title; + /** + * @var array + */ private $classes; + /** + * @var string + */ private $defaultClass; /** @@ -157,6 +169,7 @@ public function getClasses(GridField $grid) * Sets the classes that can be created using this button. * * @param array $classes a set of class names, optionally mapped to titles + * @param string $default * @return GridFieldAddNewMultiClass $this */ public function setClasses(array $classes, $default = null) @@ -184,14 +197,17 @@ public function setDefaultClass($default) * Handles adding a new instance of a selected class. * * @param GridField $grid - * @param SS_HTTPRequest $request + * @param HTTPRequest $request * @return GridFieldAddNewMultiClassHandler + * @throws Exception + * @throws HTTPResponse_Exception */ public function handleAdd($grid, $request) { $class = $request->param('ClassName'); $classes = $this->getClasses($grid); - $component = $grid->getConfig()->getComponentByType('SilverStripe\\Forms\\GridField\\GridFieldDetailForm'); + /** @var GridFieldDetailForm $component */ + $component = $grid->getConfig()->getComponentByType(GridFieldDetailForm::class); if (!$component) { throw new Exception('The add new multi class component requires the detail form component.'); @@ -228,7 +244,7 @@ public function getHTMLFragments($grid) GridFieldExtensions::include_requirements(); - $field = new DropdownField(sprintf('%s[ClassName]', __CLASS__), '', $classes, $this->defaultClass); + $field = new DropdownField(sprintf('%s[ClassName]', self::POST_KEY), '', $classes, $this->defaultClass); if (Config::inst()->get(__CLASS__, 'showEmptyString')) { $field->setEmptyString(_t('GridFieldExtensions.SELECTTYPETOCREATE', '(Select type to create)')); } @@ -263,6 +279,8 @@ public function setItemRequestClass($class) /** * Sanitise a model class' name for inclusion in a link + * + * @param string $class * @return string */ protected function sanitiseClassName($class) @@ -272,6 +290,8 @@ protected function sanitiseClassName($class) /** * Unsanitise a model class' name from a URL param + * + * @param string $class * @return string */ protected function unsanitiseClassName($class) diff --git a/src/GridFieldEditableColumns.php b/src/GridFieldEditableColumns.php index 11653e23..0e7128a3 100644 --- a/src/GridFieldEditableColumns.php +++ b/src/GridFieldEditableColumns.php @@ -2,7 +2,9 @@ namespace Symbiote\GridFieldExtensions; +use Closure; use SilverStripe\Control\Controller; +use SilverStripe\Control\HTTPRequest; use SilverStripe\Control\HTTPResponse_Exception; use SilverStripe\Core\Injector\Injector; use SilverStripe\Forms\FieldList; @@ -13,8 +15,11 @@ use SilverStripe\Forms\GridField\GridField_HTMLProvider; use SilverStripe\Forms\GridField\GridField_SaveHandler; use SilverStripe\Forms\GridField\GridField_URLHandler; +use SilverStripe\Forms\HTMLEditor\HTMLEditorField; use SilverStripe\Forms\LiteralField; use SilverStripe\Forms\ReadonlyField; +use SilverStripe\ORM\DataList; +use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObjectInterface; use SilverStripe\ORM\ManyManyList; use Exception; @@ -34,6 +39,10 @@ class GridFieldEditableColumns extends GridFieldDataColumns implements GridField_SaveHandler, GridField_URLHandler { + /** + * @skipUpgrade + */ + const POST_KEY = 'GridFieldEditableColumns'; private static $allowed_actions = array( 'handleForm' @@ -104,19 +113,20 @@ public function getHTMLFragments($grid) public function handleSave(GridField $grid, DataObjectInterface $record) { + /** @var DataList $list */ $list = $grid->getList(); $value = $grid->Value(); - if (!isset($value[__CLASS__]) || !is_array($value[__CLASS__])) { + if (!isset($value[self::POST_KEY]) || !is_array($value[self::POST_KEY])) { return; } /** @var GridFieldOrderableRows $sortable */ - $sortable = $grid->getConfig()->getComponentByType('Symbiote\\GridFieldExtensions\\GridFieldOrderableRows'); + $sortable = $grid->getConfig()->getComponentByType(GridFieldOrderableRows::class); $form = $this->getForm($grid, $record); - foreach ($value[__CLASS__] as $id => $fields) { + foreach ($value[self::POST_KEY] as $id => $fields) { if (!is_numeric($id) || !is_array($fields)) { continue; } @@ -147,6 +157,12 @@ public function handleSave(GridField $grid, DataObjectInterface $record) } } + /** + * @param GridField $grid + * @param HTTPRequest $request + * @return Form + * @throws HTTPResponse_Exception + */ public function handleForm(GridField $grid, $request) { $id = $request->param('ID'); @@ -182,12 +198,14 @@ public function getURLHandlers($grid) * @param GridField $grid * @param DataObjectInterface $record * @return FieldList + * @throws Exception */ public function getFields(GridField $grid, DataObjectInterface $record) { $cols = $this->getDisplayFields($grid); $fields = new FieldList(); + /** @var DataList $list */ $list = $grid->getList(); $class = $list ? $list->dataClass() : null; @@ -200,7 +218,7 @@ public function getFields(GridField $grid, DataObjectInterface $record) if (isset($info['callback'])) { $field = call_user_func($info['callback'], $record, $col, $grid); } elseif (isset($info['field'])) { - if ($info['field'] == 'SilverStripe\\Forms\\LiteralField') { + if ($info['field'] == LiteralField::class) { $field = new $info['field']($col, null); } else { $field = new $info['field']($col); @@ -234,12 +252,12 @@ public function getFields(GridField $grid, DataObjectInterface $record) // available or is readonly // $colRelation = explode('.', $col); - if ($class && $obj = singleton($class)->dbObject($colRelation[0])) { + if ($class && $obj = DataObject::singleton($class)->dbObject($colRelation[0])) { $field = $obj->scaffoldFormField(); } else { $field = new ReadonlyField($colRelation[0]); } - } elseif ($class && $obj = singleton($class)->dbObject($col)) { + } elseif ($class && $obj = DataObject::singleton($class)->dbObject($col)) { $field = $obj->scaffoldFormField(); } else { $field = new ReadonlyField($col); @@ -292,7 +310,7 @@ protected function getFieldName($name, GridField $grid, DataObjectInterface $rec return sprintf( '%s[%s][%s][%s]', $grid->getName(), - __CLASS__, + self::POST_KEY, $record->ID, $name );