NEW: Adding a option to run a batch job to the front end

This commit is contained in:
Kirk Mayo 2014-07-30 12:34:39 +12:00
parent d25adca175
commit 093322fcd3
7 changed files with 151 additions and 29 deletions

View File

@ -26,15 +26,22 @@ The external links module is a task and ModelAdmin to track and to report on bro
5. Run in your browser - `/dev/build` to rebuild the database. 5. Run in your browser - `/dev/build` to rebuild the database.
6. Run the following task *http://path.to.silverstripe/dev/tasks/CheckExternalLinks* to check for broken external links 6. Run the following task *http://path.to.silverstripe/dev/tasks/CheckExternalLinks* to check for broken external links
## Report ##
A new report is added called 'External Broken links report' from here you can also start a new job which is run
via AJAX and in batches of 10 so it can be run via content editors who do not have access to jobs or tasks.
## Dev task ## ## Dev task ##
Run the following task *http://path.to.silverstripe/dev/tasks/CheckExternalLinks* to check your site for external Run the following task *http://path.to.silverstripe/dev/tasks/CheckExternalLinks* to check your site for external
broken links. broken links.
## Queued job ##
If you have the queuedjobs module installed you can set the task to be run every so ofter If you have the queuedjobs module installed you can set the task to be run every so ofter
Add the following yml config to config.yml in mysite/_config have the the task run once every day (86400 seconds) Add the following yml config to config.yml in mysite/_config have the the task run once every day (86400 seconds)
`--- ```
Name: externallinkssettings
---
CheckExternalLinks: CheckExternalLinks:
Delay: 86400` Delay: 86400
```

View File

@ -2,19 +2,69 @@
class CMSExternalLinks_Controller extends Controller { class CMSExternalLinks_Controller extends Controller {
private static $allowed_actions = array('createQueuedReport'); private static $allowed_actions = array('getJobStatus', 'clear', 'start');
/*
* Respond to Ajax requests for info on a running job
* also calls continueJob and clear depending on the status of the job
*
* @return string JSON string detailing status of the job
*/
public function getJobStatus() {
$trackID = Session::get('ExternalLinksTrackID');
if (!$trackID) return;
$noPages = Versioned::get_by_stage('SiteTree', 'Live')->count();
$result = BrokenExternalPageTrack::get()
->filter('TrackID', $trackID)
->exclude('PageID', 0);
$completedPages = count($result);
public function createQueuedReport() { echo json_encode(array(
if (!Permission::check('ADMIN')) return; 'TrackID' => $trackID,
'Completed' => $completedPages,
'Total' => $noPages
));
// setup external links job if ($completedPages >= $noPages) {
$externalLinks = new CheckExternalLinksJob(); $this->clear();
$job = singleton('QueuedJobService'); } else {
$jobID = $job->queueJob($externalLinks); $this->continueJob();
}
}
// redirect to the jobs page /*
$admin = QueuedJobsAdmin::create(); * Clears the tracking id and any surplus entries for the BrokenExternalPageTrack model
$this->Redirect($admin->Link()); */
public function clear() {
// clear any old entries
$trackID = Session::get('ExternalLinksTrackID');
$oldEntries = BrokenExternalPageTrack::get()
->exclude('TrackID', $trackID);
foreach ($oldEntries as $entry) {
$entry->delete();
}
Session::clear('ExternalLinksTrackID');
}
/*
* Starts a broken external link check
*/
public function start() {
$track = BrokenExternalPageTrack::create();
$track->write();
$track->TrackID = $track->ID;
$track->write();
Session::set('ExternalLinksTrackID', $track->ID);
$this->continueJob();
}
/*
* Continues a broken external link check
*/
public function continueJob() {
$task = new CheckExternalLinks();
$task->run(null);
} }
} }

View File

@ -56,7 +56,8 @@ class CheckExternalLinksJob extends AbstractQueuedJob implements QueuedJob {
} }
$task = new CheckExternalLinks(); $task = new CheckExternalLinks();
$task->run($page); $task->pageToProcess = $page;
$task->run();
// and now we store the new list of remaining children // and now we store the new list of remaining children
$this->pagesToProcess = $remainingPages; $this->pagesToProcess = $remainingPages;

View File

@ -31,3 +31,13 @@ class BrokenExternalLink extends DataObject {
return Permission::checkMember($member, $codes); return Permission::checkMember($member, $codes);
} }
} }
class BrokenExternalPageTrack extends DataObject {
private static $db = array(
'TrackID' => 'Int'
);
private static $has_one = array(
'Page' => 'Page'
);
}

View File

@ -66,19 +66,20 @@ class BrokenExternalLinksReport extends SS_Report {
} }
public function getCMSFields() { public function getCMSFields() {
Requirements::javascript('externallinks/javascript/BrokenExternalLinksReport.js');
$fields = parent::getCMSFields(); $fields = parent::getCMSFields();
if (class_exists('AbstractQueuedJob')) { if (class_exists('AbstractQueuedJob')) {
$button = '<a href = "%s"><button class="externalLinksReport" type="button">%s</button></a>'; $button = '<button id="externalLinksReport" type="button">%s</button>';
$runReportButton = new LiteralField( $runReportButton = new LiteralField(
'runReport', 'runReport',
sprintf( sprintf(
$button, $button,
'admin/externallinks/createQueuedReport',
_t('ExternalBrokenLinksReport.RUNREPORT', 'Create new report') _t('ExternalBrokenLinksReport.RUNREPORT', 'Create new report')
) )
); );
$fields->push($runReportButton); $fields->push($runReportButton);
$reportResultSpan = '<span id="ReportHolder"></span></ br><span id="ReportProgress"></span>';
$reportResultSpan = '</ br></ br><h3 id="ReportHolder"></h3>';
$reportResult = new LiteralField('ResultTitle', $reportResultSpan); $reportResult = new LiteralField('ResultTitle', $reportResultSpan);
$fields->push($reportResult); $fields->push($reportResult);
} }

View File

@ -1,6 +1,7 @@
<?php <?php
class CheckExternalLinks extends BuildTask { class CheckExternalLinks extends BuildTask {
public static $pageToProcess;
protected $title = 'Checking broken External links in the SiteTree'; protected $title = 'Checking broken External links in the SiteTree';
protected $description = 'A task that records external broken links in the SiteTree'; protected $description = 'A task that records external broken links in the SiteTree';
@ -10,19 +11,20 @@ class CheckExternalLinks extends BuildTask {
private $completedPages; private $completedPages;
private $totalPages; private $totalPages;
public function getCompletedPages() {
return $this->completedPages;
}
public function getTotalPages() {
return $this->totalPages;
}
function run($request) { function run($request) {
if (isset($request->ID)) { $trackID = Session::get('ExternalLinksTrackID');
$pages = $request; if (isset($this->pageToProcess)) {
$pages = $this->pageToProcess;
} else { } else {
$pages = Versioned::get_by_stage('SiteTree', 'Live'); if ($trackID) {
$result = BrokenExternalPageTrack::get()
->filter('TrackID', $trackID);
$pages = Versioned::get_by_stage('SiteTree', 'Live')
->exclude('ID', $result->column('PageID'))
->limit(10);
} else {
$pages = Versioned::get_by_stage('SiteTree', 'Live');
}
} }
foreach ($pages as $page) { foreach ($pages as $page) {
++$this->totalPages; ++$this->totalPages;
@ -93,6 +95,12 @@ class CheckExternalLinks extends BuildTask {
} }
} }
++$this->completedPages; ++$this->completedPages;
if ($trackID) {
$trackPage = new BrokenExternalPageTrack();
$trackPage->PageID = $page->ID;
$trackPage->TrackID = $trackID;
$trackPage->write();
}
} }
// run this again if queued jobs exists and is a valid int // run this again if queued jobs exists and is a valid int

View File

@ -0,0 +1,45 @@
(function($) {
$('#externalLinksReport').entwine({
onclick: function() {
$(this).start();
$(this).poll();
},
start: function() {
// initiate a new job
$('#ReportHolder').empty();
$('#ReportHolder').text('Running report 0%');
$('#ReportHolder').append('<span class="ss-ui-loading-icon"></span>');
$.ajax({url: "admin/externallinks/start", async: true, timeout: 1000 });
},
poll: function() {
// poll the current job and update the front end status
$.ajax({
url: "admin/externallinks/getJobStatus",
async: true,
success: function(data) {
var obj = $.parseJSON(data);
if (!obj) return;
var completed = obj.Completed ? obj.Completed : 0;
var total = obj.Total ? obj.Total : 0;
if (total > 0 && completed == total) {
$('#ReportHolder').text('Report Finished ' + completed + '/' + total);
} else {
setTimeout(function() { $('#externalLinksReport').poll(); }, 1);
}
if (total && completed) {
if (completed < total) {
var percent = (completed / total) * 100;
$('#ReportHolder').text('Running report ' + completed + '/' +
total + ' (' + percent.toFixed(2) + '%)');
$('#ReportHolder').
append('<span class="ss-ui-loading-icon"></span>');
}
}
},
error: function(e) {
console.log(e);
}
});
}
});
}(jQuery));