Passed
Push — master ( 693377...95d81f )
by Davide
75:43
created

TeacherController   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 301
Duplicated Lines 0 %

Test Coverage

Coverage 96.4%

Importance

Changes 7
Bugs 1 Features 2
Metric Value
wmc 19
eloc 106
c 7
b 1
f 2
dl 0
loc 301
ccs 107
cts 111
cp 0.964
rs 10

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A index() 0 57 5
A create() 0 10 1
A show() 0 28 1
A teacherBySlug() 0 7 1
A edit() 0 10 1
A storeFromModal() 0 9 1
A modal() 0 8 1
A destroy() 0 6 1
A update() 0 14 2
A teachersValidator() 0 25 2
A store() 0 14 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\Auth;
14
use Illuminate\Support\Facades\Cache;
15
use Illuminate\Support\Facades\DB;
16
use Illuminate\Support\Facades\Route;
17
use Illuminate\Support\Str;
18
use Validator;
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 16
    public function __construct()
24
    {
25 16
        $this->middleware('auth', ['except' => ['index', 'show', 'teacherBySlug']]);
26 16
    }
27
28
    /***************************************************************************/
29
30
    /**
31
     * Display a listing of the resource.
32
     *
33
     * @return \Illuminate\View\View
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\View\View
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\RedirectResponse
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
        $teacher->preSave($request);
131 1
        $teacher->save();
132
133 1
        return redirect()->route('teachers.index')
134 1
                        ->with('success', __('laravel-events-calendar::messages.teacher_added_successfully'));
135
    }
136
137
    /***************************************************************************/
138
139
    /**
140
     * Display the specified resource.
141
     *
142
     * @param  \DavideCasiraghi\LaravelEventsCalendar\Models\Teacher  $teacher
143
     * @return \Illuminate\View\View
144
     */
145 3
    public function show(Teacher $teacher)
146
    {
147
        // Get the name of the teacher's country
148 3
        $country = Country::select('name')
149 3
            ->where('id', $teacher->country_id)
150 3
            ->first();
151
152 3
        $cacheExpireTime = 900; // Set the duration time of the cache (15 min - 900sec)
153
        $eventCategories = Cache::remember('categories', $cacheExpireTime, function () {
154
            //return EventCategory::orderBy('name')->pluck('name', 'id');
155 3
            return EventCategory::listsTranslations('name')->pluck('name', 'id');
156 3
        });
157
158
        // Get for each event the first event repetition in the near future (JUST THE QUERY)
159 3
        date_default_timezone_set('Europe/Rome');
160 3
        $searchStartDate = date('Y-m-d', time()); // search start from today's date
161 3
        $lastestEventsRepetitionsQuery = EventRepetition::getLastestEventsRepetitionsQuery($searchStartDate, null);
162
163
        // Get the events where this teacher is teaching to
164
        //DB::enableQueryLog();
165 3
        $eventsTeacherWillTeach = Teacher::eventsByTeacher($teacher, $lastestEventsRepetitionsQuery);
166
167
        //dd(DB::getQueryLog());
168
169 3
        return view('laravel-events-calendar::teachers.show', compact('teacher'))
170 3
            ->with('country', $country)
171 3
            ->with('eventCategories', $eventCategories)
172 3
            ->with('eventsTeacherWillTeach', $eventsTeacherWillTeach);
173
    }
174
175
    /**
176
     * Show the form for editing the specified resource.
177
     *
178
     * @param  \DavideCasiraghi\LaravelEventsCalendar\Models\Teacher  $teacher
179
     * @return \Illuminate\View\View
180
     */
181 1
    public function edit(Teacher $teacher)
182
    {
183 1
        $authorUserId = $this->getLoggedAuthorId();
184 1
        $users = User::pluck('name', 'id');
185 1
        $countries = Country::getCountries();
186
187 1
        return view('laravel-events-calendar::teachers.edit', compact('teacher'))
188 1
            ->with('countries', $countries)
189 1
            ->with('users', $users)
190 1
            ->with('authorUserId', $authorUserId);
191
    }
192
193
    /***************************************************************************/
194
195
    /**
196
     * Update the specified resource in storage.
197
     *
198
     * @param  \Illuminate\Http\Request  $request
199
     * @param  \DavideCasiraghi\LaravelEventsCalendar\Models\Teacher  $teacher
200
     * @return \Illuminate\Http\RedirectResponse
201
     */
202 2
    public function update(Request $request, Teacher $teacher)
203
    {
204
        // Validate form datas
205 2
        $validator = $this->teachersValidator($request);
206
        //dd($validator->errors());
207 2
        if ($validator->fails()) {
208 1
            return back()->withErrors($validator)->withInput();
209
        }
210
211 1
        $teacher->preSave($request);
212 1
        $teacher->save();
213
214 1
        return redirect()->route('teachers.index')
215 1
                        ->with('success', __('laravel-events-calendar::messages.teacher_updated_successfully'));
216
    }
217
218
    /***************************************************************************/
219
220
    /**
221
     * Remove the specified resource from storage.
222
     *
223
     * @param  \DavideCasiraghi\LaravelEventsCalendar\Models\Teacher  $teacher
224
     * @return \Illuminate\Http\RedirectResponse
225
     */
226 1
    public function destroy(Teacher $teacher)
227
    {
228 1
        $teacher->delete();
229
230 1
        return redirect()->route('teachers.index')
231 1
                        ->with('success', __('laravel-events-calendar::messages.teacher_deleted_successfully'));
232
    }
233
234
    /***************************************************************************/
235
236
    /**
237
     * Open a modal in the event view when 'create new teacher' button is clicked.
238
     *
239
     * @return \Illuminate\View\View
240
     */
241 1
    public function modal()
242
    {
243 1
        $countries = Country::getCountries();
244 1
        $users = User::pluck('name', 'id');
245
246 1
        return view('laravel-events-calendar::teachers.modal')
247 1
                ->with('countries', $countries)
248 1
                ->with('users', $users);
249
    }
250
251
    /***************************************************************************/
252
253
    /**
254
     * Store a newly created teacher from the create event view modal in storage.
255
     *
256
     * @param  \Illuminate\Http\Request  $request
257
     * @return \Illuminate\Http\JsonResponse
258
     */
259 1
    public function storeFromModal(Request $request)
260
    {
261 1
        $teacher = new Teacher();        
262 1
        $teacher->preSave($request);
263 1
        $teacher->save();
264
        
265 1
        return response()->json([
266 1
            'teacherId' => $teacher->id,
267 1
            'teacherName' => $teacher->name,
268
        ]);
269
    }
270
271
    /***************************************************************************/
272
273
    /**
274
     * Return the teacher by SLUG. (eg. http://websitename.com/teacher/xxxx).
275
     *
276
     * @param  string  $slug
277
     * @return \Illuminate\View\View
278
     */
279 1
    public function teacherBySlug($slug)
280
    {
281
        $teacher = Teacher::
282 1
                where('slug', $slug)
283 1
                ->first();
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 4
    public function teachersValidator(Request $request)
297
    {
298 4
        $maxYear = Carbon::now()->year;
299
300
        $rules = [
301 4
            'name' => 'required',
302 4
            'year_starting_practice' => 'required|integer|min:1972|max:'.($maxYear),
303 4
            'year_starting_teach' => 'required|integer|min:1972|max:'.($maxYear),
304 4
            'facebook' => 'nullable|url',
305 4
            '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 4
        if ($request->hasFile('profile_picture')) {
310
            $rules['profile_picture'] = 'nullable|image|mimes:jpeg,jpg,png|max:5000';
311
        }
312
        $messages = [
313 4
            '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 4
        $validator = Validator::make($request->all(), $rules, $messages);
319
320 4
        return $validator;
321
    }
322
}
323