Passed
Push — master ( bec2a0...9c6a4b )
by Nicolaas
02:11
created

AllLinks::is_admin_link()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 1
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Sunnysideup\TemplateOverview\Api;
4
5
use ReflectionClass;
6
7
use Sunnysideup\TemplateOverview\Api\Providers\AllLinksControllerInfo;
8
use Sunnysideup\TemplateOverview\Api\Providers\AllLinksDataObjects;
9
use Sunnysideup\TemplateOverview\Api\Providers\AllLinksModelAdmin;
10
use Sunnysideup\TemplateOverview\Api\Providers\AllLinksReports;
11
12
13
14
15
use SilverStripe\Admin\CMSMenu;
16
use SilverStripe\CMS\Model\SiteTree;
17
use SilverStripe\Control\Director;
18
use SilverStripe\Core\ClassInfo;
19
use SilverStripe\Core\Config\Configurable;
20
use SilverStripe\Core\Extensible;
21
use SilverStripe\Core\Injector\Injectable;
22
use SilverStripe\Core\Injector\Injector;
23
24
25
use SilverStripe\ORM\DataObject;
26
use SilverStripe\ORM\DB;
27
use SilverStripe\Versioned\Versioned;
28
29
class AllLinks extends AllLinksProviderBase
30
{
31
32
33
    /**
34
     * @var array
35
     */
36
    protected $allNonCMSLinks = [];
37
38
    /**
39
     * @var array
40
     */
41
    protected $pagesOnFrontEnd = [];
42
43
    /**
44
     * @var array
45
     */
46
    protected $dataObjectsOnFrontEnd = [];
47
48
    /**
49
     * @var array
50
     */
51
    protected $otherControllerMethods = [];
52
53
    /**
54
     * @var array
55
     */
56
    protected $customNonCMSLinks = [];
57
58
    /**
59
     * @var array
60
     */
61
    protected $allCMSLinks = [];
62
63
    /**
64
     * @var array
65
     */
66
    protected $pagesInCMS = [];
67
68
    /**
69
     * @var array
70
     */
71
    protected $dataObjectsInCMS = [];
72
73
    /**
74
     * @var array
75
     */
76
    protected $modelAdmins = [];
77
78
    /**
79
     * @var array
80
     */
81
    protected $reportLinks = [];
82
83
    /**
84
     * @var array
85
     */
86
    protected $leftAndMainLnks = [];
87
88
    /**
89
     * @var array
90
     */
91
    protected $customCMSLinks = [];
92
93
    /**
94
     * url snippets that if found in links should exclude the link altogether.
95
     * e.g. 'admin/registry'
96
     *
97
     * @var array
98
     */
99
    private static $exclude_list = [];
100
101
    /**
102
     * @var int
103
     */
104
    private static $number_of_examples = 1;
105
106
    /**
107
     * @var array
108
     */
109
    private static $custom_links = [];
110
111
    /**
112
     * @var array
113
     */
114
    private static $controller_name_space_filter = [];
115
116
    /**
117
     * @param  string  $link
118
     * @return bool
119
     */
120
    public static function is_admin_link($link): bool
121
    {
122
        return substr(ltrim($link, '/'), 0, 5) === 'admin' ? true : false;
123
    }
124
125
    /**
126
     * Sanitise a model class' name for inclusion in a link
127
     *
128
     * @param string $class
129
     * @return string
130
     */
131
    public static function sanitise_class_name($class)
132
    {
133
        return str_replace('\\', '-', $class);
134
    }
135
136
    /**
137
     * returns an array of allNonCMSLinks => [] , allCMSLinks => [], otherControllerMethods => []
138
     * @return array
139
     */
140
    public function getAllLinks() : array
141
    {
142
143
        foreach ($this->Config()->get('custom_links') as $link) {
144
            $link = '/' . ltrim($link, '/') . '/';
145
            if (self::is_admin_link($link)) {
146
                $this->customCMSLinks[] = $link;
147
            } else {
148
                $this->customNonCMSLinks[] = $link;
149
            }
150
        }
151
        $this->pagesOnFrontEnd = $this->ListOfPagesLinks(false);
152
        $this->dataObjectsOnFrontEnd = $this->ListOfDataObjectsLinks(false);
153
154
        $this->allNonCMSLinks = $this->addToArrayOfLinks($this->allNonCMSLinks, $this->pagesOnFrontEnd);
155
        $this->allNonCMSLinks = $this->addToArrayOfLinks($this->allNonCMSLinks, $this->dataObjectsOnFrontEnd);
156
        $this->allNonCMSLinks = $this->addToArrayOfLinks($this->allNonCMSLinks, $this->customNonCMSLinks);
157
        sort($this->allNonCMSLinks);
158
159
        $this->pagesInCMS = $this->ListOfPagesLinks(true);
160
        $this->dataObjectsInCMS = $this->ListOfDataObjectsLinks(true);
161
        $this->modelAdmins = $this->ListOfAllModelAdmins();
162
        $this->leftAndMainLnks = $this->ListOfAllLeftAndMains();
163
        $this->reportLinks = $this->listOfAllReports();
164
165
        $this->allCMSLinks = $this->addToArrayOfLinks($this->allCMSLinks, $this->pagesInCMS);
166
        $this->allCMSLinks = $this->addToArrayOfLinks($this->allCMSLinks, $this->dataObjectsInCMS);
167
        $this->allCMSLinks = $this->addToArrayOfLinks($this->allCMSLinks, $this->modelAdmins);
168
        $this->allCMSLinks = $this->addToArrayOfLinks($this->allCMSLinks, $this->leftAndMainLnks);
169
        $this->allCMSLinks = $this->addToArrayOfLinks($this->allCMSLinks, $this->reportLinks);
170
        $this->allCMSLinks = $this->addToArrayOfLinks($this->allCMSLinks, $this->customCMSLinks);
171
        sort($this->allCMSLinks);
172
173
        $this->otherControllerMethods = $this->ListOfAllControllerMethods();
174
175
        return [
176
            'allNonCMSLinks' => $this->allNonCMSLinks,
177
            'allCMSLinks' => $this->allCMSLinks,
178
            'otherLinks' => $this->otherControllerMethods,
179
        ];
180
    }
181
182
    /**
183
     * returns a list of all model admin links
184
     * @return array
185
     */
186
    public function ListOfAllModelAdmins()
187
    {
188
        $obj = Injector::inst()->get(AllLinksModelAdmin::class);
189
        $obj->setNumberOfExamples($this->Config()->number_of_examples);
190
191
        return $obj->getAllLinksInner();
192
    }
193
194
    /**
195
     * @return array
196
     */
197
    public function ListOfAllControllerMethods(): array
198
    {
199
        $obj = Injector::inst()->get(AllLinksControllerInfo::class);
200
        $obj->setValidNameSpaces($this->Config()->controller_name_space_filter);
201
202
        return $obj->getAllLinksInner();
203
    }
204
    /**
205
     * @return array
206
     */
207
    public function ListOfDataObjectsLinks(bool $inCMS): array
208
    {
209
        $obj = Injector::inst()->get(AllLinksDataObjects::class);
210
        $obj->setNumberOfExamples($this->Config()->number_of_examples);
211
212
        return $obj->getAllLinksInner($inCMS);
213
    }
214
215
    /**
216
     * Takes {@link #$classNames}, gets the URL of the first instance of it
217
     * (will exclude extensions of the class) and
218
     * appends to the {@link #$urls} list to be checked
219
     *
220
     * @param bool $pageInCMS
221
     *
222
     * @return array
223
     */
224
    public function ListOfPagesLinks($pageInCMS = false)
225
    {
226
        //first() will return null or the object
227
        $return = [];
228
        $siteTreeClassNames = $this->getListOfAllSiteTreeClasses();
229
        foreach ($siteTreeClassNames as $class) {
230
            for ($i = 0; $i < $this->Config()->number_of_examples; $i++) {
231
                $excludedClasses = $this->arrayExcept($siteTreeClassNames, $class);
232
                $page = Versioned::get_by_stage($class, Versioned::LIVE)
233
                    ->exclude(['ClassName' => $excludedClasses])
234
                    ->sort(DB::get_conn()->random() . ' ASC')
235
                    ->first();
236
                if (! $page) {
237
                    $page = Versioned::get_by_stage($class, Versioned::DRAFT)
238
                        ->exclude(['ClassName' => $excludedClasses])
239
                        ->sort(DB::get_conn()->random() . ' ASC')
240
                        ->first();
241
                }
242
                if ($page) {
243
                    if ($pageInCMS) {
244
                        $url = $page->CMSEditLink();
245
                        $return[] = $url;
246
                        $return[] = str_replace('/edit/', '/settings/', $url);
247
                        $return[] = str_replace('/edit/', '/history/', $url);
248
                    } else {
249
                        $url = $page->Link();
250
                        $return[] = $url;
251
                    }
252
                }
253
            }
254
        }
255
256
        return $return;
257
    }
258
259
    /**
260
     * @return array
261
     */
262
    public function ListOfAllLeftAndMains()
263
    {
264
        //first() will return null or the object
265
        $return = [];
266
        $list = CMSMenu::get_cms_classes();
267
        foreach ($list as $class) {
268
            if ($this->isValidClass($class)) {
269
                $obj = Injector::inst()->get($class);
270
                if ($obj) {
271
                    $url = $obj->Link();
272
                    if ($url) {
273
                        $return[] = $url;
274
                    }
275
                }
276
            }
277
        }
278
279
        return $return;
280
    }
281
282
283
    /**
284
     * returns a list of all reports
285
     * @return array
286
     */
287
    public function ListOfAllReports()
288
    {
289
        $reportsLinks = Injector::inst()->get(AllLinksReports::class);
290
        return $reportsLinks->getAllLinksInner();
291
    }
292
293
    /**
294
     * Pushes an array of items to an array
295
     * @param array $array Array to push items to (will overwrite)
296
     * @param array $pushArray Array of items to push to $array.
297
     *
298
     * @return array
299
     */
300
    protected function addToArrayOfLinks($array, $pushArray): array
301
    {
302
        $excludeList = $this->Config()->exclude_list;
303
        foreach ($pushArray as $pushItem) {
304
            //clean
305
            if (self::is_admin_link($pushItem)) {
306
                $pushItem = str_replace('?stage=Stage', '', $pushItem);
307
            }
308
            $pushItem = self::sanitise_class_name($pushItem);
309
            $pushItem = '/' . Director::makeRelative($pushItem);
310
311
            if (is_array($excludeList) && count($excludeList)) {
312
                foreach ($excludeList as $excludeItem) {
313
                    if (stripos($pushItem, $excludeItem) !== false) {
314
                        continue 2;
315
                    }
316
                }
317
            }
318
            if (! in_array($pushItem, $array, true)) {
319
                array_push($array, $pushItem);
320
            }
321
        }
322
        return $array;
323
    }
324
325
326
}
327