Completed
Push — master ( 79e784...30adf6 )
by ARCANEDEV
05:39
created

FormRequest::formatJsonErrorsResponse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 1
dl 0
loc 8
ccs 0
cts 0
cp 0
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php namespace Arcanedev\Support\Bases;
2
3
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
4
use Illuminate\Contracts\Validation\Validator;
5
use Illuminate\Foundation\Http\FormRequest as BaseFormRequest;
6
use Illuminate\Http\JsonResponse;
7
8
/**
9
 * Class     FormRequest
10
 *
11
 * @package  Arcanedev\Support\Laravel
12
 * @author   ARCANEDEV <[email protected]>
13
 */
14
abstract class FormRequest extends BaseFormRequest
15
{
16
    /* ------------------------------------------------------------------------------------------------
17
     |  Properties
18
     | ------------------------------------------------------------------------------------------------
19
     */
20
    /**
21
     * Specify if the form request is an ajax request.
22
     *
23
     * @var bool
24
     */
25
    protected $ajaxRequest = false;
26
27
    /**
28
     * The errors format.
29
     *
30
     * @var string|null
31
     */
32
    protected $errorsFormat = null;
33
34
    /* ------------------------------------------------------------------------------------------------
35
     |  Main Functions
36
     | ------------------------------------------------------------------------------------------------
37
     */
38
    /**
39
     * Determine if the user is authorized to make this request.
40
     *
41
     * @return bool
42
     */
43
    public function authorize()
44
    {
45
        return false;
46
    }
47
48
    /**
49
     * Get the validation rules that apply to the request.
50
     *
51
     * @return array
52
     */
53
    abstract public function rules();
54
55
    /**
56
     * Get the validator instance for the request.
57
     *
58
     * @param  \Illuminate\Contracts\Validation\Factory  $factory
59
     *
60
     * @return \Illuminate\Contracts\Validation\Validator
61
     */
62
    public function validator(ValidationFactory $factory)
63
    {
64
        return $factory->make(
65
            $this->sanitizedInputs(),
66
            $this->container->call([$this, 'rules']),
67
            $this->messages(),
68
            $this->attributes()
69
        );
70
    }
71
72
    /**
73
     * Get the proper failed validation response for the request.
74
     *
75
     * @param  array  $errors
76
     *
77
     * @return \Symfony\Component\HttpFoundation\Response
78
     */
79
    public function response(array $errors)
80
    {
81
        if ($this->ajaxRequest && $this->expectsJson())
82
            return $this->formatJsonErrorsResponse($errors);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->formatJsonErrorsResponse($errors); (Illuminate\Http\JsonResponse) is incompatible with the return type documented by Arcanedev\Support\Bases\FormRequest::response of type Symfony\Component\HttpFoundation\Response.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
83
84
        return parent::response($errors);
85
    }
86
87
    /* ------------------------------------------------------------------------------------------------
88
     |  Other Functions
89
     | ------------------------------------------------------------------------------------------------
90
     */
91
    /**
92
     * Sanitize the inputs.
93
     *
94
     * @return array
95
     */
96
    protected function sanitizedInputs()
97
    {
98
        $inputs = $this->all();
99
100
        if (method_exists($this, 'sanitize')) {
101
            $this->replace(
102
                $inputs = $this->container->call([$this, 'sanitize'], [$inputs])
103
            );
104
        }
105
106
        return $inputs;
107
    }
108
109
    /**
110
     * Format the json response.
111
     *
112
     * @param  array  $errors
113
     *
114
     * @return \Symfony\Component\HttpFoundation\Response
115
     */
116
    protected function formatJsonErrorsResponse(array $errors)
117
    {
118
        return new JsonResponse([
119
            'status' => 'error',
120
            'code'   => 422,
121
            'errors' => array_map('reset', $errors)
122
        ], 422);
123
    }
124
125
    /**
126
     * {@inheritdoc}
127
     */
128
    protected function formatErrors(Validator $validator)
129
    {
130
        if (is_null($this->errorsFormat)) {
131
            return parent::formatErrors($validator);
132
        }
133
134
        $errors   = [];
135
        $messages = $validator->getMessageBag();
136
137
        foreach ($messages->keys() as $key) {
138
            $errors[$key] = $messages->get($key, $this->errorsFormat);
139
        }
140
141
        return $errors;
142
    }
143
}
144