Passed
Push — master ( 841329...2eab24 )
by Nicolaas
02:08
created

DashboardWelcomeQuicklinks::getFontColor()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 12
rs 10
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\Injector\Injector;
8
use SilverStripe\Forms\LiteralField;
9
use SilverStripe\ORM\ArrayList;
10
use SilverStripe\ORM\DataObject;
11
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...
12
use SilverStripe\View\ArrayData;
13
use Sunnysideup\DashboardWelcomeQuicklinks\Api\DefaultDashboardProvider;
14
use Sunnysideup\DashboardWelcomeQuicklinks\Interfaces\DashboardWelcomeQuickLinksProvider;
15
16
/**
17
 * Class \Sunnysideup\DashboardWelcomeQuicklinks\Admin\DashboardWelcomeQuicklinks
18
 *
19
 */
20
class DashboardWelcomeQuicklinks extends LeftAndMain
21
{
22
    private static $url_segment = 'go';
0 ignored issues
show
introduced by
The private property $url_segment is not used, and could be removed.
Loading history...
23
24
    private static $use_default_dashboard = true;
0 ignored issues
show
introduced by
The private property $use_default_dashboard is not used, and could be removed.
Loading history...
25
26
    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...
27
28
    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...
29
30
    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...
31
32
    private static $colour_options = [
0 ignored issues
show
introduced by
The private property $colour_options is not used, and could be removed.
Loading history...
33
        '#F2F3F4',
34
        '#222222',
35
        '#F3C300',
36
        '#875692',
37
        '#F38400',
38
        '#A1CAF1',
39
        '#BE0032',
40
        '#C2B280',
41
        '#848482',
42
        '#008856',
43
        '#E68FAC',
44
        '#0067A5',
45
        '#F99379',
46
        '#604E97',
47
        '#F6A600',
48
        '#B3446C',
49
        '#DCD300',
50
        '#882D17',
51
        '#8DB600',
52
        '#654522',
53
        '#E25822',
54
        '#2B3D26',
55
    ];
56
57
    public function getEditForm($id = null, $fields = null)
58
    {
59
        $form = parent::getEditForm($id, $fields);
60
61
        // if ($form instanceof HTTPResponse) {
62
        //     return $form;
63
        // }
64
        // $form->Fields()->removeByName('LastVisited');
65
66
        $this->updateFormWithQuicklinks($form);
67
68
        return $form;
69
    }
70
71
    public function updateFormWithQuicklinks($form)
72
    {
73
        $shortcuts = $this->getLinksFromImplementor();
74
        $html = '';
75
        if (count($shortcuts)) {
76
            $html = '<div class="grid-wrapper">';
77
78
            usort(
79
                $shortcuts,
80
                function ($a, $b) {
81
                    ($a['SortOrder'] ?? 0) <=> ($b['SortOrder'] ?? 0);
82
                }
83
            );
84
85
            foreach ($shortcuts as $groupCode => $groupDetails) {
86
                $colour = '';
87
                if (!empty($groupDetails['Colour'])) {
88
                    $colour = 'style="background-color: ' . $groupDetails['Colour'] . '"';
89
                }
90
                $icon = '';
91
                if (!empty($groupDetails['IconClass'])) {
92
                    $icon = '<i class="' . $groupDetails['IconClass'] . '"></i> ';
93
                }
94
                $html .= '
95
                <div class="grid-cell" ' . $colour . '>
96
                    <div class="header">
97
                    <h1>' . $icon . '' . ($groupDetails['Title'] ?? $groupCode) . '</h1>
98
                    </div>
99
                    <div class="entries">';
100
                $items = $groupDetails['Items'] ?? [];
101
                if (!empty($entry['Link']) && class_exists($entry['Link'])) {
102
                    $obj = Injector::inst()->get($entry['Link']);
103
                    if ($obj instanceof DataObject) {
104
                        $entry['Link'] = DataObject::get_one($entry['Link'])->CMSEditLink();
105
                    } else {
106
                        $entry['Link'] = $obj->Link();
107
                    }
108
                }
109
                foreach ($items as $entry) {
110
                    $html .= $this->makeShortCut(
111
                        $entry['Title'],
112
                        $entry['Link'],
113
                        $entry['OnClick'] ?? '',
114
                        $entry['Script'] ?? '',
115
                        $entry['Style'] ?? '',
116
                        $entry['IconClass'] ?? '',
117
                        $entry['Target'] ?? '',
118
                    )->Field();
119
                }
120
                $html .= '</div></div>';
121
            }
122
        }
123
        $kc = $this->Config()->get('colour_options');
124
        $kcCount = count($kc);
125
        $colours = '';
126
        foreach ($kc as $key => $colour) {
127
            $colours .= ' .grid-wrapper .grid-cell:nth-child(' . $kcCount . 'n+' . ($key + 1) . ') div.header {background-color: ' . $colour . '; color: '.$this->getFontColor($colour).'!important;}';
128
        }
129
        $html .= '</div>';
130
        $html .= '<style>
131
132
        .grid-wrapper {
133
          display: grid;
134
          grid-template-columns: repeat( auto-fit, minmax(300px, 1fr) );;
135
          grid-gap: 20px;
136
        }
137
138
        .grid-wrapper .grid-cell {
139
          max-width: 500px;
140
          font-size: 150%;
141
          border-radius: 1rem;
142
          border: 1px solid #004e7f55;
143
          display: flex;
144
          flex-direction: column;
145
          overflow: hidden;
146
          box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
147
          transition: all 0.3s ease;
148
          opacity: 0.8;
149
          &:hover {
150
              transform: scale(1.05);
151
              box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
152
              opacity: 1;
153
          }
154
        }
155
        .grid-wrapper .grid-cell > div {
156
            padding: 20px;
157
        }
158
        .grid-wrapper .grid-cell > div.header {
159
            padding-bottom: 0;
160
            border-bottom: 1px solid #004e7f55;
161
        }
162
        .grid-wrapper .grid-cell > div.header h1 {
163
            font-weight: 700;
164
            font-size: 1.3rem!important;
165
        }
166
        .grid-wrapper .grid-cell > div.entries {
167
            background-color: #fff;
168
            height: 100%;
169
        }
170
        ' . $colours . '
171
        .grid-wrapper .grid-cell div.entries *,
172
        .grid-wrapper .grid-cell div.entries a:link,
173
        .grid-wrapper .grid-cell div.entries a:visited {
174
            color: #222;
175
        }
176
        .grid-wrapper .grid-cell div.entries a:link:hover,
177
        .grid-wrapper .grid-cell div.entries a:visited:hover {
178
            color: #0071c4;
179
            text-decoration: none;
180
        }
181
        </style>';
182
        $form->Fields()->push(LiteralField::create('ShortCuts', $html));
183
    }
184
185
    protected function getLinksFromImplementor()
186
    {
187
        $array = [];
188
        $useDefaultDashboard = $this->config()->get('use_default_dashboard');
189
        $classNames = ClassInfo::implementorsOf(DashboardWelcomeQuickLinksProvider::class);
190
        foreach ($classNames as $className) {
191
            if($useDefaultDashboard === false && $className === DefaultDashboardProvider::class) {
192
                continue;
193
            }
194
            $array += Injector::inst()->get($className)->provideDashboardWelcomeQuickLinks();
195
        }
196
        return $array;
197
    }
198
199
    protected function makeShortCut(string $title, string $link, ?string $onclick = '', ?string $script = '', ?string $style = '', ?string $iconClass = '', ?string $target = '')
200
    {
201
        $name = preg_replace('#[\W_]+#u', '', (string) $title);
202
        $html = '';
203
        if ($onclick) {
204
            $onclick = ' onclick="' . $onclick . '"';
205
        }
206
        if ($script) {
207
            $script = '<script>' . $script . '</script>';
208
        }
209
        $icon = '';
210
        if (!empty($iconClass)) {
211
            $icon = '<i class="' . $iconClass . '"></i> ';
212
        }
213
        if(!$target) {
214
            $target = '_self';
215
        }
216
        $target = ' target="'.$target.'"';
217
        if ($link) {
218
            $html = '
219
            ' . $script . '
220
            <h2 style="' . $style . '">
221
                ' . $icon . '<a href="' . $link . '" id="' . $name . '" ' . $target . ' ' . $onclick . '>' . $title . '</a>
222
            </h2>';
223
        } else {
224
            $html = '
225
            ' . $script . '
226
            <p>
227
                &raquo; ' . $title . '
228
            </p>
229
            ';
230
        }
231
        if ($style) {
232
            $html .= '<style>' . $style . '</style>';
233
        }
234
235
        return LiteralField::create(
236
            $name,
237
            $html
238
        );
239
    }
240
    /**
241
     * @return string
242
     */
243
    public function Title()
244
    {
245
        $app = $this->getApplicationName();
246
        $siteConfigTitle = SiteConfig::current_site_config()->Title;
247
        if($siteConfigTitle) {
248
            $app = $siteConfigTitle . ' ('.$app.')';
249
        }
250
        return ($section = $this->SectionTitle()) ? sprintf('%s for %s', $section, $app) : $app;
251
    }
252
    /**
253
     * @param bool $unlinked
254
     * @return ArrayList<ArrayData>
255
     */
256
    public function Breadcrumbs($unlinked = false)
257
    {
258
        $items = new ArrayList([
259
            new ArrayData([
260
                'Title' => $this->Title(),
261
                'Link' => ($unlinked) ? false : $this->Link()
262
            ])
263
        ]);
264
265
        return $items;
266
    }
267
    protected function getFontColor(string $backgroundColor): string
268
    {
269
        // Convert hex color to RGB
270
        $r = hexdec(substr($backgroundColor, 1, 2));
271
        $g = hexdec(substr($backgroundColor, 3, 2));
272
        $b = hexdec(substr($backgroundColor, 5, 2));
273
274
        // Calculate luminance
275
        $luminance = (0.299 * $r + 0.587 * $g + 0.114 * $b) / 255;
276
277
        // If luminance is greater than 0.5, use black font; otherwise, use white
278
        return $luminance > 0.5 ? '#222' : '#fff';
279
    }
280
281
}
282