Completed
Push — master ( a18731...e2e070 )
by
unknown
99:54 queued 47:45
created

LoadUsersCalendarData::getRecurringEvents()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 120
Code Lines 110

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 120
rs 8.2857
c 0
b 0
f 0
cc 1
eloc 110
nc 1
nop 0

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 OroCRM\Bundle\DemoDataBundle\Migrations\Data\Demo\ORM;
4
5
use Doctrine\Common\Collections\Criteria;
6
use Doctrine\Common\DataFixtures\AbstractFixture;
7
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
8
use Doctrine\Common\Persistence\ObjectManager;
9
use Doctrine\ORM\EntityManager;
10
use Doctrine\ORM\EntityRepository;
11
12
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
13
use Symfony\Component\DependencyInjection\ContainerInterface;
14
use Symfony\Component\Security\Core\SecurityContext;
15
16
use Oro\Bundle\CalendarBundle\Entity\Calendar;
17
use Oro\Bundle\CalendarBundle\Entity\CalendarEvent;
18
use Oro\Bundle\CalendarBundle\Entity\CalendarProperty;
19
use Oro\Bundle\CalendarBundle\Entity\Recurrence;
20
use Oro\Bundle\CalendarBundle\Entity\Repository\CalendarRepository;
21
use Oro\Bundle\CalendarBundle\Model;
22
use Oro\Bundle\OrganizationBundle\Entity\Organization;
23
use Oro\Bundle\SecurityBundle\Authentication\Token\UsernamePasswordOrganizationToken;
24
use Oro\Bundle\UserBundle\Entity\User;
25
26
class LoadUsersCalendarData extends AbstractFixture implements ContainerAwareInterface, DependentFixtureInterface
27
{
28
    /** @var ContainerInterface */
29
    private $container;
30
31
    /** @var User[] */
32
    private $users;
33
34
    /** @var EntityRepository */
35
    protected $user;
36
37
    /** @var CalendarRepository */
38
    protected $calendar;
39
40
    /** @var Organization */
41
    protected $organization;
42
43
    /** @var EntityManager */
44
    protected $em;
45
46
    /** @var SecurityContext */
47
    protected $securityContext;
48
49
    /** @var \DateTimeZone */
50
    protected $timeZone;
51
52
    /**
53
     * {@inheritdoc}
54
     */
55
    public function getDependencies()
56
    {
57
        return [
58
            'OroCRM\Bundle\DemoDataBundle\Migrations\Data\Demo\ORM\LoadUsersData',
59
            'OroCRM\Bundle\DemoDataBundle\Migrations\Data\Demo\ORM\LoadUserData'
60
        ];
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66
    public function setContainer(ContainerInterface $container = null)
67
    {
68
        $this->container = $container;
69
70
        $this->em              = $container->get('doctrine')->getManager();
0 ignored issues
show
Bug introduced by
It seems like $container is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
71
        $this->securityContext = $container->get('security.context');
72
73
        $this->user     = $this->em->getRepository('OroUserBundle:User');
74
        $this->calendar = $this->em->getRepository('OroCalendarBundle:Calendar');
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80
    public function load(ObjectManager $manager)
81
    {
82
        $this->users = $this->user->findAll();
83
        $this->organization = $this->getReference('default_organization');
84
85
        $this->loadCalendars();
86
        $this->connectCalendars();
87
    }
88
89
    protected function loadCalendars()
90
    {
91
        $days   = $this->getDatePeriod();
92
        $events = [];
93
        foreach ($days as $day) {
94
            /** @var \DateTime $day */
95
            if (!$this->isWeekend($day)) {
96
                //work day
97
                $event = new CalendarEvent();
98
                $event->setTitle('Work Reminder');
99
                $day->setTime(8, 0, 0);
100
                $event->setStart(clone $day);
101
                $day->setTime(18, 0, 0);
102
                $event->setEnd(clone $day);
103
                $event->setAllDay(true);
104
105
                $events['workday'][] = $event;
106
107
                //call
108
                $event = new CalendarEvent();
109
                $event->setTitle('Client Call');
110
                $day->setTime(11, 0, 0);
111
                $event->setStart(clone $day);
112
                $day->setTime(12, 0, 0);
113
                $event->setEnd(clone $day);
114
                $event->setAllDay(false);
115
116
                $events['call'][] = $event;
117
118
                //meeting
119
                $event = new CalendarEvent();
120
                $event->setTitle('Meeting');
121
                $day->setTime(16, 0, 0);
122
                $event->setStart(clone $day);
123
                $day->setTime(18, 0, 0);
124
                $event->setEnd(clone $day);
125
                $event->setAllDay(false);
126
127
                $events['meeting'][] = $event;
128
129
                //lunch
130
                $event = new CalendarEvent();
131
                $event->setTitle('Lunch');
132
                $day->setTime(12, 0, 0);
133
                $event->setStart(clone $day);
134
                $day->setTime(12, 30, 0);
135
                $event->setEnd(clone $day);
136
                $event->setAllDay(false);
137
138
                $events['lunch'][] = $event;
139
140
                //business trip
141
                $event = new CalendarEvent();
142
                $event->setTitle('Business trip');
143
                $day->setTime(0, 0, 0);
144
                $event->setStart(clone $day);
145
                $day->setTime(0, 0, 0);
146
                $day->add(\DateInterval::createFromDateString('+3 days'));
147
                $event->setEnd(clone $day);
148
                $event->setAllDay(true);
149
150
                $events['b_trip'][] = $event;
151
            } else {
152
                $event = new CalendarEvent();
153
                $event->setTitle('Weekend');
154
                $day->setTime(8, 0, 0);
155
                $event->setStart(clone $day);
156
                $day->setTime(18, 0, 0);
157
                $event->setEnd(clone $day);
158
                $event->setAllDay(true);
159
160
                $events['weekend'][] = $event;
161
            }
162
        }
163
164
        foreach ($this->users as $user) {
165
            //get default calendar, each user has default calendar after creation
166
            $calendar = $this->calendar->findDefaultCalendar($user->getId(), $this->organization->getId());
167
            $this->setSecurityContext($calendar->getOwner());
168
            //recurring events
169
            $events['recurring_events'] = $this->getRecurringEvents();
170
            foreach ($events as $typeEvents) {
171
                if (mt_rand(0, 1)) {
172
                    foreach ($typeEvents as $typeEvent) {
173
                        $calendar->addEvent(clone $typeEvent);
174
                    }
175
                }
176
            }
177
178
            $this->em->persist($calendar);
0 ignored issues
show
Bug introduced by
It seems like $calendar defined by $this->calendar->findDef...>organization->getId()) on line 166 can also be of type null; however, Doctrine\ORM\EntityManager::persist() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
179
        }
180
181
        $this->em->flush();
182
        $this->em->clear('Oro\Bundle\CalendarBundle\Entity\CalendarEvent');
183
        $this->em->clear('Oro\Bundle\CalendarBundle\Entity\Calendar');
184
185
        $this->addRecurringEventExceptions();
186
    }
187
188
    protected function connectCalendars()
189
    {
190
        // first user is admin, often
191
        /** @var \Oro\Bundle\UserBundle\Entity\User $admin */
192
        $admin = $this->user->find(1);
193
        /** @var Calendar $calendarAdmin */
194
        $calendarAdmin = $this->calendar->findDefaultCalendar($admin->getId(), $admin->getOrganization()->getId());
195
196
        /** @var \Oro\Bundle\UserBundle\Entity\User $sale */
197
        $sale = $this->user->findOneBy(['username' => 'sale']);
198
        /** @var Calendar $calendarSale */
199
        $calendarSale = $this->calendar->findDefaultCalendar($sale->getId(), $sale->getOrganization()->getId());
200
201
        /** @var \Oro\Bundle\UserBundle\Entity\User $market */
202
        $market = $this->user->findOneBy(['username' => 'marketing']);
203
        /** @var Calendar $calendarMarket */
204
        $calendarMarket = $this->calendar->findDefaultCalendar($market->getId(), $market->getOrganization()->getId());
205
206
        /** @var User[] $users */
207
        $users = $this->getRandomUsers();
208
209
        foreach ($users as $user) {
210
            if (in_array($user->getId(), [$admin->getId(), $sale->getId(), $market->getId()])) {
211
                //to prevent self assignment
212
                continue;
213
            }
214
            /** @var Calendar $calendar */
215
            $calendar = $this->calendar->findDefaultCalendar($user->getId(), $user->getOrganization()->getId());
216
217 View Code Duplication
            if (mt_rand(0, 1)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
218
                $calendarProperty = new CalendarProperty();
219
                $calendarProperty
220
                    ->setTargetCalendar($calendarAdmin)
221
                    ->setCalendarAlias('user')
222
                    ->setCalendar($calendar->getId());
223
224
                $this->em->persist($calendarProperty);
225
            }
226
227 View Code Duplication
            if (mt_rand(0, 1)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
228
                $calendarProperty = new CalendarProperty();
229
                $calendarProperty
230
                    ->setTargetCalendar($calendarSale)
231
                    ->setCalendarAlias('user')
232
                    ->setCalendar($calendar->getId());
233
234
                $this->em->persist($calendarProperty);
235
            }
236
237 View Code Duplication
            if (mt_rand(0, 1)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
238
                $calendarProperty = new CalendarProperty();
239
                $calendarProperty
240
                    ->setTargetCalendar($calendarMarket)
241
                    ->setCalendarAlias('user')
242
                    ->setCalendar($calendar->getId());
243
244
                $this->em->persist($calendarProperty);
245
            }
246
247
            $this->em->persist($calendar);
248
        }
249
250
        $this->em->flush();
251
    }
252
253
    /**
254
     * @param int $limit
255
     *
256
     * @return User[]
257
     */
258
    protected function getRandomUsers($limit = 5)
259
    {
260
        $userIds = $this->user->createQueryBuilder('u')
261
            ->select('u.id')
262
            ->getQuery()
263
            ->getScalarResult();
264
265
        if (count($userIds) > $limit) {
266
            $rawList = [];
267
            foreach ($userIds as $key => $value) {
268
                // due array_rand() will pick only keywords
269
                $rawList[$value['id']] = null;
270
            }
271
272
            $keyList = array_rand($rawList, $limit);
273
274
            $criteria = new Criteria();
275
            $criteria->where(Criteria::expr()->in('id', $keyList));
276
277
            $result = $this->user->createQueryBuilder('u')
278
                ->addCriteria($criteria)
279
                ->getQuery()
280
                ->getResult();
281
        } else {
282
            $result = $this->users;
283
        }
284
285
        return $result;
286
    }
287
288
    /**
289
     * @return \DatePeriod
290
     */
291
    protected function getDatePeriod()
292
    {
293
        $month = new \DatePeriod(
294
            new \DateTime('now'),
295
            \DateInterval::createFromDateString('+1 day'),
296
            new \DateTime('now +1 month'),
297
            \DatePeriod::EXCLUDE_START_DATE
298
        );
299
300
        return $month;
301
    }
302
303
    /**
304
     * @param \DateTime $date
305
     * @return bool
306
     */
307
    protected function isWeekend($date)
308
    {
309
        $day = date('w', $date->getTimestamp());
310
        if ($day == 0 || $day == 6) {
311
            return true;
312
        }
313
314
        return false;
315
    }
316
317
    /**
318
     * @param User $user
319
     */
320
    protected function setSecurityContext(User $user)
321
    {
322
        $token = new UsernamePasswordOrganizationToken($user, $user->getUsername(), 'main', $this->organization);
323
        $this->securityContext->setToken($token);
0 ignored issues
show
Deprecated Code introduced by
The method Symfony\Component\Securi...rityContext::setToken() has been deprecated with message: since version 2.6, to be removed in 3.0. Use TokenStorageInterface::setToken() instead. {@inheritdoc}

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
324
    }
325
326
    /**
327
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
328
     *
329
     * Returns the list of recurring events.
330
     *
331
     * @return array
332
     */
333
    protected function getRecurringEvents()
334
    {
335
        $recurringEvents = [];
336
337
        $day = new \DateTime('+2 day', $this->getTimeZone());
338
        $event = new CalendarEvent();
339
        $event->setTitle('Gym Visiting');
340
        $day->setTime(19, 0, 0);
341
        $event->setEnd(clone $day);
342
        $day->setTime(18, 0, 0);
343
        $event->setStart(clone $day);
344
        $event->setAllDay(true);
345
        $recurrence = new Recurrence();
346
        $recurrence->setRecurrenceType(Model\Recurrence::TYPE_DAILY);
347
        $recurrence->setInterval(3)
348
            ->setTimeZone('America/Los_Angeles')
349
            ->setStartTime($day)
350
            ->setOccurrences(12);
351
        $event->setRecurrence($recurrence);
352
        $recurringEvents[] = $event;
353
354
        $day = new \DateTime('+1 day', $this->getTimeZone());
355
        $event = new CalendarEvent();
356
        $event->setTitle('Standup meeting');
357
        $day->setTime(10, 15, 0);
358
        $event->setEnd(clone $day);
359
        $day->setTime(10, 0, 0);
360
        $event->setStart(clone $day);
361
        $event->setAllDay(true);
362
        $recurrence = new Recurrence();
363
        $recurrence->setRecurrenceType(Model\Recurrence::TYPE_WEEKLY);
364
        $recurrence->setInterval(1)
365
            ->setTimeZone('America/Los_Angeles')
366
            ->setDayOfWeek([
367
                Model\Recurrence::DAY_MONDAY,
368
                Model\Recurrence::DAY_TUESDAY,
369
                Model\Recurrence::DAY_WEDNESDAY,
370
                Model\Recurrence::DAY_THURSDAY,
371
                Model\Recurrence::DAY_FRIDAY
372
            ])
373
            ->setStartTime($day);
374
        $event->setRecurrence($recurrence);
375
        $recurringEvents[] = $event;
376
377
        $day = new \DateTime('-3 day', $this->getTimeZone());
378
        $event = new CalendarEvent();
379
        $event->setTitle('Monthly Team Meeting');
380
        $day->setTime(18, 0, 0);
381
        $event->setEnd(clone $day);
382
        $day->setTime(16, 0, 0);
383
        $event->setStart(clone $day);
384
        $event->setAllDay(false);
385
        $recurrence = new Recurrence();
386
        $recurrence->setRecurrenceType(Model\Recurrence::TYPE_MONTHLY);
387
        $recurrence->setInterval(2)
388
            ->setTimeZone('America/Los_Angeles')
389
            ->setDayOfMonth(1)
390
            ->setStartTime($day)
391
            ->setEndTime(new \DateTime('Dec 31', $this->getTimeZone()));
392
        $event->setRecurrence($recurrence);
393
        $recurringEvents[] = $event;
394
395
        $day = new \DateTime('+5 day', $this->getTimeZone());
396
        $event = new CalendarEvent();
397
        $event->setTitle('Update News');
398
        $day->setTime(14, 0, 0);
399
        $event->setEnd(clone $day);
400
        $day->setTime(10, 0, 0);
401
        $event->setStart(clone $day);
402
        $event->setAllDay(true);
403
        $recurrence = new Recurrence();
404
        $recurrence->setRecurrenceType(Model\Recurrence::TYPE_MONTH_N_TH);
405
        $recurrence->setInterval(2)
406
            ->setTimeZone('America/Los_Angeles')
407
            ->setInstance(Model\Recurrence::INSTANCE_THIRD)
408
            ->setDayOfWeek([Model\Recurrence::DAY_SATURDAY, Model\Recurrence::DAY_SUNDAY])
409
            ->setStartTime($day)
410
            ->setOccurrences(6);
411
        $event->setRecurrence($recurrence);
412
        $recurringEvents[] = $event;
413
414
        $day = new \DateTime('now', $this->getTimeZone());
415
        $event = new CalendarEvent();
416
        $event->setTitle('Yearly Conference');
417
        $day->setTime(19, 0, 0);
418
        $event->setEnd(clone $day);
419
        $day->setTime(10, 0, 0);
420
        $event->setStart(clone $day);
421
        $event->setAllDay(true);
422
        $recurrence = new Recurrence();
423
        $recurrence->setRecurrenceType(Model\Recurrence::TYPE_YEARLY);
424
        $recurrence->setInterval(12)
425
            ->setTimeZone('America/Los_Angeles')
426
            ->setDayOfMonth(1)
427
            ->setMonthOfYear(4)
428
            ->setStartTime($day);
429
        $event->setRecurrence($recurrence);
430
        $recurringEvents[] = $event;
431
432
        $day = new \DateTime('-2 day', $this->getTimeZone());
433
        $event = new CalendarEvent();
434
        $event->setTitle('New Year Party');
435
        $day->setTime(23, 0, 0);
436
        $event->setEnd(clone $day);
437
        $day->setTime(18, 0, 0);
438
        $event->setStart(clone $day);
439
        $event->setAllDay(true);
440
        $recurrence = new Recurrence();
441
        $recurrence->setRecurrenceType(Model\Recurrence::TYPE_YEAR_N_TH);
442
        $recurrence->setInterval(12)
443
            ->setTimeZone('America/Los_Angeles')
444
            ->setInstance(Model\Recurrence::INSTANCE_LAST)
445
            ->setDayOfWeek([Model\Recurrence::DAY_SATURDAY])
446
            ->setMonthOfYear(12)
447
            ->setStartTime($day);
448
        $event->setRecurrence($recurrence);
449
        $recurringEvents[] = $event;
450
451
        return $recurringEvents;
452
    }
453
454
    /**
455
     * Adds exceptions to recurring events.
456
     */
457
    protected function addRecurringEventExceptions()
458
    {
459
        $event = $this->em->getRepository('OroCalendarBundle:CalendarEvent')->findOneBy(['title' => 'Standup meeting']);
460
        $day = new \DateTime('next friday', $this->getTimeZone());
461
        $day->setTime(10, 0, 0);
462
        $exception = new CalendarEvent();
463
        $exception->setTitle('Changed Standup meeting');
464
        $exception->setOriginalStart(clone $day);
465
        $day->setTime(9, 15, 0);
466
        $exception->setEnd(clone $day);
467
        $day->setTime(9, 0, 0);
468
        $exception->setStart(clone $day)
469
            ->setCalendar($event->getCalendar())
470
            ->setAllDay(true);
471
        $event->addRecurringEventException($exception);
472
473
        $day = new \DateTime('next monday', $this->getTimeZone());
474
        $day->setTime(10, 0, 0);
475
        $exception = new CalendarEvent();
476
        $exception->setTitle('Evening Standup meeting');
477
        $exception->setOriginalStart(clone $day);
478
        $day->setTime(19, 15, 0);
479
        $exception->setEnd(clone $day);
480
        $day->setTime(19, 0, 0);
481
        $exception->setStart(clone $day)
482
            ->setCalendar($event->getCalendar())
483
            ->setAllDay(false);
484
        $event->addRecurringEventException($exception);
485
486
        $day = new \DateTime('first wednesday of next month', $this->getTimeZone());
487
        $day->setTime(10, 0, 0);
488
        $exception = new CalendarEvent();
489
        $exception->setTitle('Late meeting');
490
        $exception->setOriginalStart(clone $day);
491
        $day->setTime(23, 15, 0);
492
        $exception->setEnd(clone $day);
493
        $day->setTime(23, 0, 0);
494
        $exception->setStart(clone $day)
495
            ->setCalendar($event->getCalendar())
496
            ->setAllDay(false);
497
        $event->addRecurringEventException($exception);
498
499
        $this->em->persist($event);
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->em->getRepository... => 'Standup meeting')) on line 459 can also be of type null; however, Doctrine\ORM\EntityManager::persist() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
500
501
        $this->em->flush();
502
    }
503
504
    /**
505
     * @return \DateTimeZone
506
     */
507
    protected function getTimeZone()
508
    {
509
        if ($this->timeZone === null) {
510
            $this->timeZone = new \DateTimeZone('UTC');
511
        }
512
513
        return $this->timeZone;
514
    }
515
}
516