Passed
Push — master ( c430e0...09e8fc )
by Davide
02:42 queued 11s
created

TeacherController   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 343
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 22
eloc 127
dl 0
loc 343
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A show() 0 34 1
A teacherBySlug() 0 7 1
A edit() 0 10 1
A storeFromModal() 0 11 1
A modal() 0 5 1
A __construct() 0 3 1
A create() 0 10 1
A destroy() 0 6 1
A saveOnDb() 0 33 3
A update() 0 12 2
A store() 0 13 2
A index() 0 54 5
1
<?php
2
3
namespace DavideCasiraghi\LaravelEventsCalendar\Http\Controllers;
4
5
use DavideCasiraghi\LaravelEventsCalendar\Models\User;
6
use DavideCasiraghi\LaravelEventsCalendar\Models\Event;
7
use Validator;
8
use DavideCasiraghi\LaravelEventsCalendar\Models\Country;
9
use DavideCasiraghi\LaravelEventsCalendar\Models\Teacher;
10
use Carbon\Carbon;
11
use DavideCasiraghi\LaravelEventsCalendar\Models\EventCategory;
12
use DavideCasiraghi\LaravelEventsCalendar\Models\EventRepetition;
13
use Illuminate\Support\Str;
14
use Illuminate\Http\Request;
15
use Illuminate\Support\Facades\DB;
16
use Illuminate\Support\Facades\Auth;
17
use Illuminate\Support\Facades\Cache;
18
use Illuminate\Support\Facades\Route;
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
    public function __construct()
24
    {
25
        $this->middleware('auth', ['except' => ['index', 'show', 'teacherBySlug']]);
26
    }
27
28
    /***************************************************************************/
29
30
    /**
31
     * Display a listing of the resource.
32
     *
33
     * @return \Illuminate\Http\Response
34
     */
35
    public function index(Request $request)
36
    {
37
        $countries = Country::orderBy('countries.name')->pluck('name', 'id');
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
        $searchKeywords = $request->input('keywords');
50
        $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
        $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
        if (Route::currentRouteName() == 'teachers.directory') {
57
            $authorUserId = null;
58
        }
59
60
        if ($searchKeywords || $searchCountry) {
61
            $teachers = DB::table('teachers')
0 ignored issues
show
Unused Code introduced by
The assignment to $teachers is dead and can be removed.
Loading history...
62
                ->when($authorUserId, function ($query, $authorUserId) {
63
                    return $query->where('created_by', $authorUserId);
64
                })
65
                ->when($searchKeywords, function ($query, $searchKeywords) {
66
                    return $query->where('name', $searchKeywords)->orWhere('name', 'like', '%'.$searchKeywords.'%');
67
                })
68
                ->when($searchCountry, function ($query, $searchCountry) {
69
                    return $query->where('country_id', '=', $searchCountry);
70
                })
71
                ->orderBy('name')
72
                ->paginate(20);
73
        } else {
74
            $teachers = Teacher::
75
            when($authorUserId, function ($query, $authorUserId) {
76
                return $query->where('created_by', $authorUserId);
77
            })
78
            ->orderBy('name')
79
            ->paginate(20);
80
        }
81
        
82
        //return view('teachers.index', compact('teachers'))
83
        return view('laravel-events-calendar::teachers.create')
84
            ->with('i', (request()->input('page', 1) - 1) * 20)
85
            ->with('countries', $countries)
86
            ->with('searchKeywords', $searchKeywords)
87
            ->with('searchCountry', $searchCountry)
88
            ->with('loggedUser', $authorUserId);
89
    }
90
91
    /***************************************************************************/
92
93
    /**
94
     * Show the form for creating a new resource.
95
     *
96
     * @return \Illuminate\Http\Response
97
     */
98
    public function create()
99
    {
100
        $countries = Country::getCountries();
101
        $users = User::pluck('name', 'id');
102
        $authorUserId = $this->getLoggedUser();
103
104
        return view('teachers.create')
105
            ->with('countries', $countries)
106
            ->with('users', $users)
107
            ->with('authorUserId', $authorUserId);
108
    }
109
110
    /***************************************************************************/
111
112
    /**
113
     * Store a newly created resource in storage.
114
     *
115
     * @param  \Illuminate\Http\Request  $request
116
     * @return \Illuminate\Http\Response
117
     */
118
    public function store(Request $request)
119
    {
120
        // Validate form datas
121
        $validator = $this->teachersValidator($request);
122
        if ($validator->fails()) {
123
            return back()->withErrors($validator)->withInput();
124
        }
125
126
        $teacher = new Teacher();
127
        $this->saveOnDb($request, $teacher);
128
129
        return redirect()->route('teachers.index')
130
                        ->with('success', __('messages.teacher_added_successfully'));
131
    }
132
133
    /***************************************************************************/
134
135
    /**
136
     * Display the specified resource.
137
     *
138
     * @param  \App\Teacher  $teacher
0 ignored issues
show
Bug introduced by
The type App\Teacher was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
139
     * @return \Illuminate\Http\Response
140
     */
141
    public function show(Teacher $teacher)
142
    {
143
144
        // Get the name of the teacher's country
145
        $country = Country::select('name')
146
            ->where('id', $teacher->country_id)
147
            ->first();
148
149
        $cacheExpireTime = 900; // Set the duration time of the cache (15 min - 900sec)
150
        $eventCategories = Cache::remember('categories', $cacheExpireTime, function () {
151
            return EventCategory::orderBy('name')->pluck('name', 'id');
152
        });
153
154
        // Get for each event the first event repetition in the near future (JUST THE QUERY)
155
        date_default_timezone_set('Europe/Rome');
156
        $searchStartDate = date('Y-m-d', time()); // search start from today's date
157
        $lastestEventsRepetitionsQuery = EventRepetition::getLastestEventsRepetitionsQuery($searchStartDate, null);
158
159
        // Get the events where this teacher is teaching to
160
        //DB::enableQueryLog();
161
        $eventsTeacherWillTeach = $teacher->events()
162
                                              ->select('events.title', 'events.category_id', 'events.slug', 'events.sc_venue_name', 'events.sc_country_name', 'events.sc_city_name', 'events.sc_teachers_names', 'event_repetitions.start_repeat', 'event_repetitions.end_repeat')
163
                                              ->joinSub($lastestEventsRepetitionsQuery, 'event_repetitions', function ($join) {
164
                                                  $join->on('events.id', '=', 'event_repetitions.event_id');
165
                                              })
166
                                              ->orderBy('event_repetitions.start_repeat', 'asc')
167
                                              ->get();
168
        //dd(DB::getQueryLog());
169
        //dd($eventsTeacherWillTeach);
170
171
        return view('teachers.show', compact('teacher'))
172
            ->with('country', $country)
173
            ->with('eventCategories', $eventCategories)
174
            ->with('eventsTeacherWillTeach', $eventsTeacherWillTeach);
175
    }
176
177
    /**
178
     * Show the form for editing the specified resource.
179
     *
180
     * @param  \App\Teacher  $teacher
181
     * @return \Illuminate\Http\Response
182
     */
183
    public function edit(Teacher $teacher)
184
    {
185
        $authorUserId = $this->getLoggedAuthorId();
186
        $users = User::pluck('name', 'id');
187
        $countries = Country::getCountries();
188
189
        return view('teachers.edit', compact('teacher'))
190
            ->with('countries', $countries)
191
            ->with('users', $users)
192
            ->with('authorUserId', $authorUserId);
193
    }
194
195
    /***************************************************************************/
196
197
    /**
198
     * Update the specified resource in storage.
199
     *
200
     * @param  \Illuminate\Http\Request  $request
201
     * @param  \App\Teacher  $teacher
202
     * @return \Illuminate\Http\Response
203
     */
204
    public function update(Request $request, Teacher $teacher)
205
    {
206
        // Validate form datas
207
        $validator = $this->teachersValidator($request);
208
        if ($validator->fails()) {
209
            return back()->withErrors($validator)->withInput();
210
        }
211
212
        $this->saveOnDb($request, $teacher);
213
214
        return redirect()->route('teachers.index')
215
                        ->with('success', __('messages.teacher_updated_successfully'));
216
    }
217
218
    /***************************************************************************/
219
220
    /**
221
     * Remove the specified resource from storage.
222
     *
223
     * @param  \App\Teacher  $teacher
224
     * @return \Illuminate\Http\Response
225
     */
226
    public function destroy(Teacher $teacher)
227
    {
228
        $teacher->delete();
229
230
        return redirect()->route('teachers.index')
231
                        ->with('success', __('messages.teacher_deleted_successfully'));
232
    }
233
234
    /***************************************************************************/
235
236
    /**
237
     * Save the record on DB.
238
     *
239
     * @param  \App\Teacher  $teacher
240
     * @return \Illuminate\Http\Response
241
     */
242
    public function saveOnDb($request, $teacher)
243
    {
244
        $teacher->name = $request->get('name');
245
        //$teacher->bio = $request->get('bio');
246
        $teacher->bio = clean($request->get('bio'));
0 ignored issues
show
Bug introduced by
The function clean was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

246
        $teacher->bio = /** @scrutinizer ignore-call */ clean($request->get('bio'));
Loading history...
247
        $teacher->country_id = $request->get('country_id');
248
        $teacher->year_starting_practice = $request->get('year_starting_practice');
249
        $teacher->year_starting_teach = $request->get('year_starting_teach');
250
        $teacher->significant_teachers = $request->get('significant_teachers');
251
252
        // Teacher profile picture upload
253
        if ($request->file('profile_picture')) {
254
            $imageFile = $request->file('profile_picture');
255
            $imageName = $imageFile->hashName();
256
            $imageSubdir = 'teachers_profile';
257
            $imageWidth = '968';
258
            $thumbWidth = '300';
259
260
            $this->uploadImageOnServer($imageFile, $imageName, $imageSubdir, $imageWidth, $thumbWidth);
261
            $teacher->profile_picture = $imageName;
262
        } else {
263
            $teacher->profile_picture = $request->profile_picture;
264
        }
265
266
        $teacher->website = $request->get('website');
267
        $teacher->facebook = $request->get('facebook');
268
269
        $teacher->created_by = \Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
270
        if (! $teacher->slug) {
271
            $teacher->slug = Str::slug($teacher->name, '-').'-'.rand(10000, 100000);
272
        }
273
274
        $teacher->save();
275
    }
276
277
    /***************************************************************************/
278
279
    /**
280
     * Open a modal in the event view when create teachers is clicked.
281
     *
282
     * @return \Illuminate\Http\Response
283
     */
284
    public function modal()
285
    {
286
        $countries = Country::getCountries();
287
288
        return view('teachers.modal')->with('countries', $countries);
289
    }
290
291
    /***************************************************************************/
292
293
    /**
294
     * Store a newly created teacher from the create event view modal in storage.
295
     *
296
     * @param  \Illuminate\Http\Request  $request
297
     * @return \Illuminate\Http\Response
298
     */
299
    public function storeFromModal(Request $request)
300
    {
301
        $teacher = new Teacher();
302
303
        request()->validate([
304
            'name' => 'required',
305
        ]);
306
307
        $this->saveOnDb($request, $teacher);
308
309
        return redirect()->back()->with('message', __('messages.teacher_added_successfully'));
310
        //return redirect()->back()->with('message', __('auth.successfully_registered'));
311
        //return true;
312
    }
313
314
    /***************************************************************************/
315
316
    /**
317
     * Return the teacher by SLUG. (eg. http://websitename.com/teacher/xxxx).
318
     *
319
     * @param  \App\Teacher  $post
320
     * @return \Illuminate\Http\Response
321
     */
322
    public function teacherBySlug($slug)
323
    {
324
        $teacher = Teacher::
325
                where('slug', $slug)
326
                ->first();
327
328
        return $this->show($teacher);
329
    }
330
331
    /***************************************************************************/
332
333
    /**
334
     * Return the validator with all the defined constraint.
335
     *
336
     * @param  \Illuminate\Http\Request  $request
337
     * @return \Illuminate\Validation\Validator
338
     */
339
    public function teachersValidator($request)
340
    {
341
        $maxYear = Carbon::now()->year;
342
343
        $rules = [
344
            'name' => 'required',
345
            'year_starting_practice' => 'required|integer|min:1972|max:'.($maxYear),
346
            'year_starting_teach' => 'required|integer|min:1972|max:'.($maxYear),
347
            'facebook' => 'nullable|url',
348
            'website' => 'nullable|url',
349
            // 'profile_picture' => 'nullable|image|mimes:jpeg,jpg,png|max:3000',   // BUG create problems to validate on edit. Fix this after the rollout
350
            // '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
351
        ];
352
        if ($request->hasFile('profile_picture')) {
353
            $rules['profile_picture'] = 'nullable|image|mimes:jpeg,jpg,png|max:5000';
354
        }
355
        $messages = [
356
            'facebook.url' => 'The facebook link is invalid. It should start with https://',
357
            'website.url' => 'The website link is invalid. It should start with https://',
358
            'profile_picture.max' => 'The maximum image size is 5MB. If you need to resize it you can use: www.simpleimageresizer.com',
359
        ];
360
361
        $validator = Validator::make($request->all(), $rules, $messages);
362
363
        return $validator;
364
    }
365
}
366