Completed
Push — master ( d27d79...fd5cc8 )
by
unknown
06:45
created

ModelController::customController()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 12
ccs 0
cts 9
cp 0
rs 9.2
cc 4
eloc 7
nc 3
nop 1
crap 20
1
<?php
2
namespace Anavel\Crud\Http\Controllers;
3
4
use Anavel\Crud\Contracts\Abstractor\Model;
5
use Anavel\Foundation\Http\Controllers\Controller;
6
use Anavel\Crud\Contracts\Abstractor\ModelFactory as ModelAbstractorFactory;
7
use ANavallaSuiza\Laravel\Database\Contracts\Manager\ModelManager;
8
use Anavel\Crud\Contracts\Controllers\CustomController;
9
use Anavel\Crud\Contracts\Form\Generator as FormGenerator;
10
use Anavel\Crud\Repository\Criteria\OrderByCriteria;
11
use Anavel\Crud\Repository\Criteria\SearchCriteria;
12
use Illuminate\Http\Request;
13
use App;
14
15
class ModelController extends Controller
16
{
17
    protected $modelFactory;
18
    protected $modelManager;
19
    protected $formGenerator;
20
21
    public function __construct(ModelAbstractorFactory $modelFactory, ModelManager $modelManager, FormGenerator $formGenerator)
22
    {
23
        $this->modelFactory = $modelFactory;
24
        $this->modelManager = $modelManager;
25
        $this->formGenerator = $formGenerator;
26
    }
27
    
28
    private function authorizeMethod(Model $modelAbstractor, $methodName)
29
    {
30
        if (array_key_exists('authorize', $config = $modelAbstractor->getConfig()) && $config['authorize'] === true) {
31
            $this->authorize($methodName, $modelAbstractor->getInstance());
0 ignored issues
show
Bug introduced by
The method authorize() does not exist on Anavel\Crud\Http\Controllers\ModelController. Did you maybe mean authorizeMethod()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
32
        }
33
    }
34
35
    /**
36
     * @param Model $modelAbstractor
37
     * @return null|CustomController
38
     */
39
    private function customController(Model $modelAbstractor)
40
    {
41
        if (! $this instanceof CustomController) { //Avoid infinite recursion
42
            if (array_key_exists('controller', $config = $modelAbstractor->getConfig()) && (! empty($config['controller']))) {
43
                /** @var CustomController $controller */
44
                $controller = App::make($config['controller']);
45
                $controller->setAbstractor($modelAbstractor);
46
                return $controller;
47
            }
48
        }
49
        return null;
50
    }
51
52
    /**
53
     * Display a listing of the resource.
54
     *
55
     * @param Request $request
56
     * @param  string  $model
57
     * @return Response
58
     */
59
    public function index(Request $request, $model)
60
    {
61
        $modelAbstractor = $this->modelFactory->getBySlug($model);
62
63
        $this->authorizeMethod($modelAbstractor, 'adminIndex');
64
65
        if (! empty($customController = $this->customController($modelAbstractor))) {
66
            return $customController->index($request, $model);
67
        }
68
69
        $repository = $this->modelManager->getRepository($modelAbstractor->getModel());
70
71
        if ($request->has('search')) {
72
            $searchByColumns = array();
73
74
            foreach ($modelAbstractor->getListFields() as $field) {
75
                $searchByColumns[] = $field->getName();
76
            }
77
78
            $repository->pushCriteria(new SearchCriteria($searchByColumns, $request->get('search')));
79
        }
80
81
        if ($request->has('sort')) {
82
            $repository->pushCriteria(new OrderByCriteria($request->get('sort'), $request->get('direction') === 'desc' ? true : false));
83
        }
84
85
        $items = $repository->paginate(config('anavel-crud.list_max_results'));
86
87
        return view('anavel-crud::pages.index', [
0 ignored issues
show
Bug Best Practice introduced by
The return type of return view('anavel-crud...r, 'items' => $items)); (Illuminate\View\View|Ill...\Contracts\View\Factory) is incompatible with the return type documented by Anavel\Crud\Http\Control...\ModelController::index of type Anavel\Crud\Http\Controllers\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...
88
            'abstractor' => $modelAbstractor,
89
            'items' => $items
90
        ]);
91
    }
92
93
    /**
94
     * Show the form for creating a new resource.
95
     *
96
     * @param  string  $model
97
     * @return Response
98
     */
99
    public function create($model)
100
    {
101
        $modelAbstractor = $this->modelFactory->getBySlug($model);
102
103
        $this->authorizeMethod($modelAbstractor, 'adminCreate');
104
105
        if (! empty($customController = $this->customController($modelAbstractor))) {
106
            return $customController->create($model);
107
        }
108
109
        $form = $modelAbstractor->getForm(route('anavel-crud.model.store', $modelAbstractor->getSlug()));
110
111
        return view('anavel-crud::pages.create', [
0 ignored issues
show
Bug Best Practice introduced by
The return type of return view('anavel-crud...ctor->getRelations())); (Illuminate\View\View|Ill...\Contracts\View\Factory) is incompatible with the return type documented by Anavel\Crud\Http\Control...ModelController::create of type Anavel\Crud\Http\Controllers\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...
112
            'abstractor' => $modelAbstractor,
113
            'form' => $form,
114
            'relations' => $modelAbstractor->getRelations()
115
        ]);
116
    }
117
118
    /**
119
     * Store a newly created resource in storage.
120
     *
121
     * @param Request $request
122
     * @param  string  $model
123
     * @return Response
124
     */
125
    public function store(Request $request, $model)
126
    {
127
        $modelAbstractor = $this->modelFactory->getBySlug($model);
128
129
        $this->authorizeMethod($modelAbstractor, 'adminStore');
130
131
        if (! empty($customController = $this->customController($modelAbstractor))) {
132
            return $customController->store($request, $model);
133
        }
134
135
        // Sets the validation rules
136
        $modelAbstractor->getForm(route('anavel-crud.model.store', $modelAbstractor->getSlug()));
137
138
        $this->validate($request, $modelAbstractor->getValidationRules());
139
140
        $modelAbstractor->persist($request);
141
142
        session()->flash('anavel-alert', [
143
            'type'  => 'success',
144
            'icon'  => 'fa-check',
145
            'title' => trans('anavel-crud::messages.alert_success_model_store_title'),
146
            'text'  => trans('anavel-crud::messages.alert_success_model_store_text')
147
        ]);
148
149
        return redirect()->route('anavel-crud.model.index', $model);
0 ignored issues
show
Documentation introduced by
$model is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug Best Practice introduced by
The return type of return redirect()->route....model.index', $model); (Illuminate\Http\RedirectResponse) is incompatible with the return type documented by Anavel\Crud\Http\Control...\ModelController::store of type Anavel\Crud\Http\Controllers\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...
150
    }
151
152
    /**
153
     * Display the specified resource.
154
     *
155
     * @param  string  $model
156
     * @param  int  $id
157
     * @return Response
158
     */
159
    public function show($model, $id)
160
    {
161
        $modelAbstractor = $this->modelFactory->getBySlug($model);
162
163
        $this->authorizeMethod($modelAbstractor, 'adminShow');
164
165
        if (! empty($customController = $this->customController($modelAbstractor))) {
166
            return $customController->show($model, $id);
167
        }
168
169
        $repository = $this->modelManager->getRepository($modelAbstractor->getModel());
170
        $item = $repository->findByOrFail($repository->getModel()->getKeyName(), $id);
171
172
        return view('anavel-crud::pages.show', [
0 ignored issues
show
Bug Best Practice introduced by
The return type of return view('anavel-crud...tor, 'item' => $item)); (Illuminate\View\View|Ill...\Contracts\View\Factory) is incompatible with the return type documented by Anavel\Crud\Http\Controllers\ModelController::show of type Anavel\Crud\Http\Controllers\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...
173
            'abstractor' => $modelAbstractor,
174
            'item' => $item
175
        ]);
176
    }
177
178
    /**
179
     * Show the form for editing the specified resource.
180
     *
181
     * @param  string  $model
182
     * @param  int  $id
183
     * @return Response
184
     */
185
    public function edit($model, $id)
186
    {
187
        /** @var Model $modelAbstractor */
188
        $modelAbstractor = $this->modelFactory->getBySlug($model, $id);
189
190
        $this->authorizeMethod($modelAbstractor, 'adminEdit');
191
192
        if (! empty($customController = $this->customController($modelAbstractor))) {
193
            return $customController->edit($model, $id);
194
        }
195
196
        $form = $modelAbstractor->getForm(route('anavel-crud.model.update', [$modelAbstractor->getSlug(), $id]));
197
        $repository = $this->modelManager->getRepository($modelAbstractor->getModel());
198
        $item = $repository->findByOrFail($repository->getModel()->getKeyName(), $id);
199
200
        return view('anavel-crud::pages.edit', [
0 ignored issues
show
Bug Best Practice introduced by
The return type of return view('anavel-crud...ctor->getRelations())); (Illuminate\View\View|Ill...\Contracts\View\Factory) is incompatible with the return type documented by Anavel\Crud\Http\Controllers\ModelController::edit of type Anavel\Crud\Http\Controllers\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...
201
            'abstractor' => $modelAbstractor,
202
            'form' => $form,
203
            'item' => $item,
204
            'relations' => $modelAbstractor->getRelations()
205
        ]);
206
    }
207
208
    /**
209
     * Update the specified resource in storage.
210
     *
211
     * @param Request $request
212
     * @param  string  $model
213
     * @param  int  $id
214
     * @return Response
215
     */
216
    public function update(Request $request, $model, $id)
217
    {
218
        $modelAbstractor = $this->modelFactory->getBySlug($model, $id);
219
220
        $this->authorizeMethod($modelAbstractor, 'adminUpdate');
221
222
        if (! empty($customController = $this->customController($modelAbstractor))) {
223
            return $customController->update($request, $model, $id);
224
        }
225
226
        // Sets the validation rules
227
        $modelAbstractor->getForm(route('anavel-crud.model.update', [$modelAbstractor->getSlug(), $id]));
228
229
        $this->validate($request, $modelAbstractor->getValidationRules());
230
231
        $modelAbstractor->persist($request);
232
233
        session()->flash('anavel-alert', [
234
            'type'  => 'success',
235
            'icon'  => 'fa-check',
236
            'title' => trans('anavel-crud::messages.alert_success_model_update_title'),
237
            'text'  => trans('anavel-crud::messages.alert_success_model_update_text')
238
        ]);
239
240
        return redirect()->route('anavel-crud.model.edit', [$model, $id]);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return redirect()->route...', array($model, $id)); (Illuminate\Http\RedirectResponse) is incompatible with the return type documented by Anavel\Crud\Http\Control...ModelController::update of type Anavel\Crud\Http\Controllers\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...
241
    }
242
243
    /**
244
     * Remove the specified resource from storage.
245
     *
246
     * @param Request $request
247
     * @param  string  $model
248
     * @param  int  $id
249
     * @return Response
250
     */
251
    public function destroy(Request $request, $model, $id)
252
    {
253
        $modelAbstractor = $this->modelFactory->getBySlug($model);
254
255
        $this->authorizeMethod($modelAbstractor, 'adminDestroy');
256
257
        if (! empty($customController = $this->customController($modelAbstractor))) {
258
            return $customController->destroy($request, $model, $id);
259
        }
260
261
        $repository = $this->modelManager->getRepository($modelAbstractor->getModel());
262
        $item = $repository->findByOrFail($repository->getModel()->getKeyName(), $id);
263
264
        $item->delete();
265
266
        session()->flash('anavel-alert', [
267
            'type'  => 'success',
268
            'icon'  => 'fa-check',
269
            'title' => trans('anavel-crud::messages.alert_success_model_destroy_title'),
270
            'text'  => trans('anavel-crud::messages.alert_success_model_destroy_text')
271
        ]);
272
273
        return redirect()->route('anavel-crud.model.index', $model);
0 ignored issues
show
Documentation introduced by
$model is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug Best Practice introduced by
The return type of return redirect()->route....model.index', $model); (Illuminate\Http\RedirectResponse) is incompatible with the return type documented by Anavel\Crud\Http\Control...odelController::destroy of type Anavel\Crud\Http\Controllers\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...
274
    }
275
}
276