Completed
Push — master ( cdad02...2b0328 )
by Elf
07:32
created

AdminUserDataTable   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 111
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 6

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 0
loc 111
ccs 0
cts 33
cp 0
rs 10
c 0
b 0
f 0
wmc 9
lcom 2
cbo 6

7 Methods

Rating   Name   Duplication   Size   Complexity  
A dataTable() 0 12 1
A query() 0 6 1
A html() 0 7 1
A getColumns() 0 10 1
A getAvatarColumnData() 0 8 1
A getActionColumnData() 0 16 3
A getBuilderParameters() 0 6 1
1
<?php
2
3
namespace App\DataTables;
4
5
use App\Models\AdminUser;
6
use App\Support\Datatables\Services\DataTable;
7
use Illuminate\Support\Facades\Auth;
8
9
class AdminUserDataTable extends DataTable
10
{
11
    /**
12
     * Build DataTable class.
13
     *
14
     * @return \Yajra\Datatables\Engines\BaseEngine
15
     */
16
    public function dataTable()
17
    {
18
        return $this->datatables
19
            ->eloquent($this->query())
20
            ->editColumn('avatar', function ($user) {
21
                return $this->getAvatarColumnData($user);
22
            })
23
            ->editColumn('action', function ($user) {
24
                return $this->getActionColumnData($user);
25
            })
26
            ->rawColumns(['avatar', 'action']);
27
    }
28
29
    /**
30
     * Get the query object to be processed by dataTables.
31
     *
32
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder|\Illuminate\Support\Collection
33
     */
34
    public function query()
35
    {
36
        $query = AdminUser::query();
37
38
        return $this->applyScopes($query);
39
    }
40
41
    /**
42
     * Optional method if you want to use html builder.
43
     *
44
     * @return \Yajra\Datatables\Html\Builder
45
     */
46
    public function html()
47
    {
48
        return $this->builder()
49
            ->columns($this->getColumns())
50
            ->addAction()
51
            ->parameters($this->getBuilderParameters());
52
    }
53
54
    /**
55
     * Get columns.
56
     *
57
     * @return array
58
     */
59
    protected function getColumns()
60
    {
61
        return [
62
            'id' => ['title' => 'ID'],
63
            'avatar' => $this->staticColumn('avatar', ['title' => '头像']),
64
            'username' => ['title' => '用户名'],
65
            'email' => ['title' => '邮箱'],
66
            'created_at' => ['title' => '创建日期'],
67
        ];
68
    }
69
70
    /**
71
     * Get the "avatar" column data.
72
     *
73
     * @param  AdminUser  $user
74
     * @return mixed
75
     */
76
    protected function getAvatarColumnData($user)
77
    {
78
        return <<<HTML
79
<a href='{$user->avatar}' data-lightbox='admin-user-avatar-{$user->id}'>
80
    <img src='{$user->avatar}' class='img-circle' style='width:28px;height:28px'>
81
</a>
82
HTML;
83
    }
84
85
    /**
86
     * Get the "action" column data.
87
     *
88
     * @param  AdminUser  $user
89
     * @return mixed
90
     */
91
    protected function getActionColumnData($user)
92
    {
93
        $html = '<div class="btn-group" role="group">';
94
95
        if (Auth::user()->can('update', $user)) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Illuminate\Contracts\Auth\Authenticatable as the method can() does only exist in the following implementations of said interface: App\Models\AdminUser, App\Models\User, Illuminate\Foundation\Auth\User.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
96
            $html .= '<button type="button" class="btn btn-info admin-user-action-edit"><i class="fa fa-edit"></i></button>';
97
        }
98
99
        if (Auth::user()->can('delete', $user)) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Illuminate\Contracts\Auth\Authenticatable as the method can() does only exist in the following implementations of said interface: App\Models\AdminUser, App\Models\User, Illuminate\Foundation\Auth\User.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
100
            $html .= '<button type="button" class="btn btn-danger admin-user-action-delete"><i class="fa fa-trash"></i></button>';
101
        }
102
103
        $html .= '</div>';
104
105
        return $html;
106
    }
107
108
    /**
109
     * Get the default builder parameters.
110
     *
111
     * @return array
112
     */
113
    protected function getBuilderParameters()
114
    {
115
        return [
116
            'order' => [[0, 'asc']],
117
        ];
118
    }
119
}
120