Completed
Push — master ( 6dd141...c48c3b )
by Emmanuel
01:41
created

TicketController::close()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 25

Duplication

Lines 9
Ratio 36 %

Importance

Changes 0
Metric Value
dl 9
loc 25
rs 9.2088
c 0
b 0
f 0
cc 5
nc 5
nop 1
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\Routing\Controller;
11
use Illuminate\Validation\Rule;
12
use Illuminate\View\View;
13
use RexlManu\LaravelTickets\Events\TicketCloseEvent;
14
use RexlManu\LaravelTickets\Events\TicketMessageEvent;
15
use RexlManu\LaravelTickets\Events\TicketOpenEvent;
16
use RexlManu\LaravelTickets\Models\Ticket;
17
use RexlManu\LaravelTickets\Models\TicketMessage;
18
use RexlManu\LaravelTickets\Models\TicketUpload;
19
use Symfony\Component\HttpFoundation\BinaryFileResponse;
20
21
/**
22
 * Class TicketController
23
 *
24
 * The main logic of the ticket system. All actions are performed here.
25
 *
26
 * If the accept header is json, the response will be a json response
27
 *
28
 * @package RexlManu\LaravelTickets\Controllers
29
 */
30
class TicketController extends Controller
31
{
32
33
    /**
34
     * @link TicketController constructor
35
     */
36
    public function __construct()
37
    {
38
        if (! config('laravel-tickets.permission')) {
39
            return;
40
        }
41
42
        $this->middleware(config('laravel-tickets.permissions.list-ticket'))->only('index');
43
        $this->middleware(config('laravel-tickets.permissions.create-ticket'))->only('store', 'create');
44
        $this->middleware(config('laravel-tickets.permissions.close-ticket'))->only('close');
45
        $this->middleware(config('laravel-tickets.permissions.show-ticket'))->only('show');
46
        $this->middleware(config('laravel-tickets.permissions.message-ticket'))->only('message');
47
        $this->middleware(config('laravel-tickets.permissions.download-ticket'))->only('download');
48
    }
49
50
    /**
51
     * Show every @return View|JsonResponse
52
     *
53
     * @link Ticket that the user has created
54
     *
55
     * If the accept header is json, the response will be a json response
56
     *
57
     */
58
    public function index()
59
    {
60
        $tickets = request()->user()->tickets()->orderBy('id', 'desc')->paginate(10);
61
62
        return request()->wantsJson() ?
63
            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...
64
            view('laravel-tickets::tickets.index',
65
                compact('tickets')
66
            );
67
    }
68
69
    /**
70
     * Show the create form
71
     *
72
     * @return View
73
     */
74
    public function create()
75
    {
76
        return view('laravel-tickets::tickets.create');
77
    }
78
79
    /**
80
     * Creates a @param Request $request the request
81
     *
82
     * @return View|JsonResponse|RedirectResponse
83
     * @link Ticket
84
     *
85
     */
86
    public function store(Request $request)
87
    {
88
        $rules = [
89
            'subject' => [ 'required', 'string', 'max:191' ],
90
            'priority' => [ 'required', Rule::in(config('laravel-tickets.priorities')) ],
91
            'message' => [ 'required', 'string' ],
92
            'files' => [ 'max:' . config('laravel-tickets.file.max-files') ],
93
            'files.*' => [
94
                'sometimes',
95
                'file',
96
                'max:' . config('laravel-tickets.file.size-limit'),
97
                'mimes:' . config('laravel-tickets.file.memes'),
98
            ],
99
        ];
100
        if (config('laravel-tickets.category')) {
101
            $rules[ 'category_id' ] = [
102
                'required',
103
                Rule::exists(config('laravel-tickets.database.ticket-categories-table'), 'id'),
104
            ];
105
        }
106
        $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...
107
        if ($request->user()->tickets()->where('state', '!=', 'CLOSED')->count() >= config('laravel-tickets.maximal-open-tickets')) {
108
            $message = trans('You have reached the limit of open tickets');
109
            return \request()->wantsJson() ?
110
                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...
111
                back()->with(
112
                    'message',
113
                    $message
114
                );
115
        }
116
        $ticket = $request->user()->tickets()->create(
117
            $data
118
        );
119
        $ticketMessage = new TicketMessage($data);
120
        $ticketMessage->user()->associate($request->user());
121
        $ticketMessage->ticket()->associate($ticket);
122
        $ticketMessage->save();
123
124
        $this->handleFiles($data[ 'files' ] ?? [], $ticketMessage);
125
126
        event(new TicketOpenEvent($ticket));
127
128
        $message = trans('The ticket was successfully created');
129
        return $request->wantsJson() ?
130
            response()->json(compact('message', 'ticket', 'ticketMessage')) :
131
            redirect(route(
132
                'laravel-tickets.tickets.show',
133
                compact('ticket')
134
            ))->with(
135
                'message',
136
                $message
137
            );
138
    }
139
140
    /**
141
     * Show detailed informations about the @param Ticket $ticket
142
     *
143
     * @return View|JsonResponse|RedirectResponse|void
144
     * @link Ticket and the informations
145
     *
146
     */
147
    public function show(Ticket $ticket)
148
    {
149
        if (! $ticket->user()->get()->contains(\request()->user())) {
150
            return abort(403);
151
        }
152
153
        $messages = $ticket->messages()->with('uploads')->orderBy('created_at', 'desc')->paginate(4);
154
155
        return \request()->wantsJson() ?
156
            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...
157
                'ticket',
158
                'messages'
159
            )) :
160
            view('laravel-tickets::tickets.show',
161
                compact(
162
                    'ticket',
163
                    'messages'
164
                )
165
            );
166
    }
167
168
    /**
169
     * Send a message to the @param Request $request
170
     *
171
     * @param Ticket $ticket
172
     *
173
     * @return JsonResponse|RedirectResponse|void
174
     * @link Ticket
175
     *
176
     */
177
    public function message(Request $request, Ticket $ticket)
178
    {
179
        if (! $ticket->user()->get()->contains(\request()->user())) {
180
            return abort(403);
181
        }
182
183 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...
184
            $message = trans('You cannot reply to a closed ticket');
185
            return \request()->wantsJson() ?
186
                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...
187
                back()->with(
188
                    'message',
189
                    $message
190
                );
191
        }
192
193
        $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...
194
            'message' => [ 'required', 'string' ],
195
            'files' => [ 'max:' . config('laravel-tickets.file.max-files') ],
196
            'files.*' => [
197
                'sometimes',
198
                'file',
199
                'max:' . config('laravel-tickets.file.size-limit'),
200
                'mimes:' . config('laravel-tickets.file.memes'),
201
            ]
202
        ]);
203
204
        $ticketMessage = new TicketMessage($data);
205
        $ticketMessage->user()->associate($request->user());
206
        $ticketMessage->ticket()->associate($ticket);
207
        $ticketMessage->save();
208
209
        $this->handleFiles($data[ 'files' ] ?? [], $ticketMessage);
210
211
        $ticket->update([ 'state' => 'OPEN' ]);
212
213
        event(new TicketMessageEvent($ticket, $ticketMessage));
214
215
        $message = trans('Your answer was sent successfully');
216
        return $request->wantsJson() ?
217
            response()->json(compact('message')) :
218
            back()->with(
219
                'message',
220
                $message
221
            );
222
    }
223
224
    /**
225
     * Declare the @param Ticket $ticket
226
     *
227
     * @return JsonResponse|RedirectResponse|void
228
     * @link Ticket as closed.
229
     *
230
     */
231
    public function close(Ticket $ticket)
232
    {
233
        if (! $ticket->user()->get()->contains(\request()->user())) {
234
            return abort(403);
235
        }
236 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...
237
            $message = trans('The ticket is already closed');
238
            return \request()->wantsJson() ?
239
                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...
240
                back()->with(
241
                    'message',
242
                    $message
243
                );
244
        }
245
        $ticket->update([ 'state' => 'CLOSED' ]);
246
        event(new TicketCloseEvent($ticket));
247
248
        $message = trans('The ticket was successfully closed');
249
        return \request()->wantsJson() ?
250
            response()->json(compact('message')) :
251
            back()->with(
252
                'message',
253
                $message
254
            );
255
    }
256
257
    /**
258
     * Downloads the file from @param Ticket $ticket
259
     *
260
     * @param TicketUpload $ticketUpload
261
     *
262
     * @return BinaryFileResponse
263
     * @link TicketUpload
264
     *
265
     */
266
    public function download(Ticket $ticket, TicketUpload $ticketUpload)
267
    {
268
        if (! $ticket->user()->get()->contains(\request()->user()) ||
269
            ! $ticket->messages()->get()->contains($ticketUpload->message()->first())) {
270
            return abort(403);
271
        }
272
273
        $storagePath = storage_path('app/' . $ticketUpload->path);
274
        if (config('laravel-tickets.pdf-force-preview') && pathinfo($ticketUpload->path, PATHINFO_EXTENSION) === 'pdf') {
275
            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...
276
        }
277
278
        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...
279
    }
280
281
    /**
282
     * Handles the uploaded files for the @param $files array uploaded files
283
     *
284
     * @param TicketMessage $ticketMessage
285
     *
286
     * @link TicketMessage
287
     *
288
     */
289
    private function handleFiles($files, TicketMessage $ticketMessage)
290
    {
291
        if (! config('laravel-tickets.files') || $files === null) {
292
            return;
293
        }
294
        foreach ($files as $file) {
295
            $ticketMessage->uploads()->create([
296
                'path' => $file->storeAs(
297
                    config('laravel-tickets.file.path') . $ticketMessage->id,
298
                    $file->getClientOriginalName(),
299
                    config('laravel-tickets.file.driver')
300
                )
301
            ]);
302
        }
303
    }
304
305
}
306