Completed
Push — master ( 8f387d...47c518 )
by Davide
12:19
created

TeacherController   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 347
Duplicated Lines 0 %

Test Coverage

Coverage 91.67%

Importance

Changes 11
Bugs 2 Features 2
Metric Value
wmc 22
eloc 127
c 11
b 2
f 2
dl 0
loc 347
ccs 121
cts 132
cp 0.9167
rs 10

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A show() 0 28 1
A edit() 0 10 1
A create() 0 10 1
A destroy() 0 6 1
A saveOnDb() 0 37 3
A update() 0 13 2
A store() 0 13 2
A index() 0 57 5
A teacherBySlug() 0 7 1
A storeFromModal() 0 10 1
A modal() 0 8 1
A teachersValidator() 0 25 2
1
<?php
2
3
namespace DavideCasiraghi\LaravelEventsCalendar\Http\Controllers;
4
5
use Validator;
6
use Carbon\Carbon;
7
use Illuminate\Support\Str;
8
use Illuminate\Http\Request;
9
use Illuminate\Support\Facades\DB;
10
use Illuminate\Foundation\Auth\User;
11
use Illuminate\Support\Facades\Auth;
12
use Illuminate\Support\Facades\Cache;
13
use Illuminate\Support\Facades\Route;
14
use DavideCasiraghi\LaravelEventsCalendar\Models\Event;
15
use DavideCasiraghi\LaravelEventsCalendar\Models\Country;
16
use DavideCasiraghi\LaravelEventsCalendar\Models\Teacher;
17
use DavideCasiraghi\LaravelEventsCalendar\Models\EventCategory;
18
use DavideCasiraghi\LaravelEventsCalendar\Models\EventRepetition;
19
20
class TeacherController extends Controller
21
{
22
    /* Restrict the access to this resource just to logged in users except show and index view */
23 15
    public function __construct()
24
    {
25 15
        $this->middleware('auth', ['except' => ['index', 'show', 'teacherBySlug']]);
26 15
    }
27
28
    /***************************************************************************/
29
30
    /**
31
     * Display a listing of the resource.
32
     *
33
     * @return \Illuminate\Http\Response
34
     */
35 3
    public function index(Request $request)
36
    {
37
        //$countries = Country::orderBy('countries.name')->pluck('name', 'id');
38
39 3
        $countries = Country::getCountriesWithTeachers();
40
41
        // 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)
42
        /*    $cacheExpireTime = 900; // Set the duration time of the cache (15 min - 900sec)
43
            $countries = Cache::remember('teachers_countries', cacheExpireTime, function () {
44
                return DB::table('countries')
45
                    ->join('teachers', 'countries.id', '=', 'teachers.country_id')
46
                    ->orderBy('countries.name')
47
                    ->pluck('countries.name', 'countries.id');
48
            });*/
49
50
        // Search keywords
51 3
        $searchKeywords = $request->input('keywords');
52 3
        $searchCountry = $request->input('country_id');
53
54
        // To show just the teachers created by the the user - If admin or super admin is set to null show all the teachers
55 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
56
57
        // To retrieve all the teachers when the route is teacher.directory, we set the logged user id to null
58 3
        if (Route::currentRouteName() == 'teachers.directory') {
59 1
            $authorUserId = null;
60
        }
61
62 3
        if ($searchKeywords || $searchCountry) {
63 1
            $teachers = DB::table('teachers')
64
                ->when($authorUserId, function ($query, $authorUserId) {
65
                    return $query->where('created_by', $authorUserId);
66 1
                })
67
                ->when($searchKeywords, function ($query, $searchKeywords) {
68 1
                    return $query->where('name', $searchKeywords)->orWhere('name', 'like', '%'.$searchKeywords.'%');
69 1
                })
70
                ->when($searchCountry, function ($query, $searchCountry) {
71
                    return $query->where('country_id', '=', $searchCountry);
72 1
                })
73 1
                ->orderBy('name')
74 1
                ->paginate(20);
75
        } else {
76
            $teachers = Teacher::
77
            when($authorUserId, function ($query, $authorUserId) {
78
                return $query->where('created_by', $authorUserId);
79 2
            })
80 2
            ->orderBy('name')
81 2
            ->paginate(20);
82
        }
83
84
        //return view('teachers.index', compact('teachers'))
85 3
        return view('laravel-events-calendar::teachers.index', compact('teachers'))
86
        //return view('laravel-events-calendar::teachers.index')
87 3
            ->with('i', (request()->input('page', 1) - 1) * 20)
88 3
            ->with('countries', $countries)
89 3
            ->with('searchKeywords', $searchKeywords)
90 3
            ->with('searchCountry', $searchCountry)
91 3
            ->with('loggedUser', $authorUserId);
92
    }
93
94
    /***************************************************************************/
95
96
    /**
97
     * Show the form for creating a new resource.
98
     *
99
     * @return \Illuminate\Http\Response
100
     */
101 1
    public function create()
102
    {
103 1
        $countries = Country::getCountries();
104 1
        $users = User::pluck('name', 'id');
105 1
        $authorUserId = $this->getLoggedAuthorId();
106
107 1
        return view('laravel-events-calendar::teachers.create')
108 1
            ->with('countries', $countries)
109 1
            ->with('users', $users)
110 1
            ->with('authorUserId', $authorUserId);
111
    }
112
113
    /***************************************************************************/
114
115
    /**
116
     * Store a newly created resource in storage.
117
     *
118
     * @param  \Illuminate\Http\Request  $request
119
     * @return \Illuminate\Http\Response
120
     */
121 2
    public function store(Request $request)
122
    {
123
        // Validate form datas
124 2
        $validator = $this->teachersValidator($request);
125 2
        if ($validator->fails()) {
126 1
            return back()->withErrors($validator)->withInput();
127
        }
128
129 1
        $teacher = new Teacher();
130 1
        $this->saveOnDb($request, $teacher);
131
132 1
        return redirect()->route('teachers.index')
133 1
                        ->with('success', __('laravel-events-calendar::messages.teacher_added_successfully'));
134
    }
135
136
    /***************************************************************************/
137
138
    /**
139
     * Display the specified resource.
140
     *
141
     * @param  \DavideCasiraghi\LaravelEventsCalendar\Models\Teacher  $teacher
142
     * @return \Illuminate\Http\Response
143
     */
144 3
    public function show(Teacher $teacher)
145
    {
146
        // Get the name of the teacher's country
147 3
        $country = Country::select('name')
148 3
            ->where('id', $teacher->country_id)
149 3
            ->first();
150
151 3
        $cacheExpireTime = 900; // Set the duration time of the cache (15 min - 900sec)
152
        $eventCategories = Cache::remember('categories', $cacheExpireTime, function () {
153
            //return EventCategory::orderBy('name')->pluck('name', 'id');
154 3
            return EventCategory::listsTranslations('name')->pluck('name', 'id');
155 3
        });
156
157
        // Get for each event the first event repetition in the near future (JUST THE QUERY)
158 3
        date_default_timezone_set('Europe/Rome');
159 3
        $searchStartDate = date('Y-m-d', time()); // search start from today's date
160 3
        $lastestEventsRepetitionsQuery = EventRepetition::getLastestEventsRepetitionsQuery($searchStartDate, null);
161
162
        // Get the events where this teacher is teaching to
163
        //DB::enableQueryLog();
164 3
        $eventsTeacherWillTeach = Teacher::eventsByTeacher($teacher, $lastestEventsRepetitionsQuery);
165
166
        //dd(DB::getQueryLog());
167
168 3
        return view('laravel-events-calendar::teachers.show', compact('teacher'))
169 3
            ->with('country', $country)
170 3
            ->with('eventCategories', $eventCategories)
171 3
            ->with('eventsTeacherWillTeach', $eventsTeacherWillTeach);
172
    }
173
174
    /**
175
     * Show the form for editing the specified resource.
176
     *
177
     * @param  \DavideCasiraghi\LaravelEventsCalendar\Models\Teacher  $teacher
178
     * @return \Illuminate\Http\Response
179
     */
180 1
    public function edit(Teacher $teacher)
181
    {
182 1
        $authorUserId = $this->getLoggedAuthorId();
183 1
        $users = User::pluck('name', 'id');
184 1
        $countries = Country::getCountries();
185
186 1
        return view('laravel-events-calendar::teachers.edit', compact('teacher'))
187 1
            ->with('countries', $countries)
188 1
            ->with('users', $users)
189 1
            ->with('authorUserId', $authorUserId);
190
    }
191
192
    /***************************************************************************/
193
194
    /**
195
     * Update the specified resource in storage.
196
     *
197
     * @param  \Illuminate\Http\Request  $request
198
     * @param  \DavideCasiraghi\LaravelEventsCalendar\Models\Teacher  $teacher
199
     * @return \Illuminate\Http\Response
200
     */
201 2
    public function update(Request $request, Teacher $teacher)
202
    {
203
        // Validate form datas
204 2
        $validator = $this->teachersValidator($request);
205
        //dd($validator->errors());
206 2
        if ($validator->fails()) {
207 1
            return back()->withErrors($validator)->withInput();
208
        }
209
210 1
        $this->saveOnDb($request, $teacher);
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\Response
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
     * Save the record on DB.
236
     *
237
     * @param  \DavideCasiraghi\LaravelEventsCalendar\Models\Teacher  $teacher
238
     * @return \Illuminate\Http\Response
239
     */
240 3
    public function saveOnDb($request, $teacher)
241
    {
242 3
        $teacher->name = $request->get('name');
243
        //$teacher->bio = $request->get('bio');
244 3
        $teacher->bio = clean($request->get('bio'));
245 3
        $teacher->country_id = $request->get('country_id');
246 3
        $teacher->year_starting_practice = $request->get('year_starting_practice');
247 3
        $teacher->year_starting_teach = $request->get('year_starting_teach');
248 3
        $teacher->significant_teachers = $request->get('significant_teachers');
249
250
        // Teacher profile picture upload
251 3
        if ($request->file('profile_picture')) {
252
            $imageFile = $request->file('profile_picture');
253
            $imageName = $imageFile->hashName();
254
            $imageSubdir = 'teachers_profile';
255
            $imageWidth = '968';
256
            $thumbWidth = '300';
257
258
            $this->uploadImageOnServer($imageFile, $imageName, $imageSubdir, $imageWidth, $thumbWidth);
259
            $teacher->profile_picture = $imageName;
260
        } else {
261 3
            $teacher->profile_picture = $request->profile_picture;
262
        }
263
264 3
        $teacher->website = $request->get('website');
265 3
        $teacher->facebook = $request->get('facebook');
266
267
        //$teacher->created_by = Auth::id();
268 3
        $teacher->created_by = $request->get('created_by');
269
270 3
        if (! $teacher->slug) {
271 2
            $teacher->slug = Str::slug($teacher->name, '-').'-'.rand(10000, 100000);
272
        }
273
274 3
        $teacher->save();
275
276 3
        return $teacher->id;
277
    }
278
279
    /***************************************************************************/
280
281
    /**
282
     * Open a modal in the event view when create teachers is clicked.
283
     *
284
     * @return \Illuminate\Http\Response
285
     */
286 1
    public function modal()
287
    {
288 1
        $countries = Country::getCountries();
289 1
        $users = User::pluck('name', 'id');
290
291 1
        return view('laravel-events-calendar::teachers.modal')
292 1
                ->with('countries', $countries)
293 1
                ->with('users', $users);
294
    }
295
296
    /***************************************************************************/
297
298
    /**
299
     * Store a newly created teacher from the create event view modal in storage.
300
     *
301
     * @param  \Illuminate\Http\Request  $request
302
     * @return \Illuminate\Http\Response
303
     */
304 1
    public function storeFromModal(Request $request)
305
    {
306 1
        $teacher = new Teacher();
307
308 1
        $teacherId = $this->saveOnDb($request, $teacher);
309 1
        $teacher = Teacher::find($teacherId);
310
311 1
        return response()->json([
312 1
                        'teacherId' => $teacherId,
313 1
                        'teacherName' => $teacher->name,
314
                    ]);
315
    }
316
317
    /***************************************************************************/
318
319
    /**
320
     * Return the teacher by SLUG. (eg. http://websitename.com/teacher/xxxx).
321
     *
322
     * @param  \DavideCasiraghi\LaravelEventsCalendar\Models\Teacher  $post
323
     * @return \Illuminate\Http\Response
324
     */
325 1
    public function teacherBySlug($slug)
326
    {
327
        $teacher = Teacher::
328 1
                where('slug', $slug)
329 1
                ->first();
330
331 1
        return $this->show($teacher);
332
    }
333
334
    /***************************************************************************/
335
336
    /**
337
     * Return the validator with all the defined constraint.
338
     *
339
     * @param  \Illuminate\Http\Request  $request
340
     * @return \Illuminate\Validation\Validator
341
     */
342 4
    public function teachersValidator($request)
343
    {
344 4
        $maxYear = Carbon::now()->year;
345
346
        $rules = [
347 4
            'name' => 'required',
348 4
            'year_starting_practice' => 'required|integer|min:1972|max:'.($maxYear),
349 4
            'year_starting_teach' => 'required|integer|min:1972|max:'.($maxYear),
350 4
            'facebook' => 'nullable|url',
351 4
            'website' => 'nullable|url',
352
            // 'profile_picture' => 'nullable|image|mimes:jpeg,jpg,png|max:3000',   // BUG create problems to validate on edit. Fix this after the rollout
353
            // '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
354
        ];
355 4
        if ($request->hasFile('profile_picture')) {
356
            $rules['profile_picture'] = 'nullable|image|mimes:jpeg,jpg,png|max:5000';
357
        }
358
        $messages = [
359 4
            'facebook.url' => 'The facebook link is invalid. It should start with https://',
360
            'website.url' => 'The website link is invalid. It should start with https://',
361
            'profile_picture.max' => 'The maximum image size is 5MB. If you need to resize it you can use: www.simpleimageresizer.com',
362
        ];
363
364 4
        $validator = Validator::make($request->all(), $rules, $messages);
365
366 4
        return $validator;
367
    }
368
}
369