TextCase::__construct()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 4
c 2
b 0
f 0
nc 2
nop 2
dl 0
loc 7
rs 10
1
<?php
2
/*
3
 * This file is part of Phypes <https://github.com/2DSharp/Phypes>.
4
 *
5
 * (c) Dedipyaman Das <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Phypes\Rule\String;
12
13
use Phypes\Error\RuleError;
14
use Phypes\Error\RuleErrorCode;
15
use Phypes\Exception\InvalidRuleOption;
16
use Phypes\Result\Failure;
17
use Phypes\Result\Result;
18
use Phypes\Result\Success;
19
use Phypes\Rule\Primitive\StringType;
20
use Phypes\Rule\Rule;
21
22
class TextCase implements Rule
23
{
24
    const ALL_LOWER = 0;
25
    const ALL_UPPER = 1;
26
    const MIXED = 2;
27
    const SOME_UPPER = 3;
28
    const SOME_LOWER = 4;
29
    
30
    const LEVEL_STRICT = 0;
31
    const LEVEL_TOLERANT = 1;
32
    /**
33
     * @var integer $caseType
34
     */
35
    private $caseType;
36
37
    /**
38
     * @var bool $strictCheck
39
     */
40
    private $strictCheck;
41
42
    /**
43
     * TextCase constructor.
44
     * @throws InvalidRuleOption
45
     * @param int $caseType
46
     * @param bool $allowSpecialChars
47
     */
48
    public function __construct(int $caseType, bool $allowSpecialChars = true)
49
    {
50
        if ($caseType > 4 || $caseType < 0)
51
            throw new InvalidRuleOption($caseType, TextCase::class);
52
53
        $this->caseType = $caseType;
54
        $this->strictCheck = !$allowSpecialChars;
55
    }
56
57
    /**
58
     * @param string $text
59
     * @return bool
60
     */
61
    private function isMixed(string $text) : bool
62
    {
63
        if ($this->strictCheck) {
64
            if (preg_match("/^[a-zA-Z]+$/", $text))
65
                return preg_match('/[a-z]/', $text) && preg_match('/[A-Z]/', $text);
66
            else
67
                return false;
68
        }
69
70
        return preg_match('/[a-z]/', $text) && preg_match('/[A-Z]/', $text);
71
    }
72
73
    private function isAllUpper(string $text) : bool
74
    {
75
        if ($this->strictCheck)
76
            return ctype_upper($text);
77
        else
78
            return !preg_match('/[a-z]/', $text) && preg_match('/[A-Z]/', $text);
79
            
80
    }
81
82
    private function isAllLower(string $text) : bool
83
    {
84
        if ($this->strictCheck)
85
            return ctype_lower($text);
86
        else
87
            return preg_match('/[a-z]/', $text) && !preg_match('/[A-Z]/', $text);
88
    }
89
90
    private function isSomeLower(string $text) : bool
91
    {
92
        $containsLower = (bool) preg_match('/[a-z]/', $text);
93
94
        if ($this->strictCheck)
95
           return !preg_match('/[\W]/', $text) && $containsLower;
96
        else
97
            return $containsLower;
98
    }
99
100
    private function isSomeUpper(string $text) : bool
101
    {
102
        $containsUpper = (bool) preg_match('/[A-Z]/', $text);
103
104
        if ($this->strictCheck)
105
            return !preg_match('/[\W]/', $text) && $containsUpper;
106
        else
107
            return $containsUpper;
108
    }
109
110
    public function validate($data): Result
111
    {
112
        $result = (new StringType())->validate($data);
113
114
        if (!$result->isValid())
115
            return new $result;
116
117
        $isValid = false;
118
119
        switch ($this->caseType) {
120
            case self::MIXED:
121
                $isValid = $this->isMixed($data);
122
                break;
123
            case self::ALL_UPPER:
124
                $isValid = $this->isAllUpper($data);
125
                break;
126
            case self::ALL_LOWER:
127
                $isValid = $this->isAllLower($data);
128
                break;
129
            case self::SOME_LOWER:
130
                $isValid = $this->isSomeLower($data);
131
                break;
132
            case self::SOME_UPPER:
133
                $isValid = $this->isSomeUpper($data);
134
                break;
135
        }
136
137
        if ($isValid)
138
            return new Success();
139
        else
140
            return new Failure(new RuleError(RuleErrorCode::CASING_MISMATCH,
141
                "The given string doesn't match the required case"));
142
    }
143
}