Passed
Pull Request — master (#5)
by Christopher
02:47
created

BitMask::isFlag()   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
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cruxinator\BitMask;
6
7
use function array_key_exists;
8
use BadMethodCallException;
9
use MyCLabs\Enum\Enum;
10
11
abstract class BitMask extends Enum
12
{
13
    protected function isFlag(int $flag): bool
14
    {
15
        return $flag === 0 ? $this->value === 0 : (($this->value & $flag) == $flag);
16
    }
17
18
    protected function setFlag(int $flag, bool $value)
19
    {
20
        if ($value) {
21
            $this->value = $flag === 0 ? 0 : $this->value | $flag;
22
        } else {
23
            $this->value = $flag === 0 ? $this->value : $this->value & ~$flag;
24
        }
25
        return $this;
26
    }
27
28
    /**
29
     * @param $name
30
     * @param $arguments
31
     * @return bool|self
32
     */
33
    public function __call($name, $arguments)
34
    {
35
        $array = static::toArray();
36
        $regexBase = '/(is|set)(%s)/m';
37
        $regexFull = sprintf($regexBase, implode('|', array_keys($array)));
38
        preg_match($regexFull, $name, $match);
39
        if (count($match)>0 && $match[0] === $name) {
40
            return $this->{$match[1] . 'Flag'}($array[$match[2]], $arguments[0] ?? true);
41
        }
42
        throw new BadMethodCallException(sprintf('Enum %s not found on %s', $name, get_class($this)));
43
    }
44
45
    /**
46
     * @param $value
47
     * @return bool
48
     */
49
    public static function isValid($value)
50
    {
51
        $min = min(static::toArray());
52
        $max = max(static::toArray()) * 2 - 1;
53
        return $value >= $min && $value <= $max;
54
    }
55
56
    /**
57
     * @return array
58
     */
59
    public static function toArray()
60
    {
61
        $array = parent::toArray();
62
        //TODO: check that the array is defined correctly. basically check everything in the array is a int.
63
        /*$array = array_filter($array, function ($temp) {
64
            $raw = log($temp, 2);
65
            return is_int($temp) && 0.01 > abs($raw - round($raw));
66
        }
67
        );*/
68
        return $array;
69
    }
70
71
    /**
72
     * @return array|mixed
73
     */
74
    public function getKey()
75
    {
76
        $value = $this->value;
77
        $f     = array_filter(static::toArray(), function () use (&$value) {
78
            $isSet = $value & 1;
79
            $value = $value >> 1;
80
            return $isSet;
81
        });
82
83
        return array_keys($f);
84
    }
85
86
    /**
87
     * @return string
88
     */
89
    public function __toString()
90
    {
91
        $name  = $this->getName();
92
        $array = static::toArray();
93
        $ret   = '';
94
        foreach ($array as $key => $value) {
95
            $ret .= "'" . $key . "' => " . ($this->{'is' . $key}() ? 'TRUE' : 'FALSE') . PHP_EOL;
96
        }
97
        return $name . '[' . PHP_EOL .
98
            $ret .
99
            ']' . PHP_EOL;
100
    }
101
102
    public function getName()
103
    {
104
        $path = explode('\\', __CLASS__);
105
        return array_pop($path);
106
    }
107
}
108