Passed
Pull Request — master (#281)
by
unknown
02:12
created

ElementalAreaField::getArea()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace DNADesign\Elemental\Forms;
4
5
use DNADesign\Elemental\Models\BaseElement;
6
use DNADesign\Elemental\Models\ElementalArea;
7
use SilverStripe\Forms\CompositeField;
8
use SilverStripe\Forms\FieldGroup;
9
use SilverStripe\Forms\FieldList;
10
use SilverStripe\Forms\FormField;
11
use SilverStripe\Forms\TabSet;
12
13
class ElementalAreaField extends FormField
14
{
15
    /**
16
     * @var ElementalArea $area
17
     */
18
    protected $area;
19
20
    /**
21
     * @var array $type
22
     */
23
    protected $types = [];
24
25
    /**
26
     * @var null
27
     */
28
    protected $inputType = null;
29
30
    /**
31
     * @param string $name
32
     * @param ElementalArea $area
33
     */
34
    public function __construct($name, ElementalArea $area)
35
    {
36
        // By default, no need for a title on the editor. If there is more than one area then use `setTitle` to describe
37
        parent::__construct($name, '');
38
        $this->area = $area;
39
40
        $this->addExtraClass('element-editor__container');
41
    }
42
43
    /**
44
     * @param array $types
45
     *
46
     * @return $this
47
     */
48
    public function setTypes($types)
49
    {
50
        $this->types = $types;
51
52
        return $this;
53
    }
54
55
    /**
56
     * @return array
57
     */
58
    public function getTypes()
59
    {
60
        $types = $this->types;
61
62
        $this->extend('updateGetTypes', $types);
63
64
        return $types;
65
    }
66
67
    /**
68
     * @return ElementalArea
69
     */
70
    public function getArea()
71
    {
72
        return $this->area;
73
    }
74
75
    public function getSchemaDataDefaults()
76
    {
77
        $schemaData = parent::getSchemaDataDefaults();
78
        $pageId = ($this->getArea() && ($page = $this->getArea()->getOwnerPage())) ? $page->ID : null;
79
        $schemaData['page-id'] = $pageId;
80
81
        $blockTypes = [];
82
83
        foreach ($this->getTypes() as $className => $blockTitle) {
84
            $blockTypes[] = [
85
                'value' => $className,
86
                'title' => $blockTitle,
87
            ];
88
        }
89
90
        $schemaData['element-types'] = $blockTypes;
91
        return $schemaData;
92
    }
93
94
    /**
95
     * A getter method that seems redundant in that it is a function that returns a function,
96
     * however the returned closure is used in an array map function to return a complete FieldList
97
     * representing a read only view of the element passed in (to the closure).
98
     *
99
     * @return callable
100
     */
101
    protected function getReadOnlyBlockReducer()
102
    {
103
        return function (BaseElement $element) {
104
            $parentName = 'Element' . $element->ID;
105
            $elementFields = $element->getCMSFields();
106
107
            // Obtain highest impact fields for a summary (e.g. Title & Content)
108
            foreach ($elementFields as $field) {
109
                if (is_object($field) && $field instanceof TabSet) {
110
                    // Assign the fields of the first Tab in the TabSet - most regularly 'Root.Main'
111
                    $elementFields = $field->FieldList()->first()->FieldList();
112
                    break;
113
                }
114
            }
115
116
            // Set values (before names don't match anymore)
117
            $elementFields->setValues($element->getQueriedDatabaseFields());
118
119
            // Ensure field names are unique between elements on parent form
120
            $elementFields->recursiveWalk(function ($field) use ($parentName) {
121
                $field->setName($parentName . '_' . $field->getName());
122
            });
123
124
            // Combine into an appropriately named group
125
            $elementGroup = FieldGroup::create($elementFields);
126
            $elementGroup->setForm($this->getForm());
127
            $elementGroup->setName($parentName);
128
            $elementGroup->addExtraClass('elemental-area__element--historic');
129
130
            // Also set the important data for the rendering Component
131
            $elementGroup->setSchemaData([
132
                'data' => [
133
                    'ElementID' => $element->ID,
134
                    'ElementType' => $element->getType(),
135
                    'ElementIcon' => $element->config()->icon,
136
                    'ElementTitle' => $element->Title,
137
                    // @todo: Change this to block history permalink when that functionality becomes available.
138
                    'ElementEditLink' => $element->CMSEditLink()
139
                ]
140
            ]);
141
142
            return $elementGroup;
143
        };
144
    }
145
146
    /**
147
     * Provides a readonly representation of the GridField (superclass) Uses a reducer
148
     * {@see ElementalAreaField::getReadOnlyBlockReducer()} to fetch a read only representation of the listed class
149
     * {@see GridField::getModelClass()}
150
     *
151
     * @return CompositeField
152
     */
153
    public function performReadonlyTransformation()
154
    {
155
        /** @var CompositeField $readOnlyField */
156
        $readOnlyField = $this->castedCopy(CompositeField::class);
157
        $blockReducer = $this->getReadOnlyBlockReducer();
158
        $readOnlyField->setChildren(
159
            FieldList::create(array_map($blockReducer, $this->getArea()->Elements()->toArray()))
160
        );
161
162
        $readOnlyField = $readOnlyField->performReadonlyTransformation();
163
        return $readOnlyField
164
            ->setReadOnly(true)
165
            ->setName($this->getName())
166
            ->addExtraClass('elemental-area--read-only');
167
    }
168
}
169