Completed
Push — master ( 1a570a...fa1d82 )
by Alexander
03:46 queued 45s
created

ConvertsToSnakeCase   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 142
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 0
loc 142
rs 10
c 0
b 0
f 0
wmc 19
lcom 1
cbo 1

10 Methods

Rating   Name   Duplication   Size   Complexity  
A ConvertsParameters::__isset() 0 4 1
A ConvertsParameters::__get() 0 4 1
A ConvertsParameters::getValidatorInstance() 0 6 1
ConvertsParameters::getInputSource() 0 1 ?
A ConvertsParameters::getConvertedParameters() 0 12 2
ConvertsParameters::all() 0 1 ?
A ConvertsParameters::castBooleans() 0 14 4
B ConvertsParameters::castValueToBoolean() 0 12 5
A ConvertsParameters::convertToSnakeCase() 0 10 3
A ConvertsParameters::convertArrayToSnakeCase() 0 10 2
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 ( isset( $this->castBooleans ) && ! $this->castBooleans ) {
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
     * Cast a given value to a boolean if it is in fact a boolean.
105
     *
106
     * @param  mixed $value
107
     * @return mixed
108
     */
109
    protected function castValueToBoolean( $value )
110
    {
111
        if ( isset( $this->convertToSnakeCase ) && ! $this->convertToSnakeCase ) {
112
            return;
113
        }
114
115
        if ( $value === 'true' || $value === 'false' ) {
116
            return filter_var( $value, FILTER_VALIDATE_BOOLEAN );
117
        }
118
119
        return $value;
120
    }
121
122
    /**
123
     * Convert a string or array to snake case.
124
     *
125
     * @param  mixed $input
126
     * @return mixed
127
     */
128
    protected function convertToSnakeCase( $input )
129
    {
130
        if ( is_null( $input ) ) {
131
            return null;
132
        } elseif ( is_array( $input ) ) {
133
            return $this->convertArrayToSnakeCase( $input );
134
        }
135
136
        return snake_case( $input );
137
    }
138
139
    /**
140
     * Convert all keys of an array to snake case.
141
     *
142
     * @param  array $input
143
     * @return array
144
     */
145
    protected function convertArrayToSnakeCase( array $input ):array
146
    {
147
        $converted = [ ];
148
149
        foreach ( $input as $key => $value ) {
150
            $converted[ snake_case( $key ) ] = $value;
151
        }
152
153
        return $converted;
154
    }
155
}