VariableNameValidator   A
last analyzed

Complexity

Total Complexity 24

Size/Duplication

Total Lines 129
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 24
eloc 54
dl 0
loc 129
c 0
b 0
f 0
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 8 1
B validateValue() 0 24 7
B validateAttribute() 0 32 7
B containsInvalidCharacters() 0 17 9
1
<?php
2
3
namespace dameter\abstracts\validators;
4
5
use yii\validators\StringValidator;
6
use Yii;
7
8
/**
9
 * Class VariableNameValidator
10
 * Validates the variable name based mainly on SPSS variable name limitations
11
 * @link https://www.ibm.com/support/knowledgecenter/en/SSLVMB_23.0.0/spss/base/syn_variables_variable_names.html
12
 * @author Tõnis Ormisson <[email protected]>
13
 */
14
class VariableNameValidator extends StringValidator
15
{
16
    public $max = 64;
17
18
    /** @var string $containsSpacesMsg A message if the value contains spaces */
19
    public $containsSpacesMsg;
20
21
    /** @var string $invalidFirstChrMsg A message if invalid first letter */
22
    public $invalidFirstChrMsg;
23
24
    /** @var string $invalidCharsMsg A message if contains invalid characters */
25
    public $invalidCharsMsg;
26
27
    /** @var string $endsWithInvalidMsg A message if ends with an invaid character */
28
    public $endsWithInvalidMsg;
29
30
    /** @var string $reservedValueMsg A message if value is reserved */
31
    public $reservedValueMsg;
32
33
    const ALLOWED_NON_ALPHA_CHARACTERS = ['.', '-', '_'];
34
35
    /**
36
     * @var string[] The values reserved by SPSS as non suitable variable names
37
     * @link https://www.ibm.com/support/knowledgecenter/en/SSLVMB_23.0.0/spss/base/syn_variables_variable_names.html
38
     */
39
    const RESERVED_VALUES = ["ALL", "AND", "BY", "EQ", "GE", "GT", "LE", "LT", "NE", "NOT", "OR", "TO", "WITH"];
40
41
    /**
42
     * {@inheritdoc}
43
     */
44
    public function init()
45
    {
46
        parent::init();
47
        $this->containsSpacesMsg = Yii::t('dmabstract', "{attribute} must not contain spaces!");
48
        $this->invalidFirstChrMsg = Yii::t('dmabstract', "The first character of {attribute} must be a letter!");
49
        $this->invalidCharsMsg = Yii::t('dmabstract', "{attribute} contains invalid characters!");
50
        $this->endsWithInvalidMsg = Yii::t('dmabstract', "{attribute} ends with an invalid character!");
51
        $this->reservedValueMsg = Yii::t('dmabstract', "{attribute} value is reserved for system use only!");
52
    }
53
54
55
    /**
56
     * {@inheritdoc}
57
     */
58
    public function validateAttribute($model, $attribute)
59
    {
60
        parent::validateAttribute($model, $attribute);
61
62
        $value = $model->{$attribute};
63
64
        if (!is_string($value)) {
65
            $this->addError($model, $attribute, $this->message);
66
            return null;
67
        }
68
69
        if (strpos($value, ' ') !== false) {
70
            $this->addError($model, $attribute, $this->containsSpacesMsg);
71
        }
72
73
        if (!ctype_alpha($value[0])) {
74
            $this->addError($model, $attribute, $this->invalidFirstChrMsg);
75
        }
76
77
        if (in_array(substr($value, -1), self::ALLOWED_NON_ALPHA_CHARACTERS)) {
78
            $this->addError($model, $attribute, $this->endsWithInvalidMsg);
79
        }
80
81
        if (in_array(strtoupper($value), self::RESERVED_VALUES)) {
82
            $this->addError($model, $attribute, $this->reservedValueMsg);
83
        }
84
85
        if ($this->containsInvalidCharacters($value)) {
86
            $this->addError($model, $attribute, $this->invalidCharsMsg);
87
        }
88
89
        return null;
90
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96
    protected function validateValue($value)
97
    {
98
99
        $validation = parent::validateValue($value);
100
101
        if (!is_null($validation)) {
102
            return $validation;
103
        }
104
        if (strpos($value, ' ') !== false) {
105
            return [$this->containsSpacesMsg, []];
106
        }
107
        if (!ctype_alpha($value[0])) {
108
            return [$this->invalidFirstChrMsg, []];
109
        }
110
        if (in_array(substr($value, -1), self::ALLOWED_NON_ALPHA_CHARACTERS)) {
111
            return [$this->endsWithInvalidMsg, []];
112
        }
113
        if (in_array(strtoupper($value), self::RESERVED_VALUES)) {
114
            return [$this->reservedValueMsg, []];
115
        }
116
        if ($this->containsInvalidCharacters($value)) {
117
            return [$this->invalidCharsMsg, []];
118
        }
119
        return null;
120
    }
121
122
    /**
123
     * @param string $value
124
     * @return bool
125
     */
126
    private function containsInvalidCharacters($value)
127
    {
128
        if (!ctype_alnum($value) && is_string($value)) {
129
            $array = str_split($value);
130
            foreach ($array as $char) {
131
                // allowed non-alpha must not be in teh end of value
132
                if (!ctype_alnum($char) && $char === end($array) && in_array($char, self::ALLOWED_NON_ALPHA_CHARACTERS)) {
133
                    return true;
134
                }
135
                if (!ctype_alnum($char) && !in_array($char, self::ALLOWED_NON_ALPHA_CHARACTERS)) {
136
                    return true;
137
                }
138
            }
139
            // allowed chars only
140
            return false;
141
        }
142
        return false;
143
    }
144
145
146
147
}