Completed
Push — master ( 686084...a2bb6b )
by
unknown
9s
created

SynonymValidator::validateValue()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 22
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 8.9197
c 0
b 0
f 0
cc 4
eloc 9
nc 3
nop 1
1
<?php
2
3
namespace CWP\Search\Extensions;
4
5
use SilverStripe\Forms\Validator;
6
7
class SynonymValidator extends Validator
8
{
9
    /**
10
     * @var array
11
     */
12
    protected $fieldNames;
13
14
    /**
15
     * @inheritdoc
16
     *
17
     * @param array $fieldNames
18
     */
19
    public function __construct(array $fieldNames)
20
    {
21
        $this->fieldNames = $fieldNames;
22
23
        parent::__construct();
24
    }
25
26
    /**
27
     * @inheritdoc
28
     *
29
     * @param array $data
30
     *
31
     * @return mixed
32
     */
33
    public function php($data)
34
    {
35
        foreach ($this->fieldNames as $fieldName) {
36
            if (empty($data[$fieldName])) {
37
                return;
38
            }
39
40
            $this->validateField($fieldName, $data[$fieldName]);
41
        }
42
    }
43
44
    /**
45
     * Validate field values, raising errors if the values are invalid.
46
     *
47
     * @param string $fieldName
48
     * @param mixed $value
49
     */
50
    protected function validateField($fieldName, $value)
51
    {
52
        if (!$this->validateValue($value)) {
53
            $this->validationError(
54
                $fieldName,
55
                _t(
56
                    __CLASS__ . '.InvalidValue',
57
                    'Synonyms cannot contain words separated by spaces'
58
                )
59
            );
60
        }
61
    }
62
63
    /**
64
     * Check field values to see that they doesn't contain spaces between words.
65
     *
66
     * @param mixed $value
67
     *
68
     * @return bool
69
     */
70
    protected function validateValue($value)
71
    {
72
        // strip empty lines
73
        $lines = array_filter(
74
            explode("\n", $value)
75
        );
76
77
        // strip comments (lines beginning with "#")
78
        $lines = array_filter($lines, function ($line) {
79
            $line = trim($line);
80
81
            return !empty($line) && $line[0] !== '#';
82
        });
83
84
        // validate each line
85
        foreach ($lines as $line) {
86
            if (!$this->validateLine($line)) {
87
                return false;
88
            }
89
        }
90
91
        return true;
92
    }
93
94
    /**
95
     * Check each line to see that it doesn't contain spaces between words.
96
     *
97
     * @param string $line
98
     *
99
     * @return bool
100
     */
101
    protected function validateLine($line)
102
    {
103
        $line = trim($line);
104
105
        $parts = explode(',', $line);
106
        $parts = array_filter($parts);
107
108
        foreach ($parts as $part) {
109
            if (!$this->validatePart($part)) {
110
                return false;
111
            }
112
        }
113
114
        return true;
115
    }
116
117
    /**
118
     * Check each part of the line doesn't contain spaces between words.
119
     *
120
     * @param string $part
121
     *
122
     * @return bool
123
     */
124
    protected function validatePart($part)
125
    {
126
        if (strpos($part, '=>') !== false) {
127
            $subs = explode('=>', $part);
128
            $subs = array_filter($subs);
129
130
            foreach ($subs as $sub) {
131
                if (!$this->validateNoSpaces($sub)) {
132
                    return false;
133
                }
134
            }
135
136
            return true;
137
        }
138
139
        return $this->validateNoSpaces($part);
140
    }
141
142
    /**
143
     * @param string $value
144
     *
145
     * @return bool
146
     */
147
    protected function validateNoSpaces($value)
148
    {
149
        // allow spaces at the beginning and end of the value
150
        $value = trim($value);
151
152
        // does the value contain 1 or more whitespace characters?
153
        if (preg_match('/\s+/', $value)) {
154
            return false;
155
        }
156
157
        return true;
158
    }
159
}
160