null, ], [ 'viewButtonClass' => GridFieldViewButton::class, ], [ 'viewButtonClass' => GridFieldViewButtonReplacement::class, ], ]; } /** * The CMS can set the value of a GridField to be a hasMany relation, which needs a readonly state. * This test ensures GridField has a readonly transformation. * * @dataProvider provideReadOnlyTransformation */ public function testReadOnlyTransformation(?string $viewButtonClass) { // Build a hasMany Relation via getComponents like ModelAdmin does. $components = Team::get_one(Team::class) ->getComponents('Cheerleaders'); $gridConfig = GridFieldConfig_RelationEditor::create(); // Build some commonly used components to make sure we're only allowing the correct components $gridConfig->addComponent(new GridFieldButtonRow('before')); $gridConfig->addComponent(new GridFieldAddNewButton('buttons-before-left')); $gridConfig->addComponent(new GridFieldAddExistingAutocompleter('buttons-before-right')); $gridConfig->addComponent(new GridFieldToolbarHeader()); $gridConfig->addComponent($sort = new GridFieldSortableHeader()); $gridConfig->addComponent($filter = new GridFieldFilterHeader()); $gridConfig->addComponent(new GridFieldDataColumns()); $gridConfig->addComponent(new GridFieldEditButton()); $gridConfig->addComponent(new GridFieldDeleteAction(true)); $gridConfig->addComponent(new GridField_ActionMenu()); $gridConfig->addComponent(new GridFieldPageCount('toolbar-header-right')); $gridConfig->addComponent($pagination = new GridFieldPaginator(2)); $gridConfig->addComponent(new GridFieldDetailForm()); $gridConfig->addComponent(new GridFieldDeleteAction()); $gridConfig->addComponent(new VersionedGridFieldState()); $gridField = GridField::create( 'Cheerleaders', 'Cheerleaders', $components, $gridConfig ); if ($viewButtonClass !== GridFieldViewButton::class) { $allowedComponents = $gridField->getReadonlyComponents(); $viewButtonIndex = array_search(GridFieldViewButton::class, $allowedComponents); if ($viewButtonIndex !== false) { unset($allowedComponents[$viewButtonIndex]); } if ($viewButtonClass !== null) { $allowedComponents[] = $viewButtonClass; } $gridField->setReadonlyComponents($allowedComponents); } // Model Admin sets the value of the GridField directly to the relation, which doesn't have a forTemplate() // function, if we rely on FormField to render into a ReadonlyField we'll get an error as HasManyRelation // doesn't have a forTemplate() function. $gridField->setValue($components); $gridField->setModelClass(Cheerleader::class); // This function is called by $form->makeReadonly(). $readonlyGridField = $gridField->performReadonlyTransformation(); // if we've made it this far, then the GridField is at least transforming correctly. $readonlyComponents = $readonlyGridField->getReadonlyComponents(); // assert that all the components in the readonly version are present in the whitelist. foreach ($readonlyGridField->getConfig()->getComponents() as $component) { $this->assertTrue(in_array(get_class($component), $readonlyComponents ?? [])); } } }