Completed
Pull Request — master (#3)
by Clayton
06:29
created

Sanitizer   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 139
c 0
b 0
f 0
wmc 18
lcom 1
cbo 2
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A parseRulesArray() 0 14 4
A parseRuleString() 0 14 3
A applyFilter() 0 14 3
A sanitize() 0 14 4
A sanitizeAttribute() 0 9 3
1
<?php
2
3
namespace PerfectOblivion\Valid\Sanitizer;
4
5
use Closure;
6
use Illuminate\Support\Arr;
7
use InvalidArgumentException;
8
use Illuminate\Validation\ValidationRuleParser;
9
10
/**
11
 * File copied from Waavi/Sanitizer https://github.com/waavi/sanitizer
12
 * Sanitization functionality to be customized within this project before a 1.0 release.
13
 */
14
class Sanitizer
15
{
16
    /** @var array */
17
    protected $data;
18
19
    /** @var array */
20
    protected $rules;
21
22
    /** @var array */
23
    protected $filters = [
24
        'capitalize'  => \Waavi\Sanitizer\Filters\Capitalize::class,
25
        'cast'        => \Waavi\Sanitizer\Filters\Cast::class,
26
        'escape'      => \Waavi\Sanitizer\Filters\EscapeHTML::class,
27
        'format_date' => \Waavi\Sanitizer\Filters\FormatDate::class,
28
        'lowercase'   => \Waavi\Sanitizer\Filters\Lowercase::class,
29
        'uppercase'   => \Waavi\Sanitizer\Filters\Uppercase::class,
30
        'trim'        => \Waavi\Sanitizer\Filters\Trim::class,
31
        'strip_tags'  => \Waavi\Sanitizer\Filters\StripTags::class,
32
        'digit'       => \Waavi\Sanitizer\Filters\Digit::class,
33
    ];
34
35
    /**
36
     * Create a new sanitizer instance.
37
     *
38
     * @param  array  $data
39
     * @param  array  $rules      Rules to be applied to each data attribute
40
     * @param  array  $filters    Available filters for this sanitizer
0 ignored issues
show
Documentation introduced by
There is no parameter named $filters. Did you maybe mean $customFilters?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
41
     */
42
    public function __construct(array $data, array $rules, array $customFilters = [])
43
    {
44
        $this->data    = $data;
45
        $this->rules   = $this->parseRulesArray($rules);
46
        $this->filters = array_merge($this->filters, $customFilters);
47
    }
48
49
    /**
50
     * Parse a rules array.
51
     *
52
     * @param  array $rules
53
     *
54
     * @return array
55
     */
56
    protected function parseRulesArray(array $rules)
57
    {
58
        $parsedRules = [];
59
        $rawRules = (new ValidationRuleParser($this->data))->explode($rules);
60
        foreach ($rawRules->rules as $attribute => $attributeRules) {
61
            foreach ($attributeRules as $attributeRule) {
62
                $parsedRule = $this->parseRuleString($attributeRule);
63
                if ($parsedRule) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $parsedRule of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
64
                    $parsedRules[$attribute][] = $parsedRule;
65
                }
66
            }
67
        }
68
        return $parsedRules;
69
    }
70
71
    /**
72
     * Parse a rule string formatted as filterName:option1, option2 into an array formatted as [name => filterName, options => [option1, option2]]
73
     *
74
     * @param  string  $rule    Formatted as 'filterName:option1, option2' or just 'filterName'
75
     *
76
     * @return array
77
     */
78
    protected function parseRuleString($rule)
79
    {
80
        if (strpos($rule, ':') !== false) {
81
            list($name, $options) = explode(':', $rule, 2);
82
            $options              = array_map('trim', explode(',', $options));
83
        } else {
84
            $name    = $rule;
85
            $options = [];
86
        }
87
        if (!$name) {
88
            return [];
89
        }
90
        return compact('name', 'options');
91
    }
92
93
    /**
94
     * Apply the given filter by its name
95
     *
96
     * @param  mixed  $name
97
     *
98
     * @return Filter
99
     */
100
    protected function applyFilter($name, $value, $options = [])
101
    {
102
        // If the filter does not exist, throw an Exception:
103
        if (!isset($this->filters[$name])) {
104
            throw new InvalidArgumentException("No filter found by the name of $name");
105
        }
106
        $filter = $this->filters[$name];
107
        if ($filter instanceof Closure) {
108
            return call_user_func_array($filter, [$value, $options]);
109
        } else {
110
            $filter = new $filter;
111
            return $filter->apply($value, $options);
112
        }
113
    }
114
115
    /**
116
     * Sanitize the given data
117
     *
118
     * @return array
119
     */
120
    public function sanitize()
121
    {
122
        $sanitized = $this->data;
123
        foreach ($this->rules as $attr => $rules) {
124
            if (Arr::has($this->data, $attr)) {
125
                $value = Arr::get($this->data, $attr);
126
                foreach ($rules as $rule) {
127
                    $value = $this->applyFilter($rule['name'], $value, $rule['options']);
128
                }
129
                Arr::set($sanitized, $attr, $value);
130
            }
131
        }
132
        return $sanitized;
133
    }
134
135
    /**
136
     * Sanitize the given attribute
137
     *
138
     * @param  string  $attribute  Attribute name
139
     * @param  mixed  $value      Attribute value
140
     *
141
     * @return mixed   Sanitized value
142
     */
143
    protected function sanitizeAttribute($attribute, $value)
144
    {
145
        if (isset($this->rules[$attribute])) {
146
            foreach ($this->rules[$attribute] as $rule) {
147
                $value = $this->applyFilter($rule['name'], $value, $rule['options']);
148
            }
149
        }
150
        return $value;
151
    }
152
}
153