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