Completed
Push — master ( f57602...4c0e5b )
by Emmanuel
06:53
created

TicketController::download()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 3
nc 2
nop 2
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
        $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...
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 ($request->user()->tickets()->where('state', '!=', 'CLOSED')->count() >= config('laravel-tickets.maximal-open-tickets')) {
101
            $message = trans('You have reached the limit of open tickets');
102
            return \request()->wantsJson() ?
103
                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...
104
                back()->with(
105
                    'message',
106
                    $message
107
                );
108
        }
109
        $ticket = $request->user()->tickets()->create(
110
            $data
111
        );
112
        $ticketMessage = new TicketMessage($data);
113
        $ticketMessage->user()->associate($request->user());
114
        $ticketMessage->ticket()->associate($ticket);
115
        $ticketMessage->save();
116
117
        $this->handleFiles($data[ 'files' ], $ticketMessage);
118
119
        event(new TicketOpenEvent($ticket));
120
121
        $message = trans('The ticket was successfully created');
122
        return $request->wantsJson() ?
123
            response()->json(compact('message', 'ticket', 'ticketMessage')) :
124
            redirect(route(
125
                'laravel-tickets.tickets.show',
126
                compact('ticket')
127
            ))->with(
128
                'message',
129
                $message
130
            );
131
    }
132
133
    /**
134
     * Show detailed informations about the @param Ticket $ticket
135
     *
136
     * @return View|JsonResponse|RedirectResponse|void
137
     * @link Ticket and the informations
138
     *
139
     */
140
    public function show(Ticket $ticket)
141
    {
142
        if (! $ticket->user()->get()->contains(\request()->user())) {
143
            return abort(403);
144
        }
145
146
        $messages = $ticket->messages()->with('uploads')->orderBy('created_at', 'desc')->paginate(4);
147
148
        return \request()->wantsJson() ?
149
            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...
150
                'ticket',
151
                'messages'
152
            )) :
153
            view('laravel-tickets::tickets.show',
154
                compact(
155
                    'ticket',
156
                    'messages'
157
                )
158
            );
159
    }
160
161
    /**
162
     * Send a message to the @param Request $request
163
     *
164
     * @param Ticket $ticket
165
     *
166
     * @return JsonResponse|RedirectResponse|void
167
     * @link Ticket
168
     *
169
     */
170
    public function message(Request $request, Ticket $ticket)
171
    {
172
        if (! $ticket->user()->get()->contains(\request()->user())) {
173
            return abort(403);
174
        }
175
176 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...
177
            $message = trans('You cannot reply to a closed ticket');
178
            return \request()->wantsJson() ?
179
                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...
180
                back()->with(
181
                    'message',
182
                    $message
183
                );
184
        }
185
186
        $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...
187
            'message' => [ 'required', 'string' ],
188
            'files' => [ 'max:' . config('laravel-tickets.file.max-files') ],
189
            'files.*' => [
190
                'sometimes',
191
                'file',
192
                'max:' . config('laravel-tickets.file.size-limit'),
193
                'mimes:' . config('laravel-tickets.file.memes'),
194
            ]
195
        ]);
196
197
        $ticketMessage = new TicketMessage($data);
198
        $ticketMessage->user()->associate($request->user());
199
        $ticketMessage->ticket()->associate($ticket);
200
        $ticketMessage->save();
201
202
        $this->handleFiles($data[ 'files' ], $ticketMessage);
203
204
        $ticket->update([ 'state' => 'OPEN' ]);
205
206
        event(new TicketMessageEvent($ticket, $ticketMessage));
207
208
        $message = trans('Your answer was sent successfully');
209
        return $request->wantsJson() ?
210
            response()->json(compact('message')) :
211
            back()->with(
212
                'message',
213
                $message
214
            );
215
    }
216
217
    /**
218
     * Declare the @param Ticket $ticket
219
     *
220
     * @return JsonResponse|RedirectResponse|void
221
     * @link Ticket as closed.
222
     *
223
     */
224
    public function close(Ticket $ticket)
225
    {
226
        if (! $ticket->user()->get()->contains(\request()->user())) {
227
            return abort(403);
228
        }
229 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...
230
            $message = trans('The ticket is already closed');
231
            return \request()->wantsJson() ?
232
                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...
233
                back()->with(
234
                    'message',
235
                    $message
236
                );
237
        }
238
        $ticket->update([ 'state' => 'CLOSED' ]);
239
        event(new TicketCloseEvent($ticket));
240
241
        $message = trans('The ticket was successfully closed');
242
        return \request()->wantsJson() ?
243
            response()->json(compact('message')) :
244
            back()->with(
245
                'message',
246
                $message
247
            );
248
    }
249
250
    /**
251
     * Downloads the file from @param Ticket $ticket
252
     *
253
     * @param TicketUpload $ticketUpload
254
     *
255
     * @return BinaryFileResponse
256
     * @link TicketUpload
257
     *
258
     */
259
    public function download(Ticket $ticket, TicketUpload $ticketUpload)
260
    {
261
        if (! $ticket->user()->get()->contains(\request()->user()) ||
262
            ! $ticket->messages()->get()->contains($ticketUpload->message()->first())) {
263
            return abort(403);
264
        }
265
266
        return response()->download(storage_path('app/'.$ticketUpload->path));
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...
267
    }
268
269
    /**
270
     * Handles the uploaded files for the @param $files array uploaded files
271
     *
272
     * @param TicketMessage $ticketMessage
273
     *
274
     * @link TicketMessage
275
     *
276
     */
277
    private function handleFiles($files, TicketMessage $ticketMessage)
278
    {
279
        if (! config('laravel-tickets.files') || $files === null) {
280
            return;
281
        }
282
        foreach ($files as $file) {
283
            $ticketMessage->uploads()->create([
284
                'path' => $file->storeAs(
285
                    config('laravel-tickets.file.path') . $ticketMessage->id,
286
                    $file->getClientOriginalName(),
287
                    config('laravel-tickets.file.driver')
288
                )
289
            ]);
290
        }
291
    }
292
293
}
294