TicketsController.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. <?php
  2. namespace App\Http\Controllers\Moderation;
  3. use App\Http\Controllers\Controller;
  4. use App\Models\Server;
  5. use App\Models\Ticket;
  6. use App\Models\TicketBlacklist;
  7. use App\Models\TicketCategory;
  8. use App\Models\TicketComment;
  9. use App\Models\User;
  10. use App\Notifications\Ticket\User\ReplyNotification;
  11. use App\Settings\LocaleSettings;
  12. use App\Settings\PterodactylSettings;
  13. use Illuminate\Http\Request;
  14. use Illuminate\Support\Facades\Auth;
  15. class TicketsController extends Controller
  16. {
  17. public function index(LocaleSettings $locale_settings)
  18. {
  19. return view('moderator.ticket.index', [
  20. 'tickets' => Ticket::orderBy('id', 'desc')->paginate(10),
  21. 'ticketcategories' => TicketCategory::all(),
  22. 'locale_datatables' => $locale_settings->datatables
  23. ]);
  24. }
  25. public function show($ticket_id, PterodactylSettings $ptero_settings)
  26. {
  27. try {
  28. $ticket = Ticket::where('ticket_id', $ticket_id)->firstOrFail();
  29. } catch (Exception $e)
  30. {
  31. return redirect()->back()->with('warning', __('Ticket not found on the server. It potentially got deleted earlier'));
  32. }
  33. $ticketcomments = $ticket->ticketcomments;
  34. $ticketcategory = $ticket->ticketcategory;
  35. $server = Server::where('id', $ticket->server)->first();
  36. $pterodactyl_url = $ptero_settings->panel_url;
  37. return view('moderator.ticket.show', compact('ticket', 'ticketcategory', 'ticketcomments', 'server', 'pterodactyl_url'));
  38. }
  39. public function changeStatus($ticket_id)
  40. {
  41. try {
  42. $ticket = Ticket::where('ticket_id', $ticket_id)->firstOrFail();
  43. } catch(Exception $e)
  44. {
  45. return redirect()->back()->with('warning', __('Ticket not found on the server. It potentially got deleted earlier'));
  46. }
  47. if($ticket->status == "Closed"){
  48. $ticket->status = "Reopened";
  49. $ticket->save();
  50. return redirect()->back()->with('success', __('A ticket has been reopened, ID: #') . $ticket->ticket_id);
  51. }
  52. $ticket->status = 'Closed';
  53. $ticket->save();
  54. $ticketOwner = $ticket->user;
  55. return redirect()->back()->with('success', __('A ticket has been closed, ID: #').$ticket->ticket_id);
  56. }
  57. public function delete($ticket_id)
  58. {
  59. try {
  60. $ticket = Ticket::where('ticket_id', $ticket_id)->firstOrFail();
  61. } catch (Exception $e)
  62. {
  63. return redirect()->back()->with('warning', __('Ticket not found on the server. It potentially got deleted earlier'));
  64. }
  65. TicketComment::where('ticket_id', $ticket->id)->delete();
  66. $ticket->delete();
  67. return redirect()->back()->with('success', __('A ticket has been deleted, ID: #').$ticket_id);
  68. }
  69. public function reply(Request $request)
  70. {
  71. $this->validate($request, ['ticketcomment' => 'required']);
  72. try {
  73. $ticket = Ticket::where('id', $request->input('ticket_id'))->firstOrFail();
  74. } catch (Exception $e){
  75. return redirect()->back()->with('warning', __('Ticket not found on the server. It potentially got deleted earlier'));
  76. }
  77. $ticket->status = 'Answered';
  78. $ticket->update();
  79. TicketComment::create([
  80. 'ticket_id' => $request->input('ticket_id'),
  81. 'user_id' => Auth::user()->id,
  82. 'ticketcomment' => $request->input('ticketcomment'),
  83. ]);
  84. try {
  85. $user = User::where('id', $ticket->user_id)->firstOrFail();
  86. } catch(Exception $e)
  87. {
  88. return redirect()->back()->with('warning', __('User not found on the server. Check on the admin database or try again later.'));
  89. }
  90. $newmessage = $request->input('ticketcomment');
  91. $user->notify(new ReplyNotification($ticket, $user, $newmessage));
  92. return redirect()->back()->with('success', __('Your comment has been submitted'));
  93. }
  94. public function dataTable()
  95. {
  96. $query = Ticket::query();
  97. return datatables($query)
  98. ->addColumn('category', function (Ticket $tickets) {
  99. return $tickets->ticketcategory->name;
  100. })
  101. ->editColumn('title', function (Ticket $tickets) {
  102. return '<a class="text-info" href="'.route('moderator.ticket.show', ['ticket_id' => $tickets->ticket_id]).'">'.'#'.$tickets->ticket_id.' - '.htmlspecialchars($tickets->title).'</a>';
  103. })
  104. ->editColumn('user_id', function (Ticket $tickets) {
  105. return '<a href="'.route('admin.users.show', $tickets->user->id).'">'.$tickets->user->name.'</a>';
  106. })
  107. ->addColumn('actions', function (Ticket $tickets) {
  108. $statusButtonColor = ($tickets->status == "Closed") ? 'btn-success' : 'btn-warning';
  109. $statusButtonIcon = ($tickets->status == "Closed") ? 'fa-redo' : 'fa-times';
  110. $statusButtonText = ($tickets->status == "Closed") ? __('Reopen') : __('Close');
  111. return '
  112. <a data-content="'.__('View').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('moderator.ticket.show', ['ticket_id' => $tickets->ticket_id]).'" class="btn btn-sm text-white btn-info mr-1"><i class="fas fa-eye"></i></a>
  113. <form class="d-inline" method="post" action="'.route('moderator.ticket.changeStatus', ['ticket_id' => $tickets->ticket_id]).'">
  114. '.csrf_field().'
  115. '.method_field('POST').'
  116. <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>
  117. </form>
  118. <form class="d-inline" method="post" action="'.route('moderator.ticket.delete', ['ticket_id' => $tickets->ticket_id]).'">
  119. '.csrf_field().'
  120. '.method_field('POST').'
  121. <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm text-white btn-danger mr-1"><i class="fas fa-trash"></i></button>
  122. </form>
  123. ';
  124. })
  125. ->editColumn('status', function (Ticket $tickets) {
  126. switch ($tickets->status) {
  127. case 'Reopened':
  128. case 'Open':
  129. $badgeColor = 'badge-success';
  130. break;
  131. case 'Closed':
  132. $badgeColor = 'badge-danger';
  133. break;
  134. case 'Answered':
  135. $badgeColor = 'badge-info';
  136. break;
  137. default:
  138. $badgeColor = 'badge-warning';
  139. break;
  140. }
  141. return '<span class="badge '.$badgeColor.'">'.$tickets->status.'</span>';
  142. })
  143. ->editColumn('priority', function (Ticket $tickets) {
  144. return __($tickets->priority);
  145. })
  146. ->editColumn('updated_at', function (Ticket $tickets) {
  147. return ['display' => $tickets->updated_at ? $tickets->updated_at->diffForHumans() : '',
  148. 'raw' => $tickets->updated_at ? strtotime($tickets->updated_at) : ''];
  149. })
  150. ->rawColumns(['category', 'title', 'user_id', 'status', 'priority', 'updated_at', 'actions'])
  151. ->make(true);
  152. }
  153. public function blacklist(LocaleSettings $locale_settings)
  154. {
  155. return view('moderator.ticket.blacklist', [
  156. 'locale_datatables' => $locale_settings->datatables
  157. ]);
  158. }
  159. public function blacklistAdd(Request $request)
  160. {
  161. try {
  162. $user = User::where('id', $request->user_id)->firstOrFail();
  163. $check = TicketBlacklist::where('user_id', $user->id)->first();
  164. }
  165. catch (Exception $e){
  166. return redirect()->back()->with('warning', __('User not found on the server. Check the admin database or try again later.'));
  167. }
  168. if ($check) {
  169. $check->reason = $request->reason;
  170. $check->status = 'True';
  171. $check->save();
  172. return redirect()->back()->with('info', __('Target User already in blacklist. Reason updated'));
  173. }
  174. TicketBlacklist::create([
  175. 'user_id' => $user->id,
  176. 'status' => 'True',
  177. 'reason' => $request->reason,
  178. ]);
  179. return redirect()->back()->with('success', __('Successfully add User to blacklist, User name: '.$user->name));
  180. }
  181. public function blacklistDelete($id)
  182. {
  183. $blacklist = TicketBlacklist::where('id', $id)->first();
  184. $blacklist->delete();
  185. return redirect()->back()->with('success', __('Successfully remove User from blacklist, User name: '.$blacklist->user->name));
  186. }
  187. public function blacklistChange($id)
  188. {
  189. try {
  190. $blacklist = TicketBlacklist::where('id', $id)->first();
  191. }
  192. catch (Exception $e){
  193. return redirect()->back()->with('warning', __('User not found on the server. Check the admin database or try again later.'));
  194. }
  195. if ($blacklist->status == 'True') {
  196. $blacklist->status = 'False';
  197. } else {
  198. $blacklist->status = 'True';
  199. }
  200. $blacklist->update();
  201. return redirect()->back()->with('success', __('Successfully change status blacklist from, User name: '.$blacklist->user->name));
  202. }
  203. public function dataTableBlacklist()
  204. {
  205. $query = TicketBlacklist::with(['user']);
  206. $query->select('ticket_blacklists.*');
  207. return datatables($query)
  208. ->editColumn('user', function (TicketBlacklist $blacklist) {
  209. return '<a href="'.route('admin.users.show', $blacklist->user->id).'">'.$blacklist->user->name.'</a>';
  210. })
  211. ->editColumn('status', function (TicketBlacklist $blacklist) {
  212. switch ($blacklist->status) {
  213. case 'True':
  214. $text = 'Blocked';
  215. $badgeColor = 'badge-danger';
  216. break;
  217. default:
  218. $text = 'Unblocked';
  219. $badgeColor = 'badge-success';
  220. break;
  221. }
  222. return '<span class="badge '.$badgeColor.'">'.$text.'</span>';
  223. })
  224. ->editColumn('reason', function (TicketBlacklist $blacklist) {
  225. return $blacklist->reason;
  226. })
  227. ->addColumn('actions', function (TicketBlacklist $blacklist) {
  228. return '
  229. <form class="d-inline" method="post" action="'.route('moderator.ticket.blacklist.change', ['id' => $blacklist->id]).'">
  230. '.csrf_field().'
  231. '.method_field('POST').'
  232. <button data-content="'.__('Change Status').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm text-white btn-warning mr-1"><i class="fas fa-sync-alt"></i></button>
  233. </form>
  234. <form class="d-inline" method="post" action="'.route('moderator.ticket.blacklist.delete', ['id' => $blacklist->id]).'">
  235. '.csrf_field().'
  236. '.method_field('POST').'
  237. <button data-content="'.__('Delete').'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm text-white btn-danger mr-1"><i class="fas fa-trash"></i></button>
  238. </form>
  239. ';
  240. })
  241. ->editColumn('created_at', function (TicketBlacklist $blacklist) {
  242. return $blacklist->created_at ? $blacklist->created_at->diffForHumans() : '';
  243. })
  244. ->rawColumns(['user', 'status', 'reason', 'created_at', 'actions'])
  245. ->make(true);
  246. }
  247. }