TeacherController   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 303
Duplicated Lines 0 %

Test Coverage

Coverage 95.54%

Importance

Changes 9
Bugs 2 Features 2
Metric Value
wmc 20
eloc 106
c 9
b 2
f 2
dl 0
loc 303
ccs 107
cts 112
cp 0.9554
rs 10

12 Methods

Rating   Name   Duplication   Size   Complexity  
A create() 0 10 1
A destroy() 0 6 1
A teachersValidator() 0 25 2
A show() 0 28 1
A edit() 0 10 1
A storeFromModal() 0 9 1
A modal() 0 8 1
A __construct() 0 3 1
A update() 0 14 2
A index() 0 57 5
A store() 0 14 2
A teacherBySlug() 0 9 2
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
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 ignore-type  annotation

128
        $teacher->preSave($request->all(), /** @scrutinizer ignore-type */ $request->file('profile_picture'));
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
Bug introduced by
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 ignore-type  annotation

209
        $teacher->preSave($request->all(), /** @scrutinizer ignore-type */ $request->file('profile_picture'));
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
Bug introduced by
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 ignore-type  annotation

260
        $teacher->preSave($request->all(), /** @scrutinizer ignore-type */ $request->file('profile_picture'));
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