protected function execute($arguments = array(), $options = array())
 {
     // initialize the database connection
     $databaseManager = new sfDatabaseManager($this->configuration);
     $connection = $databaseManager->getDatabase($options['connection'])->getConnection();
     $applicationConfig = sfProjectConfiguration::getApplicationConfiguration('frontend', 'prod', true);
     $context = sfContext::createInstance($applicationConfig);
     ProjectConfiguration::registerCron();
     $quiet = (bool) $options['quiet'];
     $passed = array();
     $assigned = array();
     if ($arguments['subreddit'] == '%') {
         if (!$quiet) {
             echo "Advancing EpisodeAssignments for all Subreddits...";
         }
         SubredditTable::getInstance()->advanceEpisodeAssignments();
     } else {
         $subreddit = SubredditTable::getInstance()->findOneByName($arguments['subreddit']);
         if ($subreddit) {
             if (!$quiet) {
                 echo "Advancing EpisodeAssignments for {$subreddit} Subreddit...";
             }
             $subreddit->advanceEpisodeAssignments();
         } else {
             throw new sfException('Cannot find Subreddit: ' . $arguments['subreddit']);
         }
     }
     if (!$quiet) {
         echo "\n";
     }
 }
 protected function execute($arguments = array(), $options = array())
 {
     // initialize the database connection
     $databaseManager = new sfDatabaseManager($this->configuration);
     $connection = $databaseManager->getDatabase($options['connection'])->getConnection();
     $quiet = (bool) $options['quiet'];
     $domain = $arguments['domain'];
     if (!$quiet) {
         echo "Creating deadlines...";
     }
     $subreddit = SubredditTable::getInstance()->findOneBy('domain', $domain);
     /* @var $subreddit Subreddit */
     if (!$subreddit) {
         return new sfException("Cannot find subreddit by the domain name {$domain}.", 404);
     }
     if (count($subreddit->getDeadlines())) {
         return new sfException("Subreddit has deadlines already.");
     }
     $authortype_one = AuthorTypeTable::getInstance()->findOneBy('type', 'first_place');
     $authortype_two = AuthorTypeTable::getInstance()->findOneBy('type', 'second_place');
     $authortype_three = AuthorTypeTable::getInstance()->findOneBy('type', 'third_place');
     $authortype_four = AuthorTypeTable::getInstance()->findOneBy('type', 'sudden_death');
     $deadlines = new Doctrine_Collection('Deadline');
     $deadlines[0] = new Deadline();
     $deadlines[0]->setAuthorType($authortype_one);
     $deadlines[0]->setSubreddit($subreddit);
     $deadlines[0]->setSeconds(259200);
     $deadlines[1] = new Deadline();
     $deadlines[1]->setAuthorType($authortype_two);
     $deadlines[1]->setSubreddit($subreddit);
     $deadlines[1]->setSeconds(172800);
     $deadlines[2] = new Deadline();
     $deadlines[2]->setAuthorType($authortype_three);
     $deadlines[2]->setSubreddit($subreddit);
     $deadlines[2]->setSeconds(86400);
     $deadlines[3] = new Deadline();
     $deadlines[3]->setAuthorType($authortype_four);
     $deadlines[3]->setSubreddit($subreddit);
     $deadlines[3]->setSeconds(0);
     $deadlines->save();
     if (!$quiet) {
         echo "\nFinished.\n";
     }
 }
 /**
  * Similar to the testGetSubredditsNotNeedingEpisodeGeneration() test above,
  * this tests whether we can grab the inevrse: all of the Subreddits that
  * *don't* have future Episodes beyond one interval of the creation
  * interval.
  */
 public function testGetSubredditsNeedingEpisodeGeneration()
 {
     // Create Test Subreddit
     $subreddit = new Subreddit();
     $subreddit->setName('test2');
     $subreddit->setDomain('test2');
     $subreddit->setCreateNewEpisodesCronFormatted('0 0 1 * *');
     $subreddit->setEpisodeScheduleCronFormatted('0 0 1 * *');
     $subreddit->setCreationInterval('0');
     $subreddit->save();
     // Test against all Subreddits
     $subreddits = SubredditTable::getInstance()->getSubredditsNeedingEpisodeGeneration();
     $this->assertTrue(!empty($subreddits));
     $this->assertTrue($subreddits[0] instanceof Subreddit);
     // Test against Test Subreddit
     $subreddits = SubredditTable::getInstance()->getSubredditsNeedingEpisodeGeneration($subreddit->getName());
     $this->assertTrue(!empty($subreddits));
     $this->assertTrue($subreddits[0] instanceof Subreddit);
     $this->assertTrue($subreddits[0] == $subreddit);
     $subreddit->delete();
 }
 public function advanceEpisodeAssignments()
 {
     $subreddit_first_deadlines = array();
     $subreddit_deadline_rules = array();
     // We establish the pool of emails we'll be sending.
     // First to those who pass their deadline
     $passed_deadline_assignments = array();
     // And to the new episode assignments that are reassigned
     $newly_assigned_assignments = array();
     // Now we can start on the assignments that are misassigned
     $assignments = EpisodeAssignmentTable::getInstance()->getMisassignedEpisodes();
     $episodes = new Doctrine_Collection('Episode');
     $e = -1;
     for ($i = 0; $i < count($assignments); $i++) {
         $passed_deadline_assignments[] = $assignments[$i];
         $assignments[$i]->setMissedDeadline(true);
         $episodes[++$e] = $assignments[$i]->getEpisode();
         // Clean up the Episode for any new user to use.
         $episodes[$e]->setEpisodeAssignmentId(null);
         $audio_file = $episodes[$e]->getAudioFile();
         $nice_filename = $episodes[$e]->getNiceFilename();
         $graphic_file = $episodes[$e]->getGraphicFile();
         $episodes[$e]->setAudioFile(null);
         $episodes[$e]->setNiceFilename(null);
         $episodes[$e]->setGraphicFile(null);
         $episodes[$e]->setIsNsfw(false);
         $episodes[$e]->setTitle(null);
         $episodes[$e]->setDescription(null);
         $episodes[$e]->setIsSubmitted(false);
         $episodes[$e]->setSubmittedAt(null);
         $episodes[$e]->setFileIsRemote(null);
         $episodes[$e]->setRemoteUrl(null);
         $episodes[$e]->setRedditPostUrl(null);
     }
     $episodes->save();
     $assignments->save();
     /* Now we make sure that all assignments past deadline are marked as
      * such.  If the assignment is here, however, then it hasn't ever
      * actually BEEN assigned and isn't added to the list of emails to send
      * out. */
     $assignments = EpisodeAssignmentTable::getInstance()->getUnmarkedEpisodesThatMissedDeadlines();
     for ($i = 0; $i < count($assignments); $i++) {
         $assignments[$i]->setMissedDeadline(true);
     }
     $assignments->save();
     /* Now all episodes are cleared and we need to see if they need to be
      * reassigned to an existing asignment. */
     /* Returns assignments closest to the front for each unassigned episode,
      * in order of closeness. */
     $assignments = EpisodeAssignmentTable::getInstance()->getEpisodesPossiblyNeedingAssignment();
     $subreddit_ids = EpisodeAssignmentTable::getInstance()->getSubrbedditsOfEpisodesPossiblyNeedingAssignment();
     $deadlines = DeadlineTable::getInstance()->getDeadlinesForGivenSubreddits($subreddit_ids);
     $subreddit_first_authortypes = array();
     $subreddit_deadline_rules = array();
     $begun = false;
     $prev_subreddit_id = null;
     foreach ($deadlines as $deadline) {
         $subreddit_id = $deadline['subreddit_id'];
         if ($prev_subreddit_id != $subreddit_id && $begun) {
             $begun = false;
             $prev_subreddit_id = $subreddit_id;
         }
         if (!$begun) {
             $subreddit_deadline_rules[$subreddit_id] = array($deadline['author_type_id'] => $deadline['seconds']);
             $subreddit_first_authortypes[$subreddit_id] = $deadline['author_type_id'];
             $begun = true;
         } else {
             $author_type_id = $deadline['author_type_id'];
             $subreddit_deadline_rules[$subreddit_id][$author_type_id] = $deadline['seconds'];
         }
     }
     $episodes_affected = array();
     // Things used from assignment: episode_id, epsiode, author_type_id, id, sf_guard_user_id
     // Things used from episode: subreddit_id, surbeddit, release_date,
     // Things used from subreddit: getFirstDeadlineId(), getDeadlineRules()
     foreach ($assignments as $assignment) {
         if (!in_array($assignment['episode_id'], $episodes_affected)) {
             /* Ignore all subsequent assignments for an episode after the
              * first!  We should only be dealing with assignments that have
              * not missed their deadlines! */
             $episodes_affected[] = $assignment['episode_id'];
             $assign_to_episode = false;
             $subreddit_id = $assignment['subreddit_id'];
             $subreddit = SubredditTable::getInstance()->find($subreddit_id);
             /* If the *first* assignment is in the first spot, then assign
              * it. */
             $deadline_rules = $subreddit_deadline_rules[$subreddit_id];
             $author_type_id = $assignment['author_type_id'];
             if ($author_type_id == $subreddit_first_authortypes[$subreddit_id]) {
                 $assign_to_episode = true;
             } else {
                 /* Otherwise, check if we are past the deadline for the
                  * previous deadline. */
                 /*$previous_author_type_id = DeadlineTable::getInstance()
                   ->getFirstAuthorTypeIdBySubredditWhereDeadlineIsGreaterThan(
                   $deadline_rules[$author_type_id],
                   $subreddit_id);*/
                 $inverse_deadline_rules = array_reverse($deadline_rules, true);
                 $previous_author_type_id = null;
                 foreach ($inverse_deadline_rules as $author_type => $seconds) {
                     if ($seconds > $deadline_rules[$author_type_id]) {
                         $previous_author_type_id = $author_type;
                         break;
                     }
                 }
                 $past_deadline_for_previous = strtotime($assignment['release_date']) - $deadline_rules[$previous_author_type_id] <= time();
                 if ($past_deadline_for_previous) {
                     $assign_to_episode = true;
                 }
             }
             if ($assign_to_episode) {
                 $saved_episode = EpisodeTable::getInstance()->find($assignment['episode_id']);
                 $saved_episode->setEpisodeAssignmentId($assignment['id']);
                 $saved_episode->save();
                 $newly_assigned_assignments[] = $assignment;
             }
         }
     }
     // We send the emails for the current deadline we're checking.
     foreach ($passed_deadline_assignments as $assignment) {
         $this->sendEmailAboutPassedDeadline($assignment['sf_guard_user_id'], $assignment['episode_id']);
     }
     foreach ($newly_assigned_assignments as $assignment) {
         $release_date = strtotime($assignment['release_date']);
         $author_type_id = $assignment['author_type_id'];
         $seconds = $deadline_rules[$author_type_id];
         $deadline = $release_date - $seconds;
         $this->sendEmailAboutNewAssignment($assignment['sf_guard_user_id'], $assignment['episode_id'], $deadline);
     }
 }
 /**
  * Retrieves the release date for the youngest Episode of the Subreddit.
  *
  * @return string  The release date of the youngest Episode. 
  */
 public function getDateOfLastEpisode()
 {
     return SubredditTable::getInstance()->getLastEpisodeReleaseDate($this->getIncremented());
 }
 /**
  * Checks if the User of the EpisodeAssignment has a "blocked" Membership in
  * the Subreddit.
  * 
  * @see sfGuardUserSubredditMembership::getFirstByUserSubredditAndMemberships()
  *
  * @return bool Whether the user has a "blocked" Membership
  */
 public function subredditBlocksPendingUsers()
 {
     $pending_membership = Doctrine::getTable('sfGuardUserSubredditMembership')->getFirstByUserSubredditAndMemberships($this->getSfGuardUserId(), $this->getEpisode()->getSubredditId(), array('pending'));
     if ($pending_membership) {
         $subreddit = SubredditTable::getInstance()->find($this->getEpisode()->getSubredditId());
         return $subreddit->getPendingUsersAreFullMembers() ? false : true;
     }
     return false;
 }