Passed
Push — master ( 7a1513...4920f4 )
by Nicolaas
02:01
created

DBColour::Inverted()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
nc 1
nop 0
dl 0
loc 18
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace Sunnysideup\SelectedColourPicker\Model\Fields\DBColour;
4
5
use SilverStripe\Forms\FormField;
6
use SilverStripe\Forms\LiteralField;
7
use SilverStripe\ORM\FieldType\DBVarchar;
8
9
use SilverStripe\Core\Config\Config;
10
use SilverStripe\ORM\FieldType\DBField;
11
use Sunnysideup\SelectedColourPicker\Forms\SelectedColourPickerFormField;
12
use Sunnysideup\SelectedColourPicker\Forms\SelectedColourPickerFormFieldDropdown;
13
use Sunnysideup\SelectedColourPicker\ViewableData\SelectedColourPickerFormFieldSwatches;
14
use TractorCow\Colorpicker\Color;
0 ignored issues
show
Bug introduced by
The type TractorCow\Colorpicker\Color 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...
15
16
class DBColour extends Color
17
{
18
    private static $colour_picker_field_class_name = SelectedColourPickerFormFieldDropdown::class;
19
20
    /**
21
     * please set
22
     * must be defined as #AABB99 (hex codes).
23
     * Needs to be set like this:
24
     * ```php
25
     *     [
26
     *         '#fff000' => 'My Colour 1',
27
     *         '#fff000' => 'My Colour 2',
28
     *     ]
29
     *
30
     * ```
31
     *
32
     * @var array
33
     */
34
    private static $colours = self::DEFAULT_COLOURS;
35
36
    /**
37
     * You can link colours to other colours.
38
     * e.g.
39
     * ```php
40
     *     '#ffffff' => [
41
     *          'link' => '#000000',
42
     *          'foreground' => '#000000',
43
     *          'background' => '#000000',
44
     *     ],
45
     *     '#aabbcc' => [
46
     *          'link' => '#123123',
47
     *          'foreground' => '#123312',
48
     *          'somethingelse' => '#000000',
49
     *     ],
50
     * ```
51
     *
52
     * @var array
53
     */
54
55
    private static $linked_colours = [
56
    ];
57
58
    protected const DEFAULT_COLOURS = [
59
        '#FF0000' => 'Red',
60
        '#0000FF' => 'Blue',
61
        '#00FF00' => 'Green',
62
    ];
63
64
    /**
65
     * please set.
66
     *
67
     * @var string`
68
     */
69
    protected const CSS_CLASS_PREFIX = 'db-colour';
70
71
    /**
72
     * please set.
73
     *
74
     * @var bool
75
     */
76
    protected const IS_LIMITED_TO_OPTIONS = true;
77
78
    /**
79
     * please set.
80
     *
81
     * @var bool
82
     */
83
    protected const IS_BG_COLOUR = true;
84
85
    private static $casting = [
86
        'CssVariableDefinition' => 'Varchar',
87
        'CssClass' => 'Varchar',
88
        'CssClassAlternative' => 'Boolean',
89
        'ReadableColor' => 'Varchar',
90
        'RelatedColourByName' => 'Varchar',
91
        'IsDarkColour' => 'Boolean',
92
        'IsLightColour' => 'Boolean',
93
        'Inverted' => 'Boolean',
94
    ];
95
96
97
    public function __construct($name = null, $options = [])
98
    {
99
        parent::__construct($name, $options);
100
    }
101
102
    public function getCssVariableDefinition(): string
103
    {
104
        return '--' . $this->getName() . ': ' . $this->getValue() . ';';
105
    }
106
107
    public static function my_colours(string $name): array
108
    {
109
        return self::get_colour_as_db_field(DBColour::class)->getColours();
110
    }
111
112
    public static function get_swatches_field(string $name, string $value): LiteralField
113
    {
114
        return SelectedColourPickerFormFieldSwatches::get_swatches_field(
115
            (string) $name,
116
            (string) $value,
117
            self::my_colours(($name)),
118
            static::IS_BG_COLOUR
119
        );
120
    }
121
122
    /**
123
     *
124
     * @param  string $name
125
     * @param  string $title
126
     * @return FormField
127
     */
128
    public static function get_dropdown_field(string $name, ?string $title = '', ?bool $isBackgroundColour = null)
129
    {
130
        if($isBackgroundColour === null) {
131
            $isBackgroundColour = static::IS_BG_COLOUR;
132
        }
133
        $className = Config::inst()->get(static::class, 'colour_picker_field_class_name');
134
        return $className::create(
135
            $name,
136
            $title
137
        )
138
            ->setSource(self::my_colours($name))
139
            ->setLimitedToOptions(static::IS_LIMITED_TO_OPTIONS)
140
            ->setIsBgColour($isBackgroundColour);
141
        ;
142
    }
143
144
145
    public function get_colours_for_dropdown(?string $name = 'default', ?bool $isBackgroundColour = null): ?array
146
    {
147
        if($isBackgroundColour === null) {
148
            $isBackgroundColour = static::IS_BG_COLOUR;
149
        }
150
        $colours = self::my_colours($name);
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type null; however, parameter $name of Sunnysideup\SelectedColo...\DBColour::my_colours() 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

150
        $colours = self::my_colours(/** @scrutinizer ignore-type */ $name);
Loading history...
151
        if (!empty($colours)) {
152
            $array = [];
153
154
            foreach ($colours as $code => $label) {
155
                $textColor = $this->getIsColorLight($code) ? '#000000' : '#FFFFFF';
156
                if($isBackgroundColour) {
157
                    $array[$code] = [
158
                        'label' => $label,
159
                        'background_css' => $code,
160
                        'color_css' => $textColor,
161
                        'sample_text' => 'Aa',
162
                    ];
163
164
                } else {
165
                    $array[$code] = [
166
                        'label' => $label,
167
                        'background_css' => $textColor,
168
                        'color_css' => $code,
169
                        'sample_text' => 'Aa',
170
                    ];
171
                }
172
            }
173
174
            return $array;
175
        }
176
        return null;
177
    }
178
179
180
    /**
181
     * Detects if the given color is light
182
     * @param string $colour HEX color code
183
     */
184
    public static function get_font_colour(?string $colour = ''): string
185
    {
186
        return self::is_light_colour((string) $colour) ? '#000000' : '#ffffff';
187
    }
188
189
    /**
190
     * @param string $colour HEX color code
191
     */
192
    public static function is_dark_colour(?string $colour = ''): bool
193
    {
194
        return self::is_light_colour((string) $colour) ? false : true;
195
    }
196
197
    /**
198
     * Detects if the given color is light
199
     * @param string $colour HEX color code
200
     */
201
    public static function is_light_colour(?string $colour = ''): bool
202
    {
203
        return DBField::create_field(DBColour::class, $colour)
204
            ->Luminance() > 0.5;
205
    }
206
207
208
    public static function check_colour(?string $colour, ?bool $isBackgroundColour = false): string
209
    {
210
        $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

210
        $colour = strtolower(/** @scrutinizer ignore-type */ $colour);
Loading history...
211
        if($colour === 'transparent') {
212
            return 'transparent';
213
        }
214
        if(! strpos($colour, '#')) {
215
            $colour = '#' . $colour;
216
        }
217
        if(! $colour) {
218
            if($isBackgroundColour) {
219
                $colour = '#ffffff';
220
            } else {
221
                $colour = '#000000';
222
            }
223
        }
224
        return $colour;
225
    }
226
227
    public function scaffoldFormField($title = null, $params = null)
228
    {
229
        return static::get_dropdown_field($this->name, $title);
230
    }
231
232
    public function getCssClass(?bool $isTransparent = false): string
233
    {
234
        $colours = $this->getColours();
235
        if($isTransparent) {
236
            $name = 'transparent';
237
        } else {
238
            $name = $colours[$this->value] ?? 'colour-error';
239
        }
240
241
        return $this->classCleanup($name);
242
    }
243
244
245
    public function getCssClassAlternative(?bool $isTransparent = false): string
246
    {
247
        if($isTransparent) {
248
            $name = 'ffffff00';
249
        } else {
250
            $name = $this->value ?: 'no-colour';
251
        }
252
        return $this->classCleanup($name);
253
    }
254
255
256
    public function getReadableColor(): string
257
    {
258
        // Remove '#' if it's present
259
        return $this->getFontColour();
260
    }
261
262
    public function getIsLightColour(): bool
263
    {
264
        return self::is_light_colour($this->value);
265
    }
266
267
    public function getIsDarkColour(): bool
268
    {
269
        return self::is_light_colour($this->value) ? false : true;
270
    }
271
272
    public function Inverted(): string
273
    {
274
        // Ensure the color is 6 characters long
275
        $color = str_pad(ltrim($this->value, "#"), 6, '0', STR_PAD_RIGHT);
276
277
        // Convert the color to decimal
278
        $color = hexdec($color);
279
280
        // Invert the color
281
        $color = 0xFFFFFF - $color;
282
283
        // Convert the color back to hex
284
        $color = dechex($color);
0 ignored issues
show
Bug introduced by
$color 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

284
        $color = dechex(/** @scrutinizer ignore-type */ $color);
Loading history...
285
286
        // Ensure the color is 6 characters long
287
        $color = str_pad($color, 6, '0', STR_PAD_LEFT);
288
289
        return $color;
290
    }
291
292
    private function classCleanup(string $name): string
293
    {
294
        $name = str_replace('#', '', $name);
295
        $name = preg_replace('#[^A-Za-z0-9]#', '-', $name);
296
297
        return static::CSS_CLASS_PREFIX . '-' . trim(trim(strtolower($name), '-'));
298
    }
299
300
301
    public function getRelatedColourByName(string $name): string
302
    {
303
        $colours = Config::inst()->get(static::class, 'linked_colours');
304
        $colour = $colours($this->value)[$name] ?? 'error';
305
        return DBField::create_field(DBColour::class, $colour)->getValue();
306
    }
307
308
309
    protected function getColours(): array
310
    {
311
        return $this->Config()->get('colours');
312
    }
313
314
    protected function getMyColours(): array
315
    {
316
        $colours = $this->getColours();
317
318
        return empty($colours) ? self::DEFAULT_COLOURS : $colours;
319
    }
320
321
322
    protected static $object_cache = [];
323
324
    protected static function get_colour_as_db_field(string $colour)
325
    {
326
        if(! isset(self::$object_cache[$colour])) {
327
            self::$object_cache[$colour] = DBField::create_field(DBColour::class, $colour);
328
        }
329
        return self::$object_cache[$colour];
330
    }
331
332
333
334
335
}
336