Created
March 2, 2017 12:23
-
-
Save 1mursaleen/2cad127855e32f94bc21602d9a23b092 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http\Controllers; | |
use Illuminate\Http\Request; | |
use App\Http\Requests; | |
use Illuminate\Support\Facades\Auth; | |
use Illuminate\Support\Facades\File; | |
use Illuminate\Support\Facades\Storage; | |
use View; | |
use \DB as DB; | |
use App\Http\Requests\PostQuestion; | |
use App\Http\Requests\CallDibs; | |
use App\Http\Requests\AddNote; | |
use DateTime; | |
use Carbon\Carbon; | |
use App\Question as Question; | |
use App\Answer as Answer; | |
use App\User as User; | |
use App\Dib as Dib; | |
use App\Note as Note; | |
class QuestionsController extends Controller | |
{ | |
/** | |
* Display a listing of the resource. | |
* | |
* @return \Illuminate\Http\Response | |
*/ | |
public function index() | |
{ | |
$questions = Question::orderBy('id', 'desc')->paginate(20); | |
return view('questions.index', ['questions' => $questions]); | |
} | |
/** | |
* Show the form for creating a new resource. | |
* | |
* @return \Illuminate\Http\Response | |
*/ | |
public function create() | |
{ | |
return view('questions.post'); | |
} | |
/** | |
* Store a newly created resource in storage. | |
* | |
* @param \Illuminate\Http\Request $request | |
* @return \Illuminate\Http\Response | |
*/ | |
public function store(PostQuestion $request) | |
{ | |
// Check if the question already exists then create. | |
$question = Question::firstOrCreate([ | |
'user_id' => Auth::id(), | |
'username' => Auth::user()->username, | |
'title' => $request->input('title'), | |
'description' => $request->input('description'), | |
'subject' => $request->input('subject'), | |
'due_at' => $request->input('date'), | |
'price' => $request->input('price') | |
]); | |
// format URL | |
$title = $request->input('title'); | |
$title = preg_replace('/[^A-Za-z0-9\-\ ]/', '', $title); | |
$title = str_slug($title, '-'); | |
// create URL | |
$question->url = 'question' . '-' . $title . '-' . 'hb' . uniqid(); | |
$question->save(); | |
// Increment User's Question_posted record. | |
$user = Auth::user(); | |
$user->questions_posted = ++$user->questions_posted; | |
// Try to save user else revert storeQuetion and abort. | |
try { | |
$user->save(); | |
} catch (Exception $e) { | |
$question->forceDelete(); | |
return response()->json(["error" => "Internal server error, Contact support."], 500); | |
} | |
// Get Files | |
$files = request()->file(); | |
// List of malicious extensions that should not be accepted. | |
$malicious_extensions = array('exe', 'pif', 'application', 'gadget', 'msi', 'msp', 'com', 'scr', 'hta', 'cpl', 'msc', 'jar', 'bat', 'cmd', 'vb', 'vbs', 'vbe', 'js', 'jse', 'ws', 'wsf', 'wsc', 'wsh', 'ps1', 'ps1xml', 'ps2', 'ps2xml', 'psc1', 'psc2', 'msh', 'msh1', 'msh2', 'mshxml', 'msh1xml', 'msh2xml', 'scf', 'lnk', 'inf', 'reg'); | |
// foreach file: sanitize filename, store on disk, insert database record. | |
foreach($files as $file) | |
{ | |
// check: is successfully uploded && is acceptable size && is not malicious | |
if ($file->isValid() | |
&& (filesize($file) < 26000000) | |
&& ! in_array($file->extension(), $malicious_extensions)) | |
{ | |
try | |
{ | |
// Get original file name + extension. | |
$original_name_ext = $file->getClientOriginalName(); | |
// Get only original name | |
$original_name = pathinfo($original_name_ext, PATHINFO_FILENAME); | |
// Trim special characters and whitespaces from the beginning and end of the string | |
$trimmed_name = trim($original_name); | |
// Remove all whitespaces | |
$continuous_name = preg_replace('/\s+/', '_', $trimmed_name); | |
// Remove all special characters | |
$clean_name = preg_replace('/[^A-Za-z0-9\_]/', '', $continuous_name); | |
// Get substring of name if strlen > 150 | |
$substr_name = substr($clean_name,0,150); | |
// Name: add uniqueID and guessed Extension. | |
$extension = $file->extension(); if(!$extension){$extension = 'txt';} | |
$filename = $substr_name . '_hb' . uniqid() . '.' . $extension; | |
// return File::mimeType($file); | |
// Store file | |
$file->storeAs('Question_Files/question_id_'.$question->id, $filename); | |
// Database entry (Table: question_files) | |
DB::table('question_files')->insert([ | |
'user_id' => $user->id, | |
'question_id' => $question->id, | |
'filename' => $filename | |
]); | |
} | |
catch (Exception $e) | |
{ | |
return $this->revertStore($question); | |
} | |
} | |
} | |
} | |
public function revertStore(Question $question) | |
{ | |
// Decrement back User's Question_posted record. | |
$user = Auth::user(); | |
$user->questions_posted = --$user->questions_posted; | |
$user->save(); | |
// Revert Question. | |
$question->forceDelete(); | |
// Delete Question directory from Question_Files directory. | |
$directory = 'Question_Files/question_id_' . $question->id; | |
Storage::deleteDirectory($directory); | |
return response()->json(["error" => "There was a problem with the files, See FAQ for Files."], 403); | |
} | |
/** | |
* Display the specified Question. | |
* | |
* @param string $url | |
* @return \Illuminate\Http\Response | |
*/ | |
public function show($url) | |
{ | |
// Get questions, including withdrawn_Questions | |
$question = Question::withTrashed()->where('url', $url)->firstOrFail(); | |
// Normal Behaviour | |
if (!$question->trashed()) | |
{ | |
// Determine whether this user has already called dib. | |
$user_has_called_dib = Dib::where('question_id', $question->id)->where('user_id', Auth::id())->first(); | |
// Get relevant dibs | |
$dibs = Dib::where('question_id', $question->id)->whereNotIn('status', [1])->get(); | |
// Set $accepted_dib to null by default | |
$accepted_dib = NULL; | |
// Set submitted_answer to null by default. | |
$submitted_answer = NULL; | |
// Check: if question_status is 'pending'. | |
if ($question->status != 0) { | |
// Get accepted dib. | |
$accepted_dib = Dib::where('question_id', $question->id)->where('status', 1)->first(); | |
} | |
// Check: if question_status is 'answer_submitted'. | |
if ($question->status == 2) { | |
// Get submitted answer. | |
$submitted_answer = Answer::where('answerable_id', $question->id) | |
->where('answerable_type', 'App\Question')->first(); | |
} | |
// Get relevant files. | |
$files = DB::table('question_files')->where('question_id', $question->id)->get(); | |
return view('questions.view', [ | |
'question' => $question, | |
'dibs' => $dibs, | |
// Get relevant notes. | |
'notes' => $question->notes, | |
'files' => $files, | |
// Get relevant answers. | |
'answers' => $question->answers, | |
'user_has_called_dib' => $user_has_called_dib, | |
'accepted_dib' => $accepted_dib, | |
'submitted_answer' => $submitted_answer, | |
'display' => "" | |
]); | |
} | |
// Owner's Withdrawn/softDeleted Question | |
elseif ($question->trashed() && Auth::id() == $question->user_id) | |
{ | |
// Loading relevant notes | |
$notes = $question->notes; | |
// Loading relevant Dibs | |
$dibs = Dib::where('question_id', $question->id)->get(); | |
return view('questions.withdrawn', ['question' => $question, 'dibs' => $dibs, 'notes' => $notes]); | |
} | |
// Question not found or User ain't the Owner | |
else | |
{ | |
abort(404); | |
} | |
} | |
/** | |
* Show the form for editing the specified resource. | |
* | |
* @param int $id | |
* @return \Illuminate\Http\Response | |
*/ | |
public function edit($id) | |
{ | |
// | |
} | |
/** | |
* Update the specified resource in storage. | |
* | |
* @param \Illuminate\Http\Request $request | |
* @param int $id | |
* @return \Illuminate\Http\Response | |
*/ | |
public function update(Request $request, $id) | |
{ | |
// | |
} | |
/** | |
* Remove the specified resource from storage. | |
* | |
* @param int $id | |
* @return \Illuminate\Http\Response | |
*/ | |
public function destroy($id) | |
{ | |
// | |
} | |
/** | |
* softDelete question. | |
* | |
* @param int $id | |
* @return \Illuminate\Http\Response | |
*/ | |
public function withdraw($url) | |
{ | |
// Get questions: including withdrawn_questions. | |
$question = Question::withTrashed()->where('url', $url)->firstOrFail(); | |
// Fail safe: if question already withdrawn then show withdrawn_question. | |
if ($question->trashed()) | |
{ | |
return $this->show($url); | |
} | |
// Check if this user is the Owner, and question_status is 'open'. | |
if (Auth::id() == $question->user_id && $question->status == 0) | |
{ | |
$question->status = 4; // Update question status to withdrawn. | |
$question->save(); // ^ | |
$question->delete(); // Soft_delete question. | |
$user = Auth::user(); | |
$user->questions_posted = --$user->questions_posted; | |
$user->save(); | |
} | |
else { | |
abort(403, 'Unauthorized'); | |
} | |
return $this->show($url); // Show soft_deleted question. | |
} | |
/** | |
* Add note for the relevant Question. | |
* | |
* @param string $url | |
* @return \Illuminate\Http\Response | |
*/ | |
public function addNote(AddNote $request, $url) | |
{ | |
// Get Question | |
$question = Question::where('url', $url)->firstOrFail(); | |
// Check if this user is the Owner of the Question. | |
if (Auth::id() != $question->user_id){ | |
abort(403, "Unauthorized Action!"); | |
} | |
// Search for duplicate notes. | |
$note_duplicate_check = Note::where('notable_id', $question->id) | |
->where('body', $request->body) | |
->where('notable_type',"App\Question") | |
->first(); | |
// Show error for duplicate note. | |
if ($note_duplicate_check){ | |
return view('errors.note-duplicate'); | |
} | |
// Get Notes count | |
$note_count_check = Note::where('notable_id', $question->id)->count(); | |
// One question cannot have more than 20 notes, show error if limit reached. | |
if ($note_count_check >= 20) { | |
return view('errors.note-maximum'); | |
} | |
// Normal behavior: save and return an instance of the note to viewNote | |
elseif(! $note_duplicate_check && $note_count_check < 20){ | |
$note = new Note; | |
$note->body = $request->body; | |
$note->created_at = Carbon::now(); | |
$note->notable_id = $question->id; | |
$note->notable_type = "App\Question"; | |
$note->save(); | |
return view('notes.note',['note' => $note]); | |
} | |
} | |
/** | |
* Store a newly created resource in storage. | |
* | |
* @param \Illuminate\Http\Request $request | |
* @return \Illuminate\Http\Response | |
*/ | |
/* public function store(PostQuestion $request) | |
{ | |
$question = new Question; | |
$question->title = $request->input('title'); | |
$question->description = $request->input('description'); | |
$question->subject = $request->input('subject'); | |
$question->due_at = $request->input('date'); | |
$question->price = $request->input('price'); | |
$question->user_id = Auth::id(); | |
$question->username = User::find(Auth::id())->username; | |
$title = $request->input('title'); | |
$title = preg_replace('/[^A-Za-z0-9\-\ ]/', '', $title); | |
$title = str_slug($title, '-'); | |
$question->url = 'question' . '-' . $title . '-' . 'hb' . uniqid(); | |
$question->save(); | |
} | |
*/ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment