mirror of
https://github.com/silverstripe/silverstripe-frameworktest
synced 2024-10-22 11:06:02 +02:00
Merge pull request #159 from creative-commoners/pulls/1/arbitrarydata-gridfield
NEW Add fixtures for arbitrary data gridfield behat tests
This commit is contained in:
commit
5f70444e06
@ -15,6 +15,18 @@ SilverStripe\FrameworkTest\Model\Employee:
|
|||||||
extensions:
|
extensions:
|
||||||
- SilverStripe\FrameworkTest\Extension\TestDataObjectExtension
|
- SilverStripe\FrameworkTest\Extension\TestDataObjectExtension
|
||||||
|
|
||||||
|
SilverStripe\ORM\DatabaseAdmin:
|
||||||
|
extensions:
|
||||||
|
- SilverStripe\FrameworkTest\GridFieldArbitraryData\DatabaseBuildExtension
|
||||||
|
|
||||||
|
---
|
||||||
|
Only:
|
||||||
|
moduleexists: 'silverstripe/testsession'
|
||||||
|
---
|
||||||
|
SilverStripe\TestSession\TestSessionEnvironment:
|
||||||
|
extensions:
|
||||||
|
- SilverStripe\FrameworkTest\GridFieldArbitraryData\DatabaseBuildExtension
|
||||||
|
|
||||||
---
|
---
|
||||||
Only:
|
Only:
|
||||||
moduleexists: 'dnadesign/silverstripe-elemental'
|
moduleexists: 'dnadesign/silverstripe-elemental'
|
||||||
|
240
code/GridFieldArbitraryData/ArbitraryDataAdmin.php
Normal file
240
code/GridFieldArbitraryData/ArbitraryDataAdmin.php
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\FrameworkTest\GridFieldArbitraryData;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
use SilverStripe\Admin\LeftAndMain;
|
||||||
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\Form;
|
||||||
|
use SilverStripe\Forms\GridField\GridField;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldConfig;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldConfig_Base;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldDataColumns;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldDetailForm;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldExportButton;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldFilterHeader;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldPaginator;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldPrintButton;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldViewButton;
|
||||||
|
use SilverStripe\Forms\HiddenField;
|
||||||
|
use SilverStripe\Forms\TextField;
|
||||||
|
use SilverStripe\ORM\ArrayList;
|
||||||
|
use SilverStripe\ORM\Queries\SQLSelect;
|
||||||
|
use SilverStripe\ORM\Search\BasicSearchContext;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
|
||||||
|
class ArbitraryDataAdmin extends LeftAndMain
|
||||||
|
{
|
||||||
|
public const TAB_ARRAYDATA = 'arraydata';
|
||||||
|
|
||||||
|
public const TAB_CUSTOM_MODEL = 'custommodel';
|
||||||
|
|
||||||
|
private static $url_segment = 'arbitrary-data';
|
||||||
|
|
||||||
|
private static $menu_title = 'Arbitrary Data Gridfield';
|
||||||
|
|
||||||
|
private static $url_rule = '/$Tab/$Action';
|
||||||
|
|
||||||
|
private static $url_handlers = [
|
||||||
|
'$Tab/$Action' => 'handleAction'
|
||||||
|
];
|
||||||
|
|
||||||
|
private ?string $tab = null;
|
||||||
|
|
||||||
|
private static int $num_initial_items = 30;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directly copied from ModelAdmin with minor tweaks
|
||||||
|
*/
|
||||||
|
protected function init()
|
||||||
|
{
|
||||||
|
parent::init();
|
||||||
|
|
||||||
|
$this->tab = $this->getRequest()->param('Tab');
|
||||||
|
|
||||||
|
// accessing the admin directly
|
||||||
|
if ($this->tab === null) {
|
||||||
|
$this->tab = self::TAB_ARRAYDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->tab !== self::TAB_ARRAYDATA && $this->tab !== self::TAB_CUSTOM_MODEL) {
|
||||||
|
throw new RuntimeException("Unexpected url segment: {$this->tab}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getList()
|
||||||
|
{
|
||||||
|
$list = ArrayList::create();
|
||||||
|
|
||||||
|
switch ($this->tab) {
|
||||||
|
case self::TAB_ARRAYDATA:
|
||||||
|
foreach (self::getInitialRecords() as $stub) {
|
||||||
|
$list->add(ArrayData::create($stub));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case self::TAB_CUSTOM_MODEL:
|
||||||
|
$rawData = SQLSelect::create()->setFrom(ArbitraryDataModel::TABLE_NAME)->execute();
|
||||||
|
foreach ($rawData as $record) {
|
||||||
|
$list->add(ArbitraryDataModel::create($record));
|
||||||
|
}
|
||||||
|
$list->setDataClass(ArbitraryDataModel::class);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Unexpected tab: {$this->tab}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->extend('updateList', $list);
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getInitialRecords()
|
||||||
|
{
|
||||||
|
$numRecords = static::config()->get('num_initial_items');
|
||||||
|
$records = [];
|
||||||
|
for ($id = 1; $id <= $numRecords; $id++) {
|
||||||
|
$records[] = [
|
||||||
|
'ID' => $id,
|
||||||
|
'Title' => "item $id",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return $records;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getGridFieldConfig(): GridFieldConfig
|
||||||
|
{
|
||||||
|
if ($this->tab === self::TAB_CUSTOM_MODEL) {
|
||||||
|
$config = GridFieldConfig_RecordEditor::create();
|
||||||
|
} else {
|
||||||
|
// This is effectively the same as a GridFieldConfig_RecordViewer, but without removing the GridFieldFilterHeader.
|
||||||
|
$config = GridFieldConfig_Base::create();
|
||||||
|
$config->addComponent(GridFieldViewButton::create());
|
||||||
|
$config->addComponent(GridFieldDetailForm::create());
|
||||||
|
$fieldNames = array_keys(self::getInitialRecords()[0]);
|
||||||
|
$config->getComponentByType(GridFieldDataColumns::class)->setDisplayFields(array_combine($fieldNames, $fieldNames));
|
||||||
|
$fields = array_map(fn ($name) => $name === 'ID' ? HiddenField::create($name) : TextField::create($name), $fieldNames);
|
||||||
|
$config->getComponentByType(GridFieldDetailForm::class)->setFields(FieldList::create($fields));
|
||||||
|
$searchContext = BasicSearchContext::create(ArrayData::class);
|
||||||
|
$searchFields = array_map(
|
||||||
|
fn ($name) => $name === 'ID'
|
||||||
|
? HiddenField::create(BasicSearchContext::config()->get('general_search_field_name'))
|
||||||
|
: TextField::create($name),
|
||||||
|
$fieldNames
|
||||||
|
);
|
||||||
|
$searchContext->setFields(FieldList::create($searchFields));
|
||||||
|
$config->getComponentByType(GridFieldFilterHeader::class)->setSearchContext($searchContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
$config->getComponentByType(GridFieldPaginator::class)->setItemsPerPage(10);
|
||||||
|
|
||||||
|
$exportButton = GridFieldExportButton::create('buttons-before-left');
|
||||||
|
// $exportButton->setExportColumns($this->getExportFields());
|
||||||
|
|
||||||
|
$config->addComponents([
|
||||||
|
$exportButton,
|
||||||
|
GridFieldPrintButton::create('buttons-before-left')
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->extend('updateGridFieldConfig', $config);
|
||||||
|
|
||||||
|
return $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directly copied from ModelAdmin with minor tweaks
|
||||||
|
*/
|
||||||
|
protected function getGridField(): GridField
|
||||||
|
{
|
||||||
|
$field = GridField::create(
|
||||||
|
$this->tab,
|
||||||
|
false,
|
||||||
|
$this->getList(),
|
||||||
|
$this->getGridFieldConfig()
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->extend('updateGridField', $field);
|
||||||
|
|
||||||
|
return $field;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directly copied from ModelAdmin with minor tweaks
|
||||||
|
*/
|
||||||
|
public function getEditForm($id = null, $fields = null)
|
||||||
|
{
|
||||||
|
$form = Form::create(
|
||||||
|
$this,
|
||||||
|
'EditForm',
|
||||||
|
FieldList::create($this->getGridField()),
|
||||||
|
FieldList::create()
|
||||||
|
)->setHTMLID('Form_EditForm');
|
||||||
|
|
||||||
|
$form->addExtraClass('cms-edit-form cms-panel-padded center flexbox-area-grow');
|
||||||
|
$form->setTemplate($this->getTemplatesWithSuffix('_EditForm'));
|
||||||
|
$editFormAction = Controller::join_links($this->Link($this->tab), 'EditForm');
|
||||||
|
$form->setFormAction($editFormAction);
|
||||||
|
$form->setAttribute('data-pjax-fragment', 'CurrentForm');
|
||||||
|
|
||||||
|
$this->extend('updateEditForm', $form);
|
||||||
|
|
||||||
|
return $form;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directly copied from ModelAdmin with minor tweaks
|
||||||
|
*/
|
||||||
|
protected function getManagedTabs()
|
||||||
|
{
|
||||||
|
$tabs = [
|
||||||
|
self::TAB_ARRAYDATA => 'ArrayData',
|
||||||
|
self::TAB_CUSTOM_MODEL => 'Custom Model',
|
||||||
|
];
|
||||||
|
$forms = new ArrayList();
|
||||||
|
|
||||||
|
foreach ($tabs as $tab => $title) {
|
||||||
|
$forms->push(new ArrayData([
|
||||||
|
'Title' => $title,
|
||||||
|
'Tab' => $tab,
|
||||||
|
'Link' => $this->Link($tab),
|
||||||
|
'LinkOrCurrent' => ($tab === $this->tab) ? 'current' : 'link'
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $forms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directly copied from ModelAdmin with minor tweaks
|
||||||
|
*/
|
||||||
|
public function Link($action = null)
|
||||||
|
{
|
||||||
|
if (!$action) {
|
||||||
|
$action = $this->tab;
|
||||||
|
}
|
||||||
|
return parent::Link($action);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directly copied from ModelAdmin with minor tweaks
|
||||||
|
*/
|
||||||
|
public function Breadcrumbs($unlinked = false)
|
||||||
|
{
|
||||||
|
$items = parent::Breadcrumbs($unlinked);
|
||||||
|
|
||||||
|
// Show the class name rather than ModelAdmin title as root node
|
||||||
|
$params = $this->getRequest()->getVars();
|
||||||
|
if (isset($params['url'])) {
|
||||||
|
unset($params['url']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$items[0]->Title = $this->tab;
|
||||||
|
$items[0]->Link = Controller::join_links(
|
||||||
|
$this->Link($this->tab),
|
||||||
|
'?' . http_build_query($params ?? [])
|
||||||
|
);
|
||||||
|
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
}
|
205
code/GridFieldArbitraryData/ArbitraryDataModel.php
Normal file
205
code/GridFieldArbitraryData/ArbitraryDataModel.php
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\FrameworkTest\GridFieldArbitraryData;
|
||||||
|
|
||||||
|
use LogicException;
|
||||||
|
use SilverStripe\Forms\DatetimeField;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\HiddenField;
|
||||||
|
use SilverStripe\Forms\TextField;
|
||||||
|
use SilverStripe\ORM\DataObjectInterface;
|
||||||
|
use SilverStripe\ORM\DB;
|
||||||
|
use SilverStripe\ORM\FieldType\DBDatetime;
|
||||||
|
use SilverStripe\ORM\Queries\SQLDelete;
|
||||||
|
use SilverStripe\ORM\Search\BasicSearchContext;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class of arbitrary data for testing GridField components.
|
||||||
|
*
|
||||||
|
* It stores its data in the database, but it doesn't use DataObject abstractions
|
||||||
|
* to do so. The database in this scenario could just as easily be an API or other
|
||||||
|
* way to fetch and send data.
|
||||||
|
*/
|
||||||
|
class ArbitraryDataModel extends ArrayData implements DataObjectInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* In order to validate that writing/deleting works for arbitrary data, we'll be storing these
|
||||||
|
* records in the database - just not using the DataObject abstraction.
|
||||||
|
*
|
||||||
|
* For our purposes, the database is acting as an abitrary data storage layer. It could just as
|
||||||
|
* easily be sending/recieving data through an API, for example.
|
||||||
|
*
|
||||||
|
* Note that the database will not be used for filtering/sorting/etc - it is only used to store
|
||||||
|
* the data on save, delete the data on delete, and fetch the data when loading the admin.
|
||||||
|
*/
|
||||||
|
public const TABLE_NAME = 'frameworktest_ArbitraryDataModel';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We need to ensure there is an ID field for new records
|
||||||
|
*/
|
||||||
|
public function __construct($value = [])
|
||||||
|
{
|
||||||
|
if (!isset($value['ID'])) {
|
||||||
|
$value['ID'] = 0;
|
||||||
|
}
|
||||||
|
parent::__construct($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the current data into the database - but could just as easily send it through an API
|
||||||
|
* endpoint for storing somewhere else, or save to a file, etc.
|
||||||
|
*/
|
||||||
|
public function write()
|
||||||
|
{
|
||||||
|
$isNew = !$this->ID;
|
||||||
|
$now = DBDatetime::now()->Rfc2822();
|
||||||
|
$record = $this->array;
|
||||||
|
$record['LastEdited'] = $now;
|
||||||
|
if ($isNew) {
|
||||||
|
$record['Created'] = $now;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove anything that isn't storable in the DB, such as Security ID
|
||||||
|
$dbColumns = DB::field_list(self::TABLE_NAME);
|
||||||
|
foreach ($record as $fieldName => $value) {
|
||||||
|
if (!array_key_exists($fieldName, $dbColumns)) {
|
||||||
|
unset($record[$fieldName]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is basically a fancy SQLInsert or SQLUpdate - I just copied DataObject so I didn't have to think.
|
||||||
|
$manipulation = [
|
||||||
|
'command' => $isNew ? 'insert' : 'update',
|
||||||
|
'fields' => $record,
|
||||||
|
];
|
||||||
|
if (!$isNew) {
|
||||||
|
$manipulation['id'] = $this->ID;
|
||||||
|
}
|
||||||
|
DB::manipulate([self::TABLE_NAME => $manipulation]);
|
||||||
|
|
||||||
|
if ($isNew) {
|
||||||
|
// Must save the ID in this object so GridField knows what URL to redirect to.
|
||||||
|
$this->ID = DB::get_generated_id(self::TABLE_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete()
|
||||||
|
{
|
||||||
|
if (!$this->ID) {
|
||||||
|
throw new LogicException('DataObject::delete() called on a record without an ID');
|
||||||
|
}
|
||||||
|
SQLDelete::create()->setFrom(self::TABLE_NAME)->setWhere(['ID' => $this->ID])->execute();
|
||||||
|
$this->ID = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value from the form
|
||||||
|
*/
|
||||||
|
public function setCastedField($fieldName, $val)
|
||||||
|
{
|
||||||
|
$this->$fieldName = $val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives a localisable plural name for the class.
|
||||||
|
*
|
||||||
|
* Used in add button, breadcrumbs, and toasts
|
||||||
|
*/
|
||||||
|
public function i18n_singular_name()
|
||||||
|
{
|
||||||
|
return _t(__CLASS__ . '.SINGULAR_NAME', 'Arbitrary Datum');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives a localisable plural name for the class.
|
||||||
|
*
|
||||||
|
* Used in filter header as the placeholder text
|
||||||
|
*/
|
||||||
|
public function i18n_plural_name()
|
||||||
|
{
|
||||||
|
return _t(__CLASS__ . '.PLURAL_NAME', 'Arbitrary Data');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to auto-detect gridfield columns
|
||||||
|
*/
|
||||||
|
public function summaryFields()
|
||||||
|
{
|
||||||
|
$fieldNames = $this->getFieldNames();
|
||||||
|
$summaryFields = array_combine($fieldNames, $fieldNames);
|
||||||
|
unset($summaryFields['ID']);
|
||||||
|
return $summaryFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDefaultSearchContext()
|
||||||
|
{
|
||||||
|
return BasicSearchContext::create(static::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scaffoldSearchFields()
|
||||||
|
{
|
||||||
|
$fieldNames = $this->getFieldNames();
|
||||||
|
$fields = [HiddenField::create(BasicSearchContext::config()->get('general_search_field_name'))];
|
||||||
|
foreach ($fieldNames as $fieldName) {
|
||||||
|
if ($fieldName === 'ID' || $fieldName === 'Created' || $fieldName === 'LastEdited') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$fields[] = TextField::create($fieldName);
|
||||||
|
}
|
||||||
|
return FieldList::create($fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCMSFields(): FieldList
|
||||||
|
{
|
||||||
|
$fieldNames = $this->getFieldNames();
|
||||||
|
$fields = [];
|
||||||
|
foreach ($fieldNames as $fieldName) {
|
||||||
|
switch ($fieldName) {
|
||||||
|
case 'ID':
|
||||||
|
$fields[] = HiddenField::create($fieldName);
|
||||||
|
break;
|
||||||
|
case 'Created':
|
||||||
|
case 'LastEdited':
|
||||||
|
$fields[] = DatetimeField::create($fieldName)->performReadonlyTransformation();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$fields[] = TextField::create($fieldName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FieldList::create($fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that a FieldsValidator is used by default, but we can add additional validation if we want
|
||||||
|
// by implementing this method:
|
||||||
|
// public function getCMSCompositeValidator()
|
||||||
|
// {
|
||||||
|
// return CompositeValidator::create([
|
||||||
|
// FieldsValidator::create(),
|
||||||
|
// RequiredFields::create(['Title']),
|
||||||
|
// ]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
public function canCreate()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canEdit()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canDelete()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getFieldNames()
|
||||||
|
{
|
||||||
|
$fieldNames = array_keys(ArbitraryDataAdmin::getInitialRecords()[0]);
|
||||||
|
$fieldNames[] = 'Created';
|
||||||
|
$fieldNames[] = 'LastEdited';
|
||||||
|
return $fieldNames;
|
||||||
|
}
|
||||||
|
}
|
144
code/GridFieldArbitraryData/DatabaseBuildExtension.php
Normal file
144
code/GridFieldArbitraryData/DatabaseBuildExtension.php
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\FrameworkTest\GridFieldArbitraryData;
|
||||||
|
|
||||||
|
use SilverStripe\Control\Director;
|
||||||
|
use SilverStripe\Core\Extension;
|
||||||
|
use SilverStripe\ORM\DatabaseAdmin;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
use SilverStripe\ORM\DB;
|
||||||
|
use SilverStripe\ORM\FieldType\DBDatetime;
|
||||||
|
use SilverStripe\ORM\Queries\SQLSelect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the table and adds default records for the ArbitraryDataModel.
|
||||||
|
*/
|
||||||
|
class DatabaseBuildExtension extends Extension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* This extension hook is on TestSessionEnvironment, which is used by behat but not by phpunit.
|
||||||
|
* For whatever reason, behat doesn't use dev/build, so we can't rely on the below onAfterbuild
|
||||||
|
* being run in that scenario.
|
||||||
|
*/
|
||||||
|
protected function onAfterStartTestSession()
|
||||||
|
{
|
||||||
|
$this->buildTable(true);
|
||||||
|
$this->populateData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This extension hook is on DatabaseAdmin, after dev/build has finished building the database.
|
||||||
|
*/
|
||||||
|
protected function onAfterBuild(bool $quiet, bool $populate, bool $testMode): void
|
||||||
|
{
|
||||||
|
if ($testMode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$quiet) {
|
||||||
|
if (Director::is_cli()) {
|
||||||
|
echo "\nCREATING TABLE FOR FRAMEWORKTEST ARBITRARY DATA\n\n";
|
||||||
|
} else {
|
||||||
|
echo "\n<p><b>Creating table for frameworktest arbitrary data</b></p><ul>\n\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->buildTable($quiet);
|
||||||
|
|
||||||
|
if (!$quiet && !Director::is_cli()) {
|
||||||
|
echo '</ul>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($populate) {
|
||||||
|
if (!$quiet) {
|
||||||
|
if (Director::is_cli()) {
|
||||||
|
echo "\nCREATING DATABASE RECORDS FOR FRAMEWORKTEST ARBITRARY DATA\n\n";
|
||||||
|
} else {
|
||||||
|
echo "\n<p><b>Creating database records arbitrary data</b></p><ul>\n\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->populateData();
|
||||||
|
|
||||||
|
if (!$quiet && !Director::is_cli()) {
|
||||||
|
echo '</ul>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$quiet) {
|
||||||
|
echo (Director::is_cli()) ? "\n Frameworktest database build completed!\n\n" : '<p>Frameworktest database build completed!</p>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildTable(bool $quiet): void
|
||||||
|
{
|
||||||
|
$tableName = ArbitraryDataModel::TABLE_NAME;
|
||||||
|
|
||||||
|
// Log data
|
||||||
|
if (!$quiet) {
|
||||||
|
$showRecordCounts = DatabaseAdmin::config()->get('show_record_counts');
|
||||||
|
if ($showRecordCounts && DB::get_schema()->hasTable($tableName)) {
|
||||||
|
try {
|
||||||
|
$count = SQLSelect::create()->setFrom($tableName)->count();
|
||||||
|
$countSuffix = " ($count records)";
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$countSuffix = ' (error getting record count)';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$countSuffix = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Director::is_cli()) {
|
||||||
|
echo " * $tableName$countSuffix\n";
|
||||||
|
} else {
|
||||||
|
echo "<li>$tableName$countSuffix</li>\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get field schema
|
||||||
|
$fields = [
|
||||||
|
'ID' => 'PrimaryKey',
|
||||||
|
'LastEdited' => 'DBDatetime',
|
||||||
|
'Created' => 'DBDatetime',
|
||||||
|
];
|
||||||
|
$fieldNames = array_keys(ArbitraryDataAdmin::getInitialRecords()[0]);
|
||||||
|
foreach ($fieldNames as $fieldName) {
|
||||||
|
if ($fieldName === 'ID') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$fields[$fieldName] = 'Varchar';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the table to the database
|
||||||
|
DB::get_schema()->schemaUpdate(function () use ($tableName, $fields) {
|
||||||
|
DB::require_table(
|
||||||
|
$tableName,
|
||||||
|
$fields,
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
DataObject::config()->get('create_table_options')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private function populateData(): void
|
||||||
|
{
|
||||||
|
$tableName = ArbitraryDataModel::TABLE_NAME;
|
||||||
|
$count = SQLSelect::create()->setFrom($tableName)->count();
|
||||||
|
|
||||||
|
if ($count <= 0) {
|
||||||
|
$now = DBDatetime::now()->Rfc2822();
|
||||||
|
$data = ArbitraryDataAdmin::getInitialRecords();
|
||||||
|
foreach ($data as $record) {
|
||||||
|
unset($record['ID']);
|
||||||
|
$record['LastEdited'] = $now;
|
||||||
|
$record['Created'] = $now;
|
||||||
|
|
||||||
|
$item = ArbitraryDataModel::create($record);
|
||||||
|
$item->write();
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::alteration_message('Added default records for frameworktest arbitrary data', 'created');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
<div class="cms-content fill-height flexbox-area-grow cms-tabset center $BaseCSSClasses" data-layout-type="border" data-pjax-fragment="Content" id="ModelAdmin">
|
||||||
|
|
||||||
|
<div class="cms-content-header north">
|
||||||
|
<div class="cms-content-header-info vertical-align-items flexbox-area-grow">
|
||||||
|
<div class="breadcrumbs-wrapper">
|
||||||
|
<span class="cms-panel-link crumb last">
|
||||||
|
<% if $SectionTitle %>
|
||||||
|
$SectionTitle
|
||||||
|
<% else %>
|
||||||
|
<%t SilverStripe\Admin\ModelAdmin.Title 'Data Models' %>
|
||||||
|
<% end_if %>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cms-content-header-tabs cms-tabset-nav-primary ss-ui-tabs-nav">
|
||||||
|
<ul class="cms-tabset-nav-primary">
|
||||||
|
<% loop $ManagedTabs %>
|
||||||
|
<li class="tab-$Tab $LinkOrCurrent<% if $LinkOrCurrent == 'current' %> ui-tabs-active<% end_if %>">
|
||||||
|
<a href="$Link" class="cms-panel-link" title="$Title.ATT">$Title</a>
|
||||||
|
</li>
|
||||||
|
<% end_loop %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cms-content-fields center ui-widget-content cms-panel-padded fill-height flexbox-area-grow" data-layout-type="border">
|
||||||
|
$Tools
|
||||||
|
|
||||||
|
<div class="cms-content-view">
|
||||||
|
$EditForm
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
@ -0,0 +1 @@
|
|||||||
|
<% include SilverStripe/Forms/Form %>
|
@ -0,0 +1,21 @@
|
|||||||
|
<div class="importSpec" id="SpecFor{$ClassName}">
|
||||||
|
<a href="#SpecDetailsFor{$ClassName}" class="detailsLink"><%t SilverStripe\Admin\ModelAdmin.IMPORTSPECLINK 'Show Specification for {model}' model=$ModelName %></a>
|
||||||
|
<div class="details" id="SpecDetailsFor{$ClassName}">
|
||||||
|
<h4><%t SilverStripe\Admin\ModelAdmin.IMPORTSPECTITLE 'Specification for {model}' model=$ModelName %></h4>
|
||||||
|
<h5><%t SilverStripe\Admin\ModelAdmin.IMPORTSPECFIELDS 'Database columns' %></h5>
|
||||||
|
<% loop $Fields %>
|
||||||
|
<dl>
|
||||||
|
<dt><em>$Name</em></dt>
|
||||||
|
<dd>$Description</dd>
|
||||||
|
</dl>
|
||||||
|
<% end_loop %>
|
||||||
|
|
||||||
|
<h5><%t SilverStripe\Admin\ModelAdmin.IMPORTSPECRELATIONS 'Relations' %></h5>
|
||||||
|
<% loop $Relations %>
|
||||||
|
<dl>
|
||||||
|
<dt><em>$Name</em></dt>
|
||||||
|
<dd>$Description</dd>
|
||||||
|
</dl>
|
||||||
|
<% end_loop %>
|
||||||
|
</div>
|
||||||
|
</div>
|
Loading…
Reference in New Issue
Block a user