Completed
Push — master ( 099793...ff0ab0 )
by Alexander
03:07
created

ConvertsParameters::__get()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Flugg\Responder\Traits;
4
5
/**
6
 * Use this trait in your base form request to convert all camel cased parameters to
7
 * snake case and boolean strings to PHP booleans when accessing the input from
8
 * the controller.
9
 *
10
 * @package Laravel Responder
11
 * @author  Alexander Tømmerås <[email protected]>
12
 * @license The MIT License
13
 */
14
trait ConvertsParameters
15
{
16
    /**
17
     * Check if an input element is set on the request.
18
     *
19
     * @param  string $key
20
     * @return bool
21
     */
22
    public function __isset( $key )
23
    {
24
        return parent::__isset( snake_case( $key ) );
25
    }
26
27
    /**
28
     * Get an input element from the request.
29
     *
30
     * @param  string $key
31
     * @return mixed
32
     */
33
    public function __get( $key )
34
    {
35
        return parent::__get( snake_case( $key ) );
36
    }
37
38
    /**
39
     * Get the validator instance for the request.
40
     *
41
     * @return \Illuminate\Contracts\Validation\Validator
42
     */
43
    protected function getValidatorInstance()
44
    {
45
        $this->getInputSource()->replace( $this->getConvertedParameters() );
46
47
        return parent::getValidatorInstance();
48
    }
49
50
    /**
51
     * Get the input source for the request.
52
     *
53
     * @return \Symfony\Component\HttpFoundation\ParameterBag
54
     */
55
    abstract protected function getInputSource();
56
57
    /**
58
     * Cast and convert parameters.
59
     *
60
     * @return array
61
     */
62
    protected function getConvertedParameters():array
63
    {
64
        $parameters = $this->all();
65
        $parameters = $this->castBooleans( $parameters );
66
        $parameters = $this->convertToSnakeCase( $parameters );
67
68
        if ( method_exists( $this, 'convertParameters' ) ) {
69
            $parameters = $this->convertParameters( $parameters );
0 ignored issues
show
Bug introduced by
It seems like convertParameters() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
70
        }
71
72
        return $parameters;
73
    }
74
75
    /**
76
     * Get all of the input and files for the request.
77
     *
78
     * @return array
79
     */
80
    abstract public function all();
81
82
    /**
83
     * Cast all string booleans to real boolean values.
84
     *
85
     * @param  mixed $input
86
     * @return array
87
     */
88
    protected function castBooleans( $input ):array
89
    {
90
        if ( $this->castToBooleanIsDisabled() ) {
91
            return;
92
        }
93
94
        $casted = [ ];
95
96
        foreach ( $input as $key => $value ) {
97
            $casted[ $key ] = $this->castValueToBoolean( $value );
98
        }
99
100
        return $casted;
101
    }
102
103
    /**
104
     * Convert a string or array to snake case.
105
     *
106
     * @param  mixed $input
107
     * @return mixed
108
     */
109
    protected function convertToSnakeCase( $input )
110
    {
111
        if ( $this->convertToSnakeCaseIsDisabled() ) {
112
            return;
113
        }
114
115
        if ( is_null( $input ) ) {
116
            return null;
117
        } elseif ( is_array( $input ) ) {
118
            return $this->convertArrayToSnakeCase( $input );
119
        }
120
121
        return snake_case( $input );
122
    }
123
124
    /**
125
     * Checks if the user wants to cast to booleans.
126
     *
127
     * @return bool
128
     */
129
    protected function castToBooleanIsDisabled():bool
130
    {
131
        return isset( $this->castBooleans ) && ! $this->castBooleans;
132
    }
133
134
    /**
135
     * Checks if the user wants to convert to snake case.
136
     *
137
     * @return bool
138
     */
139
    protected function convertToSnakeCaseIsDisabled():bool
140
    {
141
        return isset( $this->convertToSnakeCase ) && ! $this->convertToSnakeCase;
142
    }
143
144
    /**
145
     * Cast a given value to a boolean if it is in fact a boolean.
146
     *
147
     * @param  mixed $value
148
     * @return mixed
149
     */
150
    protected function castValueToBoolean( $value )
151
    {
152
        if ( in_array( $value, [ 'true', 'false' ] ) ) {
153
            return filter_var( $value, FILTER_VALIDATE_BOOLEAN );
154
        }
155
156
        return $value;
157
    }
158
159
    /**
160
     * Convert all keys of an array to snake case.
161
     *
162
     * @param  array $input
163
     * @return array
164
     */
165
    protected function convertArrayToSnakeCase( array $input ):array
166
    {
167
        $converted = [ ];
168
169
        foreach ( $input as $key => $value ) {
170
            $converted[ snake_case( $key ) ] = $value;
171
        }
172
173
        return $converted;
174
    }
175
}