public function getCampaignWithChildren(Campaign $campaign) { $data['type'] = 'campaign'; $data['campaignchain_id'] = (string) $campaign->getId(); $data['text'] = $campaign->getName(); $data['route_edit_api'] = $campaign->getCampaignModule()->getRoutes()['edit_api']; $data['route_plan_detail'] = $campaign->getCampaignModule()->getRoutes()['plan_detail']; $campaignService = $this->container->get('campaignchain.core.campaign'); $data['tpl_teaser'] = $campaignService->tplTeaser($campaign->getCampaignModule(), array('only_icon' => true, 'size' => 24)); // Define the trigger hook's identifier. if (!$campaign->getInterval() && $campaign->getTriggerHook()) { $data['id'] = (string) $campaign->getId() . '_campaign'; $hookService = $this->container->get($campaign->getTriggerHook()->getServices()['entity']); $hook = $hookService->getHook($campaign); $data['start_date'] = $hook->getStartDate()->format(self::FORMAT_TIMELINE_DATE); if ($hook->getEndDate()) { $data['end_date'] = $hook->getEndDate()->format(self::FORMAT_TIMELINE_DATE); } else { $data['end_date'] = $data['start_date']; } $ganttCampaignData[] = $data; } elseif ($campaign->getInterval()) { // Handle repeating campaigns. if (!$campaign->getIntervalEndOccurrence()) { $occurrences = 1; } else { $occurrences = $campaign->getIntervalEndOccurrence(); } /** @var \DateTime $startDate */ $startDate = $campaign->getIntervalStartDate(); /** @var \DateInterval $duration */ $duration = $campaign->getStartDate()->diff($campaign->getEndDate()); $now = new \DateTime('now'); $maxTimelineDate = clone $now; $maxTimelineDate->modify($this->container->getParameter('campaignchain.max_date_interval')); $firstInstanceId = null; $repeatingCount = 0; // If an actual instance exists as a child campaign, then add it. /** @var Campaign $childCampaign */ $childCampaign = $this->em->getRepository('CampaignChain\\CoreBundle\\Entity\\Campaign')->findOneByParent($campaign); if ($childCampaign) { $firstInstanceId = $data['id'] = (string) $campaign->getId() . '_campaign'; $data['start_date'] = $childCampaign->getStartDate()->format(self::FORMAT_TIMELINE_DATE); $data['end_date'] = $childCampaign->getEndDate()->format(self::FORMAT_TIMELINE_DATE); $ganttCampaignData[] = $data; } /* * Let's iterate through all the future instances of a repeating * campaign. */ for ($i = 0; $i < $occurrences; $i++) { /* * Take the interval's start/end date for the first instance, * otherwise calculate the start/end date by adding the * campaign's interval to the start/end date of the * previous instance. */ $startDate->modify($campaign->getInterval()); $endDate = clone $startDate; $endDate->add($duration); $hasEnded = $campaign->getIntervalEndDate() != NULL && $endDate > $campaign->getIntervalEndDate(); /* * If the instance is in the past, skip it, * because we only want ongoing or upcoming ones. */ if (!$hasEnded && $startDate >= $campaign->getIntervalNextRun() && ($startDate > $now || $endDate > $now)) { /* * Is this the first repeating campaign instance? */ if (!$firstInstanceId) { /* * This is the first instance, so we define it as * the parent of the other repeating campaign * instances. */ $firstInstanceId = $data['id'] = (string) $campaign->getId() . '_campaign'; } else { /* * This is not the first instance of a repeating * campaign in the timeline, so let's add the first instance * as the parent campaign. */ $data['id'] = (string) $campaign->getId() . '_' . $repeatingCount . '_campaign'; $data['parent'] = $firstInstanceId; $repeatingCount++; } $data['start_date'] = $startDate->format(self::FORMAT_TIMELINE_DATE); $data['interval'] = $campaign->getIntervalHumanReadable(); $data['end_date'] = $endDate->format(self::FORMAT_TIMELINE_DATE); $ganttCampaignData[] = $data; } if ($campaign->getIntervalEndOccurrence() == NULL && (!$hasEnded && $startDate < $maxTimelineDate)) { $occurrences++; } } } else { throw new \Exception('Unknown campaign type.'); } return $ganttCampaignData; }
public function moveCampaign(Campaign $campaign, \DateTime $newStartDate, $status = null) { // Make sure that data stays intact by using transactions. try { $this->em->getConnection()->beginTransaction(); /** @var HookService $hookService */ $hookService = $this->container->get($campaign->getTriggerHook()->getServices()['entity']); $hook = $hookService->getHook($campaign, Hook::MODE_MOVE); if (!$campaign->getInterval()) { // Calculate time difference. $interval = $campaign->getStartDate()->diff($newStartDate); if ($hook->getStartDate() !== null) { $hook->setStartDate(new \DateTime($hook->getStartDate()->add($interval)->format(\DateTime::ISO8601))); } if ($hook->getEndDate() !== null) { $hook->setEndDate(new \DateTime($hook->getEndDate()->add($interval)->format(\DateTime::ISO8601))); } } else { // Calculate time difference. $interval = $campaign->getIntervalStartDate()->diff($newStartDate); /** @var DateRepeat $hook */ $hook->setIntervalStartDate(new \DateTime($hook->getIntervalStartDate()->add($interval)->format(\DateTime::ISO8601))); $hook->setIntervalNextRun($hook->getIntervalStartDate()); if ($hook->getIntervalEndDate()) { $hook->setIntervalEndDate(new \DateTime($hook->getIntervalEndDate()->add($interval)->format(\DateTime::ISO8601))); } } $campaign = $hookService->processHook($campaign, $hook); if ($status != null) { $campaign->setStatus($status); } if (!$campaign->getInterval()) { // Change due date of all related milestones. $milestones = $campaign->getMilestones(); if ($milestones->count()) { $milestoneService = $this->container->get('campaignchain.core.milestone'); foreach ($milestones as $milestone) { if ($status != null) { $milestone->setStatus($status); } $milestone = $milestoneService->moveMilestone($milestone, $interval); $campaign->addMilestone($milestone); } } // Change due date of all related activities. $activities = $campaign->getActivities(); if ($activities->count()) { $activityService = $this->container->get('campaignchain.core.activity'); foreach ($activities as $activity) { if ($status != null) { $activity->setStatus($status); } $activity = $activityService->moveActivity($activity, $interval); $campaign->addActivity($activity); } } } $this->em->flush(); $this->em->getConnection()->commit(); return $campaign; } catch (\Exception $e) { // TODO: Respond with JSON and HTTP error code. $this->em->getConnection()->rollback(); throw $e; } }