Source of file GridFieldAddNewInlineButton.php
Size: 6,952 Bytes - Last Modified: 2021-12-23T10:25:33+00:00
/var/www/docs.ssmods.com/process/src/src/GridFieldAddNewInlineButton.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 | <?php namespace Symbiote\GridFieldExtensions; use SilverStripe\Core\Convert; use SilverStripe\Core\Injector\Injector; use SilverStripe\Forms\Form; use SilverStripe\Forms\GridField\GridField; 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\ORM\ManyManyThroughList; use SilverStripe\View\ArrayData; use SilverStripe\View\Requirements; use Exception; /** * Builds on the {@link GridFieldEditableColumns} component to allow creating new records. */ class GridFieldAddNewInlineButton implements GridField_HTMLProvider, GridField_SaveHandler { /** * @skipUpgrade */ const POST_KEY = 'GridFieldAddNewInlineButton'; private $fragment; private $title; /** * @param string $fragment the fragment to render the button in */ public function __construct($fragment = 'buttons-before-left') { $this->setFragment($fragment); $this->setTitle(_t('GridFieldExtensions.ADD', 'Add')); } /** * Gets the fragment name this button is rendered into. * * @return string */ public function getFragment() { return $this->fragment; } /** * Sets the fragment name this button is rendered into. * * @param string $fragment * @return GridFieldAddNewInlineButton $this */ public function setFragment($fragment) { $this->fragment = $fragment; return $this; } /** * Gets the button title text. * * @return string */ public function getTitle() { return $this->title; } /** * Sets the button title text. * * @param string $title * @return GridFieldAddNewInlineButton $this */ public function setTitle($title) { $this->title = $title; return $this; } public function getHTMLFragments($grid) { if ($grid->getList() && !singleton($grid->getModelClass())->canCreate()) { return array(); } $fragment = $this->getFragment(); /** @var GridFieldEditableColumns $editable */ $editable = $grid->getConfig()->getComponentByType(GridFieldEditableColumns::class); if (!$editable) { throw new Exception('Inline adding requires the editable columns component'); } Requirements::javascript('symbiote/silverstripe-gridfieldextensions:javascript/tmpl.js'); GridFieldExtensions::include_requirements(); $data = new ArrayData(array( 'Title' => $this->getTitle(), )); return array( $fragment => $data->renderWith(__CLASS__), 'after' => $this->getRowTemplate($grid, $editable) ); } private function getRowTemplate(GridField $grid, GridFieldEditableColumns $editable) { $columns = new ArrayList(); $handled = array_keys($editable->getDisplayFields($grid)); if ($grid->getList()) { $record = Injector::inst()->create($grid->getModelClass()); } else { $record = null; } $fields = $editable->getFields($grid, $record); foreach ($grid->getColumns() as $column) { if (in_array($column, $handled)) { $field = $fields->dataFieldByName($column); $field->setName(sprintf( '%s[%s][{%%=o.num%%}][%s]', $grid->getName(), self::POST_KEY, $field->getName() )); if ($record && $record->hasField($column)) { $field->setValue($record->getField($column)); } $content = $field->Field(); } else { $content = $grid->getColumnContent($record, $column); // Convert GridFieldEditableColumns to the template format $content = str_replace( sprintf('[%s][0]', GridFieldEditableColumns::POST_KEY), sprintf('[%s][{%%=o.num%%}]', self::POST_KEY), $content ); } // Cast content if (! $content instanceof DBField) { $content = DBField::create_field('HTMLFragment', $content); } $attrs = ''; foreach ($grid->getColumnAttributes($record, $column) as $attr => $val) { $attrs .= sprintf(' %s="%s"', $attr, Convert::raw2att($val)); } $columns->push(new ArrayData(array( 'Content' => $content, 'Attributes' => DBField::create_field('HTMLFragment', $attrs), 'IsActions' => $column == 'Actions' ))); } return $columns->renderWith('Symbiote\\GridFieldExtensions\\GridFieldAddNewInlineRow'); } public function handleSave(GridField $grid, DataObjectInterface $record) { $list = $grid->getList(); $value = $grid->Value(); if (!isset($value[self::POST_KEY]) || !is_array($value[self::POST_KEY])) { return; } $class = $grid->getModelClass(); /** @var GridFieldEditableColumns $editable */ $editable = $grid->getConfig()->getComponentByType(GridFieldEditableColumns::class); /** @var GridFieldOrderableRows $sortable */ $sortable = $grid->getConfig()->getComponentByType(GridFieldOrderableRows::class); if (!singleton($class)->canCreate()) { return; } foreach ($value[self::POST_KEY] as $fields) { /** @var DataObject $item */ $item = $class::create(); // Add the item before the form is loaded so that the join-object is available if ($list instanceof ManyManyThroughList) { $list->add($item); } $extra = array(); $form = $editable->getForm($grid, $item); $form->loadDataFrom($fields, Form::MERGE_CLEAR_MISSING); $form->saveInto($item); // Check if we are also sorting these records if ($sortable) { $sortField = $sortable->getSortField(); $item->setField($sortField, $fields[$sortField]); } if ($list instanceof ManyManyList) { $extra = array_intersect_key($form->getData(), (array) $list->getExtraFields()); } $item->write(false, false, false, true); // Add non-through lists after the write. many_many_extraFields are added there too if (!($list instanceof ManyManyThroughList)) { $list->add($item, $extra); } } } } |