Completed
Pull Request — master (#66)
by
unknown
01:52
created

ValidatorExtension::parseTable()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 3
eloc 4
nc 3
nop 1
1
<?php namespace Felixkiss\UniqueWithValidator;
2
3
use Illuminate\Support\Str;
4
use Illuminate\Validation\Validator;
5
6
class ValidatorExtension extends Validator
7
{
8
    /**
9
     * Creates a new instance of ValidatorExtension
10
     */
11
    public function __construct($translator, $data, $rules, $messages, array $customAttributes = array())
12
    {
13
        // Set custom validation error messages
14
        if(!isset($messages['unique_with']))
15
        {
16
            $messages['unique_with'] = $translator->get(
17
                'uniquewith-validator::validation.unique_with'
18
            );
19
        }
20
21
        parent::__construct($translator, $data, $rules, $messages, $customAttributes);
22
    }
23
24
    /**
25
     * Usage: unique_with: table, column1, column2, ...
26
     *
27
     * @param  string $attribute
28
     * @param  mixed  $value
29
     * @param  array $parameters
30
     * @return boolean
31
     */
32
    public function validateUniqueWith($attribute, $value, $parameters)
33
    {
34
        // cleaning: trim whitespace
35
        $parameters = array_map('trim', $parameters);
36
37
        // first item equals table name
38
        list($connection, $table) = $this->parseTable(array_shift($parameters));
39
40
        // The second parameter position holds the name of the column that
41
        // needs to be verified as unique. If this parameter isn't specified
42
        // we will just assume that this column to be verified shares the
43
        // attribute's name.
44
        $column = $attribute;
45
46
        // Create $extra array with all other columns, so getCount() will
47
        // include them as where clauses as well
48
        $extra = array();
49
50
        // Check if last parameter is an integer. If it is, then it will
51
        // ignore the row with the specified id - useful when updating a row
52
        list($ignore_id, $ignore_column) = $this->getIgnore($parameters);
53
54
        // Figure out whether field_name is the same as column_name
55
        // or column_name is explicitly specified.
56
        //
57
        // case 1:
58
        //     $parameter = 'last_name'
59
        //     => field_name = column_name = 'last_name'
60
        // case 2:
61
        //     $parameter = 'last_name=sur_name'
62
        //     => field_name = 'last_name', column_name = 'sur_name'
63
        foreach ($parameters as $parameter)
64
        {
65
            $parameter = array_map('trim', explode('=', $parameter, 2));
66
            $field_name = $parameter[0];
67
68
            if (count($parameter) > 1)
69
            {
70
                $column_name = $parameter[1];
71
            }
72
            else
73
            {
74
                $column_name = $field_name;
75
            }
76
77
            // Figure out whether main field_name has an explicitly specified
78
            // column_name
79
            if ($field_name == $column)
80
            {
81
                $column = $column_name;
82
            }
83
            else
84
            {
85
                $extra[$column_name] = array_get($this->data, $field_name);
86
            }
87
        }
88
89
        // The presence verifier is responsible for counting rows within this
90
        // store mechanism which might be a relational database or any other
91
        // permanent data store like Redis, etc. We will use it to determine
92
        // uniqueness.
93
        $verifier = $this->getPresenceVerifier();
94
        $verifier->setConnection($connection);
95
96
        return $verifier->getCount(
97
            $table,
98
            $column,
99
            $value,
100
            $ignore_id,
101
            $ignore_column,
102
            $extra
103
        ) == 0;
104
    }
105
106
    public function replaceUniqueWith($message, $attribute, $rule, $parameters)
0 ignored issues
show
Unused Code introduced by
The parameter $rule is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
107
    {
108
        // remove trailing ID param if present
109
        $this->getIgnore($parameters);
110
111
        // merge primary field with conditional fields
112
        $fields = array($attribute) + $parameters;
113
114
        // get full language support due to mapping to validator getAttribute
115
        // function
116
        $fields = array_map(array($this, 'getAttribute'), $fields);
117
118
        // fields to string
119
        $fields = implode(', ', $fields);
120
121
        return str_replace(':fields', $fields, $message);
122
    }
123
124
    /**
125
     * Returns an array with value and column name for an optional ignore.
126
     * Shaves of the ignore_id from the end of the array, if there is one.
127
     *
128
     * @param  array $parameters
129
     * @return array [$ignoreId, $ignoreColumn]
130
     */
131
    private function getIgnore(&$parameters)
132
    {
133
        $lastParam = end($parameters);
134
        $lastParam = array_map('trim', explode('=', $lastParam));
135
136
        // An ignore_id is only specified if the last param starts with a
137
        // number greater than 1 (a valid id in the database)
138
        if (!preg_match('/^[1-9][0-9]*$/', $lastParam[0]))
139
        {
140
            return array(null, null);
141
        }
142
143
        $ignoreId = $lastParam[0];
144
        $ignoreColumn = (sizeof($lastParam) > 1) ? end($lastParam) : null;
145
146
        // Shave of the ignore_id from the array for later processing
147
        array_pop($parameters);
148
149
        return array($ignoreId, $ignoreColumn);
150
    }
151
152
    /**
153
     * Parse the connection / table for the unique / exists rules.
154
     *
155
     * @param  string  $table
156
     * @return array
157
     */
158
    protected function parseTable($table)
159
    {
160
        if (method_exists(get_parent_class($this), 'parseTable')) {
161
            return parent::parseTable($table);
162
        }
163
164
        return Str::contains($table, '.') ? explode('.', $table, 2) : [null, $table];
165
    }
166
}
167