2016-10-20 01:42:24 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace SilverStripe\Forms;
|
|
|
|
|
|
|
|
use InvalidArgumentException;
|
2017-05-04 04:07:51 +02:00
|
|
|
use SilverStripe\Control\RequestHandler;
|
2016-10-20 01:42:24 +02:00
|
|
|
use SilverStripe\Core\Extensible;
|
2020-02-13 00:51:56 +01:00
|
|
|
use SilverStripe\ORM\DataObject;
|
2016-10-20 01:42:24 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Default form builder class.
|
|
|
|
*
|
|
|
|
* @internal WARNING: Experimental and volatile API.
|
|
|
|
*
|
|
|
|
* Allows extension by either controller or object via the following methods:
|
|
|
|
* - updateFormActions
|
|
|
|
* - updateFormValidator
|
|
|
|
* - updateFormFields
|
|
|
|
* - updateForm
|
|
|
|
*/
|
2016-11-29 00:31:16 +01:00
|
|
|
class DefaultFormFactory implements FormFactory
|
|
|
|
{
|
|
|
|
use Extensible;
|
2016-10-20 01:42:24 +02:00
|
|
|
|
2016-11-29 00:31:16 +01:00
|
|
|
public function __construct()
|
|
|
|
{
|
|
|
|
}
|
2016-10-20 01:42:24 +02:00
|
|
|
|
2017-06-22 12:50:45 +02:00
|
|
|
/**
|
|
|
|
* @param RequestHandler $controller
|
|
|
|
* @param string $name
|
|
|
|
* @param array $context
|
|
|
|
* @return Form
|
2018-10-20 19:47:11 +02:00
|
|
|
* @throws InvalidArgumentException When required context is missing
|
2017-06-22 12:50:45 +02:00
|
|
|
*/
|
2017-05-04 04:07:51 +02:00
|
|
|
public function getForm(RequestHandler $controller = null, $name = FormFactory::DEFAULT_NAME, $context = [])
|
2016-11-29 00:31:16 +01:00
|
|
|
{
|
|
|
|
// Validate context
|
|
|
|
foreach ($this->getRequiredContext() as $required) {
|
|
|
|
if (!isset($context[$required])) {
|
|
|
|
throw new InvalidArgumentException("Missing required context $required");
|
|
|
|
}
|
|
|
|
}
|
2016-10-20 01:42:24 +02:00
|
|
|
|
2016-11-29 00:31:16 +01:00
|
|
|
$fields = $this->getFormFields($controller, $name, $context);
|
|
|
|
$actions = $this->getFormActions($controller, $name, $context);
|
|
|
|
$validator = $this->getFormValidator($controller, $name, $context);
|
|
|
|
$form = Form::create($controller, $name, $fields, $actions, $validator);
|
2016-10-20 01:42:24 +02:00
|
|
|
|
2016-11-29 00:31:16 +01:00
|
|
|
// Extend form
|
|
|
|
$this->invokeWithExtensions('updateForm', $form, $controller, $name, $context);
|
2016-10-20 01:42:24 +02:00
|
|
|
|
2016-11-29 00:31:16 +01:00
|
|
|
// Populate form from record
|
|
|
|
$form->loadDataFrom($context['Record']);
|
2016-10-20 01:42:24 +02:00
|
|
|
|
2016-11-29 00:31:16 +01:00
|
|
|
return $form;
|
|
|
|
}
|
2016-10-20 01:42:24 +02:00
|
|
|
|
2016-11-29 00:31:16 +01:00
|
|
|
/**
|
|
|
|
* Build field list for this form
|
|
|
|
*
|
2017-05-04 04:07:51 +02:00
|
|
|
* @param RequestHandler $controller
|
2016-11-29 00:31:16 +01:00
|
|
|
* @param string $name
|
|
|
|
* @param array $context
|
|
|
|
* @return FieldList
|
|
|
|
*/
|
2017-05-04 04:07:51 +02:00
|
|
|
protected function getFormFields(RequestHandler $controller = null, $name, $context = [])
|
2016-11-29 00:31:16 +01:00
|
|
|
{
|
|
|
|
// Fall back to standard "getCMSFields" which itself uses the FormScaffolder as a fallback
|
|
|
|
// @todo Deprecate or formalise support for getCMSFields()
|
|
|
|
$fields = $context['Record']->getCMSFields();
|
|
|
|
$this->invokeWithExtensions('updateFormFields', $fields, $controller, $name, $context);
|
|
|
|
return $fields;
|
|
|
|
}
|
2016-10-20 01:42:24 +02:00
|
|
|
|
2016-11-29 00:31:16 +01:00
|
|
|
/**
|
|
|
|
* Build list of actions for this form
|
|
|
|
*
|
2017-05-04 04:07:51 +02:00
|
|
|
* @param RequestHandler $controller
|
2016-11-29 00:31:16 +01:00
|
|
|
* @param string $name
|
|
|
|
* @param array $context
|
|
|
|
* @return FieldList
|
|
|
|
*/
|
2017-05-04 04:07:51 +02:00
|
|
|
protected function getFormActions(RequestHandler $controller = null, $name, $context = [])
|
2016-11-29 00:31:16 +01:00
|
|
|
{
|
|
|
|
// @todo Deprecate or formalise support for getCMSActions()
|
|
|
|
$actions = $context['Record']->getCMSActions();
|
|
|
|
$this->invokeWithExtensions('updateFormActions', $actions, $controller, $name, $context);
|
|
|
|
return $actions;
|
|
|
|
}
|
2016-10-20 01:42:24 +02:00
|
|
|
|
2016-11-29 00:31:16 +01:00
|
|
|
/**
|
2017-05-04 04:07:51 +02:00
|
|
|
* @param RequestHandler $controller
|
2016-11-29 00:31:16 +01:00
|
|
|
* @param string $name
|
|
|
|
* @param array $context
|
|
|
|
* @return null|Validator
|
|
|
|
*/
|
2017-05-04 04:07:51 +02:00
|
|
|
protected function getFormValidator(RequestHandler $controller = null, $name, $context = [])
|
2016-11-29 00:31:16 +01:00
|
|
|
{
|
2020-02-13 00:51:56 +01:00
|
|
|
if (!$context['Record'] instanceof DataObject) {
|
|
|
|
return null;
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
2016-10-20 01:42:24 +02:00
|
|
|
|
2020-05-27 23:35:07 +02:00
|
|
|
$compositeValidator = $context['Record']->getCompositeValidator();
|
2020-02-13 20:21:22 +01:00
|
|
|
|
2020-02-19 20:54:30 +01:00
|
|
|
// Extend validator - legacy support, will be removed in 5.0.0
|
2020-05-27 23:35:07 +02:00
|
|
|
foreach ($compositeValidator->getValidators() as $validator) {
|
2020-02-19 20:54:30 +01:00
|
|
|
$this->invokeWithExtensions('updateFormValidator', $validator, $controller, $name, $context);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Extend validator - forward support, will be supported beyond 5.0.0
|
2020-05-27 23:35:07 +02:00
|
|
|
$this->invokeWithExtensions('updateCompositeValidator', $compositeValidator);
|
2020-02-13 20:21:22 +01:00
|
|
|
|
2020-05-27 23:35:07 +02:00
|
|
|
return $compositeValidator;
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
2016-10-20 01:42:24 +02:00
|
|
|
|
2016-11-29 00:31:16 +01:00
|
|
|
/**
|
|
|
|
* Return list of mandatory context keys
|
|
|
|
*
|
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
public function getRequiredContext()
|
|
|
|
{
|
|
|
|
return ['Record'];
|
|
|
|
}
|
2016-10-20 01:42:24 +02:00
|
|
|
}
|