/**
  * @param SS_HTTPRequest $request
  */
 public function run($request)
 {
     $compatibility = ContentReviewCompatability::start();
     $now = class_exists("SS_Datetime") ? SS_Datetime::now()->URLDate() : SSDatetime::now()->URLDate();
     // First grab all the pages with a custom setting
     $pages = Page::get("Page")->where("\"SiteTree\".\"NextReviewDate\" <= '{$now}'");
     $overduePages = $this->getOverduePagesForOwners($pages);
     // Lets send one email to one owner with all the pages in there instead of no of pages
     // of emails.
     foreach ($overduePages as $memberID => $pages) {
         $this->notifyOwner($memberID, $pages);
     }
     ContentReviewCompatability::done($compatibility);
 }
 /**
  * @param array $params
  *
  * @return SS_List
  */
 public function sourceRecords($params = array())
 {
     Versioned::reading_stage("Stage");
     $records = SiteTree::get();
     $compatibility = ContentReviewCompatability::start();
     // If there's no review dates set, default to all pages due for review now.
     // Show virtual pages?
     if (empty($params["ShowVirtualPages"])) {
         $virtualPageClasses = ClassInfo::subclassesFor("VirtualPage");
         $records = $records->where(sprintf("\"SiteTree\".\"ClassName\" NOT IN ('%s')", implode("','", array_values($virtualPageClasses))));
     }
     $records->sort("ParentID");
     $records = $records->toArray();
     // Trim out calculated values
     $list = new ArrayList();
     foreach ($records as $record) {
         if (!$this->hasReviewSchedule($record)) {
             $list->push($record);
         }
     }
     ContentReviewCompatability::done($compatibility);
     return $list;
 }
 /**
  * @param SS_HTTPRequest $request
  */
 public function run($request)
 {
     $compatibility = ContentReviewCompatability::start();
     $now = SS_Datetime::now();
     // First grab all the pages with a custom setting
     $pages = Page::get()->filter('NextReviewDate:LessThanOrEqual', $now->URLDate());
     // Calculate whether today is the date a First or Second review should occur
     $config = SiteConfig::current_site_config();
     $firstReview = $config->FirstReviewDaysBefore;
     $secondReview = $config->SecondReviewDaysBefore;
     // Subtract the number of days prior to the review, from the current date
     // Get all pages where the NextReviewDate is still in the future
     $pendingPages = Page::get()->filter('NextReviewDate:GreaterThan', $now->URLDate());
     // for each of these pages, check if today is the date the First or Second
     // reminder should be sent, and if so, add it to the appropriate ArrayList
     $firstReminderPages = new ArrayList();
     $secondReminderPages = new ArrayList();
     foreach ($pendingPages as $page) {
         $notifyDate1 = date('Y-m-d', strtotime($page->NextReviewDate . ' -' . $firstReview . ' days'));
         $notifyDate2 = date('Y-m-d', strtotime($page->NextReviewDate . ' -' . $secondReview . ' days'));
         if ($notifyDate1 == $now->URLDate()) {
             $firstReminderPages->push($page);
         }
         if ($notifyDate2 == $now->URLDate()) {
             $secondReminderPages->push($page);
         }
     }
     $overduePages = $this->getNotifiablePagesForOwners($pages);
     // Send one email to one owner with all the pages in there instead of no of pages of emails.
     foreach ($overduePages as $memberID => $pages) {
         $this->notifyOwner($memberID, $pages, "due");
     }
     // Send an email to the generic address with any first or second reminders
     $this->notifyTeam($firstReminderPages, $secondReminderPages);
     ContentReviewCompatability::done($compatibility);
 }
 /**
  * @param array $params
  *
  * @return SS_List
  */
 public function sourceRecords($params = array())
 {
     Versioned::reading_stage("Stage");
     $records = SiteTree::get();
     $compatibility = ContentReviewCompatability::start();
     if (empty($params["ReviewDateBefore"]) && empty($params["ReviewDateAfter"])) {
         // If there's no review dates set, default to all pages due for review now
         $reviewDate = new Zend_Date(SS_Datetime::now()->Format("U"));
         $reviewDate->add(1, Zend_Date::DAY);
         $records = $records->where(sprintf('"NextReviewDate" < \'%s\'', $reviewDate->toString("YYYY-MM-dd")));
     } else {
         // Review date before
         if (!empty($params['ReviewDateBefore'])) {
             // TODO Get value from DateField->dataValue() once we have access to form elements here
             $reviewDate = new Zend_Date($params["ReviewDateBefore"], Config::inst()->get("i18n", "date_format"));
             $reviewDate->add(1, Zend_Date::DAY);
             $records = $records->where(sprintf("\"NextReviewDate\" < '%s'", $reviewDate->toString("YYYY-MM-dd")));
         }
         // Review date after
         if (!empty($params["ReviewDateAfter"])) {
             // TODO Get value from DateField->dataValue() once we have access to form elements here
             $reviewDate = new Zend_Date($params["ReviewDateAfter"], Config::inst()->get("i18n", "date_format"));
             $records = $records->where(sprintf("\"NextReviewDate\" >= '%s'", $reviewDate->toString("YYYY-MM-dd")));
         }
     }
     // Show virtual pages?
     if (empty($params["ShowVirtualPages"])) {
         $virtualPageClasses = ClassInfo::subclassesFor("VirtualPage");
         $records = $records->where(sprintf("\"SiteTree\".\"ClassName\" NOT IN ('%s')", implode("','", array_values($virtualPageClasses))));
     }
     // Owner dropdown
     if (!empty($params["ContentReviewOwner"])) {
         $ownerNames = Convert::raw2sql($params["ContentReviewOwner"]);
         $records = $records->filter("OwnerNames:PartialMatch", $ownerNames);
     }
     $records = new ArrayList($records->sort("NextReviewDate", "DESC")->toArray());
     ContentReviewCompatability::done($compatibility);
     return $records;
 }
 /**
  * @param array $params
  *
  * @return SS_List
  */
 public function sourceRecords($params = array())
 {
     Versioned::reading_stage("Stage");
     $records = SiteTree::get();
     $compatibility = ContentReviewCompatability::start();
     if (empty($params["ReviewDateBefore"]) && empty($params["ReviewDateAfter"])) {
         // If there's no review dates set, default to all pages due for review now
         $reviewDate = new Zend_Date(SS_Datetime::now()->Format("U"));
         $reviewDate->add(1, Zend_Date::DAY);
         $records = $records->where(sprintf('"NextReviewDate" < \'%s\'', $reviewDate->toString("YYYY-MM-dd")));
     } else {
         // Review date before
         if (!empty($params['ReviewDateBefore'])) {
             // TODO Get value from DateField->dataValue() once we have access to form elements here
             $reviewDate = new Zend_Date($params["ReviewDateBefore"], Config::inst()->get("i18n", "date_format"));
             $reviewDate->add(1, Zend_Date::DAY);
             $records = $records->where(sprintf("\"NextReviewDate\" < '%s'", $reviewDate->toString("YYYY-MM-dd")));
         }
         // Review date after
         if (!empty($params["ReviewDateAfter"])) {
             // TODO Get value from DateField->dataValue() once we have access to form elements here
             $reviewDate = new Zend_Date($params["ReviewDateAfter"], Config::inst()->get("i18n", "date_format"));
             $records = $records->where(sprintf("\"NextReviewDate\" >= '%s'", $reviewDate->toString("YYYY-MM-dd")));
         }
     }
     // Show virtual pages?
     if (empty($params["ShowVirtualPages"])) {
         $virtualPageClasses = ClassInfo::subclassesFor("VirtualPage");
         $records = $records->where(sprintf("\"SiteTree\".\"ClassName\" NOT IN ('%s')", implode("','", array_values($virtualPageClasses))));
     }
     // Owner dropdown
     if (!empty($params["ContentReviewOwner"])) {
         $ownerNames = Convert::raw2sql($params["ContentReviewOwner"]);
         $records = $records->filter("OwnerNames:PartialMatch", $ownerNames);
     }
     // Only show pages assigned to the current user?
     // This come last because it transforms $records to an ArrayList.
     if (!empty($params["OnlyMyPages"])) {
         $currentUser = Member::currentUser();
         $records = $records->filterByCallback(function ($page) use($currentUser) {
             $options = $page->getOptions();
             foreach ($options->ContentReviewOwners() as $owner) {
                 if ($currentUser->ID == $owner->ID) {
                     return true;
                 }
             }
             return false;
         });
     }
     ContentReviewCompatability::done($compatibility);
     return $records;
 }
 /**
  * Set the review data from the review period, if set.
  */
 public function onBeforeWrite()
 {
     $this->owner->LastEditedByName = $this->owner->getEditorName();
     $this->owner->OwnerNames = $this->owner->getOwnerNames();
     // If the user changed the type, we need to recalculate the review date.
     if ($this->owner->isChanged("ContentReviewType", 2)) {
         if ($this->owner->ContentReviewType == "Disabled") {
             $this->setDefaultReviewDateForDisabled();
         } elseif ($this->owner->ContentReviewType == "Custom") {
             $this->setDefaultReviewDateForCustom();
         } else {
             $this->setDefaultReviewDateForInherited();
         }
     }
     // Ensure that a inherited page always have a next review date
     if ($this->owner->ContentReviewType == "Inherit" && !$this->owner->NextReviewDate) {
         $this->setDefaultReviewDateForInherited();
     }
     // We need to update all the child pages that inherit this setting. We can only
     // change children after this record has been created, otherwise the stageChildren
     // method will grab all pages in the DB (this messes up unit testing)
     if (!$this->owner->exists()) {
         return;
     }
     // parent page change it's review period
     // && !$this->owner->isChanged('ContentReviewType', 2)
     if ($this->owner->isChanged("ReviewPeriodDays", 2)) {
         $nextReviewUnixSec = strtotime(" + " . $this->owner->ReviewPeriodDays . " days", SS_Datetime::now()->format("U"));
         $this->owner->NextReviewDate = date("Y-m-d", $nextReviewUnixSec);
     }
     //
     if ($this->owner->isChanged("NextReviewDate", 2)) {
         $children = $this->owner->stageChildren(true)->filter("ContentReviewType", "Inherit");
         $compatibility = ContentReviewCompatability::start();
         foreach ($children as $child) {
             $child->NextReviewDate = $this->owner->NextReviewDate;
             $child->write();
         }
         ContentReviewCompatability::done($compatibility);
     }
 }