Passed
Push — master ( 15b471...17fc67 )
by Nicolaas
02:18
created

DashboardWelcomeQuicklinks   A

Complexity

Total Complexity 37

Size/Duplication

Total Lines 319
Duplicated Lines 0 %

Importance

Changes 20
Bugs 0 Features 0
Metric Value
eloc 195
c 20
b 0
f 0
dl 0
loc 319
rs 9.44
wmc 37

11 Methods

Rating   Name   Duplication   Size   Complexity  
A add_group() 0 7 2
A getFontColor() 0 12 2
A get_links() 0 3 1
A get_base_phrase() 0 4 1
A Breadcrumbs() 0 10 2
A add_link() 0 6 1
B makeShortCut() 0 36 6
A Title() 0 8 3
C updateFormWithQuicklinks() 0 78 14
A getLinksFromImplementor() 0 12 4
A getEditForm() 0 12 1
1
<?php
2
3
namespace Sunnysideup\DashboardWelcomeQuicklinks\Admin;
4
5
use SilverStripe\Admin\LeftAndMain;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Admin\LeftAndMain 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\Core\ClassInfo;
7
use SilverStripe\Core\Config\Config;
8
use SilverStripe\Core\Injector\Injector;
9
use SilverStripe\Forms\LiteralField;
10
use SilverStripe\ORM\ArrayList;
11
use SilverStripe\ORM\DataObject;
12
use SilverStripe\SiteConfig\SiteConfig;
0 ignored issues
show
Bug introduced by
The type SilverStripe\SiteConfig\SiteConfig 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...
13
use SilverStripe\View\ArrayData;
14
use Sunnysideup\DashboardWelcomeQuicklinks\Api\DefaultDashboardProvider;
15
use Sunnysideup\DashboardWelcomeQuicklinks\Interfaces\DashboardWelcomeQuickLinksProvider;
16
17
/**
18
 * Class \Sunnysideup\DashboardWelcomeQuicklinks\Admin\DashboardWelcomeQuicklinks
19
 *
20
 */
21
class DashboardWelcomeQuicklinks extends LeftAndMain
22
{
23
    protected static int $item_counter = 0;
24
    protected static int $group_counter = 0;
25
    protected static array $links = [];
26
27
28
    public static function add_group(string $groupCode, string $title, ?int $sort = 0)
29
    {
30
        self::$group_counter++;
31
32
        self::$links[$groupCode] = [
33
            'Title' => $title,
34
            'SortOrder' => $sort ?: self::$group_counter,
35
        ];
36
    }
37
38
    public static function add_link(string $groupCode, string $title, string $link)
39
    {
40
        self::$item_counter++;
41
        self::$links[$groupCode]['Items'][] = [
42
            'Title' => $title,
43
            'Link' => $link,
44
        ];
45
    }
46
47
    public static function get_links()
48
    {
49
        return self::$links;
50
    }
51
52
    public static function get_base_phrase(string $phrase): string
53
    {
54
        $phrase = Config::inst()->get(static::class, $phrase .'_phrase');
55
        return _t('DashboardWelcomeQuicklinks.'.$phrase, $phrase);
56
    }
57
58
    private static string $add_phrase = '+';
0 ignored issues
show
introduced by
The private property $add_phrase is not used, and could be removed.
Loading history...
59
    private static string $review_phrase = '☑';
0 ignored issues
show
introduced by
The private property $review_phrase is not used, and could be removed.
Loading history...
60
    private static string $edit_phrase = '✎';
0 ignored issues
show
introduced by
The private property $edit_phrase is not used, and could be removed.
Loading history...
61
    private static string $url_segment = 'go';
0 ignored issues
show
introduced by
The private property $url_segment is not used, and could be removed.
Loading history...
62
63
    private static bool $use_default_dashboard_provider = true;
0 ignored issues
show
introduced by
The private property $use_default_dashboard_provider is not used, and could be removed.
Loading history...
64
65
    private static $menu_title = 'Quick-links';
0 ignored issues
show
introduced by
The private property $menu_title is not used, and could be removed.
Loading history...
66
67
    private static $menu_icon_class = 'font-icon-dashboard';
0 ignored issues
show
introduced by
The private property $menu_icon_class is not used, and could be removed.
Loading history...
68
69
    private static $menu_priority = 99999;
0 ignored issues
show
introduced by
The private property $menu_priority is not used, and could be removed.
Loading history...
70
71
    private static $colour_options = [];
0 ignored issues
show
introduced by
The private property $colour_options is not used, and could be removed.
Loading history...
72
    private static $max_shortcuts_per_group = 7;
0 ignored issues
show
introduced by
The private property $max_shortcuts_per_group is not used, and could be removed.
Loading history...
73
74
    private static $more_phrase = '... More';
0 ignored issues
show
introduced by
The private property $more_phrase is not used, and could be removed.
Loading history...
75
76
77
    private static $default_colour_options = [
0 ignored issues
show
introduced by
The private property $default_colour_options is not used, and could be removed.
Loading history...
78
        '#0D47A1',
79
        '#01579B',
80
        '#006064',
81
        '#004D40',
82
        '#1B5E20',
83
        '#33691E',
84
        '#827717',
85
        '#F57F17',
86
        '#FF6F00',
87
        '#E65100',
88
        '#BF360C',
89
        '#3E2723',
90
        '#212121',
91
        '#B71C1C',
92
        '#880E4F',
93
        '#4A148C',
94
        '#311B92',
95
        '#1A237E',
96
    ];
97
98
    /**
99
     * easy to distinguish colours
100
     *
101
     * @var array
102
     */
103
    private static $default_colour_options1 = [
0 ignored issues
show
introduced by
The private property $default_colour_options1 is not used, and could be removed.
Loading history...
104
        '#F2F3F4',
105
        '#222222',
106
        '#F3C300',
107
        '#875692',
108
        '#F38400',
109
        '#A1CAF1',
110
        '#BE0032',
111
        '#C2B280',
112
        '#848482',
113
        '#008856',
114
        '#E68FAC',
115
        '#0067A5',
116
        '#F99379',
117
        '#604E97',
118
        '#F6A600',
119
        '#B3446C',
120
        '#DCD300',
121
        '#882D17',
122
        '#8DB600',
123
        '#654522',
124
        '#E25822',
125
        '#2B3D26',
126
    ];
127
128
129
    /**
130
     * light colours
131
     *
132
     * @var array
133
     */
134
    private static $default_colour_options3 = [
0 ignored issues
show
introduced by
The private property $default_colour_options3 is not used, and could be removed.
Loading history...
135
        '#FFEBEE',
136
        '#FCE4EC',
137
        '#F3E5F5',
138
        '#EDE7F6',
139
        '#E8EAF6',
140
        '#E3F2FD',
141
        '#E1F5FE',
142
        '#E0F7FA',
143
        '#E0F2F1',
144
        '#E8F5E9',
145
        '#F1F8E9',
146
        '#F9FBE7',
147
        '#FFFDE7',
148
        '#FFF8E1',
149
        '#FFF3E0',
150
        '#FBE9E7',
151
        '#EFEBE9',
152
        '#FAFAFA'
153
    ];
154
155
    public function getEditForm($id = null, $fields = null)
156
    {
157
        $form = parent::getEditForm($id, $fields);
158
159
        // if ($form instanceof HTTPResponse) {
160
        //     return $form;
161
        // }
162
        // $form->Fields()->removeByName('LastVisited');
163
164
        $this->updateFormWithQuicklinks($form);
165
166
        return $form;
167
    }
168
169
    public function updateFormWithQuicklinks($form)
170
    {
171
        $shortcuts = $this->getLinksFromImplementor();
172
        // print_r($shortcuts);
173
        $html = '';
174
        $max = $this->Config()->get('max_shortcuts_per_group');
175
        if (count($shortcuts)) {
176
            $html = '<div class="grid-wrapper">';
177
178
            usort(
179
                $shortcuts,
180
                function ($a, $b) {
181
                    ($a['SortOrder'] ?? 0) <=> ($b['SortOrder'] ?? 0);
182
                }
183
            );
184
185
            foreach ($shortcuts as $groupCode => $groupDetails) {
186
                $colour = '';
187
                if (!empty($groupDetails['Colour'])) {
188
                    $colour = 'style="background-color: ' . $groupDetails['Colour'] . '"';
189
                }
190
                $icon = '';
191
                if (!empty($groupDetails['IconClass'])) {
192
                    $icon = '<i class="' . $groupDetails['IconClass'] . '"></i> ';
193
                }
194
                $html .= '
195
                <div class="grid-cell" ' . $colour . '>
196
                    <div class="header">
197
                    <h1>' . $icon . '' . ($groupDetails['Title'] ?? $groupCode) . '</h1>
198
                    </div>
199
                    <div class="entries">';
200
                $items = $groupDetails['Items'] ?? [];
201
                if (!empty($entry['Link']) && class_exists($entry['Link'])) {
202
                    $obj = Injector::inst()->get($entry['Link']);
203
                    if ($obj instanceof DataObject) {
204
                        $entry['Link'] = DataObject::get_one($entry['Link'])->CMSEditLink();
205
                    } else {
206
                        $entry['Link'] = $obj->Link();
207
                    }
208
                }
209
                foreach ($items as $count => $entry) {
210
                    $entry['Class'] = $entry['Class'] ?? '';
211
                    $entry['Class'] .= ($count > $max) ? ' more-item' : '';
212
                    $html .= $this->makeShortCut(
213
                        (string) $entry['Title'],
214
                        (string) $entry['Link'],
215
                        $entry['OnClick'] ?? '',
216
                        $entry['Script'] ?? '',
217
                        $entry['Class'] ?? '',
218
                        $entry['IconClass'] ?? '',
219
                        $entry['Target'] ?? '',
220
                    )->Field();
221
                    if($count > $max && count($items) == $count + 1) {
222
                        $html .= $this->makeShortCut(
223
                            $this->Config()->get('more_phrase'),
224
                            '#', // link
225
                            'dashboardWelcomeQuickLinksSetupInputAndFilterToggleMore(event); return false;', // onclick
226
                            '', // script
227
                            'more-item-more', //class
228
                        )->Field();
229
                    }
230
                }
231
                $html .= '</div></div>';
232
            }
233
        }
234
        $kc = (array) $this->Config()->get('colour_options');
235
        if(empty($kc)) {
236
            $kc = $this->Config()->get('default_colour_options');
237
        }
238
        $kcCount = count($kc);
239
        $colours = '';
240
        foreach ($kc as $key => $colour) {
241
            $colours .= ' .grid-wrapper .grid-cell:nth-child(' . $kcCount . 'n+' . ($key + 1) . ') div.header {background-color: ' . $colour . '; color: '.$this->getFontColor($colour).'!important;}';
242
        }
243
        $html .= '</div>';
244
        $html .= '<script>window.setTimeout(dashboardWelcomeQuickLinksSetupInputAndFilter, 500)</script>';
245
        $html .= '<style>' . $colours . '</style>';
246
        $form->Fields()->push(LiteralField::create('ShortCuts', $html));
247
    }
248
249
    protected function getLinksFromImplementor()
250
    {
251
        $array = [];
252
        $useDefaultDashboard = (bool) $this->config()->get('use_default_dashboard_provider');
253
        $classNames = ClassInfo::implementorsOf(DashboardWelcomeQuickLinksProvider::class);
254
        foreach ($classNames as $className) {
255
            if($useDefaultDashboard === false && (string) $className === DefaultDashboardProvider::class) {
256
                continue;
257
            }
258
            $array += Injector::inst()->get($className)->provideDashboardWelcomeQuickLinks();
259
        }
260
        return $array;
261
    }
262
263
    protected function makeShortCut(string $title, string $link, ?string $onclick = '', ?string $script = '', ?string $class = '', ?string $iconClass = '', ?string $target = '')
264
    {
265
        $name = preg_replace('#[\W_]+#u', '', (string) $title);
266
        $html = '';
267
        if ($onclick) {
268
            $onclick = ' onclick="' . $onclick . '"';
269
        }
270
        if ($script) {
271
            $script = '<script>' . $script . '</script>';
272
        }
273
        $icon = '';
274
        if (!empty($iconClass)) {
275
            $icon = '<i class="' . $iconClass . '"></i> ';
276
        }
277
        if(!$target) {
278
            $target = '_self';
279
        }
280
        $target = ' target="'.$target.'"';
281
        if ($link) {
282
            $html = '
283
            ' . $script . '
284
            <h2 class="' . $class . '">
285
                ' . $icon . '<a href="' . $link . '" ' . $target . ' ' . $onclick . '>' . $title . '</a>
286
            </h2>';
287
        } else {
288
            $html = '
289
            ' . $script . '
290
            <h2>
291
                ' . $title . '
292
            </h2>
293
            ';
294
        }
295
296
        return LiteralField::create(
297
            $name,
298
            $html
299
        );
300
    }
301
    /**
302
     * @return string
303
     */
304
    public function Title()
305
    {
306
        $app = $this->getApplicationName();
307
        $siteConfigTitle = SiteConfig::current_site_config()->Title;
308
        if($siteConfigTitle) {
309
            $app = $siteConfigTitle . ' ('.$app.')';
310
        }
311
        return ($section = $this->SectionTitle()) ? sprintf('%s for %s', $section, $app) : $app;
312
    }
313
    /**
314
     * @param bool $unlinked
315
     * @return ArrayList<ArrayData>
316
     */
317
    public function Breadcrumbs($unlinked = false)
318
    {
319
        $items = new ArrayList([
320
            new ArrayData([
321
                'Title' => $this->Title(),
322
                'Link' => ($unlinked) ? false : $this->Link()
323
            ])
324
        ]);
325
326
        return $items;
327
    }
328
    protected function getFontColor(string $backgroundColor): string
329
    {
330
        // Convert hex color to RGB
331
        $r = hexdec(substr($backgroundColor, 1, 2));
332
        $g = hexdec(substr($backgroundColor, 3, 2));
333
        $b = hexdec(substr($backgroundColor, 5, 2));
334
335
        // Calculate luminance
336
        $luminance = (0.299 * $r + 0.587 * $g + 0.114 * $b) / 255;
337
338
        // If luminance is greater than 0.5, use black font; otherwise, use white
339
        return $luminance > 0.5 ? '#222' : '#fff';
340
    }
341
342
}
343