2008-10-14 00:20:41 +02:00
|
|
|
<?php
|
|
|
|
/**
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2012-04-12 08:02:46 +02:00
|
|
|
* @package framework
|
2008-10-14 00:20:41 +02:00
|
|
|
* @subpackage forms
|
|
|
|
*
|
|
|
|
* @uses DBField::scaffoldFormField()
|
|
|
|
* @uses DataObject::fieldLabels()
|
|
|
|
*/
|
|
|
|
class FormScaffolder extends Object {
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-10-14 00:20:41 +02:00
|
|
|
/**
|
|
|
|
* @var DataObject $obj The object defining the fields to be scaffolded
|
|
|
|
* through its metadata like $db, $searchable_fields, etc.
|
|
|
|
*/
|
|
|
|
protected $obj;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-10-14 00:20:41 +02:00
|
|
|
/**
|
2014-08-15 08:53:05 +02:00
|
|
|
* @var boolean $tabbed Return fields in a tabset, with all main fields in the path "Root.Main",
|
2008-10-14 00:20:41 +02:00
|
|
|
* relation fields in "Root.<relationname>" (if {@link $includeRelations} is enabled).
|
|
|
|
*/
|
|
|
|
public $tabbed = false;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-10-14 00:20:41 +02:00
|
|
|
/**
|
2014-08-15 08:53:05 +02:00
|
|
|
* @var boolean $ajaxSafe
|
2008-10-14 00:20:41 +02:00
|
|
|
*/
|
|
|
|
public $ajaxSafe = false;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-10-14 00:20:41 +02:00
|
|
|
/**
|
|
|
|
* @var array $restrictFields Numeric array of a field name whitelist.
|
|
|
|
* If left blank, all fields from {@link DataObject->db()} will be included.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2008-10-14 00:20:41 +02:00
|
|
|
* @todo Implement restrictions for has_many and many_many relations.
|
|
|
|
*/
|
|
|
|
public $restrictFields;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-10-14 00:20:41 +02:00
|
|
|
/**
|
|
|
|
* @var array $fieldClasses Optional mapping of fieldnames to subclasses of {@link FormField}.
|
|
|
|
* By default the scaffolder will determine the field instance by {@link DBField::scaffoldFormField()}.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2008-10-14 00:20:41 +02:00
|
|
|
* @todo Implement fieldClasses for has_many and many_many relations
|
|
|
|
*/
|
|
|
|
public $fieldClasses;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-10-14 00:20:41 +02:00
|
|
|
/**
|
|
|
|
* @var boolean $includeRelations Include has_one, has_many and many_many relations
|
|
|
|
*/
|
|
|
|
public $includeRelations = false;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-10-14 00:20:41 +02:00
|
|
|
/**
|
|
|
|
* @param DataObject $obj
|
|
|
|
* @param array $params
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function __construct($obj) {
|
2008-10-14 00:20:41 +02:00
|
|
|
$this->obj = $obj;
|
2009-09-18 05:02:19 +02:00
|
|
|
parent::__construct();
|
2008-10-14 00:20:41 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-10-14 00:20:41 +02:00
|
|
|
/**
|
|
|
|
* Gets the form fields as defined through the metadata
|
|
|
|
* on {@link $obj} and the custom parameters passed to FormScaffolder.
|
|
|
|
* Depending on those parameters, the fields can be used in ajax-context,
|
|
|
|
* contain {@link TabSet}s etc.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2011-10-28 03:37:27 +02:00
|
|
|
* @return FieldList
|
2008-10-14 00:20:41 +02:00
|
|
|
*/
|
2012-05-14 05:03:22 +02:00
|
|
|
public function getFieldList() {
|
2011-05-11 09:51:54 +02:00
|
|
|
$fields = new FieldList();
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-10-14 00:20:41 +02:00
|
|
|
// tabbed or untabbed
|
2009-01-05 07:19:48 +01:00
|
|
|
if($this->tabbed) {
|
|
|
|
$fields->push(new TabSet("Root", $mainTab = new Tab("Main")));
|
|
|
|
$mainTab->setTitle(_t('SiteTree.TABMAIN', "Main"));
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2015-09-10 05:46:23 +02:00
|
|
|
// Add logical fields directly specified in db config
|
|
|
|
foreach($this->obj->config()->db as $fieldName => $fieldType) {
|
|
|
|
// Skip restricted fields
|
2008-10-14 00:20:41 +02:00
|
|
|
if($this->restrictFields && !in_array($fieldName, $this->restrictFields)) continue;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-10-14 00:20:41 +02:00
|
|
|
// @todo Pass localized title
|
|
|
|
if($this->fieldClasses && isset($this->fieldClasses[$fieldName])) {
|
|
|
|
$fieldClass = $this->fieldClasses[$fieldName];
|
|
|
|
$fieldObject = new $fieldClass($fieldName);
|
|
|
|
} else {
|
2015-09-10 05:46:23 +02:00
|
|
|
$fieldObject = $this
|
|
|
|
->obj
|
|
|
|
->dbObject($fieldName)
|
|
|
|
->scaffoldFormField(null, $this->getParamsArray());
|
|
|
|
}
|
|
|
|
// Allow fields to opt-out of scaffolding
|
|
|
|
if(!$fieldObject) {
|
|
|
|
continue;
|
2008-10-14 00:20:41 +02:00
|
|
|
}
|
|
|
|
$fieldObject->setTitle($this->obj->fieldLabel($fieldName));
|
|
|
|
if($this->tabbed) {
|
|
|
|
$fields->addFieldToTab("Root.Main", $fieldObject);
|
|
|
|
} else {
|
|
|
|
$fields->push($fieldObject);
|
|
|
|
}
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-10-14 00:20:41 +02:00
|
|
|
// add has_one relation fields
|
2015-02-25 16:21:33 +01:00
|
|
|
if($this->obj->hasOne()) {
|
|
|
|
foreach($this->obj->hasOne() as $relationship => $component) {
|
2008-10-14 00:20:41 +02:00
|
|
|
if($this->restrictFields && !in_array($relationship, $this->restrictFields)) continue;
|
2016-06-15 06:03:16 +02:00
|
|
|
$fieldName = $component === 'SilverStripe\\ORM\\DataObject'
|
2013-07-10 02:44:24 +02:00
|
|
|
? $relationship // Polymorphic has_one field is composite, so don't refer to ID subfield
|
|
|
|
: "{$relationship}ID";
|
2011-08-22 08:55:49 +02:00
|
|
|
if($this->fieldClasses && isset($this->fieldClasses[$fieldName])) {
|
|
|
|
$fieldClass = $this->fieldClasses[$fieldName];
|
|
|
|
$hasOneField = new $fieldClass($fieldName);
|
|
|
|
} else {
|
|
|
|
$hasOneField = $this->obj->dbObject($fieldName)->scaffoldFormField(null, $this->getParamsArray());
|
|
|
|
}
|
2013-07-10 02:44:24 +02:00
|
|
|
if(empty($hasOneField)) continue; // Allow fields to opt out of scaffolding
|
2008-10-14 21:31:18 +02:00
|
|
|
$hasOneField->setTitle($this->obj->fieldLabel($relationship));
|
2008-10-14 00:20:41 +02:00
|
|
|
if($this->tabbed) {
|
|
|
|
$fields->addFieldToTab("Root.Main", $hasOneField);
|
|
|
|
} else {
|
|
|
|
$fields->push($hasOneField);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-10-14 00:20:41 +02:00
|
|
|
// only add relational fields if an ID is present
|
|
|
|
if($this->obj->ID) {
|
|
|
|
// add has_many relation fields
|
2015-02-25 16:21:33 +01:00
|
|
|
if($this->obj->hasMany()
|
2012-09-26 23:34:00 +02:00
|
|
|
&& ($this->includeRelations === true || isset($this->includeRelations['has_many']))) {
|
|
|
|
|
2015-02-25 16:21:33 +01:00
|
|
|
foreach($this->obj->hasMany() as $relationship => $component) {
|
2008-10-14 00:20:41 +02:00
|
|
|
if($this->tabbed) {
|
|
|
|
$relationTab = $fields->findOrMakeTab(
|
2014-08-15 08:53:05 +02:00
|
|
|
"Root.$relationship",
|
2008-10-14 00:20:41 +02:00
|
|
|
$this->obj->fieldLabel($relationship)
|
|
|
|
);
|
|
|
|
}
|
2012-09-26 23:34:00 +02:00
|
|
|
$fieldClass = (isset($this->fieldClasses[$relationship]))
|
2014-08-15 08:53:05 +02:00
|
|
|
? $this->fieldClasses[$relationship]
|
2012-09-26 23:34:00 +02:00
|
|
|
: 'GridField';
|
2014-08-15 08:53:05 +02:00
|
|
|
$grid = Object::create($fieldClass,
|
2008-10-14 00:20:41 +02:00
|
|
|
$relationship,
|
2012-03-09 14:36:57 +01:00
|
|
|
$this->obj->fieldLabel($relationship),
|
|
|
|
$this->obj->$relationship(),
|
|
|
|
GridFieldConfig_RelationEditor::create()
|
2008-10-14 00:20:41 +02:00
|
|
|
);
|
|
|
|
if($this->tabbed) {
|
2012-03-09 14:36:57 +01:00
|
|
|
$fields->addFieldToTab("Root.$relationship", $grid);
|
2008-10-14 00:20:41 +02:00
|
|
|
} else {
|
2012-03-09 14:36:57 +01:00
|
|
|
$fields->push($grid);
|
2008-10-14 00:20:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-25 16:21:33 +01:00
|
|
|
if($this->obj->manyMany()
|
2012-09-26 23:34:00 +02:00
|
|
|
&& ($this->includeRelations === true || isset($this->includeRelations['many_many']))) {
|
|
|
|
|
2015-02-25 16:21:33 +01:00
|
|
|
foreach($this->obj->manyMany() as $relationship => $component) {
|
2008-10-14 00:20:41 +02:00
|
|
|
if($this->tabbed) {
|
|
|
|
$relationTab = $fields->findOrMakeTab(
|
2014-08-15 08:53:05 +02:00
|
|
|
"Root.$relationship",
|
2008-10-14 00:20:41 +02:00
|
|
|
$this->obj->fieldLabel($relationship)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2012-09-26 23:34:00 +02:00
|
|
|
$fieldClass = (isset($this->fieldClasses[$relationship]))
|
|
|
|
? $this->fieldClasses[$relationship]
|
|
|
|
: 'GridField';
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
|
|
$grid = Object::create($fieldClass,
|
2008-10-14 00:20:41 +02:00
|
|
|
$relationship,
|
2012-03-09 14:36:57 +01:00
|
|
|
$this->obj->fieldLabel($relationship),
|
2012-01-09 17:16:39 +01:00
|
|
|
$this->obj->$relationship(),
|
2012-03-09 14:36:57 +01:00
|
|
|
GridFieldConfig_RelationEditor::create()
|
2008-10-14 00:20:41 +02:00
|
|
|
);
|
|
|
|
if($this->tabbed) {
|
2012-03-09 14:36:57 +01:00
|
|
|
$fields->addFieldToTab("Root.$relationship", $grid);
|
2008-10-14 00:20:41 +02:00
|
|
|
} else {
|
2012-03-09 14:36:57 +01:00
|
|
|
$fields->push($grid);
|
2008-10-14 00:20:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-10-14 00:20:41 +02:00
|
|
|
return $fields;
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-10-14 00:20:41 +02:00
|
|
|
/**
|
|
|
|
* Return an array suitable for passing on to {@link DBField->scaffoldFormField()}
|
|
|
|
* without tying this call to a FormScaffolder interface.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2008-10-14 00:20:41 +02:00
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
protected function getParamsArray() {
|
|
|
|
return array(
|
|
|
|
'tabbed' => $this->tabbed,
|
|
|
|
'includeRelations' => $this->includeRelations,
|
|
|
|
'restrictFields' => $this->restrictFields,
|
|
|
|
'fieldClasses' => $this->fieldClasses,
|
|
|
|
'ajaxSafe' => $this->ajaxSafe
|
|
|
|
);
|
|
|
|
}
|
2012-03-24 04:04:52 +01:00
|
|
|
}
|