Passed
Push — master ( b25a39...01c041 )
by Davide
139:14 queued 109:43
created

EventController   C

Complexity

Total Complexity 54

Size/Duplication

Total Lines 752
Duplicated Lines 0 %

Test Coverage

Coverage 83.64%

Importance

Changes 56
Bugs 14 Features 18
Metric Value
wmc 54
eloc 322
c 56
b 14
f 18
dl 0
loc 752
ccs 276
cts 330
cp 0.8364
rs 6.4799

20 Methods

Rating   Name   Duplication   Size   Complexity  
A index() 0 48 5
A store() 0 14 2
A create() 0 24 1
A __construct() 0 3 1
A reportMisuse() 0 39 1
A setEventRepeatFields() 0 30 5
A getCreatorEmail() 0 10 1
A eventsValidator() 0 38 3
A eventBySlugAndRepetition() 0 11 2
A mailToOrganizer() 0 22 1
A mailToOrganizerSent() 0 3 1
B edit() 0 43 8
A update() 0 12 2
A eventBySlug() 0 6 1
A calculateMonthlySelectOptions() 0 68 3
A destroy() 0 10 1
A saveEventRepetitions() 0 58 5
A show() 0 32 2
A reportMisuseThankyou() 0 3 1
B saveOnDb() 0 79 8

How to fix   Complexity   

Complex Class

Complex classes like EventController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use EventController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace DavideCasiraghi\LaravelEventsCalendar\Http\Controllers;
4
5
use Carbon\Carbon;
6
use DateTime;
7
use DavideCasiraghi\LaravelEventsCalendar\Facades\LaravelEventsCalendar;
8
use DavideCasiraghi\LaravelEventsCalendar\Mail\ContactOrganizer;
9
use DavideCasiraghi\LaravelEventsCalendar\Mail\ReportMisuse;
10
use DavideCasiraghi\LaravelEventsCalendar\Models\Continent;
11
use DavideCasiraghi\LaravelEventsCalendar\Models\Country;
12
use DavideCasiraghi\LaravelEventsCalendar\Models\Event;
13
use DavideCasiraghi\LaravelEventsCalendar\Models\EventCategory;
14
use DavideCasiraghi\LaravelEventsCalendar\Models\EventRepetition;
15
use DavideCasiraghi\LaravelEventsCalendar\Models\EventVenue;
16
use DavideCasiraghi\LaravelEventsCalendar\Models\Organizer;
17
use DavideCasiraghi\LaravelEventsCalendar\Models\Region;
18
use DavideCasiraghi\LaravelEventsCalendar\Models\Teacher;
19
use Illuminate\Foundation\Auth\User;
20
use Illuminate\Http\Request;
21
use Illuminate\Support\Facades\Auth;
22
use Illuminate\Support\Facades\DB;
23
use Illuminate\Support\Facades\Mail;
24
use Illuminate\Support\Str;
25
use Illuminate\Validation\Rule;
26
use Validator;
27
28
/**
29
 * @method static string getReportMisuseReasonDescription(integer $request->reason)  Return a string that describe the report misuse reason
30
 */
31
class EventController extends Controller
32
{
33
    /***************************************************************************/
34
    /* Restrict the access to this resource just to logged in users except show view */
35 27
    public function __construct()
36
    {
37 27
        $this->middleware('auth', ['except' => ['show', 'reportMisuse', 'reportMisuseThankyou', 'mailToOrganizer', 'mailToOrganizerSent', 'eventBySlug', 'eventBySlugAndRepetition', 'EventsListByCountry', 'calculateMonthlySelectOptions']]);
38 27
    }
39
40
    /***************************************************************************/
41
42
    /**
43
     * Display a listing of the resource.
44
     * @param  \Illuminate\Http\Request  $request
45
     * @return \Illuminate\Http\Response
46
     */
47 1
    public function index(Request $request)
48
    {
49
        // To show just the events created by the the user - If admin or super admin is set to null show all the events
50 1
        $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
51
52 1
        $eventCategories = EventCategory::listsTranslations('name')->orderBy('name')->pluck('name', 'id');
53 1
        $countries = Country::orderBy('name')->pluck('name', 'id');
54 1
        $venues = EventVenue::pluck('country_id', 'id');
55
56 1
        $searchKeywords = $request->input('keywords');
57 1
        $searchCategory = $request->input('category_id');
58 1
        $searchCountry = $request->input('country_id');
59
60 1
        if ($searchKeywords || $searchCategory || $searchCountry) {
61
            $events = Event::
62
                // Show only the events owned by the user, if the user is an admin or super admin show all the events
63
                when(isset($authorUserId), function ($query, $authorUserId) {
64
                    return $query->where('created_by', $authorUserId);
65
                })
66
                ->when($searchKeywords, function ($query, $searchKeywords) {
67
                    return $query->where('title', $searchKeywords)->orWhere('title', 'like', '%'.$searchKeywords.'%');
68
                })
69
                ->when($searchCategory, function ($query, $searchCategory) {
70
                    return $query->where('category_id', '=', $searchCategory);
71
                })
72
                ->when($searchCountry, function ($query, $searchCountry) {
73
                    return $query->join('event_venues', 'events.venue_id', '=', 'event_venues.id')->where('event_venues.country_id', '=', $searchCountry);
74
                })
75
                ->select('*', 'events.id as id', 'events.slug as slug', 'events.image as image') // To keep in the join the id of the Events table - https://stackoverflow.com/questions/28062308/laravel-eloquent-getting-id-field-of-joined-tables-in-eloquent
76
                ->paginate(20);
77
78
        //dd($events);
79
        } else {
80 1
            $events = Event::latest()
81
                ->when($authorUserId, function ($query, $authorUserId) {
82
                    return $query->where('created_by', $authorUserId);
83 1
                })
84 1
                ->paginate(20);
85
        }
86
87 1
        return view('laravel-events-calendar::events.index', compact('events'))
88 1
            ->with('i', (request()->input('page', 1) - 1) * 20)
89 1
            ->with('eventCategories', $eventCategories)
90 1
            ->with('countries', $countries)
91 1
            ->with('venues', $venues)
92 1
            ->with('searchKeywords', $searchKeywords)
93 1
            ->with('searchCategory', $searchCategory)
94 1
            ->with('searchCountry', $searchCountry);
95
    }
96
97
    /***************************************************************************/
98
99
    /**
100
     * Show the form for creating a new resource.
101
     *
102
     * @return \Illuminate\Http\Response
103
     */
104 1
    public function create()
105
    {
106 1
        $authorUserId = $this->getLoggedAuthorId();
107
108 1
        $eventCategories = EventCategory::listsTranslations('name')->orderBy('name')->pluck('name', 'id');
109 1
        $users = User::orderBy('name')->pluck('name', 'id');
110 1
        $teachers = Teacher::orderBy('name')->pluck('name', 'id');
111 1
        $organizers = Organizer::orderBy('name')->pluck('name', 'id');
112
        //$venues = EventVenue::pluck('name', 'id');
113 1
        $venues = DB::table('event_venues')
114 1
                ->select('id', 'name', 'city')->orderBy('name')->get();
115
116 1
        $dateTime = [];
117 1
        $dateTime['repeatUntil'] = null;
118 1
        $dateTime['multipleDates'] = null;
119
120 1
        return view('laravel-events-calendar::events.create')
121 1
            ->with('eventCategories', $eventCategories)
122 1
            ->with('users', $users)
123 1
            ->with('teachers', $teachers)
124 1
            ->with('organizers', $organizers)
125 1
            ->with('venues', $venues)
126 1
            ->with('dateTime', $dateTime)
127 1
            ->with('authorUserId', $authorUserId);
128
    }
129
130
    /***************************************************************************/
131
132
    /**
133
     * Store a newly created resource in storage.
134
     *
135
     * @param  \Illuminate\Http\Request  $request
136
     * @return \Illuminate\Http\Response
137
     */
138 22
    public function store(Request $request)
139
    {
140
        // Validate form datas
141 22
        $validator = $this->eventsValidator($request);
142 22
        if ($validator->fails()) {
143
            //dd($validator->failed());
144 1
            return back()->withErrors($validator)->withInput();
145
        }
146
147 21
        $event = new Event();
148 21
        $this->saveOnDb($request, $event);
149
150 21
        return redirect()->route('events.index')
151 21
                        ->with('success', __('laravel-events-calendar::messages.event_added_successfully'));
152
    }
153
154
    /***************************************************************************/
155
156
    /**
157
     * Display the specified resource.
158
     *
159
     * @param  \DavideCasiraghi\LaravelEventsCalendar\Models\Event  $event
160
     * @param  \DavideCasiraghi\LaravelEventsCalendar\Models\EventRepetition $firstRpDates
161
     * @return \Illuminate\Http\Response
162
     */
163 5
    public function show(Event $event, EventRepetition $firstRpDates)
164
    {
165
        //dd($firstRpDates);
166 5
        $category = EventCategory::find($event->category_id);
167 5
        $teachers = $event->teachers()->get();
168 5
        $organizers = $event->organizers()->get();
169
170 5
        $venue = DB::table('event_venues')
171 5
                ->select('id', 'name', 'city', 'address', 'zip_code', 'country_id', 'region_id', 'description', 'website', 'extra_info')
172 5
                ->where('id', $event->venue_id)
173 5
                ->first();
174
175 5
        $country = Country::find($venue->country_id);
176 5
        $region = Region::listsTranslations('name')->find($venue->region_id);
177 5
        $continent = Continent::find($country->continent_id);
178
179 5
        $repetition_text = LaravelEventsCalendar::getRepetitionTextString($event, $firstRpDates);
0 ignored issues
show
Bug introduced by
The method getRepetitionTextString() does not exist on DavideCasiraghi\LaravelE...s\LaravelEventsCalendar. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

179
        /** @scrutinizer ignore-call */ 
180
        $repetition_text = LaravelEventsCalendar::getRepetitionTextString($event, $firstRpDates);
Loading history...
180
        
181
        // True if the repetition start and end on the same day
182 5
        $sameDateStartEnd = ((date('Y-m-d', strtotime($firstRpDates->start_repeat))) == (date('Y-m-d', strtotime($firstRpDates->end_repeat)))) ? 1 : 0;
183
184 5
        return view('laravel-events-calendar::events.show', compact('event'))
185 5
                ->with('category', $category)
186 5
                ->with('teachers', $teachers)
187 5
                ->with('organizers', $organizers)
188 5
                ->with('venue', $venue)
189 5
                ->with('country', $country)
190 5
                ->with('region', $region)
191 5
                ->with('continent', $continent)
192 5
                ->with('datesTimes', $firstRpDates)
193 5
                ->with('repetition_text', $repetition_text)
194 5
                ->with('sameDateStartEnd', $sameDateStartEnd);
195
    }
196
197
    /***************************************************************************/
198
199
    /**
200
     * Show the form for editing the specified resource.
201
     *
202
     * @param  \DavideCasiraghi\LaravelEventsCalendar\Models\Event  $event
203
     * @return \Illuminate\Http\Response
204
     */
205 1
    public function edit(Event $event)
206
    {
207
        //if (Auth::user()->id == $event->created_by || Auth::user()->isSuperAdmin() || Auth::user()->isAdmin()) {
208 1
        if (Auth::user()->id == $event->created_by || Auth::user()->group == 1 || Auth::user()->group == 2) {
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...
Bug introduced by
Accessing group on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
209 1
            $authorUserId = $this->getLoggedAuthorId();
210
211
            //$eventCategories = EventCategory::pluck('name', 'id');  // removed because was braking the tests
212 1
            $eventCategories = EventCategory::listsTranslations('name')->orderBy('name')->pluck('name', 'id');
213
214 1
            $users = User::orderBy('name')->pluck('name', 'id');
215 1
            $teachers = Teacher::orderBy('name')->pluck('name', 'id');
216 1
            $organizers = Organizer::orderBy('name')->pluck('name', 'id');
217 1
            $venues = DB::table('event_venues')
218 1
                    ->select('id', 'name', 'address', 'city')->orderBy('name')->get();
219
220 1
            $eventFirstRepetition = DB::table('event_repetitions')
221 1
                    ->select('id', 'start_repeat', 'end_repeat')
222 1
                    ->where('event_id', '=', $event->id)
223 1
                    ->first();
224
225 1
            $dateTime = [];
226 1
            $dateTime['dateStart'] = (isset($eventFirstRepetition->start_repeat)) ? date('d/m/Y', strtotime($eventFirstRepetition->start_repeat)) : '';
227 1
            $dateTime['dateEnd'] = (isset($eventFirstRepetition->end_repeat)) ? date('d/m/Y', strtotime($eventFirstRepetition->end_repeat)) : '';
228 1
            $dateTime['timeStart'] = (isset($eventFirstRepetition->start_repeat)) ? date('g:i A', strtotime($eventFirstRepetition->start_repeat)) : '';
229 1
            $dateTime['timeEnd'] = (isset($eventFirstRepetition->end_repeat)) ? date('g:i A', strtotime($eventFirstRepetition->end_repeat)) : '';
230 1
            $dateTime['repeatUntil'] = date('d/m/Y', strtotime($event->repeat_until));
231 1
            $dateTime['multipleDates'] = $event->multiple_dates;
232
233 1
            $multiple_teachers = LaravelEventsCalendar::getCollectionIdsSeparatedByComma($event->teachers);
0 ignored issues
show
Bug introduced by
The method getCollectionIdsSeparatedByComma() does not exist on DavideCasiraghi\LaravelE...s\LaravelEventsCalendar. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

233
            /** @scrutinizer ignore-call */ 
234
            $multiple_teachers = LaravelEventsCalendar::getCollectionIdsSeparatedByComma($event->teachers);
Loading history...
234 1
            $multiple_organizers = LaravelEventsCalendar::getCollectionIdsSeparatedByComma($event->organizers);
235
236 1
            return view('laravel-events-calendar::events.edit', compact('event'))
237 1
                        ->with('eventCategories', $eventCategories)
238 1
                        ->with('users', $users)
239 1
                        ->with('teachers', $teachers)
240 1
                        ->with('multiple_teachers', $multiple_teachers)
241 1
                        ->with('organizers', $organizers)
242 1
                        ->with('multiple_organizers', $multiple_organizers)
243 1
                        ->with('venues', $venues)
244 1
                        ->with('dateTime', $dateTime)
245 1
                        ->with('authorUserId', $authorUserId);
246
        } else {
247
            return redirect()->route('home')->with('message', __('auth.not_allowed_to_access'));
248
        }
249
    }
250
251
    /***************************************************************************/
252
253
    /**
254
     * Update the specified resource in storage.
255
     *
256
     * @param  \Illuminate\Http\Request  $request
257
     * @param  \DavideCasiraghi\LaravelEventsCalendar\Models\Event  $event
258
     * @return \Illuminate\Http\Response
259
     */
260 2
    public function update(Request $request, Event $event)
261
    {
262
        // Validate form datas
263 2
        $validator = $this->eventsValidator($request);
264 2
        if ($validator->fails()) {
265 1
            return back()->withErrors($validator)->withInput();
266
        }
267
268 1
        $this->saveOnDb($request, $event);
269
270 1
        return redirect()->route('events.index')
271 1
                        ->with('success', __('laravel-events-calendar::messages.event_updated_successfully'));
272
    }
273
274
    /***************************************************************************/
275
276
    /**
277
     * Remove the specified resource from storage.
278
     *
279
     * @param  \DavideCasiraghi\LaravelEventsCalendar\Models\Event  $event
280
     * @return \Illuminate\Http\Response
281
     */
282 1
    public function destroy(Event $event)
283
    {
284 1
        DB::table('event_repetitions')
285 1
                ->where('event_id', $event->id)
286 1
                ->delete();
287
288 1
        $event->delete();
289
290 1
        return redirect()->route('events.index')
291 1
                        ->with('success', __('laravel-events-calendar::messages.event_deleted_successfully'));
292
    }
293
294
    /***************************************************************************/
295
296
    /**
297
     * To save event repetitions for create and update methods.
298
     *
299
     * @param  \Illuminate\Http\Request  $request
300
     * @param  \DavideCasiraghi\LaravelEventsCalendar\Models\Event  $event
301
     * @return void
302
     */
303 21
    public function saveEventRepetitions(Request $request, int $eventId)
304
    {
305 21
        EventRepetition::deletePreviousRepetitions($eventId);
306
307
        // Saving repetitions - If it's a single event will be stored with just one repetition
308
        //$timeStart = date('H:i:s', strtotime($request->get('time_start')));
309
        //$timeEnd = date('H:i:s', strtotime($request->get('time_end')));
310
        //$timeStart = $request->get('time_start');
311
        //$timeEnd = $request->get('time_end');
312 21
        $timeStart = date('H:i', strtotime($request->get('time_start')));
313 21
        $timeEnd = date('H:i', strtotime($request->get('time_end')));
314
315 21
        switch ($request->get('repeat_type')) {
316 21
                case '1':  // noRepeat
317 13
                    $eventRepetition = new EventRepetition();
318 13
                    $eventRepetition->event_id = $eventId;
319
320 13
                    $dateStart = implode('-', array_reverse(explode('/', $request->get('startDate'))));
321 13
                    $dateEnd = implode('-', array_reverse(explode('/', $request->get('endDate'))));
322
323 13
                    $eventRepetition->start_repeat = $dateStart.' '.$timeStart;
324 13
                    $eventRepetition->end_repeat = $dateEnd.' '.$timeEnd;
325 13
                    $eventRepetition->save();
326
327 13
                    break;
328
329 8
                case '2':   // repeatWeekly
330
                    // Convert the start date in a format that can be used for strtotime
331 2
                        $startDate = implode('-', array_reverse(explode('/', $request->get('startDate'))));
332
333
                    // Calculate repeat until day
334 2
                        $repeatUntilDate = implode('-', array_reverse(explode('/', $request->get('repeat_until'))));
335 2
                        EventRepetition::saveWeeklyRepeatDates($eventId, $request->get('repeat_weekly_on_day'), $startDate, $repeatUntilDate, $timeStart, $timeEnd);
0 ignored issues
show
Bug introduced by
It seems like $request->get('repeat_weekly_on_day') can also be of type null; however, parameter $weekDays of DavideCasiraghi\LaravelE...saveWeeklyRepeatDates() does only seem to accept array, 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

335
                        EventRepetition::saveWeeklyRepeatDates($eventId, /** @scrutinizer ignore-type */ $request->get('repeat_weekly_on_day'), $startDate, $repeatUntilDate, $timeStart, $timeEnd);
Loading history...
336
337 2
                    break;
338
339 6
                case '3':  //repeatMonthly
340
                    // Same of repeatWeekly
341 5
                        $startDate = implode('-', array_reverse(explode('/', $request->get('startDate'))));
342 5
                        $repeatUntilDate = implode('-', array_reverse(explode('/', $request->get('repeat_until'))));
343
344
                    // Get the array with month repeat details
345 5
                        $monthRepeatDatas = explode('|', $request->get('on_monthly_kind'));
346
                        //dump("pp_1");
347 5
                        EventRepetition::saveMonthlyRepeatDates($eventId, $monthRepeatDatas, $startDate, $repeatUntilDate, $timeStart, $timeEnd);
348
349 5
                    break;
350
351 1
                case '4':  //repeatMultipleDays
352
                    // Same of repeatWeekly
353 1
                        $startDate = implode('-', array_reverse(explode('/', $request->get('startDate'))));
354
355
                    // Get the array with single day repeat details
356 1
                        $singleDaysRepeatDatas = explode(',', $request->get('multiple_dates'));
357
358 1
                        EventRepetition::saveMultipleRepeatDates($eventId, $singleDaysRepeatDatas, $startDate, $timeStart, $timeEnd);
359
360 1
                    break;
361
            }
362 21
    }
363
364
    /***************************************************************************/
365
366
    /**
367
     * Send the Misuse mail.
368
     *
369
     * @param  \Illuminate\Http\Request  $request
370
     * @return \Illuminate\Http\Response
371
     */
372
    public function reportMisuse(Request $request)
373
    {
374
        $report = [];
375
376
        //$report['senderEmail'] = '[email protected]';
377
        $report['senderEmail'] = $request->user_email;
378
        $report['senderName'] = 'Anonymus User';
379
        $report['subject'] = 'Report misuse form';
380
        //$report['adminEmail'] = env('ADMIN_MAIL');
381
        $report['creatorEmail'] = $this->getCreatorEmail($request->created_by);
382
383
        $report['message_misuse'] = $request->message_misuse;
384
        $report['event_title'] = $request->event_title;
385
        $report['event_id'] = $request->event_id;
386
        $report['event_slug'] = $request->slug;
387
388
        $report['reason'] = LaravelEventsCalendar::getReportMisuseReasonDescription($request->reason);
0 ignored issues
show
Bug introduced by
The method getReportMisuseReasonDescription() does not exist on DavideCasiraghi\LaravelE...s\LaravelEventsCalendar. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

388
        /** @scrutinizer ignore-call */ 
389
        $report['reason'] = LaravelEventsCalendar::getReportMisuseReasonDescription($request->reason);
Loading history...
389
390
        /*
391
                switch ($request->reason) {
392
                    case '1':
393
                        $report['reason'] = 'Not about Contact Improvisation';
394
                        break;
395
                    case '2':
396
                        $report['reason'] = 'Contains wrong informations';
397
                        break;
398
                    case '3':
399
                        $report['reason'] = 'It is not translated in english';
400
                        break;
401
                    case '4':
402
                        $report['reason'] = 'Other (specify in the message)';
403
                        break;
404
                }
405
        */
406
407
        //Mail::to($request->user())->send(new ReportMisuse($report));
408
        Mail::to(env('ADMIN_MAIL'))->send(new ReportMisuse($report));
409
410
        return redirect()->route('events.misuse-thankyou');
411
    }
412
413
    /***************************************************************************/
414
415
    /**
416
     * Send the mail to the Organizer (from the event modal in the event show view).
417
     *
418
     * @param  \Illuminate\Http\Request  $request
419
     * @return \Illuminate\Http\Response
420
     */
421
    public function mailToOrganizer(Request $request)
422
    {
423
        $message = [];
424
        $message['senderEmail'] = $request->user_email;
425
        $message['senderName'] = $request->user_name;
426
        $message['subject'] = 'Request from the Global CI Calendar';
427
        //$message['emailTo'] = $organizersEmails;
428
429
        $message['message'] = $request->message;
430
        $message['event_title'] = $request->event_title;
431
        $message['event_id'] = $request->event_id;
432
        $message['event_slug'] = $request->slug;
433
434
        /*
435
        $eventOrganizers = Event::find($request->event_id)->organizers;
436
        foreach ($eventOrganizers as $eventOrganizer) {
437
            Mail::to($eventOrganizer->email)->send(new ContactOrganizer($message));
438
        }*/
439
440
        Mail::to($request->contact_email)->send(new ContactOrganizer($message));
441
442
        return redirect()->route('events.organizer-sent');
443
    }
444
445
    /***************************************************************************/
446
447
    /**
448
     * Display the thank you view after the mail to the organizer is sent (called by /mailToOrganizer/sent route).
449
     *
450
     * @return \Illuminate\Http\Response
451
     */
452 1
    public function mailToOrganizerSent()
453
    {
454 1
        return view('laravel-events-calendar::emails.contact.organizer-sent');
455
    }
456
457
    /***************************************************************************/
458
459
    /**
460
     * Display the thank you view after the misuse report mail is sent (called by /misuse/thankyou route).
461
     *
462
     * @return \Illuminate\Http\Response
463
     */
464 1
    public function reportMisuseThankyou()
465
    {
466 1
        return view('laravel-events-calendar::emails.report-thankyou');
467
    }
468
469
    /***************************************************************************/
470
471
    /**
472
     * Set the Event attributes about repeating before store or update (repeat until field and multiple days).
473
     *
474
     * @param  \Illuminate\Http\Request  $request
475
     * @param  \DavideCasiraghi\LaravelEventsCalendar\Models\Event  $event
476
     * @return \DavideCasiraghi\LaravelEventsCalendar\Models\Event  $event
477
     */
478 21
    public function setEventRepeatFields(Request $request, Event $event)
479
    {
480
        // Set Repeat Until
481 21
        $event->repeat_type = $request->get('repeat_type');
482 21
        if ($request->get('repeat_until')) {
483 7
            $dateRepeatUntil = implode('-', array_reverse(explode('/', $request->get('repeat_until'))));
484 7
            $event->repeat_until = $dateRepeatUntil.' 00:00:00';
485
        }
486
487
        // Weekely - Set multiple week days
488 21
        if ($request->get('repeat_weekly_on_day')) {
489 2
            $repeat_weekly_on_day = $request->get('repeat_weekly_on_day');
490
            //dd($repeat_weekly_on_day);
491 2
            $i = 0;
492 2
            $len = count($repeat_weekly_on_day); // to put "," to all items except the last
493 2
            $event->repeat_weekly_on = '';
494 2
            foreach ($repeat_weekly_on_day as $key => $weeek_day) {
495 2
                $event->repeat_weekly_on .= $weeek_day;
496 2
                if ($i != $len - 1) {  // not last
497 2
                    $event->repeat_weekly_on .= ',';
498
                }
499 2
                $i++;
500
            }
501
        }
502
503
        // Monthly
504
505
        /* $event->repeat_type = $request->get('repeat_monthly_on');*/
506
507 21
        return $event;
508
    }
509
510
    /***************************************************************************/
511
512
    /**
513
     * Return the HTML of the monthly select dropdown - inspired by - https://www.theindychannel.com/calendar
514
     * - Used by the AJAX in the event repeat view -
515
     * - The HTML contain a <select></select> with four <options></options>.
516
     *
517
     * @param  \Illuminate\Http\Request  $request  - Just the day
518
     * @return string
519
     */
520 1
    public function calculateMonthlySelectOptions(Request $request)
521
    {
522 1
        $monthlySelectOptions = [];
523 1
        $date = implode('-', array_reverse(explode('/', $request->day)));  // Our YYYY-MM-DD date string
524 1
        $unixTimestamp = strtotime($date);  // Convert the date string into a unix timestamp.
525 1
        $dayOfWeekString = date('l', $unixTimestamp); // Monday | Tuesday | Wednesday | ..
526
527
        // Same day number - eg. "the 28th day of the month"
528 1
        $dateArray = explode('/', $request->day);
529 1
        $dayNumber = ltrim($dateArray[0], '0'); // remove the 0 in front of a day number eg. 02/10/2018
530
531 1
        $format = __('laravel-events-calendar::ordinalDays.the_'.($dayNumber).'_x_of_the_month');
532 1
        $repeatText = sprintf($format, 'day');
0 ignored issues
show
Bug introduced by
It seems like $format can also be of type array and array; however, parameter $format of sprintf() does only seem to accept string, 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

532
        $repeatText = sprintf(/** @scrutinizer ignore-type */ $format, 'day');
Loading history...
533
534 1
        array_push($monthlySelectOptions, [
535 1
            'value' => '0|'.$dayNumber,
536 1
            'text' => $repeatText,
537
        ]);
538
539
        // Same weekday/week of the month - eg. the "1st Monday" 1|1|1 (first week, monday)
540 1
            $dayOfWeekValue = date('N', $unixTimestamp); // 1 (for Monday) through 7 (for Sunday)
541 1
            $weekOfTheMonth = LaravelEventsCalendar::weekdayNumberOfMonth($date, $dayOfWeekValue); // 1 | 2 | 3 | 4 | 5
0 ignored issues
show
Bug introduced by
The method weekdayNumberOfMonth() does not exist on DavideCasiraghi\LaravelE...s\LaravelEventsCalendar. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

541
            /** @scrutinizer ignore-call */ 
542
            $weekOfTheMonth = LaravelEventsCalendar::weekdayNumberOfMonth($date, $dayOfWeekValue); // 1 | 2 | 3 | 4 | 5
Loading history...
542
543 1
            $format = __('laravel-events-calendar::ordinalDays.the_'.($weekOfTheMonth).'_x_of_the_month');
544 1
        $repeatText = sprintf($format, $dayOfWeekString);
545
546 1
        array_push($monthlySelectOptions, [
547 1
            'value' => '1|'.$weekOfTheMonth.'|'.$dayOfWeekValue,
548 1
            'text' => $repeatText,
549
        ]);
550
551
        // Same day of the month (from the end) - the 3rd to last day (0 if last day, 1 if 2nd to last day, , 2 if 3rd to last day)
552 1
            $dayOfMonthFromTheEnd = LaravelEventsCalendar::dayOfMonthFromTheEnd($unixTimestamp); // 1 | 2 | 3 | 4 | 5
0 ignored issues
show
Bug introduced by
The method dayOfMonthFromTheEnd() does not exist on DavideCasiraghi\LaravelE...s\LaravelEventsCalendar. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

552
            /** @scrutinizer ignore-call */ 
553
            $dayOfMonthFromTheEnd = LaravelEventsCalendar::dayOfMonthFromTheEnd($unixTimestamp); // 1 | 2 | 3 | 4 | 5
Loading history...
553
554 1
            $format = __('laravel-events-calendar::ordinalDays.the_'.($dayOfMonthFromTheEnd + 1).'_to_last_x_of_the_month');
555 1
        $repeatText = sprintf($format, 'day');
556
557 1
        array_push($monthlySelectOptions, [
558 1
            'value' => '2|'.$dayOfMonthFromTheEnd,
559 1
            'text' => $repeatText,
560
        ]);
561
562
        // Same weekday/week of the month (from the end) - the last Friday - (0 if last Friday, 1 if the 2nd to last Friday, 2 if the 3nd to last Friday)
563 1
            $weekOfMonthFromTheEnd = LaravelEventsCalendar::weekOfMonthFromTheEnd($unixTimestamp); // 1 | 2 | 3 | 4 | 5
0 ignored issues
show
Bug introduced by
The method weekOfMonthFromTheEnd() does not exist on DavideCasiraghi\LaravelE...s\LaravelEventsCalendar. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

563
            /** @scrutinizer ignore-call */ 
564
            $weekOfMonthFromTheEnd = LaravelEventsCalendar::weekOfMonthFromTheEnd($unixTimestamp); // 1 | 2 | 3 | 4 | 5
Loading history...
564
565 1
            if ($weekOfMonthFromTheEnd == 1) {
566
                $weekValue = 0;
567
            } else {
568 1
                $weekValue = $weekOfMonthFromTheEnd - 1;
569
            }
570
571 1
        $format = __('laravel-events-calendar::ordinalDays.the_'.($weekOfMonthFromTheEnd).'_to_last_x_of_the_month');
572 1
        $repeatText = sprintf($format, $dayOfWeekString);
573
574 1
        array_push($monthlySelectOptions, [
575 1
            'value' => '3|'.$weekValue.'|'.$dayOfWeekValue,
576 1
            'text' => $repeatText,
577
        ]);
578
579
        // GENERATE the HTML to return
580 1
        $selectTitle = __('laravel-events-calendar::general.select_repeat_monthly_kind');
581 1
        $onMonthlyKindSelect = "<select name='on_monthly_kind' id='on_monthly_kind' class='selectpicker' title='".$selectTitle."'>";
0 ignored issues
show
Bug introduced by
Are you sure $selectTitle of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

581
        $onMonthlyKindSelect = "<select name='on_monthly_kind' id='on_monthly_kind' class='selectpicker' title='"./** @scrutinizer ignore-type */ $selectTitle."'>";
Loading history...
582 1
        foreach ($monthlySelectOptions as $key => $monthlySelectOption) {
583 1
            $onMonthlyKindSelect .= "<option value='".$monthlySelectOption['value']."'>".$monthlySelectOption['text'].'</option>';
584
        }
585 1
        $onMonthlyKindSelect .= '</select>';
586
587 1
        return $onMonthlyKindSelect;
588
    }
589
590
    // **********************************************************************
591
592
    /**
593
     * Save/Update the record on DB.
594
     *
595
     * @param  \Illuminate\Http\Request $request
596
     * @param  \DavideCasiraghi\LaravelEventsCalendar\Models\Event $event
597
     * @return string $ret - the ordinal indicator (st, nd, rd, th)
598
     */
599 21
    public function saveOnDb(Request $request, Event $event)
600
    {
601
        //$countries = Country::getCountries();
602 21
        $teachers = Teacher::pluck('name', 'id');
603
604
        /*$venue = DB::table('event_venues')
605
                ->select('event_venues.id AS venue_id', 'event_venues.name AS venue_name', 'event_venues.country_id AS country_id', 'event_venues.continent_id', 'event_venues.city')
606
                ->where('event_venues.id', '=', $request->get('venue_id'))
607
                ->first();*/
608
609 21
        $event->title = $request->get('title');
610 21
        $event->description = clean($request->get('description'));
611
612 21
        if ($request->get('created_by')) {
613 21
            $event->created_by = $request->get('created_by');
614
        }
615
616 21
        if (! $event->slug) {
617 21
            $event->slug = Str::slug($event->title, '-').'-'.rand(100000, 1000000);
618
        }
619 21
        $event->category_id = $request->get('category_id');
620 21
        $event->venue_id = $request->get('venue_id');
621 21
        $event->image = $request->get('image');
622 21
        $event->contact_email = $request->get('contact_email');
623 21
        $event->website_event_link = $request->get('website_event_link');
624 21
        $event->facebook_event_link = $request->get('facebook_event_link');
625 21
        $event->status = $request->get('status');
626 21
        $event->on_monthly_kind = $request->get('on_monthly_kind');
627 21
        $event->multiple_dates = $request->get('multiple_dates');
628
629
        // Event teaser image upload
630 21
        if ($request->file('image')) {
631
            $imageFile = $request->file('image');
632
            $imageName = time().'.'.'jpg';  //$imageName = $teaserImageFile->hashName();
633
            $imageSubdir = 'events_teaser';
634
            $imageWidth = 968;
635
            $thumbWidth = 310;
636
637
            $this->uploadImageOnServer($imageFile, $imageName, $imageSubdir, $imageWidth, $thumbWidth);
0 ignored issues
show
Bug introduced by
It seems like $imageFile can also be of type Illuminate\Http\UploadedFile[] and array and null; however, parameter $imageFile of DavideCasiraghi\LaravelE...::uploadImageOnServer() 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

637
            $this->uploadImageOnServer(/** @scrutinizer ignore-type */ $imageFile, $imageName, $imageSubdir, $imageWidth, $thumbWidth);
Loading history...
638
            $event->image = $imageName;
639
        } else {
640 21
            $event->image = $request->get('image');
641
        }
642
643
        // Support columns for homepage search (we need this to show events in HP with less use of resources)
644 21
        $event->sc_teachers_id = json_encode(explode(',', $request->get('multiple_teachers'))); // keep just this SC
645
646
        // Multiple teachers - populate support column field
647 21
        $event->sc_teachers_names = '';
648 21
        if ($request->get('multiple_teachers')) {
649 2
            $multiple_teachers = explode(',', $request->get('multiple_teachers'));
650
651 2
            $multiple_teachers_names = [];
652 2
            foreach ($multiple_teachers as $key => $teacher_id) {
653 2
                $multiple_teachers_names[] = $teachers[$teacher_id];
654
            }
655
656 2
            $event->sc_teachers_names .= LaravelEventsCalendar::getStringFromArraySeparatedByComma($multiple_teachers_names);
0 ignored issues
show
Bug introduced by
The method getStringFromArraySeparatedByComma() does not exist on DavideCasiraghi\LaravelE...s\LaravelEventsCalendar. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

656
            $event->sc_teachers_names .= LaravelEventsCalendar::/** @scrutinizer ignore-call */ getStringFromArraySeparatedByComma($multiple_teachers_names);
Loading history...
657
        }
658
659
        // Set the Event attributes about repeating (repeat until field and multiple days)
660 21
        $event = $this->setEventRepeatFields($request, $event);
661
662
        // Save event and repetitions
663 21
        $event->save();
664 21
        $this->saveEventRepetitions($request, $event->id);
665
666
        // Update multi relationships with teachers and organizers tables.
667 21
        if ($request->get('multiple_teachers')) {
668 2
            $multiple_teachers = explode(',', $request->get('multiple_teachers'));
669 2
            $event->teachers()->sync($multiple_teachers);
670
        } else {
671 19
            $event->teachers()->sync([]);
672
        }
673 21
        if ($request->get('multiple_organizers')) {
674
            $multiple_organizers = explode(',', $request->get('multiple_organizers'));
675
            $event->organizers()->sync($multiple_organizers);
676
        } else {
677 21
            $event->organizers()->sync([]);
678
        }
679 21
    }
680
681
    /***********************************************************************/
682
683
    /**
684
     * Get creator email.
685
     *
686
     * @param  int $created_by
687
     * @return \Illuminate\Foundation\Auth\User
688
     */
689
    public function getCreatorEmail(int $created_by)
690
    {
691
        $creatorEmail = DB::table('users')  // Used to send the Report misuse (not in english)
692
                ->select('email')
693
                ->where('id', $created_by)
694
                ->first();
695
696
        $ret = $creatorEmail->email;
697
698
        return $ret;
699
    }
700
701
    /***************************************************************************/
702
703
    /**
704
     * Return the event by SLUG. (eg. http://websitename.com/event/xxxx).
705
     *
706
     * @param  string  $slug
707
     * @return \Illuminate\Http\Response
708
     */
709 1
    public function eventBySlug(string $slug)
710
    {
711 1
        $event = Event::where('slug', $slug)->first();
712 1
        $firstRpDates = EventRepetition::getFirstEventRpDatesByEventId($event->id);
713
714 1
        return $this->show($event, $firstRpDates);
715
    }
716
717
    /***************************************************************************/
718
719
    /**
720
     * Return the event by SLUG. (eg. http://websitename.com/event/xxxx/300).
721
     * @param  string $slug
722
     * @param  int $repetitionId
723
     * @return \Illuminate\Http\Response
724
     */
725 4
    public function eventBySlugAndRepetition(string $slug, int $repetitionId)
726
    {
727 4
        $event = Event::where('slug', $slug)->first();
728 4
        $firstRpDates = EventRepetition::getFirstEventRpDatesByRepetitionId($repetitionId);
729
730
        // If not found get the first repetion of the event in the future.
731 4
        if (empty($firstRpDates)) {
732 1
            $firstRpDates = EventRepetition::getFirstEventRpDatesByEventId($event->id);
733
        }
734
735 4
        return $this->show($event, $firstRpDates);
736
    }
737
738
    /***************************************************************************/
739
740
    /**
741
     * Return the Event validator with all the defined constraint.
742
     * @param  \Illuminate\Http\Request  $request
743
     * @return \Illuminate\Http\Response
744
     */
745 22
    public function eventsValidator(Request $request)
746
    {
747
        $rules = [
748 22
            'title' => 'required',
749 22
            'description' => 'required',
750 22
            'category_id' => 'required',
751 22
            'venue_id' => 'required',
752 22
            'startDate' => 'required',
753 22
            'endDate' => 'required',
754 22
            'repeat_until' => Rule::requiredIf($request->repeat_type == 2 || $request->repeat_type == 3),
755 22
            'repeat_weekly_on_day' => Rule::requiredIf($request->repeat_type == 2),
756 22
            'on_monthly_kind' => Rule::requiredIf($request->repeat_type == 3),
757 22
            'contact_email' => 'nullable|email',
758 22
            'facebook_event_link' => 'nullable|url',
759 22
            'website_event_link' => 'nullable|url',
760
            // 'image' => 'nullable|image|mimes:jpeg,jpg,png|max:3000', // BUG create problems to validate on edit. Fix this after the rollout
761
        ];
762 22
        if ($request->hasFile('image')) {
763
            $rules['image'] = 'nullable|image|mimes:jpeg,jpg,png|max:5000';
764
        }
765
766
        $messages = [
767 22
            'repeat_weekly_on_day[].required' => 'Please specify which day of the week is repeting the event.',
768
            'on_monthly_kind.required' => 'Please specify the kind of monthly repetion',
769
            'endDate.same' => 'If the event is repetitive the start date and end date must match',
770
            'facebook_event_link.url' => 'The facebook link is invalid. It should start with https://',
771
            'website_event_link.url' => 'The website link is invalid. It should start with https://',
772
            'image.max' => 'The maximum image size is 5MB. If you need to resize it you can use: www.simpleimageresizer.com',
773
        ];
774
775 22
        $validator = Validator::make($request->all(), $rules, $messages);
776
777
        // End date and start date must match if the event is repetitive
778
        $validator->sometimes('endDate', 'same:startDate', function ($input) {
779 22
            return $input->repeat_type > 1;
780 22
        });
781
782 22
        return $validator;
783
    }
784
}
785