davide-casiraghi /
laravel-events-calendar
| 1 | <?php |
||||
| 2 | |||||
| 3 | namespace DavideCasiraghi\LaravelEventsCalendar\Http\Controllers; |
||||
| 4 | |||||
| 5 | use Carbon\Carbon; |
||||
| 6 | use DavideCasiraghi\LaravelEventsCalendar\Models\Country; |
||||
| 7 | use DavideCasiraghi\LaravelEventsCalendar\Models\Event; |
||||
| 8 | use DavideCasiraghi\LaravelEventsCalendar\Models\EventCategory; |
||||
| 9 | use DavideCasiraghi\LaravelEventsCalendar\Models\EventRepetition; |
||||
| 10 | use DavideCasiraghi\LaravelEventsCalendar\Models\Teacher; |
||||
| 11 | use Illuminate\Foundation\Auth\User; |
||||
| 12 | use Illuminate\Http\Request; |
||||
| 13 | use Illuminate\Support\Facades\Cache; |
||||
| 14 | use Illuminate\Support\Facades\DB; |
||||
| 15 | use Illuminate\Support\Facades\Route; |
||||
| 16 | use Validator; |
||||
| 17 | |||||
| 18 | class TeacherController extends Controller |
||||
| 19 | { |
||||
| 20 | /* Restrict the access to this resource just to logged in users except show and index view */ |
||||
| 21 | 17 | public function __construct() |
|||
| 22 | { |
||||
| 23 | 17 | $this->middleware('auth', ['except' => ['index', 'show', 'teacherBySlug']]); |
|||
| 24 | 17 | } |
|||
| 25 | |||||
| 26 | /***************************************************************************/ |
||||
| 27 | |||||
| 28 | /** |
||||
| 29 | * Display a listing of the resource. |
||||
| 30 | * |
||||
| 31 | * @return \Illuminate\View\View |
||||
| 32 | */ |
||||
| 33 | 3 | public function index(Request $request) |
|||
| 34 | { |
||||
| 35 | //$countries = Country::orderBy('countries.name')->pluck('name', 'id'); |
||||
| 36 | |||||
| 37 | 3 | $countries = Country::getCountriesWithTeachers(); |
|||
| 38 | |||||
| 39 | // Get the countries with active teachers - BUG! IF I CACHE JUST A PART OF THE COUNTRIES WHEN I INSERT A NEW TEACHER WITH A COUNTRY THAT IS NOT IN THE CACHE I GET AN ERROR WHEN I'M BACK TO THE INDEX (eg.no index error) |
||||
| 40 | /* $cacheExpireTime = 900; // Set the duration time of the cache (15 min - 900sec) |
||||
| 41 | $countries = Cache::remember('teachers_countries', cacheExpireTime, function () { |
||||
| 42 | return DB::table('countries') |
||||
| 43 | ->join('teachers', 'countries.id', '=', 'teachers.country_id') |
||||
| 44 | ->orderBy('countries.name') |
||||
| 45 | ->pluck('countries.name', 'countries.id'); |
||||
| 46 | });*/ |
||||
| 47 | |||||
| 48 | // Search keywords |
||||
| 49 | 3 | $searchKeywords = $request->input('keywords'); |
|||
| 50 | 3 | $searchCountry = $request->input('country_id'); |
|||
| 51 | |||||
| 52 | // To show just the teachers created by the the user - If admin or super admin is set to null show all the teachers |
||||
| 53 | 3 | $authorUserId = ($this->getLoggedAuthorId()) ? $this->getLoggedAuthorId() : null; // if is 0 (super admin or admin) it's setted to null to avoid include it in the query |
|||
| 54 | |||||
| 55 | // To retrieve all the teachers when the route is teacher.directory, we set the logged user id to null |
||||
| 56 | 3 | if (Route::currentRouteName() == 'teachers.directory') { |
|||
| 57 | 1 | $authorUserId = null; |
|||
| 58 | } |
||||
| 59 | |||||
| 60 | 3 | if ($searchKeywords || $searchCountry) { |
|||
| 61 | 1 | $teachers = DB::table('teachers') |
|||
| 62 | ->when($authorUserId, function ($query, $authorUserId) { |
||||
| 63 | return $query->where('created_by', $authorUserId); |
||||
| 64 | 1 | }) |
|||
| 65 | ->when($searchKeywords, function ($query, $searchKeywords) { |
||||
| 66 | 1 | return $query->where('name', $searchKeywords)->orWhere('name', 'like', '%'.$searchKeywords.'%'); |
|||
| 67 | 1 | }) |
|||
| 68 | ->when($searchCountry, function ($query, $searchCountry) { |
||||
| 69 | return $query->where('country_id', '=', $searchCountry); |
||||
| 70 | 1 | }) |
|||
| 71 | 1 | ->orderBy('name') |
|||
| 72 | 1 | ->paginate(20); |
|||
| 73 | } else { |
||||
| 74 | $teachers = Teacher:: |
||||
| 75 | when($authorUserId, function ($query, $authorUserId) { |
||||
| 76 | return $query->where('created_by', $authorUserId); |
||||
| 77 | 2 | }) |
|||
| 78 | 2 | ->orderBy('name') |
|||
| 79 | 2 | ->paginate(20); |
|||
| 80 | } |
||||
| 81 | |||||
| 82 | //return view('teachers.index', compact('teachers')) |
||||
| 83 | 3 | return view('laravel-events-calendar::teachers.index', compact('teachers')) |
|||
| 84 | //return view('laravel-events-calendar::teachers.index') |
||||
| 85 | 3 | ->with('i', (request()->input('page', 1) - 1) * 20) |
|||
| 86 | 3 | ->with('countries', $countries) |
|||
| 87 | 3 | ->with('searchKeywords', $searchKeywords) |
|||
| 88 | 3 | ->with('searchCountry', $searchCountry) |
|||
| 89 | 3 | ->with('loggedUser', $authorUserId); |
|||
| 90 | } |
||||
| 91 | |||||
| 92 | /***************************************************************************/ |
||||
| 93 | |||||
| 94 | /** |
||||
| 95 | * Show the form for creating a new resource. |
||||
| 96 | * |
||||
| 97 | * @return \Illuminate\View\View |
||||
| 98 | */ |
||||
| 99 | 1 | public function create() |
|||
| 100 | { |
||||
| 101 | 1 | $countries = Country::getCountries(); |
|||
| 102 | 1 | $users = User::pluck('name', 'id'); |
|||
| 103 | 1 | $authorUserId = $this->getLoggedAuthorId(); |
|||
| 104 | |||||
| 105 | 1 | return view('laravel-events-calendar::teachers.create') |
|||
| 106 | 1 | ->with('countries', $countries) |
|||
| 107 | 1 | ->with('users', $users) |
|||
| 108 | 1 | ->with('authorUserId', $authorUserId); |
|||
| 109 | } |
||||
| 110 | |||||
| 111 | /***************************************************************************/ |
||||
| 112 | |||||
| 113 | /** |
||||
| 114 | * Store a newly created resource in storage. |
||||
| 115 | * |
||||
| 116 | * @param \Illuminate\Http\Request $request |
||||
| 117 | * @return \Illuminate\Http\RedirectResponse |
||||
| 118 | */ |
||||
| 119 | 3 | public function store(Request $request) |
|||
| 120 | { |
||||
| 121 | // Validate form datas |
||||
| 122 | 3 | $validator = $this->teachersValidator($request); |
|||
| 123 | 3 | if ($validator->fails()) { |
|||
| 124 | 1 | return back()->withErrors($validator)->withInput(); |
|||
| 125 | } |
||||
| 126 | |||||
| 127 | 2 | $teacher = new Teacher(); |
|||
| 128 | 2 | $teacher->preSave($request->all(), $request->file('profile_picture')); |
|||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
| 129 | 2 | $teacher->save(); |
|||
| 130 | |||||
| 131 | 2 | return redirect()->route('teachers.index') |
|||
| 132 | 2 | ->with('success', __('laravel-events-calendar::messages.teacher_added_successfully')); |
|||
| 133 | } |
||||
| 134 | |||||
| 135 | /***************************************************************************/ |
||||
| 136 | |||||
| 137 | /** |
||||
| 138 | * Display the specified resource. |
||||
| 139 | * |
||||
| 140 | * @param \DavideCasiraghi\LaravelEventsCalendar\Models\Teacher $teacher |
||||
| 141 | * @return \Illuminate\View\View |
||||
| 142 | */ |
||||
| 143 | 3 | public function show(Teacher $teacher) |
|||
| 144 | { |
||||
| 145 | // Get the name of the teacher's country |
||||
| 146 | 3 | $country = Country::select('name') |
|||
| 147 | 3 | ->where('id', $teacher->country_id) |
|||
| 148 | 3 | ->first(); |
|||
| 149 | |||||
| 150 | 3 | $cacheExpireTime = 900; // Set the duration time of the cache (15 min - 900sec) |
|||
| 151 | $eventCategories = Cache::remember('categories', $cacheExpireTime, function () { |
||||
| 152 | //return EventCategory::orderBy('name')->pluck('name', 'id'); |
||||
| 153 | 3 | return EventCategory::listsTranslations('name')->pluck('name', 'id'); |
|||
| 154 | 3 | }); |
|||
| 155 | |||||
| 156 | // Get for each event the first event repetition in the near future (JUST THE QUERY) |
||||
| 157 | 3 | date_default_timezone_set('Europe/Rome'); |
|||
| 158 | 3 | $searchStartDate = date('Y-m-d', time()); // search start from today's date |
|||
| 159 | 3 | $lastestEventsRepetitionsQuery = EventRepetition::getLastestEventsRepetitionsQuery($searchStartDate, null); |
|||
| 160 | |||||
| 161 | // Get the events where this teacher is teaching to |
||||
| 162 | //DB::enableQueryLog(); |
||||
| 163 | 3 | $eventsTeacherWillTeach = Teacher::eventsByTeacher($teacher, $lastestEventsRepetitionsQuery); |
|||
| 164 | |||||
| 165 | //dd(DB::getQueryLog()); |
||||
| 166 | |||||
| 167 | 3 | return view('laravel-events-calendar::teachers.show', compact('teacher')) |
|||
| 168 | 3 | ->with('country', $country) |
|||
| 169 | 3 | ->with('eventCategories', $eventCategories) |
|||
| 170 | 3 | ->with('eventsTeacherWillTeach', $eventsTeacherWillTeach); |
|||
| 171 | } |
||||
| 172 | |||||
| 173 | /** |
||||
| 174 | * Show the form for editing the specified resource. |
||||
| 175 | * |
||||
| 176 | * @param \DavideCasiraghi\LaravelEventsCalendar\Models\Teacher $teacher |
||||
| 177 | * @return \Illuminate\View\View |
||||
| 178 | */ |
||||
| 179 | 1 | public function edit(Teacher $teacher) |
|||
| 180 | { |
||||
| 181 | 1 | $authorUserId = $this->getLoggedAuthorId(); |
|||
| 182 | 1 | $users = User::pluck('name', 'id'); |
|||
| 183 | 1 | $countries = Country::getCountries(); |
|||
| 184 | |||||
| 185 | 1 | return view('laravel-events-calendar::teachers.edit', compact('teacher')) |
|||
| 186 | 1 | ->with('countries', $countries) |
|||
| 187 | 1 | ->with('users', $users) |
|||
| 188 | 1 | ->with('authorUserId', $authorUserId); |
|||
| 189 | } |
||||
| 190 | |||||
| 191 | /***************************************************************************/ |
||||
| 192 | |||||
| 193 | /** |
||||
| 194 | * Update the specified resource in storage. |
||||
| 195 | * |
||||
| 196 | * @param \Illuminate\Http\Request $request |
||||
| 197 | * @param \DavideCasiraghi\LaravelEventsCalendar\Models\Teacher $teacher |
||||
| 198 | * @return \Illuminate\Http\RedirectResponse |
||||
| 199 | */ |
||||
| 200 | 2 | public function update(Request $request, Teacher $teacher) |
|||
| 201 | { |
||||
| 202 | // Validate form datas |
||||
| 203 | 2 | $validator = $this->teachersValidator($request); |
|||
| 204 | //dd($validator->errors()); |
||||
| 205 | 2 | if ($validator->fails()) { |
|||
| 206 | 1 | return back()->withErrors($validator)->withInput(); |
|||
| 207 | } |
||||
| 208 | |||||
| 209 | 1 | $teacher->preSave($request->all(), $request->file('profile_picture')); |
|||
|
0 ignored issues
–
show
It seems like
$request->file('profile_picture') can also be of type Illuminate\Http\UploadedFile[] and array; however, parameter $profilePicture of DavideCasiraghi\LaravelE...dels\Teacher::preSave() does only seem to accept Illuminate\Http\UploadedFile, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 210 | 1 | $teacher->save(); |
|||
| 211 | |||||
| 212 | 1 | return redirect()->route('teachers.index') |
|||
| 213 | 1 | ->with('success', __('laravel-events-calendar::messages.teacher_updated_successfully')); |
|||
| 214 | } |
||||
| 215 | |||||
| 216 | /***************************************************************************/ |
||||
| 217 | |||||
| 218 | /** |
||||
| 219 | * Remove the specified resource from storage. |
||||
| 220 | * |
||||
| 221 | * @param \DavideCasiraghi\LaravelEventsCalendar\Models\Teacher $teacher |
||||
| 222 | * @return \Illuminate\Http\RedirectResponse |
||||
| 223 | */ |
||||
| 224 | 1 | public function destroy(Teacher $teacher) |
|||
| 225 | { |
||||
| 226 | 1 | $teacher->delete(); |
|||
| 227 | |||||
| 228 | 1 | return redirect()->route('teachers.index') |
|||
| 229 | 1 | ->with('success', __('laravel-events-calendar::messages.teacher_deleted_successfully')); |
|||
| 230 | } |
||||
| 231 | |||||
| 232 | /***************************************************************************/ |
||||
| 233 | |||||
| 234 | /** |
||||
| 235 | * Open a modal in the event view when 'create new teacher' button is clicked. |
||||
| 236 | * |
||||
| 237 | * @return \Illuminate\View\View |
||||
| 238 | */ |
||||
| 239 | 1 | public function modal() |
|||
| 240 | { |
||||
| 241 | 1 | $countries = Country::getCountries(); |
|||
| 242 | 1 | $users = User::pluck('name', 'id'); |
|||
| 243 | |||||
| 244 | 1 | return view('laravel-events-calendar::teachers.modal') |
|||
| 245 | 1 | ->with('countries', $countries) |
|||
| 246 | 1 | ->with('users', $users); |
|||
| 247 | } |
||||
| 248 | |||||
| 249 | /***************************************************************************/ |
||||
| 250 | |||||
| 251 | /** |
||||
| 252 | * Store a newly created teacher from the create event view modal in storage. |
||||
| 253 | * |
||||
| 254 | * @param \Illuminate\Http\Request $request |
||||
| 255 | * @return \Illuminate\Http\JsonResponse |
||||
| 256 | */ |
||||
| 257 | 1 | public function storeFromModal(Request $request) |
|||
| 258 | { |
||||
| 259 | 1 | $teacher = new Teacher(); |
|||
| 260 | 1 | $teacher->preSave($request->all(), $request->file('profile_picture')); |
|||
|
0 ignored issues
–
show
It seems like
$request->file('profile_picture') can also be of type Illuminate\Http\UploadedFile[] and array; however, parameter $profilePicture of DavideCasiraghi\LaravelE...dels\Teacher::preSave() does only seem to accept Illuminate\Http\UploadedFile, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 261 | 1 | $teacher->save(); |
|||
| 262 | |||||
| 263 | 1 | return response()->json([ |
|||
| 264 | 1 | 'teacherId' => $teacher->id, |
|||
| 265 | 1 | 'teacherName' => $teacher->name, |
|||
| 266 | ]); |
||||
| 267 | } |
||||
| 268 | |||||
| 269 | /***************************************************************************/ |
||||
| 270 | |||||
| 271 | /** |
||||
| 272 | * Return the teacher by SLUG. (eg. http://websitename.com/teacher/xxxx). |
||||
| 273 | * |
||||
| 274 | * @param string $slug |
||||
| 275 | * @return \Illuminate\View\View |
||||
| 276 | */ |
||||
| 277 | 1 | public function teacherBySlug($slug) |
|||
| 278 | { |
||||
| 279 | 1 | $teacher = Teacher::where('slug', $slug)->first(); |
|||
| 280 | |||||
| 281 | 1 | if (is_null($teacher)) { |
|||
| 282 | abort(404); |
||||
| 283 | } |
||||
| 284 | |||||
| 285 | 1 | return $this->show($teacher); |
|||
| 286 | } |
||||
| 287 | |||||
| 288 | /***************************************************************************/ |
||||
| 289 | |||||
| 290 | /** |
||||
| 291 | * Return the validator with all the defined constraint. |
||||
| 292 | * |
||||
| 293 | * @param \Illuminate\Http\Request $request |
||||
| 294 | * @return \Illuminate\Contracts\Validation\Validator |
||||
| 295 | */ |
||||
| 296 | 5 | public function teachersValidator(Request $request) |
|||
| 297 | { |
||||
| 298 | 5 | $maxYear = Carbon::now()->year; |
|||
| 299 | |||||
| 300 | $rules = [ |
||||
| 301 | 5 | 'name' => 'required', |
|||
| 302 | 5 | 'year_starting_practice' => 'required|integer|min:1972|max:'.($maxYear), |
|||
| 303 | 5 | 'year_starting_teach' => 'required|integer|min:1972|max:'.($maxYear), |
|||
| 304 | 5 | 'facebook' => 'nullable|url', |
|||
| 305 | 5 | 'website' => 'nullable|url', |
|||
| 306 | // 'profile_picture' => 'nullable|image|mimes:jpeg,jpg,png|max:3000', // BUG create problems to validate on edit. Fix this after the rollout |
||||
| 307 | // 'required_with:end_page|integer|min:1|digits_between: 1,5', // https://stackoverflow.com/questions/32036882/laravel-validate-an-integer-field-that-needs-to-be-greater-than-another |
||||
| 308 | ]; |
||||
| 309 | 5 | if ($request->hasFile('profile_picture')) { |
|||
| 310 | $rules['profile_picture'] = 'nullable|image|mimes:jpeg,jpg,png|max:5000'; |
||||
| 311 | } |
||||
| 312 | $messages = [ |
||||
| 313 | 5 | 'facebook.url' => 'The facebook link is invalid. It should start with https://', |
|||
| 314 | 'website.url' => 'The website link is invalid. It should start with https://', |
||||
| 315 | 'profile_picture.max' => 'The maximum image size is 5MB. If you need to resize it you can use: www.simpleimageresizer.com', |
||||
| 316 | ]; |
||||
| 317 | |||||
| 318 | 5 | $validator = Validator::make($request->all(), $rules, $messages); |
|||
| 319 | |||||
| 320 | 5 | return $validator; |
|||
| 321 | } |
||||
| 322 | } |
||||
| 323 |