Hi Bob,
the main post scheduling function seems to happen in the checkPublishStatus() function in core/model/modx/modrequest.class.php:
/**
* Checks the current status of timed publishing events.
* @todo refactor checkPublishStatus...offload to cachemanager?
*/
public function checkPublishStatus() {
$cacheRefreshTime= 0;
if (file_exists($this->modx->getOption(xPDO::OPT_CACHE_PATH) . "sitePublishing.idx.php"))
include ($this->modx->getOption(xPDO::OPT_CACHE_PATH) . "sitePublishing.idx.php");
$timeNow= time() + $this->modx->getOption('server_offset_time',null,0);
if ($cacheRefreshTime != 0 && $cacheRefreshTime <= $timeNow) {
/* FIXME: want to find a better way to handle this publishing check without mass updates to the database! */
$tblResource= $this->modx->getTableName('modResource');
if (!$result= $this->modx->exec("UPDATE {$tblResource} SET published=1,publishedon={$timeNow} WHERE pub_date < {$timeNow} AND pub_date > 0")) {
$this->modx->log(modX::LOG_LEVEL_ERROR, 'Error while refreshing resource publishing data: ' . print_r($this->modx->errorInfo(), true));
}
if (!$result= $this->modx->exec("UPDATE $tblResource SET published=0,publishedon={$timeNow} WHERE unpub_date < {$timeNow} AND unpub_date IS NOT NULL AND unpub_date > 0")) {
$this->modx->log(modX::LOG_LEVEL_ERROR, 'Error while refreshing resource unpublishing data: ' . print_r($this->modx->errorInfo(), true));
}
if ($this->modx->getCacheManager()) {
$this->modx->cacheManager->clearCache();
}
$timesArr= array ();
$sql= "SELECT MIN(pub_date) AS minpub FROM $tblResource WHERE pub_date>$timeNow AND pub_date IS NOT NULL";
if (!$result= $this->modx->query($sql)) {
$this->modx->log(modX::LOG_LEVEL_ERROR, "Failed to find publishing timestamps\n" . $sql);
} else {
$result= $result->fetchAll(PDO::FETCH_ASSOC);
$minpub= $result[0]['minpub'];
if ($minpub != null) {
$timesArr[]= $minpub;
}
}
$sql= "SELECT MIN(unpub_date) AS minunpub FROM $tblResource WHERE unpub_date>$timeNow AND unpub_date IS NOT NULL";
if (!$result= $this->modx->query($sql)) {
$this->modx->log(modX::LOG_LEVEL_ERROR, "Failed to find publishing timestamps\n" . $sql);
} else {
$result= $result->fetchAll(PDO::FETCH_ASSOC);
$minunpub= $result[0]['minunpub'];
if ($minunpub != null) {
$timesArr[]= $minunpub;
}
}
if (count($timesArr) > 0) {
$nextevent= min($timesArr);
} else {
$nextevent= 0;
}
$fp= @ fopen($this->modx->getOption(xPDO::OPT_CACHE_PATH) . "sitePublishing.idx.php", "wb");
if ($fp) {
@ flock($fp, LOCK_EX);
@ fwrite($fp, "<?php \$cacheRefreshTime=$nextevent; ?>");
@ flock($fp, LOCK_UN);
@ fclose($fp);
}
}
}
It would be nice for this code to fire the appropriate event for each document that is published or un-published here. Since documents are published or unpublished en-masse, we’d first have to retrieve a list of post that would be modified, and fire the appropriate event for each, and then run an update for each.
This function seems to be called on every page request, which is not very efficient. It would be better to separate post scheduling into a cron-job.