Completed
Pull Request — master (#14)
by Fèvre
29:13 queued 20:34
created

UserController::update()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 11
nc 3
nop 1
1
<?php
2
namespace Xetaravel\Http\Controllers;
3
4
use Illuminate\Http\RedirectResponse;
5
use Illuminate\Http\Request;
6
use Illuminate\Support\Facades\Auth;
7
use Illuminate\Support\Facades\Hash;
8
use Illuminate\Support\Facades\Route;
9
use Illuminate\View\View;
10
use Xetaravel\Models\Repositories\UserRepository;
11
use Xetaravel\Models\User;
12
use Xetaravel\Models\Validators\UserValidator;
13
14
class UserController extends Controller
15
{
16
    /**
17
     * Constructor
18
     */
19
    public function __construct()
20
    {
21
        parent::__construct();
22
23
        $route = Route::getCurrentRoute()->getActionName();
24
        list(, $action) = explode('@', $route);
25
26
        if (in_array($action, ['index', 'show'])) {
27
            $this->breadcrumbs->addCrumb('Users', route('users.user.index'));
0 ignored issues
show
Bug introduced by
The property breadcrumbs does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
28
        }
29
    }
30
31
    /**
32
     * Show all the users.
33
     *
34
     * @return \Illuminate\View\View
35
     */
36
    public function index(): View
37
    {
38
        return view('user.index');
39
    }
40
41
    /**
42
     * Show the user profile page.
43
     *
44
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
0 ignored issues
show
Documentation introduced by
Should the return type not be RedirectResponse|View|\I...\Contracts\View\Factory?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
45
     */
46
    public function show(Request $request, $slug, $id)
0 ignored issues
show
Unused Code introduced by
The parameter $request 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...
Unused Code introduced by
The parameter $slug 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...
47
    {
48
        $user = User::with('articles', 'comments')
0 ignored issues
show
Bug introduced by
The method where does only exist in Illuminate\Database\Eloquent\Builder, but not in Illuminate\Database\Eloquent\Model.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
49
            ->where('id', $id)
50
            ->first();
51
52
        if (is_null($user)) {
53
            return redirect()
54
                ->route('page.index')
55
                ->with('danger', 'This user doesn\'t exist or has been deleted !');
56
        }
57
58
        $this->breadcrumbs->addCrumb(
59
            e($user->username),
60
            route(
61
                'users.user.show',
62
                ['slug' => $user->slug, 'id' => $user->id]
63
            )
64
        );
65
        $this->breadcrumbs->setCssClasses('breadcrumb');
66
67
        return view('user.show', ['user' => $user, 'breadcrumbs' => $this->breadcrumbs]);
68
    }
69
70
    /**
71
     * Show the settings form.
72
     *
73
     * @return \Illuminate\View\View
74
     */
75
    public function showSettingsForm(): View
76
    {
77
        $this->breadcrumbs
78
            ->addCrumb('Settings', route('users.user.settings'))
79
            ->setCssClasses('breadcrumb');
80
81
        return view('user.settings', ['breadcrumbs' => $this->breadcrumbs]);
82
    }
83
84
    /**
85
     * Handle an update request for the user.
86
     *
87
     * @param \Illuminate\Http\Request $request
88
     *
89
     * @return \Illuminate\Http\RedirectResponse
90
     */
91
    public function update(Request $request): RedirectResponse
92
    {
93
        $type = $request->input('type');
94
95
        switch ($type) {
96
            case 'email':
97
                return $this->updateEmail($request);
98
99
            case 'password':
100
                return $this->updatePassword($request);
101
102
            default:
103
                return back()
104
                    ->withInput()
105
                    ->with('danger', 'Invalid type.');
106
        }
107
    }
108
109
    /**
110
     * Handle the delete request for the user.
111
     *
112
     * @param \Illuminate\Http\Request $request
113
     *
114
     * @return \Illuminate\Http\RedirectResponse
115
     */
116
    public function delete(Request $request): RedirectResponse
117
    {
118
        $user = Auth::user();
119
120 View Code Duplication
        if (!Hash::check($request->input('password'), $user->password)) {
0 ignored issues
show
Bug introduced by
Accessing password on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
121
            return redirect()
122
                ->route('users.user.settings')
123
                ->with('danger', 'Your Password does not match !');
124
        }
125
        Auth::logout();
126
127
        if ($user->delete()) {
128
            return redirect()
129
                ->route('page.index')
130
                ->with('success', 'Your Account has been deleted successfully !');
131
        }
132
133
        return redirect()
134
            ->route('page.index')
135
            ->with('danger', 'An error occurred while deleting your account !');
136
    }
137
138
    /**
139
     * Handle a E-mail update request for the user.
140
     *
141
     * @param \Illuminate\Http\Request $request
142
     *
143
     * @return \Illuminate\Http\RedirectResponse
144
     */
145
    protected function updateEmail(Request $request): RedirectResponse
146
    {
147
        UserValidator::updateEmail($request->all())->validate();
148
        UserRepository::updateEmail($request->all(), Auth::user());
0 ignored issues
show
Documentation introduced by
\Illuminate\Support\Facades\Auth::user() is of type object<Illuminate\Contra...h\Authenticatable>|null, but the function expects a object<Xetaravel\Models\User>.

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...
149
150
        return redirect()
151
            ->route('users.user.settings')
152
            ->with('success', 'Your E-mail has been updated successfully !');
153
    }
154
155
    /**
156
     * Handle a Password update request for the user.
157
     *
158
     * @param \Illuminate\Http\Request $request
159
     *
160
     * @return \Illuminate\Http\RedirectResponse
161
     */
162
    protected function updatePassword(Request $request): RedirectResponse
163
    {
164
        $user = Auth::user();
165
166 View Code Duplication
        if (!Hash::check($request->input('oldpassword'), $user->password)) {
0 ignored issues
show
Bug introduced by
Accessing password on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
167
            return redirect()
168
                ->route('users.user.settings')
169
                ->with('danger', 'Your current Password does not match !');
170
        }
171
172
        UserValidator::updatePassword($request->all())->validate();
173
        UserRepository::updatePassword($request->all(), $user);
0 ignored issues
show
Compatibility introduced by
$user of type object<Illuminate\Contracts\Auth\Authenticatable> is not a sub-type of object<Xetaravel\Models\User>. It seems like you assume a concrete implementation of the interface Illuminate\Contracts\Auth\Authenticatable to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
174
175
        return redirect()
176
            ->route('users.user.settings')
177
            ->with('success', 'Your Password has been updated successfully !');
178
    }
179
}
180