2020-11-18 10:23:51 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
|
|
2021-06-18 17:02:14 +02:00
|
|
|
use App\Enums\Role;
|
2021-04-18 20:31:07 +02:00
|
|
|
use App\Enums\TicketStatus;
|
2021-06-18 15:39:19 +02:00
|
|
|
use App\Enums\TicketType;
|
2020-11-26 15:48:35 +01:00
|
|
|
use App\Events\NotifySubscriptions;
|
2021-04-18 20:31:07 +02:00
|
|
|
use App\Http\Requests\ChangeTicketStatus;
|
|
|
|
|
use App\Http\Requests\CreateMessage;
|
|
|
|
|
use App\Http\Requests\SortTickets;
|
|
|
|
|
use App\Http\Requests\StoreTicket;
|
|
|
|
|
use App\Http\Requests\UpdateTicket;
|
2021-05-18 22:52:46 +02:00
|
|
|
use App\Jobs\SendTicketMentionMail;
|
2020-11-25 16:05:21 +01:00
|
|
|
use App\Mail\NewTicket;
|
2021-05-18 22:52:46 +02:00
|
|
|
use App\Mail\TicketMention;
|
2020-11-25 16:05:21 +01:00
|
|
|
use App\Models\Message;
|
2020-11-18 10:23:51 +01:00
|
|
|
use App\Models\Project;
|
|
|
|
|
use App\Models\Ticket;
|
2020-11-26 15:48:35 +01:00
|
|
|
use App\Models\User;
|
2021-04-18 20:31:07 +02:00
|
|
|
use Exception;
|
2021-05-18 23:10:48 +02:00
|
|
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
2021-06-18 15:39:19 +02:00
|
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
|
|
|
use Illuminate\Http\Request;
|
2020-11-18 10:23:51 +01:00
|
|
|
use Illuminate\Support\Facades\Auth;
|
2021-04-18 20:31:07 +02:00
|
|
|
use Illuminate\Support\Facades\File;
|
2020-11-25 16:05:21 +01:00
|
|
|
use Illuminate\Support\Facades\Mail;
|
2021-04-21 15:08:47 +02:00
|
|
|
use Illuminate\Support\Facades\Session;
|
2020-11-18 10:23:51 +01:00
|
|
|
use Illuminate\Support\Str;
|
|
|
|
|
|
|
|
|
|
class TicketController extends Controller
|
|
|
|
|
{
|
2021-04-18 20:31:07 +02:00
|
|
|
public function __construct()
|
2021-04-15 16:47:57 +02:00
|
|
|
{
|
2021-04-18 20:31:07 +02:00
|
|
|
$this->authorizeResource(Ticket::class, 'ticket');
|
|
|
|
|
}
|
2021-04-15 16:47:57 +02:00
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
public function index(SortTickets $request)
|
|
|
|
|
{
|
2021-06-18 16:29:16 +02:00
|
|
|
/** @var \App\Models\User */
|
|
|
|
|
$user = auth()->user();
|
2021-06-18 17:02:14 +02:00
|
|
|
$tickets = Ticket::with('project');
|
|
|
|
|
if (!$user->role->equals(Role::admin())) {
|
|
|
|
|
$tickets = $tickets->whereHas('project', function ($q) use ($user) {
|
|
|
|
|
$q->whereHas('users', function ($q) use ($user) {
|
|
|
|
|
$q->whereId($user->id);
|
|
|
|
|
});
|
2021-06-18 16:29:16 +02:00
|
|
|
});
|
2021-06-18 17:02:14 +02:00
|
|
|
}
|
2021-06-18 15:39:19 +02:00
|
|
|
$tickets = $tickets->where('status', $request->status ? '=' : '<>', TicketStatus::archived());
|
|
|
|
|
if ($request->search) {
|
|
|
|
|
$tickets = $this->searchTicket($tickets, $request);
|
2021-04-18 20:31:07 +02:00
|
|
|
}
|
2021-06-18 15:39:19 +02:00
|
|
|
$tickets = $this->filterTickets($tickets, $request);
|
|
|
|
|
$tickets = $tickets->paginate();
|
2021-04-18 20:31:07 +02:00
|
|
|
|
2021-06-21 14:59:25 +02:00
|
|
|
$projects = Project::select('id', 'name')->orderBy('name')->get();
|
2021-06-18 15:39:19 +02:00
|
|
|
|
|
|
|
|
return view('ticket.index', compact('tickets', 'projects'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function filterTickets(Builder $tickets, Request $request): Builder
|
|
|
|
|
{
|
2021-04-21 15:48:48 +02:00
|
|
|
if ($request->rst) {
|
|
|
|
|
Session::remove('tickets.pr');
|
|
|
|
|
Session::remove('tickets.sort_col');
|
|
|
|
|
Session::remove('tickets.sort_way');
|
|
|
|
|
}
|
2021-04-21 15:08:47 +02:00
|
|
|
if ($request->prs) {
|
|
|
|
|
Session::remove('tickets.pr');
|
|
|
|
|
}
|
|
|
|
|
if ($request->sort_col) {
|
|
|
|
|
Session::put('tickets.sort_col', $request->sort_col);
|
|
|
|
|
}
|
|
|
|
|
if ($request->sort_way) {
|
|
|
|
|
Session::put('tickets.sort_way', $request->sort_way);
|
|
|
|
|
}
|
|
|
|
|
if ($request->pr) {
|
|
|
|
|
Session::put('tickets.pr', $request->pr);
|
|
|
|
|
}
|
2021-06-18 15:39:19 +02:00
|
|
|
Session::save();
|
|
|
|
|
|
2021-04-21 15:08:47 +02:00
|
|
|
if (Session::has('tickets.pr')) {
|
|
|
|
|
$tickets = $tickets->where('project_id', Session::get('tickets.pr'));
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-18 15:39:19 +02:00
|
|
|
if (
|
|
|
|
|
Session::has('tickets.sort_col') and
|
|
|
|
|
Session::has('tickets.sort_way') and
|
|
|
|
|
in_array(Session::get('tickets.sort_col'), [
|
|
|
|
|
'id', 'project', 'created_at', 'created_by',
|
|
|
|
|
'type', 'status'
|
|
|
|
|
])
|
|
|
|
|
) {
|
|
|
|
|
$tickets = $tickets->orderBy(
|
|
|
|
|
Session::get('tickets.sort_col'),
|
|
|
|
|
Session::get('tickets.sort_way')
|
|
|
|
|
);
|
2020-11-18 10:23:51 +01:00
|
|
|
}
|
2021-06-18 15:39:19 +02:00
|
|
|
return $tickets;
|
|
|
|
|
}
|
2021-04-18 20:31:07 +02:00
|
|
|
|
2021-06-18 15:39:19 +02:00
|
|
|
private function searchTicket(Builder $tickets, Request $request): Builder
|
|
|
|
|
{
|
|
|
|
|
$words = explode(' ', $request->search);
|
|
|
|
|
return $tickets->where(function ($q) use ($words) {
|
|
|
|
|
foreach ($words as $word) {
|
|
|
|
|
if (!strlen($word)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
$q = $q->where(function ($q) use ($word) {
|
|
|
|
|
$s = collect(TicketStatus::toArray())->filter(function (TicketStatus $t) use ($word) {
|
|
|
|
|
return strpos(strtolower($t->label), $word) !== false;
|
|
|
|
|
})->map(function (TicketStatus $ticket) {
|
|
|
|
|
return $ticket->value;
|
|
|
|
|
});
|
|
|
|
|
$t = collect(TicketType::toArray())->filter(function (TicketType $t) use ($word) {
|
|
|
|
|
return strpos(strtolower($t->label), $word) !== false;
|
|
|
|
|
})->map(function (TicketType $ticket) {
|
|
|
|
|
return $ticket->value;
|
|
|
|
|
});
|
|
|
|
|
$q->where('text', 'LIKE', "%$word%")
|
|
|
|
|
->orWhereIn('status', $s)
|
|
|
|
|
->orWhereIn('type', $t)
|
|
|
|
|
->orWhere('file', 'LIKE', "%$word%")
|
|
|
|
|
->orWhere('file2', 'LIKE', "%$word%")
|
|
|
|
|
->orWhereHas('user', function ($q) use ($word) {
|
|
|
|
|
$q->where('name', 'LIKE', "%$word%");
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
2020-11-18 10:23:51 +01:00
|
|
|
}
|
|
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
public function show(Ticket $ticket)
|
|
|
|
|
{
|
2020-11-25 16:05:21 +01:00
|
|
|
$messages = $ticket->messages()->orderBy('created_at', 'DESC')->get();
|
2021-04-18 20:31:07 +02:00
|
|
|
$isSubscribed = (bool)$ticket->subscriptions()->where('user_id', Auth::user()->id)->count();
|
|
|
|
|
return view('ticket.show', compact('ticket', 'messages', 'isSubscribed'));
|
2020-11-25 16:05:21 +01:00
|
|
|
}
|
|
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
public function create()
|
|
|
|
|
{
|
2021-06-23 19:48:22 +02:00
|
|
|
$user = Auth::user();
|
2021-06-24 11:32:22 +02:00
|
|
|
if ($user->role->value === 1) {
|
2021-06-23 19:48:22 +02:00
|
|
|
$projects = Project::orderBy('name')->get();
|
|
|
|
|
} else {
|
|
|
|
|
$projects = $user->projects;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
if (!count($projects)) {
|
|
|
|
|
return redirect()->route('project.create')
|
|
|
|
|
->with('warning', 'Vous devez tout d\'abord créer un projet pour y ajouter un ticket');
|
|
|
|
|
}
|
2020-11-18 10:23:51 +01:00
|
|
|
return view('ticket.create', compact('projects'));
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
public function store(StoreTicket $request)
|
|
|
|
|
{
|
|
|
|
|
$project = Project::findOrFail($request->project_id);
|
2020-11-26 12:23:19 +01:00
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
$ticket = new Ticket($request->validated());
|
2020-11-25 16:05:21 +01:00
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
if ($request->file_ticket) {
|
|
|
|
|
$ticket->file = Ticket::saveFile($project, $ticket, $ticket->type, $request->file_ticket);
|
2020-11-25 16:05:21 +01:00
|
|
|
}
|
2021-04-18 20:31:07 +02:00
|
|
|
if ($request->file_ticket2) {
|
|
|
|
|
$ticket->file2 = Ticket::saveFile($project, $ticket, $ticket->type, $request->file_ticket2);
|
2020-11-18 10:23:51 +01:00
|
|
|
}
|
|
|
|
|
|
2021-06-23 19:48:22 +02:00
|
|
|
if ($request->type === TicketType::evolution()) {
|
|
|
|
|
$ticket->status = TicketStatus::estimateTodo();
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
$ticket->user()->associate(auth()->user());
|
2021-05-18 19:24:58 +02:00
|
|
|
$ticket->saveOrFail();
|
|
|
|
|
/** @var \App\Models\User */
|
|
|
|
|
$user = auth()->user();
|
|
|
|
|
$user->subscriptions()->toggle($ticket->id);
|
2020-11-26 12:23:19 +01:00
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
if (config('mail.MAIL_ADMIN')) {
|
|
|
|
|
Mail::to(config('mail.MAIL_ADMIN'))->send(new NewTicket($ticket));
|
|
|
|
|
} else {
|
|
|
|
|
throw new Exception('Missing MAIL_ADMIN in .env');
|
|
|
|
|
}
|
2020-11-25 16:05:21 +01:00
|
|
|
|
2021-05-18 19:24:58 +02:00
|
|
|
return redirect()->route('ticket.show', $ticket)->with('success', 'Ticket enregistré !');
|
2020-11-18 10:23:51 +01:00
|
|
|
}
|
|
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
|
|
|
|
public function edit(Ticket $ticket)
|
|
|
|
|
{
|
2021-06-24 11:32:22 +02:00
|
|
|
$user = Auth::user();
|
|
|
|
|
if ($user->role->value === 1) {
|
|
|
|
|
$projects = Project::orderBy('name')->get();
|
|
|
|
|
} else {
|
|
|
|
|
$projects = $user->projects;
|
|
|
|
|
}
|
2021-04-18 20:31:07 +02:00
|
|
|
return view('ticket.edit', compact('ticket', 'projects'));
|
2020-11-18 10:23:51 +01:00
|
|
|
}
|
|
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
public function update(UpdateTicket $request, Ticket $ticket)
|
|
|
|
|
{
|
|
|
|
|
$project = Project::findOrFail($request->project_id);
|
|
|
|
|
$ticket->fill($request->validated());
|
2020-11-26 12:23:19 +01:00
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
if ($request->file_ticket) {
|
|
|
|
|
if (File::exists($ticket->file)) {
|
|
|
|
|
File::delete($ticket->file);
|
|
|
|
|
}
|
|
|
|
|
$ticket->file = Ticket::saveFile($project, $ticket, $ticket->type, $request->file_ticket);
|
2020-11-18 10:23:51 +01:00
|
|
|
}
|
2021-04-18 20:31:07 +02:00
|
|
|
if ($request->file_ticket2) {
|
|
|
|
|
if (File::exists($ticket->file2)) {
|
|
|
|
|
File::delete($ticket->file2);
|
|
|
|
|
}
|
|
|
|
|
$ticket->file2 = Ticket::saveFile($project, $ticket, $ticket->type, $request->file_ticket2);
|
2020-11-25 16:05:21 +01:00
|
|
|
}
|
2020-11-18 10:23:51 +01:00
|
|
|
|
|
|
|
|
$ticket->save();
|
|
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
return redirect()->route('ticket.edit', $ticket->id)->with('success', 'Modifications enregistrées !');
|
2020-11-18 10:23:51 +01:00
|
|
|
}
|
2020-11-25 16:05:21 +01:00
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
public function changeStatus(ChangeTicketStatus $request, Ticket $ticket)
|
|
|
|
|
{
|
|
|
|
|
$ticket->fill($request->validated());
|
2020-11-25 16:05:21 +01:00
|
|
|
$ticket->save();
|
2021-04-18 20:43:20 +02:00
|
|
|
|
2020-11-25 16:05:21 +01:00
|
|
|
return back();
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
public function createMessage(CreateMessage $request, Ticket $ticket)
|
|
|
|
|
{
|
2020-11-25 16:05:21 +01:00
|
|
|
$fileMessage = $request->file_message;
|
|
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
$message = new Message($request->validated());
|
|
|
|
|
$message->user()->associate(auth()->user());
|
|
|
|
|
$message->ticket()->associate($ticket);
|
2021-05-18 20:07:42 +02:00
|
|
|
$message->saveOrFail();
|
|
|
|
|
|
|
|
|
|
/** @var \App\Models\User */
|
|
|
|
|
$user = auth()->user();
|
|
|
|
|
|
|
|
|
|
if ($request->subscribe) {
|
2021-05-18 23:06:28 +02:00
|
|
|
if (!$user->subscriptions()->find($ticket->id)) {
|
|
|
|
|
$user->subscriptions()->attach($ticket->id);
|
|
|
|
|
}
|
|
|
|
|
} elseif ($user->subscriptions()->find($ticket->id)) {
|
2021-05-18 20:07:42 +02:00
|
|
|
$user->subscriptions()->detach($ticket->id);
|
|
|
|
|
}
|
2020-11-25 16:05:21 +01:00
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
if ($request->file_message) {
|
2020-11-25 16:05:21 +01:00
|
|
|
$projectSlug = Str::slug($ticket->project->name);
|
|
|
|
|
$fileMessage = $request->file_message;
|
|
|
|
|
$fileName = $projectSlug . '-ticket-' . $ticket->id . '-message-' . $message->id . '.' . $fileMessage->extension();
|
|
|
|
|
$fileMessage->move(public_path('fichiers/' . $projectSlug . '/' . $ticket->id . '/'), $fileName);
|
|
|
|
|
$filePath = 'fichiers/' . $projectSlug . '/' . $ticket->id . '/' . $fileName;
|
|
|
|
|
$message->file = $filePath;
|
|
|
|
|
$message->save();
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-18 20:43:20 +02:00
|
|
|
event(new NotifySubscriptions(
|
|
|
|
|
$message->ticket,
|
|
|
|
|
trans('Nouvelle réponse de :name :<br> :message', [
|
|
|
|
|
'name' => $message->user->name,
|
|
|
|
|
'message' => $message->message
|
|
|
|
|
])
|
|
|
|
|
));
|
|
|
|
|
|
2021-05-18 22:52:46 +02:00
|
|
|
// find @user + send mail si un seul user est trouvé
|
|
|
|
|
$matches = [];
|
|
|
|
|
\preg_match_all('/@\w*/', $message->message, $matches);
|
|
|
|
|
$matches = collect($matches[0] ?? [])->unique();
|
|
|
|
|
foreach ($matches as $pseudo_usertag) {
|
|
|
|
|
try {
|
|
|
|
|
$user = User::where('name', 'LIKE', '%' . ltrim($pseudo_usertag, '@') . '%')
|
|
|
|
|
->whereDoesntHave('subscriptions', function ($q) use ($ticket) {
|
|
|
|
|
$q->where('id', $ticket->id);
|
|
|
|
|
})->firstOrFail();
|
|
|
|
|
SendTicketMentionMail::dispatchAfterResponse(
|
|
|
|
|
$user,
|
|
|
|
|
new TicketMention($ticket, $message->message)
|
|
|
|
|
);
|
2021-05-18 23:10:48 +02:00
|
|
|
} catch (ModelNotFoundException $e) {
|
2021-05-18 22:52:46 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-26 15:48:35 +01:00
|
|
|
return back();
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-18 20:31:07 +02:00
|
|
|
public function setToArchive(Ticket $ticket)
|
|
|
|
|
{
|
|
|
|
|
$ticket->status = TicketStatus::archived();
|
|
|
|
|
$ticket->saveOrFail();
|
|
|
|
|
return redirect()->route('ticket.index');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function subscribe(Ticket $ticket)
|
|
|
|
|
{
|
|
|
|
|
User::find(Auth::user()->id)->subscriptions()->toggle($ticket->id);
|
2020-11-25 16:05:21 +01:00
|
|
|
return back();
|
|
|
|
|
}
|
2020-11-18 10:23:51 +01:00
|
|
|
}
|