Completed
Pull Request — master (#14)
by Fèvre
16:39 queued 07:44
created

UserController::updateEmail()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 6
nc 1
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($controller, $action) = explode('@', $route);
0 ignored issues
show
Unused Code introduced by
The assignment to $controller is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
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
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
99
100
            case 'password':
101
                return $this->updatePassword($request);
102
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
103
104
            default:
105
                return back()
106
                    ->withInput()
107
                    ->with('danger', 'Invalid type.');
108
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
109
        }
110
    }
111
112
    /**
113
     * Handle the delete request for the user.
114
     *
115
     * @param \Illuminate\Http\Request $request
116
     *
117
     * @return \Illuminate\Http\RedirectResponse
118
     */
119
    public function delete(Request $request): RedirectResponse
120
    {
121
        $user = Auth::user();
122
123 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...
124
            return redirect()
125
                ->route('users.user.settings')
126
                ->with('danger', 'Your Password does not match !');
127
        }
128
        Auth::logout();
129
130
        if ($user->delete()) {
131
            return redirect()
132
                ->route('page.index')
133
                ->with('success', 'Your Account has been deleted successfully !');
134
        }
135
136
        return redirect()
137
            ->route('page.index')
138
            ->with('danger', 'An error occurred while deleting your account !');
139
    }
140
141
    /**
142
     * Handle a E-mail update request for the user.
143
     *
144
     * @param \Illuminate\Http\Request $request
145
     *
146
     * @return \Illuminate\Http\RedirectResponse
147
     */
148
    protected function updateEmail(Request $request): RedirectResponse
149
    {
150
        UserValidator::updateEmail($request->all())->validate();
151
        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...
152
153
        return redirect()
154
            ->route('users.user.settings')
155
            ->with('success', 'Your E-mail has been updated successfully !');
156
    }
157
158
    /**
159
     * Handle a Password update request for the user.
160
     *
161
     * @param \Illuminate\Http\Request $request
162
     *
163
     * @return \Illuminate\Http\RedirectResponse
164
     */
165
    protected function updatePassword(Request $request): RedirectResponse
166
    {
167
        $user = Auth::user();
168
169 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...
170
            return redirect()
171
                ->route('users.user.settings')
172
                ->with('danger', 'Your current Password does not match !');
173
        }
174
175
        UserValidator::updatePassword($request->all())->validate();
176
        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...
177
178
        return redirect()
179
            ->route('users.user.settings')
180
            ->with('success', 'Your Password has been updated successfully !');
181
    }
182
}
183