LoadUsersCalendarData::loadCalendars()   D
last analyzed

Complexity

Conditions 9
Paths 27

Size

Total Lines 97
Code Lines 76

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 97
rs 4.9219
c 0
b 0
f 0
cc 9
eloc 76
nc 27
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 Oro\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
            'Oro\Bundle\DemoDataBundle\Migrations\Data\Demo\ORM\LoadUsersData',
59
            'Oro\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
                $events['workday'][] = $event;
105
                //call
106
                $event = new CalendarEvent();
107
                $event->setTitle('Client Call');
108
                $day->setTime(11, 0, 0);
109
                $event->setStart(clone $day);
110
                $day->setTime(12, 0, 0);
111
                $event->setEnd(clone $day);
112
                $event->setAllDay(false);
113
                $events['call'][] = $event;
114
                //meeting
115
                $event = new CalendarEvent();
116
                $event->setTitle('Meeting');
117
                $day->setTime(16, 0, 0);
118
                $event->setStart(clone $day);
119
                $day->setTime(18, 0, 0);
120
                $event->setEnd(clone $day);
121
                $event->setAllDay(false);
122
                $events['meeting'][] = $event;
123
                //lunch
124
                $event = new CalendarEvent();
125
                $event->setTitle('Lunch');
126
                $day->setTime(12, 0, 0);
127
                $event->setStart(clone $day);
128
                $day->setTime(12, 30, 0);
129
                $event->setEnd(clone $day);
130
                $event->setAllDay(false);
131
                $events['lunch'][] = $event;
132
                //business trip
133
                $event = new CalendarEvent();
134
                $event->setTitle('Business trip');
135
                $day->setTime(0, 0, 0);
136
                $event->setStart(clone $day);
137
                $day->setTime(0, 0, 0);
138
                $day->add(\DateInterval::createFromDateString('+3 days'));
139
                $event->setEnd(clone $day);
140
                $event->setAllDay(true);
141
                $events['b_trip'][] = $event;
142
            } else {
143
                $event = new CalendarEvent();
144
                $event->setTitle('Weekend');
145
                $day->setTime(8, 0, 0);
146
                $event->setStart(clone $day);
147
                $day->setTime(18, 0, 0);
148
                $event->setEnd(clone $day);
149
                $event->setAllDay(true);
150
                $events['weekend'][] = $event;
151
            }
152
        }
153
154
        foreach ($this->users as $index => $user) {
155
            //get default calendar, each user has default calendar after creation
156
            $calendar = $this->calendar->findDefaultCalendar($user->getId(), $this->organization->getId());
157
            $this->setSecurityContext($calendar->getOwner());
158
            //recurring events
159
            $events['recurring_events'] = $this->getRecurringEvents();
160
            foreach ($events as $typeEvents) {
161
                if (mt_rand(0, 1)) {
162
                    foreach ($typeEvents as $typeEvent) {
163
                        $calendar->addEvent(clone $typeEvent);
164
                    }
165
                }
166
            }
167
168
            $this->em->persist($calendar);
0 ignored issues
show
Bug introduced by
It seems like $calendar defined by $this->calendar->findDef...>organization->getId()) on line 156 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...
169
            if ($index > 0 && $index % 5 === 0) {
170
                $this->em->flush();
171
                $this->em->clear('Oro\Bundle\ActivityListBundle\Entity\ActivityOwner');
172
                $this->em->clear('Oro\Bundle\ActivityListBundle\Entity\ActivityList');
173
                $this->em->clear('Oro\Bundle\CalendarBundle\Entity\CalendarEvent');
174
                $this->em->clear('Oro\Bundle\CalendarBundle\Entity\Calendar');
175
            }
176
        }
177
178
        $this->em->flush();
179
        $this->em->clear('Oro\Bundle\ActivityListBundle\Entity\ActivityOwner');
180
        $this->em->clear('Oro\Bundle\ActivityListBundle\Entity\ActivityList');
181
        $this->em->clear('Oro\Bundle\CalendarBundle\Entity\CalendarEvent');
182
        $this->em->clear('Oro\Bundle\CalendarBundle\Entity\Calendar');
183
184
        $this->addRecurringEventExceptions();
185
    }
186
187
    protected function connectCalendars()
188
    {
189
        // first user is admin, often
190
        /** @var \Oro\Bundle\UserBundle\Entity\User $admin */
191
        $admin = $this->user->find(1);
192
        /** @var Calendar $calendarAdmin */
193
        $calendarAdmin = $this->calendar->findDefaultCalendar($admin->getId(), $admin->getOrganization()->getId());
194
195
        /** @var \Oro\Bundle\UserBundle\Entity\User $sale */
196
        $sale = $this->user->findOneBy(['username' => 'sale']);
197
        /** @var Calendar $calendarSale */
198
        $calendarSale = $this->calendar->findDefaultCalendar($sale->getId(), $sale->getOrganization()->getId());
199
200
        /** @var \Oro\Bundle\UserBundle\Entity\User $market */
201
        $market = $this->user->findOneBy(['username' => 'marketing']);
202
        /** @var Calendar $calendarMarket */
203
        $calendarMarket = $this->calendar->findDefaultCalendar($market->getId(), $market->getOrganization()->getId());
204
205
        /** @var User[] $users */
206
        $users = $this->getRandomUsers();
207
208
        foreach ($users as $user) {
209
            if (in_array($user->getId(), [$admin->getId(), $sale->getId(), $market->getId()])) {
210
                //to prevent self assignment
211
                continue;
212
            }
213
            /** @var Calendar $calendar */
214
            $calendar = $this->calendar->findDefaultCalendar($user->getId(), $user->getOrganization()->getId());
215
216 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...
217
                $calendarProperty = new CalendarProperty();
218
                $calendarProperty
219
                    ->setTargetCalendar($calendarAdmin)
220
                    ->setCalendarAlias('user')
221
                    ->setCalendar($calendar->getId());
222
223
                $this->em->persist($calendarProperty);
224
            }
225
226 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...
227
                $calendarProperty = new CalendarProperty();
228
                $calendarProperty
229
                    ->setTargetCalendar($calendarSale)
230
                    ->setCalendarAlias('user')
231
                    ->setCalendar($calendar->getId());
232
233
                $this->em->persist($calendarProperty);
234
            }
235
236 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...
237
                $calendarProperty = new CalendarProperty();
238
                $calendarProperty
239
                    ->setTargetCalendar($calendarMarket)
240
                    ->setCalendarAlias('user')
241
                    ->setCalendar($calendar->getId());
242
243
                $this->em->persist($calendarProperty);
244
            }
245
246
            $this->em->persist($calendar);
247
        }
248
249
        $this->em->flush();
250
    }
251
252
    /**
253
     * @param int $limit
254
     *
255
     * @return User[]
256
     */
257
    protected function getRandomUsers($limit = 5)
258
    {
259
        $userIds = $this->user->createQueryBuilder('u')
260
            ->select('u.id')
261
            ->getQuery()
262
            ->getScalarResult();
263
264
        if (count($userIds) > $limit) {
265
            $rawList = array_column($userIds, 'id', 'id');
266
            $keyList = array_rand($rawList, $limit);
267
268
            $criteria = new Criteria();
269
            $criteria->where(Criteria::expr()->in('id', $keyList));
270
271
            $result = $this->user->createQueryBuilder('u')
272
                ->addCriteria($criteria)
273
                ->getQuery()
274
                ->getResult();
275
        } else {
276
            $result = $this->users;
277
        }
278
279
        return $result;
280
    }
281
282
    /**
283
     * @return \DatePeriod
284
     */
285
    protected function getDatePeriod()
286
    {
287
        $month = new \DatePeriod(
288
            new \DateTime('now'),
289
            \DateInterval::createFromDateString('+1 day'),
290
            new \DateTime('now +1 month'),
291
            \DatePeriod::EXCLUDE_START_DATE
292
        );
293
294
        return $month;
295
    }
296
297
    /**
298
     * @param \DateTime $date
299
     * @return bool
300
     */
301
    protected function isWeekend($date)
302
    {
303
        $day = date('w', $date->getTimestamp());
304
        if ($day == 0 || $day == 6) {
305
            return true;
306
        }
307
308
        return false;
309
    }
310
311
    /**
312
     * @param User $user
313
     */
314
    protected function setSecurityContext(User $user)
315
    {
316
        $token = new UsernamePasswordOrganizationToken($user, $user->getUsername(), 'main', $this->organization);
317
        $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...
318
    }
319
320
    /**
321
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
322
     *
323
     * Returns the list of recurring events.
324
     *
325
     * @return array
326
     */
327
    protected function getRecurringEvents()
328
    {
329
        $baseEvent = new CalendarEvent();
330
        $baseRecurrence = new Recurrence();
331
332
        $recurringEvents = [];
333
334
        $day = new \DateTime('+2 day', $this->getTimeZone());
335
        $event = clone $baseEvent;
336
        $event->setTitle('Gym Visiting');
337
        $day->setTime(19, 0, 0);
338
        $event->setEnd(clone $day);
339
        $day->setTime(18, 0, 0);
340
        $event->setStart(clone $day);
341
        $event->setAllDay(true);
342
        $recurrence = clone $baseRecurrence;
343
        $recurrence->setRecurrenceType(Model\Recurrence::TYPE_DAILY);
344
        $recurrence->setInterval(3)
345
            ->setTimeZone('America/Los_Angeles')
346
            ->setStartTime($day)
347
            ->setOccurrences(12);
348
        $event->setRecurrence($recurrence);
349
        $recurringEvents[] = $event;
350
351
        $day = new \DateTime('+1 day', $this->getTimeZone());
352
        $event = clone $baseEvent;
353
        $event->setTitle('Standup meeting');
354
        $day->setTime(10, 15, 0);
355
        $event->setEnd(clone $day);
356
        $day->setTime(10, 0, 0);
357
        $event->setStart(clone $day);
358
        $event->setAllDay(true);
359
        $recurrence = clone $baseRecurrence;
360
        $recurrence->setRecurrenceType(Model\Recurrence::TYPE_WEEKLY);
361
        $recurrence->setInterval(1)
362
            ->setTimeZone('America/Los_Angeles')
363
            ->setDayOfWeek([
364
                Model\Recurrence::DAY_MONDAY,
365
                Model\Recurrence::DAY_TUESDAY,
366
                Model\Recurrence::DAY_WEDNESDAY,
367
                Model\Recurrence::DAY_THURSDAY,
368
                Model\Recurrence::DAY_FRIDAY
369
            ])
370
            ->setStartTime($day);
371
        $event->setRecurrence($recurrence);
372
        $recurringEvents[] = $event;
373
374
        $day = new \DateTime('-3 day', $this->getTimeZone());
375
        $event = clone $baseEvent;
376
        $event->setTitle('Monthly Team Meeting');
377
        $day->setTime(18, 0, 0);
378
        $event->setEnd(clone $day);
379
        $day->setTime(16, 0, 0);
380
        $event->setStart(clone $day);
381
        $event->setAllDay(false);
382
        $recurrence = clone $baseRecurrence;
383
        $recurrence->setRecurrenceType(Model\Recurrence::TYPE_MONTHLY);
384
        $recurrence->setInterval(2)
385
            ->setTimeZone('America/Los_Angeles')
386
            ->setDayOfMonth(1)
387
            ->setStartTime($day)
388
            ->setEndTime(new \DateTime('Dec 31', $this->getTimeZone()));
389
        $event->setRecurrence($recurrence);
390
        $recurringEvents[] = $event;
391
392
        $day = new \DateTime('+5 day', $this->getTimeZone());
393
        $event = clone $baseEvent;
394
        $event->setTitle('Update News');
395
        $day->setTime(14, 0, 0);
396
        $event->setEnd(clone $day);
397
        $day->setTime(10, 0, 0);
398
        $event->setStart(clone $day);
399
        $event->setAllDay(true);
400
        $recurrence = clone $baseRecurrence;
401
        $recurrence->setRecurrenceType(Model\Recurrence::TYPE_MONTH_N_TH);
402
        $recurrence->setInterval(2)
403
            ->setTimeZone('America/Los_Angeles')
404
            ->setInstance(Model\Recurrence::INSTANCE_THIRD)
405
            ->setDayOfWeek([Model\Recurrence::DAY_SATURDAY, Model\Recurrence::DAY_SUNDAY])
406
            ->setStartTime($day)
407
            ->setOccurrences(6);
408
        $event->setRecurrence($recurrence);
409
        $recurringEvents[] = $event;
410
411
        $day = new \DateTime('now', $this->getTimeZone());
412
        $event = clone $baseEvent;
413
        $event->setTitle('Yearly Conference');
414
        $day->setTime(19, 0, 0);
415
        $event->setEnd(clone $day);
416
        $day->setTime(10, 0, 0);
417
        $event->setStart(clone $day);
418
        $event->setAllDay(true);
419
        $recurrence = clone $baseRecurrence;
420
        $recurrence->setRecurrenceType(Model\Recurrence::TYPE_YEARLY);
421
        $recurrence->setInterval(12)
422
            ->setTimeZone('America/Los_Angeles')
423
            ->setDayOfMonth(1)
424
            ->setMonthOfYear(4)
425
            ->setStartTime($day);
426
        $event->setRecurrence($recurrence);
427
        $recurringEvents[] = $event;
428
429
        $day = new \DateTime('-2 day', $this->getTimeZone());
430
        $event = clone $baseEvent;
431
        $event->setTitle('New Year Party');
432
        $day->setTime(23, 0, 0);
433
        $event->setEnd(clone $day);
434
        $day->setTime(18, 0, 0);
435
        $event->setStart(clone $day);
436
        $event->setAllDay(true);
437
        $recurrence = clone $baseRecurrence;
438
        $recurrence->setRecurrenceType(Model\Recurrence::TYPE_YEAR_N_TH);
439
        $recurrence->setInterval(12)
440
            ->setTimeZone('America/Los_Angeles')
441
            ->setInstance(Model\Recurrence::INSTANCE_LAST)
442
            ->setDayOfWeek([Model\Recurrence::DAY_SATURDAY])
443
            ->setMonthOfYear(12)
444
            ->setStartTime($day);
445
        $event->setRecurrence($recurrence);
446
        $recurringEvents[] = $event;
447
448
        return $recurringEvents;
449
    }
450
451
    /**
452
     * Adds exceptions to recurring events.
453
     */
454
    protected function addRecurringEventExceptions()
455
    {
456
        $event = $this->em->getRepository('OroCalendarBundle:CalendarEvent')->findOneBy(['title' => 'Standup meeting']);
457
        $day = new \DateTime('next friday', $this->getTimeZone());
458
        $day->setTime(10, 0, 0);
459
        $exception = new CalendarEvent();
460
        $exception->setTitle('Changed Standup meeting');
461
        $exception->setOriginalStart(clone $day);
462
        $day->setTime(9, 15, 0);
463
        $exception->setEnd(clone $day);
464
        $day->setTime(9, 0, 0);
465
        $exception->setStart(clone $day)
466
            ->setCalendar($event->getCalendar())
467
            ->setAllDay(true);
468
        $event->addRecurringEventException($exception);
469
470
        $day = new \DateTime('next monday', $this->getTimeZone());
471
        $day->setTime(10, 0, 0);
472
        $exception = new CalendarEvent();
473
        $exception->setTitle('Evening Standup meeting');
474
        $exception->setOriginalStart(clone $day);
475
        $day->setTime(19, 15, 0);
476
        $exception->setEnd(clone $day);
477
        $day->setTime(19, 0, 0);
478
        $exception->setStart(clone $day)
479
            ->setCalendar($event->getCalendar())
480
            ->setAllDay(false);
481
        $event->addRecurringEventException($exception);
482
483
        $day = new \DateTime('first wednesday of next month', $this->getTimeZone());
484
        $day->setTime(10, 0, 0);
485
        $exception = new CalendarEvent();
486
        $exception->setTitle('Late meeting');
487
        $exception->setOriginalStart(clone $day);
488
        $day->setTime(23, 15, 0);
489
        $exception->setEnd(clone $day);
490
        $day->setTime(23, 0, 0);
491
        $exception->setStart(clone $day)
492
            ->setCalendar($event->getCalendar())
493
            ->setAllDay(false);
494
        $event->addRecurringEventException($exception);
495
496
        $this->em->persist($event);
0 ignored issues
show
Bug introduced by
It seems like $event defined by $this->em->getRepository... => 'Standup meeting')) on line 456 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...
497
498
        $this->em->flush();
499
    }
500
501
    /**
502
     * @return \DateTimeZone
503
     */
504
    protected function getTimeZone()
505
    {
506
        if ($this->timeZone === null) {
507
            $this->timeZone = new \DateTimeZone('UTC');
508
        }
509
510
        return $this->timeZone;
511
    }
512
}
513