1
<?php
2

3
namespace SilverStripe\VersionedAdmin\Forms;
4

5
use InvalidArgumentException;
6
use SilverStripe\Control\RequestHandler;
7
use SilverStripe\Core\Config\Configurable;
8
use SilverStripe\Core\Extensible;
9
use SilverStripe\Core\Injector\Injectable;
10
use SilverStripe\Forms\FieldList;
11
use SilverStripe\Forms\Form;
12
use SilverStripe\Forms\FormFactory;
13
use SilverStripe\Forms\FormField;
14
use SilverStripe\Forms\Tab;
15
use SilverStripe\ORM\DataObject;
16

17
class DataObjectVersionFormFactory implements FormFactory
18
{
19
    use Configurable;
20
    use Extensible;
21
    use Injectable;
22

23
    /**
24
     * View a version of the record, readonly: Default.
25
     *
26
     * @var string
27
     */
28
    const TYPE_HISTORY = 'history';
29

30
    /**
31
     * Define context types that will automatically be converted to readonly forms
32
     *
33
     * @config
34
     * @var string[]
35
     */
36
    private static $readonly_types = [
37
        self::TYPE_HISTORY,
38
    ];
39

40 1
    public function getForm(RequestHandler $controller = null, $name = FormFactory::DEFAULT_NAME, $context = [])
41
    {
42
        // Validate context
43 1
        foreach ($this->getRequiredContext() as $required) {
44 1
            if (!isset($context[$required])) {
45 1
                throw new InvalidArgumentException("Missing required context $required");
46
            }
47
        }
48

49 1
        $fields = $this->getFormFields($controller, $name, $context);
50 1
        $actions = $this->getFormActions($controller, $name, $context);
51 1
        $form = Form::create($controller, $name, $fields, $actions);
52

53 1
        $this->invokeWithExtensions('updateForm', $form, $controller, $name, $context);
54

55
        // Populate form from record
56 1
        if (isset($context['Record'])) {
57
            /** @var DataObject $record */
58 1
            $record = $context['Record'];
59 1
            $form->loadDataFrom($record);
60

61
            // Mark as readonly for some types
62 1
            if ($this->isReadonlyFormType($context)) {
63 1
                $form->makeReadonly();
64
            }
65
        }
66

67 1
        $form->addExtraClass('form--fill-height form--no-dividers');
68 1
        return $form;
69
    }
70

71
    /**
72
     * Get form type from 'type' context
73
     *
74
     * @param array $context
75
     * @return string
76
     */
77 1
    public function getFormType(array $context)
78
    {
79 1
        return empty($context['Type']) ? static::TYPE_HISTORY : $context['Type'];
80
    }
81

82
    /**
83
     * Get whether the current form type should be treated as readonly
84
     *
85
     * @param array $context
86
     * @return bool
87
     */
88 1
    public function isReadonlyFormType(array $context)
89
    {
90 1
        return in_array($this->getFormType($context), $this->config()->get('readonly_types'));
91
    }
92

93 1
    protected function getFormFields(RequestHandler $controller = null, $name, $context = [])
94
    {
95 1
        $record = $context['Record'];
96
        /** @var FieldList $fields */
97 1
        $fields = $record->getCMSFields();
98

99 1
        $this->removeHistoryViewerFields($fields);
100 1
        $this->removeSelectedRightTitles($fields);
101

102 1
        $this->invokeWithExtensions('updateFormFields', $fields, $controller, $name, $context);
103

104 1
        return $fields;
105
    }
106

107
    /**
108
     * Do not return {@link HistoryViewerField} instances in the form - remove them if they are found
109
     *
110
     * @param FieldList $fields
111
     */
112
    protected function removeHistoryViewerFields(FieldList $fields)
113
    {
114
        // Remove HistoryViewerFields
115 1
        $fields->recursiveWalk(function (FormField $field) {
116 1
            if ($field instanceof HistoryViewerField) {
117 1
                $field->getContainerFieldList()->remove($field);
118
            }
119 1
        });
120

121
        // Cleanup empty tabs after removing HistoryViewerFields
122 1
        $fields->recursiveWalk(function (FormField $field) {
123 1
            if ($field instanceof Tab && !$field->Fields()->count()) {
124 1
                $field->getContainerFieldList()->remove($field);
125
            }
126 1
        });
127
    }
128

129
    /**
130
     * Remove right titles from selected form fields by default
131
     *
132
     * @param FieldList $fields
133
     */
134 1
    protected function removeSelectedRightTitles(FieldList $fields)
135
    {
136 1
        $noRightTitle = ['MetaDescription', 'ExtraMeta'];
137

138 1
        foreach ($noRightTitle as $fieldName) {
139 1
            if ($field = $fields->dataFieldByName($fieldName)) {
140 1
                $field->setRightTitle('');
141
            }
142
        }
143
    }
144

145 1
    protected function getFormActions(RequestHandler $controller = null, $formName, $context = [])
146
    {
147 1
        $actions = FieldList::create();
148 1
        $this->invokeWithExtensions('updateFormActions', $actions, $controller, $formName, $context);
149 1
        return $actions;
150
    }
151

152 1
    public function getRequiredContext()
153
    {
154 1
        return ['Record'];
155
    }
156
}

Read our documentation on viewing source code .

Loading