Test Setup Failed
Pull Request — master (#197)
by Gorrie
01:07
created

src/Models/ElementalArea.php (1 issue)

1
<?php
2
3
namespace DNADesign\Elemental\Models;
4
5
use DNADesign\Elemental\Extensions\ElementalAreasExtension;
6
use SilverStripe\CMS\Model\SiteTree;
7
use SilverStripe\Core\ClassInfo;
8
use SilverStripe\Core\Extensible;
9
use SilverStripe\ORM\ArrayList;
10
use SilverStripe\ORM\DataObject;
11
use SilverStripe\ORM\FieldType\DBField;
12
use SilverStripe\ORM\FieldType\DBHTMLText;
13
use SilverStripe\ORM\HasManyList;
14
use SilverStripe\Versioned\Versioned;
15
use SilverStripe\Core\Injector\Injector;
16
17
/**
18
 * Class ElementalArea
19
 * @package DNADesign\Elemental\Models
20
 *
21
 * @property string $OwnerClassName
22
 *
23
 * @method HasManyList|BaseElement[] Elements()
24
 */
25
class ElementalArea extends DataObject
26
{
27
    /**
28
     * @var array $db
29
     */
30
    private static $db = [
31
        'OwnerClassName' => 'Varchar(255)',
32
    ];
33
34
    /**
35
     * @var array $has_many
36
     */
37
    private static $has_many = [
38
        'Elements' => BaseElement::class
39
    ];
40
41
    /**
42
     * @var array
43
     */
44
    private static $extensions = [
45
        Versioned::class
46
    ];
47
48
    /**
49
     * @var array
50
     */
51
    private static $owns = [
52
        'Elements'
53
    ];
54
55
    /**
56
     * @var array
57
     */
58
    private static $cascade_deletes = [
59
        'Elements'
60
    ];
61
62
    /**
63
     * @var array
64
     */
65
    private static $summary_fields = [
66
        'Title' => 'Title'
67
    ];
68
69
    /**
70
     * @var string
71
     */
72
    private static $table_name = 'ElementalArea';
0 ignored issues
show
The private property $table_name is not used, and could be removed.
Loading history...
73
74
    /**
75
     * @return array
76
     */
77
    public function supportedPageTypes()
78
    {
79
        $elementalClasses = [];
80
81
        foreach (ClassInfo::getValidSubClasses(SiteTree::class) as $class) {
82
            if (Extensible::has_extension($class, ElementalAreasExtension::class)) {
83
                $elementalClasses[] = $class;
84
            }
85
        }
86
87
        return $elementalClasses;
88
    }
89
90
    /**
91
     * @return DBHTMLText
92
     */
93
    public function forTemplate()
94
    {
95
        return $this->renderWith(static::class);
96
    }
97
98
    /**
99
     * Necessary to display results in CMS site search.
100
     *
101
     * @return DBField
102
     */
103
    public function Breadcrumbs()
104
    {
105
        $ownerClassName = $this->OwnerClassName;
106
107
        if ($owner = $ownerClassName::get()->filter('ElementalAreaID', $this->ID)->first()) {
108
            return DBField::create_field('HTMLText', sprintf(
109
                '<a href="%s">%s</a>',
110
                $owner->CMSEditLink(),
111
                $owner->Title
112
            ));
113
        }
114
115
        return null;
116
    }
117
118
    /**
119
     * Used in template instead of {@link Elements()} to wrap each element in
120
     * its' controller, making it easier to access and process form logic and
121
     * actions stored in {@link ElementController}.
122
     *
123
     * @return ArrayList
124
     * @throws \Exception
125
     */
126
    public function ElementControllers()
127
    {
128
        $controllers = new ArrayList();
129
        $items = $this->Elements();
130
131
        if (!is_null($items)) {
132
            foreach ($items as $element) {
133
                $controller = $element->getController();
134
                $controllers->push($controller);
135
            }
136
        }
137
138
        return $controllers;
139
    }
140
141
    /**
142
     * @return null|DataObject
143
     * @throws \Psr\Container\NotFoundExceptionInterface
144
     * @throws \SilverStripe\ORM\ValidationException
145
     */
146
    public function getOwnerPage()
147
    {
148
        if ($this->OwnerClassName) {
149
            $class = $this->OwnerClassName;
150
            $instance = Injector::inst()->get($class);
151
            if (!ClassInfo::hasMethod($instance, 'getElementalRelations')) {
152
                return null;
153
            }
154
            $elementalAreaRelations = $instance->getElementalRelations();
155
156
            foreach ($elementalAreaRelations as $eaRelationship) {
157
                $areaID = $eaRelationship . 'ID';
158
159
                $page = Versioned::get_by_stage($class, Versioned::get_stage())->filter($areaID, $this->ID);
160
161
                if ($page && $page->exists()) {
162
                    return $page->first();
163
                }
164
            }
165
        }
166
167
        foreach ($this->supportedPageTypes() as $class) {
168
            $instance = Injector::inst()->get($class);
169
            if (!ClassInfo::hasMethod($instance, 'getElementalRelations')) {
170
                return null;
171
            }
172
            $elementalAreaRelations = $instance->getElementalRelations();
173
174
            foreach ($elementalAreaRelations as $eaRelationship) {
175
                $areaID = $eaRelationship . 'ID';
176
                $page = Versioned::get_by_stage($class, Versioned::DRAFT)->filter($areaID, $this->ID);
177
178
                if ($page && $page->exists()) {
179
                    $this->OwnerClassName = $class;
180
                    $this->write();
181
182
                    return $page->first();
183
                }
184
            }
185
        }
186
187
        return null;
188
    }
189
190
    /**
191
     * @param null $member
192
     * @return bool
193
     * @throws \Psr\Container\NotFoundExceptionInterface
194
     * @throws \SilverStripe\ORM\ValidationException
195
     */
196
    public function canEdit($member = null)
197
    {
198
        if (parent::canEdit($member)) {
199
            return true;
200
        }
201
202
        $ownerPage = $this->getOwnerPage();
203
        if ($ownerPage !== null) {
204
            return $this->getOwnerPage()->canEdit($member);
205
        }
206
207
        return false;
208
    }
209
210
    /**
211
     * @param null $member
212
     * @return bool
213
     * @throws \Psr\Container\NotFoundExceptionInterface
214
     * @throws \SilverStripe\ORM\ValidationException
215
     */
216
    public function canView($member = null)
217
    {
218
        if (parent::canEdit($member)) {
219
            return true;
220
        }
221
222
        $ownerPage = $this->getOwnerPage();
223
        if ($ownerPage !== null) {
224
            return $this->getOwnerPage()->canView($member);
225
        }
226
227
        return false;
228
    }
229
}
230