protected function run()
 {
     global $CONFIG;
     $userRepo = new UserAccountRepository();
     $siteRepo = new SiteRepository();
     $eventRepo = new EventRepository();
     $userWatchesSiteRepository = new UserWatchesSiteRepository();
     $userWatchesSiteStopRepository = new UserWatchesSiteStopRepository();
     $userAccountGeneralSecurityKeyRepository = new UserAccountGeneralSecurityKeyRepository();
     $userNotificationRepo = new UserNotificationRepository();
     $userHasNoEditorPermissionsInSiteRepo = new UserHasNoEditorPermissionsInSiteRepository();
     $userPermissionsRepo = new UserPermissionsRepository($this->app['extensions']);
     /** @var usernotifications/UserWatchesSiteGroupPromptNotificationType **/
     $userNotificationType = $this->app['extensions']->getCoreExtension()->getUserNotificationType('UserWatchesSitePrompt');
     $b = new UserWatchesSiteRepositoryBuilder();
     foreach ($b->fetchAll() as $userWatchesSite) {
         $user = $userRepo->loadByID($userWatchesSite->getUserAccountId());
         $site = $siteRepo->loadById($userWatchesSite->getSiteId());
         $siteRepo->loadLegacyFeaturesOnSite($site);
         // This is not the most efficient as it involves DB access and the results might not be used. But it'll do for now.
         $userPermissions = $userPermissionsRepo->getPermissionsForUserInSite($user, $site, false, true);
         $this->logVerbose(" User " . $user->getEmail() . " Site " . $site->getTitle());
         if ($site->getIsClosedBySysAdmin()) {
             $this->logVerbose(" ... site is closed");
         } else {
             if ($userHasNoEditorPermissionsInSiteRepo->isUserInSite($user, $site)) {
                 $this->logVerbose(" ... user does not have edit permissions allowed in site");
             } else {
                 if (!$userPermissions->hasPermission("org.openacalendar", "CALENDAR_CHANGE")) {
                     $this->logVerbose(" ... user does not have org.openacalendar/CALENDAR_CHANGE permission in site");
                     // Technically UserWatchesSiteRepositoryBuilder() should only return getIsWatching() == true but lets double check
                 } else {
                     if ($userWatchesSite->getIsWatching()) {
                         $this->logVerbose(" ... searching for data");
                         $lastEvent = $eventRepo->loadLastNonDeletedNonImportedByStartTimeInSiteId($site->getId());
                         $data = $userWatchesSite->getPromptEmailData($site, $lastEvent);
                         if ($data['moreEventsNeeded']) {
                             $this->logVerbose(" ... found data");
                             ///// Notification Class
                             $userNotification = $userNotificationType->getNewNotification($user, $site);
                             ////// Save Notification Class
                             $userNotificationRepo->create($userNotification);
                             ////// Send Email
                             if ($userNotification->getIsEmail()) {
                                 $userWatchesSiteStop = $userWatchesSiteStopRepository->getForUserAndSite($user, $site);
                                 configureAppForSite($site);
                                 configureAppForUser($user);
                                 $userAccountGeneralSecurityKey = $userAccountGeneralSecurityKeyRepository->getForUser($user);
                                 $unsubscribeURL = $CONFIG->getWebIndexDomainSecure() . '/you/emails/' . $user->getId() . '/' . $userAccountGeneralSecurityKey->getAccessKey();
                                 $lastEventsBuilder = new EventRepositoryBuilder();
                                 $lastEventsBuilder->setSite($site);
                                 $lastEventsBuilder->setOrderByStartAt(true);
                                 $lastEventsBuilder->setIncludeDeleted(false);
                                 $lastEventsBuilder->setIncludeImported(false);
                                 $lastEventsBuilder->setLimit($CONFIG->userWatchesGroupPromptEmailShowEvents);
                                 $lastEvents = $lastEventsBuilder->fetchAll();
                                 $message = \Swift_Message::newInstance();
                                 $message->setSubject("Any news about " . $site->getTitle() . "?");
                                 $message->setFrom(array($CONFIG->emailFrom => $CONFIG->emailFromName));
                                 $message->setTo($user->getEmail());
                                 $messageText = $this->app['twig']->render('email/userWatchesSitePromptEmail.txt.twig', array('user' => $user, 'lastEvents' => $lastEvents, 'stopCode' => $userWatchesSiteStop->getAccessKey(), 'generalSecurityCode' => $userAccountGeneralSecurityKey->getAccessKey(), 'unsubscribeURL' => $unsubscribeURL));
                                 if ($CONFIG->isDebug) {
                                     file_put_contents('/tmp/userWatchesSitePromptEmail.txt', $messageText);
                                 }
                                 $message->setBody($messageText);
                                 $messageHTML = $this->app['twig']->render('email/userWatchesSitePromptEmail.html.twig', array('user' => $user, 'lastEvents' => $lastEvents, 'stopCode' => $userWatchesSiteStop->getAccessKey(), 'generalSecurityCode' => $userAccountGeneralSecurityKey->getAccessKey(), 'unsubscribeURL' => $unsubscribeURL));
                                 if ($CONFIG->isDebug) {
                                     file_put_contents('/tmp/userWatchesSitePromptEmail.html', $messageHTML);
                                 }
                                 $message->addPart($messageHTML, 'text/html');
                                 $headers = $message->getHeaders();
                                 $headers->addTextHeader('List-Unsubscribe', $unsubscribeURL);
                                 $this->logVerbose(" ... sending");
                                 if (!$CONFIG->isDebug) {
                                     $this->app['mailer']->send($message);
                                 }
                                 $userNotificationRepo->markEmailed($userNotification);
                             }
                             $userWatchesSiteRepository->markPromptEmailSent($userWatchesSite, $data['checkTime']);
                         }
                     }
                 }
             }
         }
     }
     return array('result' => 'ok');
 }
 /**
  * One event, 31 days from now, then 30 days, then 29 days, etc, only 1 email sent
  * @global type $CONFIG
  */
 function test6()
 {
     global $CONFIG;
     $CONFIG->userWatchesPromptEmailSafeGapDays = 30;
     \TimeSource::mock(2013, 1, 1, 0, 0, 0);
     $user = new UserAccountModel();
     $user->setEmail("*****@*****.**");
     $user->setUsername("test");
     $user->setPassword("password");
     $userRepo = new UserAccountRepository();
     $userRepo->create($user);
     $site = new SiteModel();
     $site->setTitle("Test");
     $site->setSlug("test");
     $siteRepo = new SiteRepository();
     $siteRepo->create($site, $user, array(), $this->getSiteQuotaUsedForTesting());
     $event = new EventModel();
     $start = \TimeSource::getDateTime();
     $start->setDate(2013, 30, 9);
     $start->setTime(9, 0, 0);
     $event->setStartAt($start);
     $end = \TimeSource::getDateTime();
     $end->setDate(2013, 30, 9);
     $end->setTime(12, 0, 0);
     $event->setEndAt($end);
     $eventRepo = new EventRepository();
     $eventRepo->create($event, $site, $user);
     // User will watch site automatically in site->create()
     $userWatchesSiteRepo = new UserWatchesSiteRepository();
     $userWatchesSite = $userWatchesSiteRepo->loadByUserAndSite($user, $site);
     #Before email sent!
     for ($day = 1; $day <= 29; $day++) {
         \TimeSource::mock(2013, $day, 8, 1, 0, 0);
         $userWatchesSite = $userWatchesSiteRepo->loadByUserAndSite($user, $site);
         $data = $userWatchesSite->getPromptEmailData($site, $eventRepo->loadLastNonDeletedNonImportedByStartTimeInSiteId($site->getId()));
         $this->assertFalse($data['moreEventsNeeded']);
     }
     #Email sent!
     \TimeSource::mock(2013, 30, 8, 1, 0, 0);
     $userWatchesSite = $userWatchesSiteRepo->loadByUserAndSite($user, $site);
     $data = $userWatchesSite->getPromptEmailData($site, $eventRepo->loadLastNonDeletedNonImportedByStartTimeInSiteId($site->getId()));
     $this->assertTrue($data['moreEventsNeeded']);
     $userWatchesSiteRepo->markPromptEmailSent($userWatchesSite, \TimeSource::getDateTime());
     #After email sent
     \TimeSource::mock(2013, 31, 8, 1, 0, 0);
     $userWatchesSite = $userWatchesSiteRepo->loadByUserAndSite($user, $site);
     $data = $userWatchesSite->getPromptEmailData($site, $eventRepo->loadLastNonDeletedNonImportedByStartTimeInSiteId($site->getId()));
     $this->assertFalse($data['moreEventsNeeded']);
     for ($day = 1; $day <= 30; $day++) {
         \TimeSource::mock(2013, $day, 9, 1, 0, 0);
         $userWatchesSite = $userWatchesSiteRepo->loadByUserAndSite($user, $site);
         $data = $userWatchesSite->getPromptEmailData($site, $eventRepo->loadLastNonDeletedNonImportedByStartTimeInSiteId($site->getId()));
         $this->assertFalse($data['moreEventsNeeded']);
     }
     for ($day = 1; $day <= 31; $day++) {
         \TimeSource::mock(2013, $day, 10, 1, 0, 0);
         $userWatchesSite = $userWatchesSiteRepo->loadByUserAndSite($user, $site);
         $data = $userWatchesSite->getPromptEmailData($site, $eventRepo->loadLastNonDeletedNonImportedByStartTimeInSiteId($site->getId()));
         $this->assertFalse($data['moreEventsNeeded']);
     }
     for ($day = 1; $day <= 30; $day++) {
         \TimeSource::mock(2013, $day, 11, 1, 0, 0);
         $userWatchesSite = $userWatchesSiteRepo->loadByUserAndSite($user, $site);
         $data = $userWatchesSite->getPromptEmailData($site, $eventRepo->loadLastNonDeletedNonImportedByStartTimeInSiteId($site->getId()));
         $this->assertFalse($data['moreEventsNeeded']);
     }
     for ($day = 1; $day <= 31; $day++) {
         \TimeSource::mock(2013, $day, 12, 1, 0, 0);
         $userWatchesSite = $userWatchesSiteRepo->loadByUserAndSite($user, $site);
         $data = $userWatchesSite->getPromptEmailData($site, $eventRepo->loadLastNonDeletedNonImportedByStartTimeInSiteId($site->getId()));
         $this->assertFalse($data['moreEventsNeeded']);
     }
 }