Passed
Push — master ( 9e8075...242c87 )
by Dedipyaman
01:41
created

TextCase::isSomeUpper()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
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\Result\Failure;
16
use Phypes\Result\Result;
17
use Phypes\Result\Success;
18
use Phypes\Rule\Rule;
19
20
class TextCase implements Rule
21
{
22
    const ALL_LOWER = 0;
23
    const ALL_UPPER = 1;
24
    const MIXED = 2;
25
    const SOME_UPPER = 3;
26
    const SOME_LOWER = 4;
27
    
28
    const LEVEL_STRICT = 0;
29
    const LEVEL_TOLERANT = 1;
30
    /**
31
     * @var integer $caseType
32
     */
33
    private $caseType;
34
35
    /**
36
     * @var bool $strictCheck
37
     */
38
    private $strictCheck;
39
    /**
40
     * TextCase constructor.
41
     * @throws \InvalidArgumentException
42
     * @param int $caseType
43
     * @param bool $allowSpecialChars
44
     */
45
    public function __construct(int $caseType, bool $allowSpecialChars = true)
46
    {
47
        if ($caseType > 4 || $caseType < 0)
48
            throw new \InvalidArgumentException('Case Type ' . $caseType . ' is invalid. 
49
            Check the class constants available to be used as caseTypes');
50
51
        $this->caseType = $caseType;
52
        $this->strictCheck = !$allowSpecialChars;
53
    }
54
55
    /**
56
     * @param string $text
57
     * @return bool
58
     */
59
    private function isMixed(string $text) : bool
60
    {
61
        if ($this->strictCheck) {
62
            if (preg_match("/^[a-zA-Z]+$/", $text))
63
                return preg_match('/[a-z]/', $text) && preg_match('/[A-Z]/', $text);
64
            else
65
                return false;
66
        }
67
68
        return preg_match('/[a-z]/', $text) && preg_match('/[A-Z]/', $text);
69
    }
70
71
    private function isAllUpper(string $text) : bool
72
    {
73
        if ($this->strictCheck)
74
            return ctype_upper($text);
75
        else
76
            return !preg_match('/[a-z]/', $text) && preg_match('/[A-Z]/', $text);
77
            
78
    }
79
80
    private function isAllLower(string $text) : bool
81
    {
82
        if ($this->strictCheck)
83
            return ctype_lower($text);
84
        else
85
            return preg_match('/[a-z]/', $text) && !preg_match('/[A-Z]/', $text);
86
    }
87
88
    private function isSomeLower(string $text) : bool
89
    {
90
        $containsLower = preg_match('/[a-z]/', $text);
91
92
        if ($this->strictCheck)
93
           return !preg_match('/[\W]/', $text) && $containsLower;
94
        else
95
            return $containsLower;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $containsLower returns the type integer which is incompatible with the type-hinted return boolean.
Loading history...
96
    }
97
98
    private function isSomeUpper(string $text) : bool
99
    {
100
        $containsUpper = preg_match('/[A-Z]/', $text);
101
102
        if ($this->strictCheck)
103
            return !preg_match('/[\W]/', $text) && $containsUpper;
104
        else
105
            return $containsUpper;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $containsUpper returns the type integer which is incompatible with the type-hinted return boolean.
Loading history...
106
    }
107
108
    public function validate($data): Result
109
    {
110
        $isValid = false;
111
112
        switch ($this->caseType) {
113
            case self::MIXED:
114
                $isValid = $this->isMixed($data);
115
                break;
116
            case self::ALL_UPPER:
117
                $isValid = $this->isAllUpper($data);
118
                break;
119
            case self::ALL_LOWER:
120
                $isValid = $this->isAllLower($data);
121
                break;
122
            case self::SOME_LOWER:
123
                $isValid = $this->isSomeLower($data);
124
                break;
125
            case self::SOME_UPPER:
126
                $isValid = $this->isSomeUpper($data);
127
                break;
128
        }
129
130
        if ($isValid)
131
            return new Success();
132
        else
133
            return new Failure(new RuleError(RuleErrorCode::CASING_MISMATCH,
134
                "The given string doesn't match the required case"));
135
    }
136
}