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

Event::preSave()   B

Complexity

Conditions 6
Paths 16

Size

Total Lines 56
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 6.288

Importance

Changes 0
Metric Value
eloc 35
c 0
b 0
f 0
dl 0
loc 56
ccs 28
cts 35
cp 0.8
rs 8.7377
cc 6
nc 16
nop 1
crap 6.288

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace DavideCasiraghi\LaravelEventsCalendar\Models;
4
5
use Carbon\Carbon;
6
use DavideCasiraghi\LaravelEventsCalendar\Facades\LaravelEventsCalendar;
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Support\Facades\Cache;
9
use DavideCasiraghi\LaravelEventsCalendar\Models\Teacher;
10
11
use Illuminate\Http\Request; // to remove
12
use Illuminate\Support\Str;
13
14
class Event extends Model
15
{
16
    /***************************************************************************/
17
    /**
18
     * The table associated with the model.
19
     *
20
     * @var string
21
     */
22
    protected $table = 'events';
23
24
    /***************************************************************************/
25
26
    protected $fillable = [
27
        'title',
28
        'description',
29
        'organized_by',
30
        'category_id',
31
        'venue_id',
32
        'image',
33
        'facebook_event_link',
34
        'website_event_link',
35
        'status',
36
        'repeat_type',
37
        'repeat_until',
38
        'repeat_weekly_on',
39
        'repeat_monthly_on',
40
        'on_monthly_kind',
41
        'multiple_dates',
42
    ];
43
44
    /***************************************************************************/
45
46
    /**
47
     * Get the user that owns the event. eg. $event->user.
48
     */
49
    public function user()
50
    {
51
        return $this->belongsTo('\Illuminate\Foundation\Auth\User', 'created_by');
52
    }
53
54
    /***************************************************************************/
55
56
    /**
57
     * Get the teachers for the event.
58
     */
59 33
    public function teachers()
60
    {
61 33
        return $this->belongsToMany('DavideCasiraghi\LaravelEventsCalendar\Models\Teacher', 'event_has_teachers', 'event_id', 'teacher_id');
62
    }
63
64
    /***************************************************************************/
65
66
    /**
67
     * Get the organizers for the event.
68
     */
69 33
    public function organizers()
70
    {
71 33
        return $this->belongsToMany('DavideCasiraghi\LaravelEventsCalendar\Models\Organizer', 'event_has_organizers', 'event_id', 'organizer_id');
72
    }
73
74
    /***************************************************************************/
75
76
    /**
77
     * Get the organizers for the event.
78
     */
79 1
    public function eventRepetitions()
80
    {
81 1
        return $this->hasMany('DavideCasiraghi\LaravelEventsCalendar\Models\EventRepetition', 'event_id');
82
    }
83
84
    /***************************************************************************/
85
86
    /**
87
     * Return an array with active events datas.
88
     *
89
     * @return array
90
     */
91 2
    public static function getActiveEvents()
92
    {
93 2
        $seconds = 86400; // One day (this cache tag get invalidates also on event save)
94
95
        $ret = Cache::remember('active_events', $seconds, function () {
96 2
            date_default_timezone_set('Europe/Rome');
97 2
            $searchStartDate = date('Y-m-d', time());
98 2
            $lastestEventsRepetitionsQuery = EventRepetition::getLastestEventsRepetitionsQuery($searchStartDate, null);
99
100
            return self::
101 2
                    select('events.id as id', 'title', 'countries.name AS country_name', 'countries.id AS country_id', 'countries.continent_id AS continent_id', 'event_venues.city AS city', 'events.repeat_until', 'events.category_id', 'events.created_by', 'events.repeat_type')
102 2
                    ->join('event_venues', 'event_venues.id', '=', 'events.venue_id')
103 2
                    ->join('countries', 'countries.id', '=', 'event_venues.country_id')
104
                    ->joinSub($lastestEventsRepetitionsQuery, 'event_repetitions', function ($join) {
105 2
                        $join->on('events.id', '=', 'event_repetitions.event_id');
106 2
                    })
107 2
                    ->get();
108
109
            /* EVERY TIME THIS QUERY CHANGE REMEMBER TO FLUSH THE CACHE
110
            (php artisan cache:clear) */
111 2
        });
112
113 2
        return $ret;
114
    }
115
116
    /***************************************************************************/
117
118
    /**
119
     * Return the active events based on the search keys provided.
120
     *
121
     * @param array $filters
122
     * @param int $itemPerPage
123
     * @return \DavideCasiraghi\LaravelEventsCalendar\Models\Event
124
     */
125
    //$keywords, $category, $city, $country, $continent, $teacher, $venue, $startDate, $endDate,
126 2
    public static function getEvents(array $filters, $itemPerPage)
127
    {
128 2
        if (! array_key_exists('startDate', $filters) || ! $filters['startDate']) {
129 2
            $filters['startDate'] = Carbon::now()->format('Y-m-d');
130
        }
131
132
        // Sub-Query Joins - https://laravel.com/docs/5.7/queries
133 2
        $lastestEventsRepetitionsQuery = EventRepetition::getLastestEventsRepetitionsQuery($filters['startDate'], $filters['endDate']);
134
135
        // Retrieve the events that correspond to the selected filters
136 2
        if ($filters['keywords'] || $filters['category'] || $filters['city'] || $filters['country'] || $filters['region'] || $filters['continent'] || $filters['teacher'] || $filters['venue'] || $filters['endDate']) {
137
138
        //$start = microtime(true);
139
            //DB::enableQueryLog();
140
            $ret = self::
141 1
                    select('events.title', 'events.category_id', 'events.slug', 'event_venues.name as venue_name', 'event_venues.city as city_name', 'countries.name as country_name', 'events.sc_teachers_names', 'event_repetitions.start_repeat', 'event_repetitions.end_repeat')
142
                    ->when($filters['keywords'], function ($query, $keywords) {
143 1
                        return $query->where('title', 'like', '%'.$keywords.'%');
144 1
                    })
145
                    ->when($filters['category'], function ($query, $category) {
146 1
                        return $query->where('category_id', '=', $category);
147 1
                    })
148
                    ->when($filters['teacher'], function ($query, $teacher) {
149
                        return $query->whereRaw('json_contains(sc_teachers_id, \'["'.$teacher.'"]\')');
150 1
                    })
151
                    ->when($filters['country'], function ($query, $country) {
152 1
                        return $query->where('event_venues.country_id', '=', $country);
153 1
                    })
154
                    ->when($filters['region'], function ($query, $region) {
155 1
                        return $query->where('event_venues.region_id', '=', $region);
156 1
                    })
157
                    ->when($filters['continent'], function ($query, $continent) {
158 1
                        return $query->where('event_venues.continent_id', '=', $continent);  //sc_continent_id
159 1
                    })
160
                    ->when($filters['city'], function ($query, $city) {
161 1
                        return $query->where('event_venues.city', 'like', '%'.$city.'%');
162 1
                    })
163
                    ->when($filters['venue'], function ($query, $venue) {
164 1
                        return $query->where('event_venues.name', 'like', '%'.$venue.'%');
165 1
                    })
166
                    ->joinSub($lastestEventsRepetitionsQuery, 'event_repetitions', function ($join) {
167 1
                        $join->on('events.id', '=', 'event_repetitions.event_id');
168 1
                    })
169
170 1
                    ->leftJoin('event_venues', 'events.venue_id', '=', 'event_venues.id')
171 1
                    ->leftJoin('continents', 'event_venues.continent_id', '=', 'continents.id')
172 1
                    ->leftJoin('countries', 'event_venues.country_id', '=', 'countries.id')
173 1
                    ->leftJoin('regions', 'event_venues.region_id', '=', 'regions.id')
174
175 1
                    ->orderBy('event_repetitions.start_repeat', 'asc')
176 1
                    ->paginate($itemPerPage);
177
        //dd(DB::getQueryLog());
178
179
        //$time = microtime(true) - $start;
180
        //dd($time);
181
        }
182
        // If no filter selected retrieve all the events
183
        else {
184
            $ret = self::
185 1
                        select('events.title', 'events.category_id', 'events.slug', 'event_venues.name as venue_name', 'event_venues.city as city_name', 'countries.name as country_name', 'events.sc_teachers_names', 'event_repetitions.start_repeat', 'event_repetitions.end_repeat')
186
                        ->joinSub($lastestEventsRepetitionsQuery, 'event_repetitions', function ($join) {
187 1
                            $join->on('events.id', '=', 'event_repetitions.event_id');
188 1
                        })
189 1
                        ->leftJoin('event_venues', 'events.venue_id', '=', 'event_venues.id')
190 1
                        ->leftJoin('continents', 'event_venues.continent_id', '=', 'continents.id')
191 1
                        ->leftJoin('countries', 'event_venues.country_id', '=', 'countries.id')
192 1
                        ->leftJoin('regions', 'event_venues.region_id', '=', 'regions.id')
193
194 1
                        ->orderBy('event_repetitions.start_repeat', 'asc')
195 1
                        ->paginate($itemPerPage);
196
197
            // It works, but I don't use it now to develop
198
                /*$cacheExpireMinutes = 15;
199
                $events = Cache::remember('all_events', $cacheExpireTime, function () {
200
                    return DB::table('events')->latest()->paginate(20);
201
                });*/
202
        }
203
204 2
        return $ret;
205
    }
206
207
    /***************************************************************************/
208
209
    /**
210
     * Return a cached JSON with active events map markers.
211
     *
212
     * @return array
213
     */
214 2
    public static function getActiveEventsMapGeoJSON()
215
    {
216 2
        $cacheExpireMinutes = 1440; // Set the duration time of the cache (1 day - 1440 minutes) - this cache tag get invalidates also on event save
217
218
        $eventsMapGeoJSONArrayCached = Cache::remember('active_events_map_markers_json', $cacheExpireMinutes, function () {
219 2
            $eventsData = self::getActiveEventsMapMarkersDataFromDb();
220 2
            $eventsMapGeoJSONArray = [];
221 2
            foreach ($eventsData as $key => $eventData) {
222
                //dd($eventData);
223
224
                // Generates event link
225 2
                $nextEventRepetitionId = EventRepetition::getFirstEventRpIdByEventId($eventData->id);
226 2
                $eventLinkformat = 'event/%s/%s';   //event/{{$event->slug}}/{{$event->rp_id}}
227 2
                $eventLink = sprintf($eventLinkformat, $eventData->event_slug, $nextEventRepetitionId);
228
229
                // Get Next event occurrence date
230 2
                $nextDateOccurence = EventRepetition::getFirstFutureEventRpDatesByEventId($eventData->id);
231 2
                if (! empty($nextDateOccurence)) {
232 2
                    $nextDate = Carbon::parse($nextDateOccurence->start_repeat)->isoFormat('D MMM YYYY');
233
                } else {
234
                    $nextDate = '';
235
                }
236
237 2
                $address = (! empty($eventData->address)) ? ', '.$eventData->address : '';
238 2
                $city = (! empty($eventData->city)) ? $eventData->city : '';
239
240
                // Add one element to the Geo array
241 2
                $eventsMapGeoJSONArray[] = [
242 2
                    'type' => 'Feature',
243 2
                    'id' => $eventData->id,
244
                    'properties' => [
245 2
                        'Title' => $eventData->title,
246 2
                        'Category' => EventCategory::getCategoryName($eventData->category_id),
247 2
                        'VenueName' => EventVenue::getVenueName($eventData->venue_id),
248 2
                        'City' => $city,
249 2
                        'Address' => $address,
250 2
                        'Link' => $eventLink,
251 2
                        'NextDate' => $nextDate,
252 2
                        'IconColor' => LaravelEventsCalendar::getMapMarkerIconColor($eventData->category_id),
0 ignored issues
show
Bug introduced by
The method getMapMarkerIconColor() 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

252
                        'IconColor' => LaravelEventsCalendar::/** @scrutinizer ignore-call */ getMapMarkerIconColor($eventData->category_id),
Loading history...
253
                    ],
254
                    'geometry' => [
255 2
                        'type' => 'Point',
256 2
                        'coordinates' => [$eventData->lng, $eventData->lat],
257
                    ],
258
                ];
259
            }
260
261
            /* EVERY TIME THIS CHANGE REMEMBER TO FLUSH THE CACHE
262
            (php artisan cache:clear) */
263
264 2
            return $eventsMapGeoJSONArray;
265 2
        });
266
267 2
        $ret = json_encode($eventsMapGeoJSONArrayCached);
268
269 2
        return $ret;
270
    }
271
272
    /***************************************************************************/
273
274
    /**
275
     * Return an array with active events map markers.
276
     *
277
     * @return array
278
     */
279 4
    public static function getActiveEventsMapMarkersDataFromDb()
280
    {
281 4
        $seconds = 86400; // One day (this cache tag get invalidates also on event save)
282
283
        $ret = Cache::remember('active_events_map_markers_db_data', $seconds, function () {
284 4
            date_default_timezone_set('Europe/Rome');
285 4
            $searchStartDate = Carbon::now()->format('Y-m-d');
286 4
            $lastestEventsRepetitionsQuery = EventRepetition::getLastestEventsRepetitionsQuery($searchStartDate, null);
287
288
            return self::
289 4
                    select('events.id AS id',
290 4
                    'events.title AS title',
291 4
                    'events.slug AS event_slug',
292 4
                    'event_venues.id AS venue_id',
293 4
                    'event_venues.city AS city',
294 4
                    'event_venues.address AS address',
295 4
                    'event_venues.lat AS lat',
296 4
                    'event_venues.lng AS lng',
297 4
                    'events.repeat_until',
298 4
                    'events.category_id',
299 4
                    'events.created_by',
300 4
                    'events.repeat_type'
301
                    )
302 4
            ->join('event_venues', 'event_venues.id', '=', 'events.venue_id')
303 4
            ->join('countries', 'countries.id', '=', 'event_venues.country_id')
304
            ->joinSub($lastestEventsRepetitionsQuery, 'event_repetitions', function ($join) {
305 4
                $join->on('events.id', '=', 'event_repetitions.event_id');
306 4
            })
307 4
            ->get();
308
309
            /* EVERY TIME THIS QUERY CHANGE REMEMBER TO FLUSH THE CACHE
310
            (php artisan cache:clear) */
311 4
        });
312
313 4
        return $ret;
314
    }
315
316
    /***************************************************************************/
317
318
    /**
319
     * Return true if an event is in the future.
320
     *
321
     * @return array
322
     */
323 2
    public function isActive(): bool
324
    {
325 2
        $firstEventRepetitionIdInFuture = EventRepetition::getFirstEventRpIdByEventId($this->id);
326
327 2
        if (! empty($firstEventRepetitionIdInFuture)) {
328 2
            return true;
329
        } else {
330 1
            return false;
331
        }
332
    }
333
    
334
    // **********************************************************************
335
336
    /**
337
     * Save/Update the record on DB.
338
     *
339
     * @param  \Illuminate\Http\Request $request
340
     * @return void
341
     */
342 33
     public function preSave(Request $request): void
343
     {
344 33
         $teachers = Teacher::pluck('name', 'id');
345
346 33
         $this->title = $request->get('title');
347 33
         $this->description = clean($request->get('description'));
348
349 33
         if ($request->get('created_by')) {
350 33
             $this->created_by = $request->get('created_by');
351
         }
352
353 33
         if (! $this->slug) {
354 33
             $this->slug = Str::slug($this->title, '-').'-'.rand(100000, 1000000);
355
         }
356 33
         $this->category_id = $request->get('category_id');
357 33
         $this->venue_id = $request->get('venue_id');
358 33
         $this->image = $request->get('image');
359 33
         $this->contact_email = $request->get('contact_email');
360 33
         $this->website_event_link = $request->get('website_event_link');
361 33
         $this->facebook_event_link = $request->get('facebook_event_link');
362 33
         $this->status = $request->get('status');
363 33
         $this->on_monthly_kind = $request->get('on_monthly_kind');
364 33
         $this->multiple_dates = $request->get('multiple_dates');
365
366
         // Event teaser image upload
367 33
         if ($request->file('image')) {
368
             $imageFile = $request->file('image');
369
             $imageName = time().'.'.'jpg';  //$imageName = $teaserImageFile->hashName();
370
             $imageSubdir = 'events_teaser';
371
             $imageWidth = 968;
372
             $thumbWidth = 310;
373
374
             LaravelEventsCalendar::uploadImageOnServer($imageFile, $imageName, $imageSubdir, $imageWidth, $thumbWidth);
0 ignored issues
show
Bug introduced by
The method uploadImageOnServer() 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

374
             LaravelEventsCalendar::/** @scrutinizer ignore-call */ 
375
                                    uploadImageOnServer($imageFile, $imageName, $imageSubdir, $imageWidth, $thumbWidth);
Loading history...
375
             $this->image = $imageName;
376
         } else {
377 33
             $this->image = $request->get('image');
378
         }
379
380
         // Support columns for homepage search (we need this to show events in HP with less use of resources)
381 33
         $this->sc_teachers_id = json_encode(explode(',', $request->get('multiple_teachers'))); // keep just this SC
382
383
         // Multiple teachers - populate support column field
384 33
         $this->sc_teachers_names = '';
385 33
         if ($request->get('multiple_teachers')) {
386 2
             $multiple_teachers = explode(',', $request->get('multiple_teachers'));
387
388 2
             $multiple_teachers_names = [];
389 2
             foreach ($multiple_teachers as $key => $teacher_id) {
390 2
                 $multiple_teachers_names[] = $teachers[$teacher_id];
391
             }
392
393 2
             $this->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

393
             $this->sc_teachers_names .= LaravelEventsCalendar::/** @scrutinizer ignore-call */ getStringFromArraySeparatedByComma($multiple_teachers_names);
Loading history...
394
         }
395
396
         // Set the Event attributes about repeating (repeat until field and multiple days)
397 33
         $this->setEventRepeatFields($request);
398
399
         // Save event and repetitions
400
         //$this->save();
401
         //$this->saveEventRepetitions($request, $this->id);
402
403 33
     }
404
     
405
     /***************************************************************************/
406
     
407
     /**
408
      * Set the Event attributes about repeating before store or update (repeat until field and multiple days).
409
      *
410
      * @param  \Illuminate\Http\Request  $request
411
      * @return void
412
      */
413 33
     public function setEventRepeatFields(Request $request)
414
     {
415
         // Set Repeat Until
416 33
         $this->repeat_type = $request->get('repeat_type');
417 33
         if ($request->get('repeat_until')) {
418 7
             $dateRepeatUntil = implode('-', array_reverse(explode('/', $request->get('repeat_until'))));
419 7
             $this->repeat_until = $dateRepeatUntil.' 00:00:00';
420
         }
421
422
         // Weekely - Set multiple week days
423 33
         if ($request->get('repeat_weekly_on_day')) {
424 2
             $repeat_weekly_on_day = $request->get('repeat_weekly_on_day');
425
             //dd($repeat_weekly_on_day);
426 2
             $i = 0;
427 2
             $len = count($repeat_weekly_on_day); // to put "," to all items except the last
428 2
             $this->repeat_weekly_on = '';
429 2
             foreach ($repeat_weekly_on_day as $key => $weeek_day) {
430 2
                 $this->repeat_weekly_on .= $weeek_day;
431 2
                 if ($i != $len - 1) {  // not last
432 2
                     $this->repeat_weekly_on .= ',';
433
                 }
434 2
                 $i++;
435
             }
436
         }
437 33
     }
438
439
     /***************************************************************************/
440
441
}
442