/**
  * Returns newsletter statistics to be used for pie and timeline chart
  * We will get the full state for each time when something happened
  * @param Tx_Newsletter_Domain_Model_Newsletter $newsletter
  * @return array eg: array(array(time, emailNotSentCount, emailSentCount, emailOpenedCount, emailBouncedCount, emailCount, linkOpenedCount, linkCount, [and same fields but Percentage instead of Count] ))
  */
 public function getStatistics(Tx_Newsletter_Domain_Model_Newsletter $newsletter)
 {
     $uidNewsletter = $newsletter->getUid();
     $stateDifferences = array();
     $emailCount = $this->fillStateDifferences($stateDifferences, 'tx_newsletter_domain_model_email', 'newsletter = ' . $uidNewsletter, array('end_time' => array('increment' => 'emailSentCount', 'decrement' => 'emailNotSentCount'), 'open_time' => array('increment' => 'emailOpenedCount', 'decrement' => 'emailSentCount'), 'bounce_time' => array('increment' => 'emailBouncedCount', 'decrement' => 'emailSentCount')));
     $linkRepository = $this->objectManager->get('Tx_Newsletter_Domain_Repository_LinkRepository');
     $linkCount = $linkRepository->getCount($uidNewsletter);
     $this->fillStateDifferences($stateDifferences, 'tx_newsletter_domain_model_link LEFT JOIN tx_newsletter_domain_model_linkopened ON (tx_newsletter_domain_model_linkopened.link = tx_newsletter_domain_model_link.uid)', 'tx_newsletter_domain_model_link.newsletter = ' . $uidNewsletter, array('open_time' => array('increment' => 'linkOpenedCount')));
     // Find out the very first event (when the newsletter was planned)
     $plannedTime = $newsletter ? $newsletter->getPlannedTime() : null;
     $emailCount = $newsletter ? $newsletter->getEmailCount() : $emailCount;
     // We re-calculate email count so get correct number if newsletter is not sent yet
     $previousState = array('time' => $plannedTime ? (int) $plannedTime->format('U') : null, 'emailNotSentCount' => $emailCount, 'emailSentCount' => 0, 'emailOpenedCount' => 0, 'emailBouncedCount' => 0, 'emailCount' => $emailCount, 'linkOpenedCount' => 0, 'linkCount' => $linkCount, 'emailNotSentPercentage' => 100, 'emailSentPercentage' => 0, 'emailOpenedPercentage' => 0, 'emailBouncedPercentage' => 0, 'linkOpenedPercentage' => 0);
     // Find out what the best grouping step is according to number of states
     $stateCount = count($stateDifferences);
     if ($stateCount > 5000) {
         $groupingTimestep = 15 * 60;
     } elseif ($stateCount > 500) {
         $groupingTimestep = 5 * 60;
     } elseif ($stateCount > 50) {
         $groupingTimestep = 1 * 60;
     } else {
         $groupingTimestep = 0;
     }
     // no grouping at all
     $states = array($previousState);
     ksort($stateDifferences);
     $minimumTimeToInsert = 0;
     // First state must always be not grouped, so we don't increment here
     foreach ($stateDifferences as $time => $diff) {
         $newState = $previousState;
         $newState['time'] = $time;
         // Apply diff to previous state to get new state's absolute values
         foreach ($diff as $key => $value) {
             $newState[$key] += $value;
         }
         // Compute percentage for email states
         foreach (array('emailNotSent', 'emailSent', 'emailOpened', 'emailBounced') as $key) {
             $newState[$key . 'Percentage'] = $newState[$key . 'Count'] / $newState['emailCount'] * 100;
         }
         // Compute percentage for link states
         if ($newState['linkCount'] && $newState['emailCount']) {
             $newState['linkOpenedPercentage'] = $newState['linkOpenedCount'] / ($newState['linkCount'] * $newState['emailCount']) * 100;
         } else {
             $newState['linkOpenedPercentage'] = 0;
         }
         // Insert the state only if grouping allows it
         if ($time >= $minimumTimeToInsert) {
             $states[] = $newState;
             $minimumTimeToInsert = $time + $groupingTimestep;
         }
         $previousState = $newState;
     }
     // Don't forget to always add the very last state, if not already inserted
     if (!($time >= $minimumTimeToInsert)) {
         $states[] = $newState;
     }
     return $states;
 }
 /**
  * @test
  */
 public function setPlannedTimeForIntegerSetsPlannedTime()
 {
     $this->fixture->setPlannedTime(12);
     $this->assertSame(12, $this->fixture->getPlannedTime());
 }