Passed
Push — master ( 07940f...841329 )
by Nicolaas
03:51 queued 01:48
created

DefaultDashboardProvider::addPagesLinks()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 2
eloc 10
c 3
b 0
f 0
nc 2
nop 0
dl 0
loc 13
rs 9.9332
1
<?php
2
3
namespace Sunnysideup\DashboardWelcomeQuicklinks\Api;
4
5
use SilverStripe\Admin\ModelAdmin;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Admin\ModelAdmin was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use SilverStripe\Assets\File;
7
use SilverStripe\Assets\Image;
8
use SilverStripe\Assets\Folder;
9
use SilverStripe\Assets\Upload;
10
use SilverStripe\CMS\Model\SiteTree;
0 ignored issues
show
Bug introduced by
The type SilverStripe\CMS\Model\SiteTree was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use SilverStripe\Core\ClassInfo;
12
use SilverStripe\Core\Config\Config;
13
use SilverStripe\Core\Config\Configurable;
14
use SilverStripe\Core\Injector\Injector;
15
use SilverStripe\MFA\Report\EnabledMembers;
0 ignored issues
show
Bug introduced by
The type SilverStripe\MFA\Report\EnabledMembers was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use SilverStripe\ORM\DataObject;
17
use SilverStripe\Security\DefaultAdminService;
18
use SilverStripe\Security\Group;
19
use SilverStripe\Security\Member;
20
use SilverStripe\Security\Permission;
21
use SilverStripe\VersionedAdmin\ArchiveAdmin;
0 ignored issues
show
Bug introduced by
The type SilverStripe\VersionedAdmin\ArchiveAdmin was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use Sunnysideup\DashboardWelcomeQuicklinks\Interfaces\DashboardWelcomeQuickLinksProvider;
23
24
class DefaultDashboardProvider implements DashboardWelcomeQuickLinksProvider
25
{
26
    use Configurable;
27
    protected $links = [];
28
29
    public function provideDashboardWelcomeQuickLinks(): array
30
    {
31
        $this->addPagesLinks();
32
        $this->addFindPages();
33
        $this->addFilesAndImages();
34
        $this->addSiteConfigLinks();
35
        if(Permission::check('ADMIN')) {
36
            $this->addSecurityLinks();
37
        }
38
        $this->addModelAdminLinks();
39
        $this->addMeLinks();
40
        return $this->links;
41
    }
42
43
44
    private static $new_phrase = '+';
0 ignored issues
show
introduced by
The private property $new_phrase is not used, and could be removed.
Loading history...
45
    private static $review_phrase = '☑';
0 ignored issues
show
introduced by
The private property $review_phrase is not used, and could be removed.
Loading history...
46
    private static $edit_phrase = '✎';
0 ignored issues
show
introduced by
The private property $edit_phrase is not used, and could be removed.
Loading history...
47
    private static $model_admins_to_skip = [
0 ignored issues
show
introduced by
The private property $model_admins_to_skip is not used, and could be removed.
Loading history...
48
        ArchiveAdmin::class,
49
    ];
50
    private static $pages_to_skip = [
0 ignored issues
show
introduced by
The private property $pages_to_skip is not used, and could be removed.
Loading history...
51
52
    ];
53
54
55
    protected function addPagesLinks()
56
    {
57
        $this->addGroup('PAGES', 'Pages', 10);
58
        $this->addLink('PAGES', $this->phrase('add'). ' Page', '/admin/pages/add');
59
        $pagesCount = DataObject::get('Page')->count();
60
        $this->addLink('PAGES', $this->phrase('edit'). ' Pages ('.$pagesCount.')', '/admin/pages');
61
        $pageLastEdited = DataObject::get_one('Page', '', true, 'LastEdited DESC');
62
        if ($pageLastEdited) {
63
            $this->addLink('PAGES', '✎ Last Edited Page: '.$pageLastEdited->Title, $pageLastEdited->CMSEditLink());
64
        }
65
        $this->addLink('PAGES', $this->phrase('review'). ' Page Reports', '/admin/reports');
66
        $lastWeekLink = '/admin/pages?'.'q[LastEditedFrom]='.date('Y-m-d', strtotime('-1 week'));
67
        $this->addLink('PAGES', $this->phrase('review'). ' Recently Modified Pages', $lastWeekLink);
68
    }
69
70
    protected function addFindPages()
71
    {
72
        $pages = [];
73
        $pagesToSkip = (array) $this->Config()->get('pages_to_skip');
74
        foreach (ClassInfo::subclassesFor(SiteTree::class, false) as $className) {
75
            if(in_array($className, $pagesToSkip)) {
76
                continue;
77
            }
78
            $pages[$className] = $className;
79
80
        }
81
        $this->addGroup('PAGEFILTER', 'Page Types ('.count($pages).')', 300);
82
        $count = 0;
83
        foreach($pages as $pageClassName) {
84
            $pageCount = $pageClassName::get()->filter(['ClassName' => $pageClassName])->count();
85
            if($pageCount < 1) {
86
                continue;
87
            }
88
            $count++;
89
            if($count > 7) {
90
                $this->addLink('PAGEFILTER', 'More ...', '/admin/pages');
91
                break;
92
            }
93
            $page = Injector::inst()->get($pageClassName);
94
            $pageTitle = $page->i18n_singular_name();
95
            $query = 'q[ClassName]='.$pageClassName;
96
            $link = 'admin/pages?' . $query;
97
            $this->addLink('PAGEFILTER', $this->phrase('edit'). ' '.$pageTitle.' ('.$pageCount.')', $link);
98
        }
99
    }
100
    protected function addFilesAndImages()
101
    {
102
        // 'Files ('.$filesCount.') and Images ('.$imageCount.')'
103
        $this->addGroup('FILESANDIMAGES', 'Files and Images', 20);
104
        $uploadFolderName = Config::inst()->get(Upload::class, 'uploads_folder');
105
        $uploadFolder = Folder::find_or_make($uploadFolderName);
106
        // all
107
        $this->addLink('FILESANDIMAGES', $this->phrase('edit'). ' Open File Browswer', '/admin/assets');
108
        // per type
109
        $filesCount = File::get()->exclude(['ClassName' => [Folder::class, Image::class]])->count();
110
        $imageCount = File::get()->filter(['ClassName' => [Image::class]])->count();
111
        $this->addLink('FILESANDIMAGES', $this->phrase('review'). ' Images ('.$imageCount.')', 'admin/assets?filter[appCategory]=IMAGE');
112
        $this->addLink('FILESANDIMAGES', $this->phrase('review'). ' Files ('.$filesCount.')', 'admin/assets?filter[appCategory]=DOCUMENT');
113
114
        // default upload folder
115
        $this->addLink('FILESANDIMAGES', $this->phrase('review'). ' Open Default Upload Folder', $uploadFolder->CMSEditLink());
116
117
        // recent
118
        $lastWeekLink = '/admin/assets?'.'filter[lastEditedFrom]='.date('Y-m-d', strtotime('-1 week')).'&view=tile';
119
        $this->addLink('FILESANDIMAGES', $this->phrase('review'). ' Recently modified Files', $lastWeekLink);
120
    }
121
122
    protected function addSiteConfigLinks()
123
    {
124
        $this->addGroup('SITECONFIG', 'Site Wide Configuration', 20);
125
        $this->addLink('SITECONFIG', $this->phrase('review'). ' Site Settings', '/admin/settings');
126
    }
127
128
    protected function addSecurityLinks()
129
    {
130
        $this->addGroup('SECURITY', 'Security', 30);
131
        $this->addLink('SECURITY', $this->phrase('add'). ' User', '/admin/security/users/EditForm/field/users/item/new');
132
        $userCount = Member::get()->count();
133
        $groupCount = Group::get()->count();
134
        $this->addLink('SECURITY', $this->phrase('review'). ' Users ('.$userCount.')', '/admin/security');
135
        $this->addLink('SECURITY', $this->phrase('review'). ' Groups  ('.$groupCount.')', '/admin/security/groups');
136
        DefaultAdminService::singleton()->extend('addSecurityLinks', $this);
137
        $adminGroup = Permission::get_groups_by_permission('ADMIN')->first();
138
        if($adminGroup) {
139
            $userCount = $adminGroup->Members()->count();
140
            $this->addLink('SECURITY', $this->phrase('review'). ' Administrators ('.$userCount.')', '/admin/security/groups/EditForm/field/groups/item/'.$adminGroup->ID.'/edit');
141
        }
142
        if(class_exists(EnabledMembers::class)) {
143
            $obj = Injector::inst()->get(EnabledMembers::class);
144
            $this->addLink('SECURITY', $this->phrase('review'). ' Multi-Factor Authentication Status', $obj->getLink());
145
146
        }
147
    }
148
149
150
151
152
    protected function addModelAdminLinks()
153
    {
154
        $modelAdmins = [];
155
        $skips = (array) $this->Config()->get('model_admins_to_skip');
156
        foreach (ClassInfo::subclassesFor(ModelAdmin::class, false) as $className) {
157
            if(in_array($className, $skips)) {
158
                continue;
159
            }
160
            $modelAdmins[$className] = $className;
161
162
        }
163
        foreach($modelAdmins as $modelAdminClassName) {
164
            $groupAdded = false;
165
            $ma = Injector::inst()->get($modelAdminClassName);
166
            if($ma->canView()) {
167
                $mas = $ma->getManagedModels();
168
                if(count($mas)) {
169
                    $numberOfModels = count($mas);
170
                    $groupCode = strtoupper($modelAdminClassName);
171
                    $count = 0;
172
                    foreach($mas as $model => $title) {
173
                        $count++;
174
                        if($count > 7) {
175
                            $this->addLink('PAGEFILTER', 'More ...', $ma->Link());
176
                            break;
177
                        }
178
                        if(is_array($title)) {
179
                            $title = $title['title'];
180
                            $model = $title['dataClass'] ?? $model;
181
                        }
182
                        if(! class_exists($model)) {
183
                            continue;
184
                        }
185
                        $obj = Injector::inst()->get($model);
186
                        if($obj && $obj->canView()) {
187
                            if(! $groupAdded) {
188
                                $this->addGroup($groupCode, $ma->menu_title(), 100);
189
                                $groupAdded = true;
190
                            }
191
                            $link = '';
192
                            if($obj->hasMethod('CMSListLink')) {
193
                                $link = $obj->CMSListLink();
194
                            } else {
195
                                $link = $ma->getLinkForModelTab($model);
196
                            }
197
                            $objectCount = $model::get()->count();
198
                            $titleContainsObjectCount = strpos($title, ' ('.$objectCount.')');
199
                            if($titleContainsObjectCount === false) {
200
                                $title .= ' ('.$objectCount.')';
201
                            }
202
                            $this->addLink($groupCode, $this->phrase('edit'). ' '.$title, $link);
203
                            if($numberOfModels < 4) {
204
                                $obj = Injector::inst()->get($model);
205
                                if($obj->canCreate()) {
206
                                    $classNameEscaped = str_replace('\\', '-', $model);
207
                                    $linkNew = $link .= '/EditForm/field/'.$classNameEscaped.'/item/new';
208
                                    $this->addLink($groupCode, $this->phrase('add'). ' '.$obj->i18n_singular_name(), $linkNew);
209
                                }
210
                            }
211
                        }
212
                    }
213
                }
214
            }
215
        }
216
    }
217
218
219
220
    protected function addMeLinks()
221
    {
222
        $this->addGroup('ME', 'My Account', 200);
223
        $this->addLink('ME', $this->phrase('edit') . '  My Details (there is just one of you!)', '/admin/myprofile');
224
        $this->addLink('ME', $this->phrase('review') . '  Test Password Reset', 'Security/lostpassword');
225
        $this->addLink('ME', $this->phrase('review') . '  Log-out', '/Security/logout');
226
    }
227
228
229
    protected function addGroup(string $groupCode, string $title, $sort)
230
    {
231
        $this->links[$groupCode] = [
232
            'Title' => $title,
233
            'SortOrdre' => $sort,
234
        ];
235
    }
236
237
    protected function addLink($groupCode, $title, $link)
238
    {
239
        $this->links[$groupCode]['Items'][] = [
240
            'Title' => $title,
241
            'Link' => $link,
242
        ];
243
    }
244
245
    protected function phrase(string $phrase): string
246
    {
247
        if($phrase === 'add') {
248
            $phrase = $this->config()->get('new_phrase');
249
        } elseif($phrase === 'review') {
250
            $phrase = $this->config()->get('review_phrase');
251
        } elseif($phrase === 'edit') {
252
            $phrase = $this->config()->get('edit_phrase');
253
        }
254
        return _t('DashboardWelcomeQuicklinks.'.$phrase, $phrase);
255
    }
256
257
}
258