Completed
Push — master ( ac2f13...c623e5 )
by Emmanuel
01:24
created

TicketControllable::store()   B

Complexity

Conditions 8
Paths 36

Size

Total Lines 70

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 70
rs 7.4101
c 0
b 0
f 0
cc 8
nc 36
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
4
namespace RexlManu\LaravelTickets\Controllers;
5
6
7
use Illuminate\Http\JsonResponse;
8
use Illuminate\Http\RedirectResponse;
9
use Illuminate\Http\Request;
10
use Illuminate\Validation\Rule;
11
use Illuminate\View\View;
12
use RexlManu\LaravelTickets\Events\TicketCloseEvent;
13
use RexlManu\LaravelTickets\Events\TicketMessageEvent;
14
use RexlManu\LaravelTickets\Events\TicketOpenEvent;
15
use RexlManu\LaravelTickets\Models\Ticket;
16
use RexlManu\LaravelTickets\Models\TicketMessage;
17
use RexlManu\LaravelTickets\Models\TicketReference;
18
use RexlManu\LaravelTickets\Models\TicketUpload;
19
use RexlManu\LaravelTickets\Rule\TicketReferenceRule;
20
use Symfony\Component\HttpFoundation\BinaryFileResponse;
21
22
/**
23
 * Class TicketController
24
 *
25
 * The main logic of the ticket system. All actions are performed here.
26
 *
27
 * If the accept header is json, the response will be a json response
28
 *
29
 * @package RexlManu\LaravelTickets\Controllers
30
 */
31
trait TicketControllable
32
{
33
34
    /**
35
     * @link TicketControllable constructor
36
     */
37
    public function __construct()
38
    {
39
        if (! config('laravel-tickets.permission')) {
40
            return;
41
        }
42
43
        $this->middleware(config('laravel-tickets.permissions.list-ticket'))->only('index');
0 ignored issues
show
Bug introduced by
It seems like middleware() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
44
        $this->middleware(config('laravel-tickets.permissions.create-ticket'))->only('store', 'create');
0 ignored issues
show
Bug introduced by
It seems like middleware() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
45
        $this->middleware(config('laravel-tickets.permissions.close-ticket'))->only('close');
0 ignored issues
show
Bug introduced by
It seems like middleware() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
46
        $this->middleware(config('laravel-tickets.permissions.show-ticket'))->only('show');
0 ignored issues
show
Bug introduced by
It seems like middleware() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
47
        $this->middleware(config('laravel-tickets.permissions.message-ticket'))->only('message');
0 ignored issues
show
Bug introduced by
It seems like middleware() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
48
        $this->middleware(config('laravel-tickets.permissions.download-ticket'))->only('download');
0 ignored issues
show
Bug introduced by
It seems like middleware() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
49
    }
50
51
    /**
52
     * Show every @return View|JsonResponse
53
     *
54
     * @link Ticket that the user has created
55
     *
56
     * If the accept header is json, the response will be a json response
57
     *
58
     */
59
    public function index()
60
    {
61
        if (\request()->user()->can(config('laravel-tickets.permissions.all-ticket'))) {
62
            $tickets = Ticket::query();
63
        } else {
64
            $tickets = request()->user()->tickets();
65
        }
66
        $tickets = $tickets->orderBy('id', 'desc')->paginate(10);
67
68
        return request()->wantsJson() ?
69
            response()->json(compact('tickets')) :
0 ignored issues
show
Bug introduced by
The method json does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

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...
70
            view('laravel-tickets::tickets.index',
71
                compact('tickets')
72
            );
73
    }
74
75
    /**
76
     * Show the create form
77
     *
78
     * @return View
79
     */
80
    public function create()
81
    {
82
        return view('laravel-tickets::tickets.create');
83
    }
84
85
    /**
86
     * Creates a @param Request $request the request
87
     *
88
     * @return View|JsonResponse|RedirectResponse
89
     * @link Ticket
90
     *
91
     */
92
    public function store(Request $request)
93
    {
94
        $rules = [
95
            'subject' => [ 'required', 'string', 'max:191' ],
96
            'priority' => [ 'required', Rule::in(config('laravel-tickets.priorities')) ],
97
            'message' => [ 'required', 'string' ],
98
            'files' => [ 'max:' . config('laravel-tickets.file.max-files') ],
99
            'files.*' => [
100
                'sometimes',
101
                'file',
102
                'max:' . config('laravel-tickets.file.size-limit'),
103
                'mimes:' . config('laravel-tickets.file.memes'),
104
            ],
105
        ];
106
        if (config('laravel-tickets.category')) {
107
            $rules[ 'category_id' ] = [
108
                'required',
109
                Rule::exists(config('laravel-tickets.database.ticket-categories-table'), 'id'),
110
            ];
111
        }
112
        if (config('laravel-tickets.references')) {
113
            $rules[ 'reference' ] = [
114
                config('laravel-tickets.references-nullable') ? 'nullable' : 'required',
115
                new TicketReferenceRule(),
116
            ];
117
        }
118
        $data = $request->validate($rules);
0 ignored issues
show
Bug introduced by
The call to validate() misses a required argument $...$params.

This check looks for function calls that miss required arguments.

Loading history...
119
        if ($request->user()->tickets()->where('state', '!=', 'CLOSED')->count() >= config('laravel-tickets.maximal-open-tickets')) {
120
            $message = trans('You have reached the limit of open tickets');
121
            return \request()->wantsJson() ?
122
                response()->json(compact('message')) :
0 ignored issues
show
Bug introduced by
The method json does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

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...
123
                back()->with(
124
                    'message',
125
                    $message
126
                );
127
        }
128
        $ticket = $request->user()->tickets()->create(
129
            $data
130
        );
131
132
        if (array_key_exists('reference', $data)) {
133
            $reference = explode(',', $data[ 'reference' ]);
134
            $ticketReference = new TicketReference();
135
            $ticketReference->ticket()->associate($ticket);
136
            $ticketReference->referenceable()->associate(
137
                resolve($reference[ 0 ])->find($reference[ 1 ])
138
            );
139
            $ticketReference->save();
140
        }
141
142
        $ticketMessage = new TicketMessage($data);
143
        $ticketMessage->user()->associate($request->user());
144
        $ticketMessage->ticket()->associate($ticket);
145
        $ticketMessage->save();
146
147
        $this->handleFiles($data[ 'files' ] ?? [], $ticketMessage);
148
149
        event(new TicketOpenEvent($ticket));
150
151
        $message = trans('The ticket was successfully created');
152
        return $request->wantsJson() ?
153
            response()->json(compact('message', 'ticket', 'ticketMessage')) :
154
            redirect(route(
155
                'laravel-tickets.tickets.show',
156
                compact('ticket')
157
            ))->with(
158
                'message',
159
                $message
160
            );
161
    }
162
163
    /**
164
     * Show detailed informations about the @param Ticket $ticket
165
     *
166
     * @return View|JsonResponse|RedirectResponse|void
167
     * @link Ticket and the informations
168
     *
169
     */
170
    public function show(Ticket $ticket)
171
    {
172 View Code Duplication
        if (! $ticket->user()->get()->contains(\request()->user()) &&
0 ignored issues
show
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...
173
            ! request()->user()->can(config('laravel-tickets.permissions.all-ticket'))) {
174
            return abort(403);
175
        }
176
177
        $messages = $ticket->messages()->with('uploads')->orderBy('created_at', 'desc')->paginate(4);
178
179
        return \request()->wantsJson() ?
180
            response()->json(compact(
0 ignored issues
show
Bug introduced by
The method json does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

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...
181
                'ticket',
182
                'messages'
183
            )) :
184
            view('laravel-tickets::tickets.show',
185
                compact(
186
                    'ticket',
187
                    'messages'
188
                )
189
            );
190
    }
191
192
    /**
193
     * Send a message to the @param Request $request
194
     *
195
     * @param Ticket $ticket
196
     *
197
     * @return JsonResponse|RedirectResponse|void
198
     * @link Ticket
199
     *
200
     */
201
    public function message(Request $request, Ticket $ticket)
202
    {
203 View Code Duplication
        if (! $ticket->user()->get()->contains(\request()->user()) &&
0 ignored issues
show
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...
204
            ! request()->user()->can(config('laravel-tickets.permissions.all-ticket'))) {
205
            return abort(403);
206
        }
207
208 View Code Duplication
        if (! config('laravel-tickets.open-ticket-with-answer') && $ticket->state === 'CLOSED') {
0 ignored issues
show
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...
209
            $message = trans('You cannot reply to a closed ticket');
210
            return \request()->wantsJson() ?
211
                response()->json(compact('message')) :
0 ignored issues
show
Bug introduced by
The method json does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

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...
212
                back()->with(
213
                    'message',
214
                    $message
215
                );
216
        }
217
218
        $data = $request->validate([
0 ignored issues
show
Bug introduced by
The call to validate() misses a required argument $...$params.

This check looks for function calls that miss required arguments.

Loading history...
219
            'message' => [ 'required', 'string' ],
220
            'files' => [ 'max:' . config('laravel-tickets.file.max-files') ],
221
            'files.*' => [
222
                'sometimes',
223
                'file',
224
                'max:' . config('laravel-tickets.file.size-limit'),
225
                'mimes:' . config('laravel-tickets.file.memes'),
226
            ]
227
        ]);
228
229
        $ticketMessage = new TicketMessage($data);
230
        $ticketMessage->user()->associate($request->user());
231
        $ticketMessage->ticket()->associate($ticket);
232
        $ticketMessage->save();
233
234
        $this->handleFiles($data[ 'files' ] ?? [], $ticketMessage);
235
236
        $ticket->update([ 'state' => 'OPEN' ]);
237
238
        event(new TicketMessageEvent($ticket, $ticketMessage));
239
240
        $message = trans('Your answer was sent successfully');
241
        return $request->wantsJson() ?
242
            response()->json(compact('message')) :
243
            back()->with(
244
                'message',
245
                $message
246
            );
247
    }
248
249
    /**
250
     * Declare the @param Ticket $ticket
251
     *
252
     * @return JsonResponse|RedirectResponse|void
253
     * @link Ticket as closed.
254
     *
255
     */
256
    public function close(Ticket $ticket)
257
    {
258 View Code Duplication
        if (! $ticket->user()->get()->contains(\request()->user()) &&
0 ignored issues
show
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...
259
            ! request()->user()->can(config('laravel-tickets.permissions.all-ticket'))) {
260
            return abort(403);
261
        }
262 View Code Duplication
        if ($ticket->state === 'CLOSED') {
0 ignored issues
show
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...
263
            $message = trans('The ticket is already closed');
264
            return \request()->wantsJson() ?
265
                response()->json(compact('message')) :
0 ignored issues
show
Bug introduced by
The method json does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

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...
266
                back()->with(
267
                    'message',
268
                    $message
269
                );
270
        }
271
        $ticket->update([ 'state' => 'CLOSED' ]);
272
        event(new TicketCloseEvent($ticket));
273
274
        $message = trans('The ticket was successfully closed');
275
        return \request()->wantsJson() ?
276
            response()->json(compact('message')) :
277
            back()->with(
278
                'message',
279
                $message
280
            );
281
    }
282
283
    /**
284
     * Downloads the file from @param Ticket $ticket
285
     *
286
     * @param TicketUpload $ticketUpload
287
     *
288
     * @return BinaryFileResponse
289
     * @link TicketUpload
290
     *
291
     */
292
    public function download(Ticket $ticket, TicketUpload $ticketUpload)
293
    {
294 View Code Duplication
        if (! $ticket->user()->get()->contains(\request()->user()) &&
0 ignored issues
show
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...
295
            ! request()->user()->can(config('laravel-tickets.permissions.all-ticket'))) {
296
            return abort(403);
297
        }
298
299
        $storagePath = storage_path('app/' . $ticketUpload->path);
300
        if (config('laravel-tickets.pdf-force-preview') && pathinfo($ticketUpload->path, PATHINFO_EXTENSION) === 'pdf') {
301
            return response()->file($storagePath);
0 ignored issues
show
Bug introduced by
The method file does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

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...
302
        }
303
304
        return response()->download($storagePath);
0 ignored issues
show
Bug introduced by
The method download does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

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...
305
    }
306
307
    /**
308
     * Handles the uploaded files for the @param $files array uploaded files
309
     *
310
     * @param TicketMessage $ticketMessage
311
     *
312
     * @link TicketMessage
313
     *
314
     */
315
    private function handleFiles($files, TicketMessage $ticketMessage)
316
    {
317
        if (! config('laravel-tickets.files') || $files === null) {
318
            return;
319
        }
320
        foreach ($files as $file) {
321
            $ticketMessage->uploads()->create([
322
                'path' => $file->storeAs(
323
                    config('laravel-tickets.file.path') . $ticketMessage->id,
324
                    $file->getClientOriginalName(),
325
                    config('laravel-tickets.file.driver')
326
                )
327
            ]);
328
        }
329
    }
330
331
}
332