/**
  * 
  * Sets internal variables and persistent data for when job is created without
  * constructor params, and process() is called in {@link QueuedJobService}.
  * 
  * @param CacheableNavigationService $service
  * @param array $chunk                          An array of objects to cache
  * @param string $stage                         "Live" or "Stage"
  * @param number $subsiteID
  * @return void
  */
 public function __construct(CacheableNavigationService $service, $chunk, $stage, $subsiteID)
 {
     // Increase memory to max-allowable
     CacheableConfig::configure_memory_limit();
     // Setters required for internal methods except $this->process()
     $this->setService($service);
     $this->setChunk($chunk);
     $this->setStage($stage);
     $this->setSubsiteID($subsiteID);
     // Persist structured "metadata" about the job using {@link CachableChunkedRefreshJobStorageService}.
     $jobConfig = array('CachableChunkedRefreshJobStorageService' => array('service' => $this->getService(), 'chunk' => $this->getChunk()));
     $this->setCustomConfig($jobConfig);
     $this->totalSteps = $this->chunkSize();
 }
 /**
  * 
  * Physically runs the task which - dependent on QueuedJobs being installed and
  * not skipped via script params - will queue-up chunks of pages to be cached,
  * or just attempt to cache call objects at once.
  * 
  * @param SS_HTTPRequest $request
  * @return void
  */
 public function run($request)
 {
     // Increase memory to max-allowable
     CacheableConfig::configure_memory_limit();
     $startTime = time();
     $skipQueue = $request->getVar('SkipQueue');
     $currentStage = Versioned::current_stage();
     /*
      * Restrict cache rebuild to the given stage - useful for debugging or
      * "Poor Man's" chunking.
      */
     if ($paramStage = $request->getVar('Stage')) {
         $stage_mode_mapping = array(ucfirst($paramStage) => strtolower($paramStage));
         // All stages
     } else {
         $stage_mode_mapping = array("Stage" => "stage", "Live" => "live");
     }
     $canQueue = interface_exists('QueuedJob');
     $siteConfigs = DataObject::get('SiteConfig');
     foreach ($stage_mode_mapping as $stage => $mode) {
         Versioned::set_reading_mode('Stage.' . $stage);
         if (class_exists('Subsite')) {
             Subsite::disable_subsite_filter(true);
             Config::inst()->update("CacheableSiteConfig", 'cacheable_fields', array('SubsiteID'));
             Config::inst()->update("CacheableSiteTree", 'cacheable_fields', array('SubsiteID'));
         }
         foreach ($siteConfigs as $config) {
             $service = new CacheableNavigationService($mode, $config);
             if ($service->refreshCachedConfig()) {
                 echo 'Caching: SiteConfig object ' . trim($config->ID) . ' (' . $config->Title . ') with mode: ' . $mode . self::new_line(2);
             } else {
                 echo 'Caching fails: SiteConfig object ' . trim($config->ID) . ' (' . $config->Title . ') with mode: ' . $mode . self::new_line(2);
             }
             if (class_exists('Subsite')) {
                 $pages = DataObject::get("Page", "SubsiteID = '" . $config->SubsiteID . "'");
             } else {
                 $pages = DataObject::get("Page");
             }
             $pageCount = $pages->count();
             /*
              * 
              * Queueing should only occur if:
              * - QueuedJob module is available
              * - SkipQueue param is not set
              * - Total no. pages is greater than the chunk divisor
              */
             $lowPageCount = self::$chunk_divisor > $pageCount;
             $doQueue = $canQueue && !$skipQueue && !$lowPageCount;
             if ($pageCount) {
                 $i = 0;
                 $chunkNum = 0;
                 $chunk = array();
                 foreach ($pages as $page) {
                     $i++;
                     // If QueuedJobs exists and isn't user-disabled: Chunk
                     if ($doQueue) {
                         // Start building a chunk of pages to be refreshed
                         $chunk[] = $page;
                         $chunkSize = count($chunk);
                         /*
                          * Conditions of chunking:
                          * - Initial chunks are chunk-size == self::$chunk_divisor
                          * - Remaining object count equals no. objects in current $chunk
                          */
                         $doChunking = $this->chunkForQueue($pageCount, $chunkSize, $i);
                         if ($doChunking) {
                             $chunkNum++;
                             $this->queue($service, $chunk, $stage, $config->SubsiteID);
                             echo "Queued chunk #" . $chunkNum . ' (' . $chunkSize . ' objects).' . self::new_line();
                             $chunk = array();
                         }
                         // Default to non-chunking if no queuedjobs or script instructed to skip queuing
                     } else {
                         $percentComplete = $this->percentageComplete($i, $pageCount);
                         $service->set_model($page);
                         if ($service->refreshCachedPage(true)) {
                             echo 'Caching: ' . trim($page->Title) . ' (' . $percentComplete . ') ' . self::new_line();
                         } else {
                             echo 'Caching fails: ' . trim($page->Title) . ' (' . $percentComplete . ') ' . self::new_line();
                         }
                     }
                     $page->flushCache();
                 }
             }
             $service->completeBuild();
             // Completion message
             $msg = self::new_line() . $pageCount . ' ' . $stage . ' pages in subsite ' . $config->ID;
             if ($doQueue) {
                 $msg .= ' queued for caching.' . self::new_line();
             } else {
                 $msg .= ' objects cached.' . self::new_line();
             }
             echo $msg . self::new_line();
         }
         if (class_exists('Subsite')) {
             Subsite::disable_subsite_filter(false);
         }
     }
     Versioned::set_reading_mode($currentStage);
     $endTime = time();
     $totalTime = $endTime - $startTime;
     $this->showConfig($totalTime, $request, $lowPageCount);
 }
 /**
  * 
  * @param array $modes
  * @param boolean $forceRemoval Whether to unset() children in {@link CacheableSiteTree::removeChild()}.
  * @return void
  */
 public function removePageCache($modes, $forceRemoval = true)
 {
     // Increase memory to max-allowable
     CacheableConfig::configure_memory_limit();
     $siteConfig = $this->owner->getSiteConfig();
     if (!$siteConfig->exists()) {
         $siteConfig = SiteConfig::current_site_config();
     }
     foreach ($modes as $stage => $mode) {
         $service = new CacheableNavigationService($mode, $siteConfig, $this->owner);
         $cache_frontend = $service->getCacheableFrontEnd();
         $id = $service->getIdentifier();
         $cached = $cache_frontend->load($id);
         if ($cached) {
             $cached_site_config = $cached->get_site_config();
             if (!$cached_site_config) {
                 $service->refreshCachedConfig();
             }
             $service->removeCachedPage($forceRemoval);
         }
     }
 }