Passed
Push — master ( afdd76...811e82 )
by Nicolaas
01:58
created

DBColour::getIsDarkColour()   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
nc 2
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Sunnysideup\SelectedColourPicker\Model\Fields;
4
5
use Fromholdio\ColorPalette\Fields\ColorPaletteField;
6
use SilverStripe\Forms\FormField;
7
use SilverStripe\Forms\LiteralField;
8
9
use SilverStripe\Core\Config\Config;
10
use SilverStripe\ORM\FieldType\DBField;
11
use Sunnysideup\SelectedColourPicker\Forms\SelectedColourPickerFormFieldDropdown;
12
use Sunnysideup\SelectedColourPicker\ViewableData\SelectedColourPickerFormFieldSwatches;
13
use TractorCow\Colorpicker\Color;
14
15
class DBColour extends Color
16
{
17
    private static $colour_picker_field_class_name = SelectedColourPickerFormFieldDropdown::class;
18
19
    /**
20
     * please set
21
     * must be defined as #AABB99 (hex codes).
22
     * Needs to be set like this:
23
     * ```php
24
     *     [
25
     *         '#fff000' => 'My Colour 1',
26
     *         '#fff000' => 'My Colour 2',
27
     *     ]
28
     *
29
     * ```
30
     *
31
     * @var array
32
     */
33
    private static $colours = self::DEFAULT_COLOURS;
34
35
    /**
36
     * You can link colours to other colours.
37
     * e.g.
38
     * ```php
39
     *     '#ffffff' => [
40
     *          'link' => '#000000',
41
     *          'foreground' => '#000000',
42
     *          'background' => '#000000',
43
     *     ],
44
     *     '#aabbcc' => [
45
     *          'link' => '#123123',
46
     *          'foreground' => '#123312',
47
     *          'somethingelse' => '#000000',
48
     *     ],
49
     * ```
50
     *
51
     * @var array
52
     */
53
54
    private static $linked_colours = [
55
    ];
56
57
    protected const DEFAULT_COLOURS = [
58
        '#FF0000' => 'Red',
59
        '#0000FF' => 'Blue',
60
        '#00FF00' => 'Green',
61
    ];
62
63
    /**
64
     * please set.
65
     *
66
     * @var string`
67
     */
68
    protected const CSS_CLASS_PREFIX = 'db-colour';
69
70
    /**
71
     * please set.
72
     *
73
     * @var bool
74
     */
75
    protected const IS_LIMITED_TO_OPTIONS = true;
76
77
    /**
78
     * please set.
79
     *
80
     * @var bool
81
     */
82
    protected const IS_BG_COLOUR = true;
83
84
    private static $casting = [
85
        // related colours
86
        'Readablecolour' => 'Varchar',
87
        'RelatedColourByName' => 'Varchar',
88
        'Inverted' => 'Varchar',
89
        // css
90
        'CssVariableDefinition' => 'Varchar',
91
        'CssClass' => 'Varchar',
92
        'CssClassAlternative' => 'Boolean',
93
        // booleans
94
        'IsDarkColour' => 'Boolean',
95
        'IsLightColour' => 'Boolean',
96
    ];
97
98
99
    public function __construct($name = null, $options = [])
100
    {
101
        parent::__construct($name, $options);
102
    }
103
104
105
    public static function my_colours(): array
106
    {
107
        return self::get_colour_as_db_field(DBColour::class)->getColours();
108
    }
109
110
    public static function get_swatches_field(string $name, string $value): LiteralField
111
    {
112
        return SelectedColourPickerFormFieldSwatches::get_swatches_field(
113
            (string) $name,
114
            (string) $value,
115
            self::my_colours(),
116
            static::IS_BG_COLOUR
117
        );
118
    }
119
120
    /**
121
     *
122
     * @param  string $name
123
     * @param  string $title
124
     * @return FormField
125
     */
126
    public static function get_dropdown_field(string $name, ?string $title = '', ?bool $isBackgroundColour = null)
127
    {
128
        if($isBackgroundColour === null) {
129
            $isBackgroundColour = static::IS_BG_COLOUR;
130
        }
131
        $className = Config::inst()->get(static::class, 'colour_picker_field_class_name');
132
        return $className::create(
133
            $name,
134
            $title
135
        )
136
            ->setSource(self::my_colours())
137
            ->setLimitedToOptions(static::IS_LIMITED_TO_OPTIONS)
138
            ->setIsBgColour($isBackgroundColour);
139
        ;
140
    }
141
142
143
    public static function get_colours_for_dropdown(?bool $isBackgroundColour = null): ?array
144
    {
145
        if($isBackgroundColour === null) {
146
            $isBackgroundColour = static::IS_BG_COLOUR;
147
        }
148
        $colours = self::my_colours();
149
        if (!empty($colours)) {
150
            $array = [];
151
152
            foreach ($colours as $code => $label) {
153
                $textcolour = self::get_font_colour($code) ;
154
                if($isBackgroundColour) {
155
                    $array[$code] = [
156
                        'label' => $label,
157
                        'background_css' => $code,
158
                        'colour_css' => $textcolour,
159
                        'sample_text' => 'Aa',
160
                    ];
161
162
                } else {
163
                    $array[$code] = [
164
                        'label' => $label,
165
                        'background_css' => $textcolour,
166
                        'colour_css' => $code,
167
                        'sample_text' => 'Aa',
168
                    ];
169
                }
170
            }
171
172
            return $array;
173
        }
174
        return null;
175
    }
176
177
178
    /**
179
     * Detects if the given colour is light
180
     * @param string $colour HEX colour code
181
     */
182
    public static function get_font_colour(?string $colour = ''): static
183
    {
184
        $colour = self::is_light_colour((string) $colour) ? '#000000' : '#ffffff';
185
        return self::get_colour_as_db_field($colour);
186
    }
187
188
    /**
189
     * @param string $colour HEX colour code
190
     */
191
    public static function is_dark_colour(?string $colour = ''): bool
192
    {
193
        return self::is_light_colour((string) $colour) ? false : true;
194
    }
195
196
    /**
197
     * Detects if the given colour is light
198
     * @param string $colour HEX colour code
199
     */
200
    public static function is_light_colour(?string $colour = ''): bool
201
    {
202
        return self::get_colour_as_db_field($colour)
0 ignored issues
show
Bug introduced by
It seems like $colour can also be of type null; however, parameter $colour of Sunnysideup\SelectedColo...et_colour_as_db_field() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

202
        return self::get_colour_as_db_field(/** @scrutinizer ignore-type */ $colour)
Loading history...
203
            ->Luminance() > 0.5;
204
    }
205
206
207
    public static function check_colour(?string $colour, ?bool $isBackgroundColour = false): string
208
    {
209
        $colour = strtolower($colour);
0 ignored issues
show
Bug introduced by
It seems like $colour can also be of type null; however, parameter $string of strtolower() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

209
        $colour = strtolower(/** @scrutinizer ignore-type */ $colour);
Loading history...
210
        if($colour === 'transparent') {
211
            return 'transparent';
212
        }
213
        if(! strpos($colour, '#')) {
214
            $colour = '#' . $colour;
215
        }
216
        if(! $colour) {
217
            if($isBackgroundColour) {
218
                $colour = '#ffffff';
219
            } else {
220
                $colour = '#000000';
221
            }
222
        }
223
        return $colour;
224
    }
225
226
    public function scaffoldFormField($title = null, $params = null)
227
    {
228
        return ColorPaletteField::create($this->name, $title, static::get_colours_for_dropdown());
229
    }
230
231
232
    public function getReadablecolour(): static
233
    {
234
        // Remove '#' if it's present
235
        return self::get_font_colour($this->value);
236
    }
237
238
    public function Inverted(): static
239
    {
240
        // Ensure the colour is 6 characters long
241
        $colour = str_pad(ltrim($this->value, "#"), 6, '0', STR_PAD_RIGHT);
242
243
        // Convert the colour to decimal
244
        $colour = hexdec($colour);
245
246
        // Invert the colour
247
        $colour = 0xFFFFFF - $colour;
248
249
        // Convert the colour back to hex
250
        $colour = dechex($colour);
0 ignored issues
show
Bug introduced by
$colour of type double is incompatible with the type integer expected by parameter $num of dechex(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

250
        $colour = dechex(/** @scrutinizer ignore-type */ $colour);
Loading history...
251
252
        // Ensure the colour is 6 characters long
253
        $colour = str_pad($colour, 6, '0', STR_PAD_LEFT);
254
255
        return self::get_colour_as_db_field($colour);
256
    }
257
258
    public function getRelatedColourByName(string $name): static
259
    {
260
        $colours = Config::inst()->get(static::class, 'linked_colours');
261
        $colour = $colours($this->value)[$name] ?? 'error';
262
        return self::get_colour_as_db_field($colour);
263
    }
264
265
    public function getCssVariableDefinition($rootElement = ':root'): string
266
    {
267
        $style = PHP_EOL.$rootElement . '{';
268
        $style .= PHP_EOL. '--colour-' . strtolower($this->getName()) . ': ' . $this->getValue() . ';';
269
        if(self::IS_BG_COLOUR) {
270
            $readableColour = $this->getReadablecolour();
271
            $style .= PHP_EOL. '--colour-font-' . strtolower($readableColour->getName()) . ': ' . $readableColour->getValue() . ';';
272
        }
273
        $style = PHP_EOL . '}';
274
        return $style;
275
    }
276
277
    public function getCssClass(?bool $isTransparent = false): string
278
    {
279
        $colours = $this->getColours();
280
        if($isTransparent) {
281
            $name = 'transparent';
282
        } else {
283
            $name = $colours[$this->value] ?? 'colour-error';
284
        }
285
286
        return $this->classCleanup($name);
287
    }
288
289
290
    public function getCssClassAlternative(?bool $isTransparent = false): string
291
    {
292
        if($isTransparent) {
293
            $name = 'ffffff00';
294
        } else {
295
            $name = $this->value ?: 'no-colour';
296
        }
297
        return $this->classCleanup($name);
298
    }
299
300
    public function getIsLightColour(): bool
301
    {
302
        return self::is_light_colour($this->value);
303
    }
304
305
    public function getIsDarkColour(): bool
306
    {
307
        return self::is_light_colour($this->value) ? false : true;
308
    }
309
310
    private function classCleanup(string $name): string
311
    {
312
        $name = str_replace('#', '', $name);
313
        $name = preg_replace('#[^A-Za-z0-9]#', '-', $name);
314
315
        return static::CSS_CLASS_PREFIX . '-' . trim(trim(strtolower($name), '-'));
316
    }
317
318
319
320
321
    protected function getColours(): array
322
    {
323
        return $this->Config()->get('colours');
324
    }
325
326
    protected function getMyColours(): array
327
    {
328
        $colours = $this->getColours();
329
330
        return empty($colours) ? self::DEFAULT_COLOURS : $colours;
331
    }
332
333
334
    protected static $object_cache = [];
335
336
    protected static function get_colour_as_db_field(string $colour)
337
    {
338
        if(! isset(self::$object_cache[$colour])) {
339
            self::$object_cache[$colour] = DBField::create_field(static::class, $colour);
340
        }
341
        return self::$object_cache[$colour];
342
    }
343
344
345
346
347
}
348