TicketsController.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Models\Server;
  4. use App\Models\Ticket;
  5. use App\Models\TicketBlacklist;
  6. use App\Models\TicketCategory;
  7. use App\Models\TicketComment;
  8. use App\Models\User;
  9. use App\Notifications\Ticket\Admin\AdminCreateNotification;
  10. use App\Notifications\Ticket\Admin\AdminReplyNotification;
  11. use App\Notifications\Ticket\User\CreateNotification;
  12. use App\Settings\LocaleSettings;
  13. use App\Settings\PterodactylSettings;
  14. use App\Settings\TicketSettings;
  15. use Illuminate\Http\Request;
  16. use Illuminate\Support\Facades\Auth;
  17. use Illuminate\Support\Facades\Notification;
  18. use Illuminate\Support\Str;
  19. class TicketsController extends Controller
  20. {
  21. const READ_PERMISSION = 'user.ticket.read';
  22. const WRITE_PERMISSION = 'user.ticket.write';
  23. public function index(LocaleSettings $locale_settings, TicketSettings $ticketSettings)
  24. {
  25. return view('ticket.index', [
  26. 'ticketsettings' => $ticketSettings,
  27. 'tickets' => Ticket::where('user_id', Auth::user()->id)->paginate(10),
  28. 'ticketcategories' => TicketCategory::all(),
  29. 'locale_datatables' => $locale_settings->datatables
  30. ]);
  31. }
  32. public function store(Request $request, TicketSettings $ticket_settings)
  33. {
  34. $this->validate(
  35. $request,
  36. [
  37. 'title' => 'required',
  38. 'ticketcategory' => 'required',
  39. 'priority' => 'required',
  40. 'message' => 'required',
  41. 'g-recaptcha-response' => ['required', 'recaptcha'],
  42. ]
  43. );
  44. $ticket = new Ticket(
  45. [
  46. 'title' => $request->input('title'),
  47. 'user_id' => Auth::user()->id,
  48. 'ticket_id' => strtoupper(Str::random(8)),
  49. 'ticketcategory_id' => $request->input('ticketcategory'),
  50. 'priority' => $request->input('priority'),
  51. 'message' => $request->input('message'),
  52. 'status' => 'Open',
  53. 'server' => $request->input('server'),
  54. ]
  55. );
  56. $ticket->save();
  57. $user = Auth::user();
  58. $staffNotify = User::permission('admin.tickets.get_notification')->get();
  59. foreach($staffNotify as $staff){
  60. Notification::send($staff, new AdminCreateNotification($ticket, $user));
  61. }
  62. $user->notify(new CreateNotification($ticket));
  63. return redirect()->route('ticket.index')->with('success', __('A ticket has been opened, ID: #') . $ticket->ticket_id);
  64. }
  65. public function show($ticket_id, PterodactylSettings $ptero_settings)
  66. {
  67. $this->checkPermission(self::READ_PERMISSION);
  68. try {
  69. $ticket = Ticket::where('ticket_id', $ticket_id)->firstOrFail();
  70. } catch (Exception $e) {
  71. return redirect()->back()->with('warning', __('Ticket not found on the server. It potentially got deleted earlier'));
  72. }
  73. $ticketcomments = $ticket->ticketcomments;
  74. $ticketcategory = $ticket->ticketcategory;
  75. $server = Server::where('id', $ticket->server)->first();
  76. $pterodactyl_url = $ptero_settings->panel_url;
  77. return view('ticket.show', compact('ticket', 'ticketcategory', 'ticketcomments', 'server', 'pterodactyl_url'));
  78. }
  79. public function reply(Request $request)
  80. {
  81. //check in blacklist
  82. $check = TicketBlacklist::where('user_id', Auth::user()->id)->first();
  83. if ($check && $check->status == 'True') {
  84. return redirect()->route('ticket.index')->with('error', __("You can't reply a ticket because you're on the blacklist for a reason: '" . $check->reason . "', please contact the administrator"));
  85. }
  86. $this->validate($request, ['ticketcomment' => 'required']);
  87. try {
  88. $ticket = Ticket::where('id', $request->input('ticket_id'))->firstOrFail();
  89. } catch (Exception $e) {
  90. return redirect()->back()->with('warning', __('Ticket not found on the server. It potentially got deleted earlier'));
  91. }
  92. $ticket->status = 'Client Reply';
  93. $ticket->update();
  94. $ticketcomment = TicketComment::create([
  95. 'ticket_id' => $request->input('ticket_id'),
  96. 'user_id' => Auth::user()->id,
  97. 'ticketcomment' => $request->input('ticketcomment'),
  98. 'message' => $request->input('message'),
  99. ]);
  100. $user = Auth::user();
  101. $newmessage = $request->input('ticketcomment');
  102. $staffNotify = User::permission('admin.tickets.get_notification')->get();
  103. foreach($staffNotify as $staff){
  104. Notification::send($staff, new AdminReplyNotification($ticket, $user, $newmessage));
  105. }
  106. return redirect()->back()->with('success', __('Your comment has been submitted'));
  107. }
  108. public function create()
  109. {
  110. $this->checkPermission(self::WRITE_PERMISSION);
  111. //check in blacklist
  112. $check = TicketBlacklist::where('user_id', Auth::user()->id)->first();
  113. if ($check && $check->status == 'True') {
  114. return redirect()->route('ticket.index')->with('error', __("You can't make a ticket because you're on the blacklist for a reason: '" . $check->reason . "', please contact the administrator"));
  115. }
  116. $ticketcategories = TicketCategory::all();
  117. $servers = Auth::user()->servers;
  118. return view('ticket.create', compact('ticketcategories', 'servers'));
  119. }
  120. public function changeStatus($ticket_id)
  121. {
  122. try {
  123. $ticket = Ticket::where('user_id', Auth::user()->id)->where("ticket_id", $ticket_id)->firstOrFail();
  124. } catch (Exception $e) {
  125. return redirect()->back()->with('warning', __('Ticket not found on the server. It potentially got deleted earlier'));
  126. }
  127. if ($ticket->status == "Closed") {
  128. $ticket->status = "Reopened";
  129. $ticket->save();
  130. return redirect()->back()->with('success', __('A ticket has been reopened, ID: #') . $ticket->ticket_id);
  131. }
  132. $ticket->status = "Closed";
  133. $ticket->save();
  134. return redirect()->back()->with('success', __('A ticket has been closed, ID: #') . $ticket->ticket_id);
  135. }
  136. public function dataTable()
  137. {
  138. $query = Ticket::where('user_id', Auth::user()->id)->get();
  139. return datatables($query)
  140. ->addColumn('category', function (Ticket $tickets) {
  141. return $tickets->ticketcategory->name;
  142. })
  143. ->editColumn('title', function (Ticket $tickets) {
  144. return '<a class="text-info" href="' . route('ticket.show', ['ticket_id' => $tickets->ticket_id]) . '">' . '#' . $tickets->ticket_id . ' - ' . htmlspecialchars($tickets->title) . '</a>';
  145. })
  146. ->editColumn('status', function (Ticket $tickets) {
  147. switch ($tickets->status) {
  148. case 'Reopened':
  149. case 'Open':
  150. $badgeColor = 'badge-success';
  151. break;
  152. case 'Closed':
  153. $badgeColor = 'badge-danger';
  154. break;
  155. case 'Answered':
  156. $badgeColor = 'badge-info';
  157. break;
  158. default:
  159. $badgeColor = 'badge-warning';
  160. break;
  161. }
  162. return '<span class="badge ' . $badgeColor . '">' . $tickets->status . '</span>';
  163. })
  164. ->editColumn('priority', function (Ticket $tickets) {
  165. return __($tickets->priority);
  166. })
  167. ->editColumn('updated_at', function (Ticket $tickets) {
  168. return [
  169. 'display' => $tickets->updated_at ? $tickets->updated_at->diffForHumans() : '',
  170. 'raw' => $tickets->updated_at ? strtotime($tickets->updated_at) : ''
  171. ];
  172. })
  173. ->addColumn('actions', function (Ticket $tickets) {
  174. $statusButtonColor = ($tickets->status == "Closed") ? 'btn-success' : 'btn-warning';
  175. $statusButtonIcon = ($tickets->status == "Closed") ? 'fa-redo' : 'fa-times';
  176. $statusButtonText = ($tickets->status == "Closed") ? __('Reopen') : __('Close');
  177. return '
  178. <a data-content="' . __('View') . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('ticket.show', ['ticket_id' => $tickets->ticket_id]) . '" class="btn btn-sm text-white btn-info mr-1"><i class="fas fa-eye"></i></a>
  179. <form class="d-inline" method="post" action="' . route('ticket.changeStatus', ['ticket_id' => $tickets->ticket_id]) . '">
  180. ' . csrf_field() . '
  181. ' . method_field('POST') . '
  182. <button data-content="' . __($statusButtonText) . '" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm text-white ' . $statusButtonColor . ' mr-1"><i class="fas ' . $statusButtonIcon . '"></i></button>
  183. </form>
  184. </form>
  185. ';
  186. })
  187. ->rawColumns(['category', 'title', 'status', 'updated_at', "actions"])
  188. ->make(true);
  189. }
  190. }