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.
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 ##
Run the following task *http://path.to.silverstripe/dev/tasks/CheckExternalLinks* to check your site for external
broken links.
## Queued job ##
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)
`---
Name: externallinkssettings
---
```
CheckExternalLinks:
Delay: 86400`
Delay: 86400
```

View File

@ -2,19 +2,69 @@
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() {
if (!Permission::check('ADMIN')) return;
echo json_encode(array(
'TrackID' => $trackID,
'Completed' => $completedPages,
'Total' => $noPages
));
// setup external links job
$externalLinks = new CheckExternalLinksJob();
$job = singleton('QueuedJobService');
$jobID = $job->queueJob($externalLinks);
if ($completedPages >= $noPages) {
$this->clear();
} else {
$this->continueJob();
}
}
// redirect to the jobs page
$admin = QueuedJobsAdmin::create();
$this->Redirect($admin->Link());
/*
* Clears the tracking id and any surplus entries for the BrokenExternalPageTrack model
*/
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->run($page);
$task->pageToProcess = $page;
$task->run();
// and now we store the new list of remaining children
$this->pagesToProcess = $remainingPages;

View File

@ -31,3 +31,13 @@ class BrokenExternalLink extends DataObject {
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() {
Requirements::javascript('externallinks/javascript/BrokenExternalLinksReport.js');
$fields = parent::getCMSFields();
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(
'runReport',
sprintf(
$button,
'admin/externallinks/createQueuedReport',
_t('ExternalBrokenLinksReport.RUNREPORT', 'Create new report')
)
);
$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);
$fields->push($reportResult);
}

View File

@ -1,6 +1,7 @@
<?php
class CheckExternalLinks extends BuildTask {
public static $pageToProcess;
protected $title = 'Checking broken External 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 $totalPages;
public function getCompletedPages() {
return $this->completedPages;
}
public function getTotalPages() {
return $this->totalPages;
}
function run($request) {
if (isset($request->ID)) {
$pages = $request;
$trackID = Session::get('ExternalLinksTrackID');
if (isset($this->pageToProcess)) {
$pages = $this->pageToProcess;
} 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) {
++$this->totalPages;
@ -93,6 +95,12 @@ class CheckExternalLinks extends BuildTask {
}
}
++$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

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));