Passed
Pull Request — master (#27)
by
unknown
01:48
created
src/Controllers/CMSExternalLinksController.php 1 patch
Indentation   +53 added lines, -53 removed lines patch added patch discarded remove patch
@@ -12,62 +12,62 @@
 block discarded – undo
12 12
 class CMSExternalLinksController extends Controller
13 13
 {
14 14
 
15
-    private static $allowed_actions = [
16
-        'getJobStatus',
17
-        'start'
18
-    ];
15
+	private static $allowed_actions = [
16
+		'getJobStatus',
17
+		'start'
18
+	];
19 19
 
20
-    /**
21
-     * Respond to Ajax requests for info on a running job
22
-     *
23
-     * @return string JSON string detailing status of the job
24
-     */
25
-    public function getJobStatus()
26
-    {
27
-        // Set headers
28
-        HTTP::set_cache_age(0);
29
-        HTTP::add_cache_headers($this->response);
30
-        $this->response
31
-            ->addHeader('Content-Type', 'application/json')
32
-            ->addHeader('Content-Encoding', 'UTF-8')
33
-            ->addHeader('X-Content-Type-Options', 'nosniff');
20
+	/**
21
+	 * Respond to Ajax requests for info on a running job
22
+	 *
23
+	 * @return string JSON string detailing status of the job
24
+	 */
25
+	public function getJobStatus()
26
+	{
27
+		// Set headers
28
+		HTTP::set_cache_age(0);
29
+		HTTP::add_cache_headers($this->response);
30
+		$this->response
31
+			->addHeader('Content-Type', 'application/json')
32
+			->addHeader('Content-Encoding', 'UTF-8')
33
+			->addHeader('X-Content-Type-Options', 'nosniff');
34 34
 
35
-        // Format status
36
-        $track = BrokenExternalPageTrackStatus::get_latest();
37
-        if ($track) {
38
-            return json_encode([
39
-                'TrackID' => $track->ID,
40
-                'Status' => $track->Status,
41
-                'Completed' => $track->getCompletedPages(),
42
-                'Total' => $track->getTotalPages()
43
-            ]);
44
-        }
45
-    }
35
+		// Format status
36
+		$track = BrokenExternalPageTrackStatus::get_latest();
37
+		if ($track) {
38
+			return json_encode([
39
+				'TrackID' => $track->ID,
40
+				'Status' => $track->Status,
41
+				'Completed' => $track->getCompletedPages(),
42
+				'Total' => $track->getTotalPages()
43
+			]);
44
+		}
45
+	}
46 46
 
47 47
 
48
-    /**
49
-     * Starts a broken external link check
50
-     */
51
-    public function start()
52
-    {
53
-        // return if the a job is already running
54
-        $status = BrokenExternalPageTrackStatus::get_latest();
55
-        if ($status && $status->Status == 'Running') {
56
-            return;
57
-        }
48
+	/**
49
+	 * Starts a broken external link check
50
+	 */
51
+	public function start()
52
+	{
53
+		// return if the a job is already running
54
+		$status = BrokenExternalPageTrackStatus::get_latest();
55
+		if ($status && $status->Status == 'Running') {
56
+			return;
57
+		}
58 58
 
59
-        // Create a new job
60
-        if (class_exists(QueuedJobService::class)) {
61
-            // Force the creation of a new run
62
-            BrokenExternalPageTrackStatus::create_status();
63
-            $checkLinks = new CheckExternalLinksJob();
64
-            singleton(QueuedJobService::class)->queueJob($checkLinks);
65
-        } else {
66
-            //TODO this hangs as it waits for the connection to be released
67
-            // should return back and continue processing
68
-            // http://us3.php.net/manual/en/features.connection-handling.php
69
-            $task = CheckExternalLinksTask::create();
70
-            $task->runLinksCheck();
71
-        }
72
-    }
59
+		// Create a new job
60
+		if (class_exists(QueuedJobService::class)) {
61
+			// Force the creation of a new run
62
+			BrokenExternalPageTrackStatus::create_status();
63
+			$checkLinks = new CheckExternalLinksJob();
64
+			singleton(QueuedJobService::class)->queueJob($checkLinks);
65
+		} else {
66
+			//TODO this hangs as it waits for the connection to be released
67
+			// should return back and continue processing
68
+			// http://us3.php.net/manual/en/features.connection-handling.php
69
+			$task = CheckExternalLinksTask::create();
70
+			$task->runLinksCheck();
71
+		}
72
+	}
73 73
 }
Please login to merge, or discard this patch.
src/Tasks/CheckExternalLinksTask.php 1 patch
Indentation   +209 added lines, -209 removed lines patch added patch discarded remove patch
@@ -18,213 +18,213 @@
 block discarded – undo
18 18
 class CheckExternalLinksTask extends BuildTask
19 19
 {
20 20
 
21
-    private static $dependencies = [
22
-        'LinkChecker' => '%$' . LinkChecker::class
23
-    ];
24
-
25
-    /**
26
-     * @var bool
27
-     */
28
-    protected $silent = false;
29
-
30
-    /**
31
-     * @var LinkChecker
32
-     */
33
-    protected $linkChecker;
34
-
35
-    protected $title = 'Checking broken External links in the SiteTree';
36
-
37
-    protected $description = 'A task that records external broken links in the SiteTree';
38
-
39
-    protected $enabled = true;
40
-
41
-    /**
42
-     * Log a message
43
-     *
44
-     * @param string $message
45
-     */
46
-    protected function log($message)
47
-    {
48
-        if (!$this->silent) {
49
-            Debug::message($message);
50
-        }
51
-    }
52
-
53
-    public function run($request)
54
-    {
55
-        $this->runLinksCheck();
56
-    }
57
-    /**
58
-     * Turn on or off message output
59
-     *
60
-     * @param bool $silent
61
-     */
62
-    public function setSilent($silent)
63
-    {
64
-        $this->silent = $silent;
65
-    }
66
-
67
-    /**
68
-     * @param LinkChecker $linkChecker
69
-     */
70
-    public function setLinkChecker(LinkChecker $linkChecker)
71
-    {
72
-        $this->linkChecker = $linkChecker;
73
-    }
74
-
75
-    /**
76
-     * @return LinkChecker
77
-     */
78
-    public function getLinkChecker()
79
-    {
80
-        return $this->linkChecker;
81
-    }
82
-
83
-    /**
84
-     * Check the status of a single link on a page
85
-     *
86
-     * @param BrokenExternalPageTrack $pageTrack
87
-     * @param DOMNode $link
88
-     */
89
-    protected function checkPageLink(BrokenExternalPageTrack $pageTrack, DOMNode $link)
90
-    {
91
-        $class = $link->getAttribute('class');
92
-        $href = $link->getAttribute('href');
93
-        $markedBroken = preg_match('/\b(ss-broken)\b/', $class);
94
-
95
-        // Check link
96
-        $httpCode = $this->linkChecker->checkLink($href);
97
-        if ($httpCode === null) {
98
-            return; // Null link means uncheckable, such as an internal link
99
-        }
100
-
101
-        // If this code is broken then mark as such
102
-        if ($foundBroken = $this->isCodeBroken($httpCode)) {
103
-            // Create broken record
104
-            $brokenLink = new BrokenExternalLink();
105
-            $brokenLink->Link = $href;
106
-            $brokenLink->HTTPCode = $httpCode;
107
-            $brokenLink->TrackID = $pageTrack->ID;
108
-            $brokenLink->StatusID = $pageTrack->StatusID; // Slight denormalisation here for performance reasons
109
-            $brokenLink->write();
110
-        }
111
-
112
-        // Check if we need to update CSS class, otherwise return
113
-        if ($markedBroken == $foundBroken) {
114
-            return;
115
-        }
116
-        if ($foundBroken) {
117
-            $class .= ' ss-broken';
118
-        } else {
119
-            $class = preg_replace('/\s*\b(ss-broken)\b\s*/', ' ', $class);
120
-        }
121
-        $link->setAttribute('class', trim($class));
122
-    }
123
-
124
-    /**
125
-     * Determine if the given HTTP code is "broken"
126
-     *
127
-     * @param int $httpCode
128
-     * @return bool True if this is a broken code
129
-     */
130
-    protected function isCodeBroken($httpCode)
131
-    {
132
-        // Null represents no request attempted
133
-        if ($httpCode === null) {
134
-            return false;
135
-        }
136
-
137
-        // do we have any whitelisted codes
138
-        $ignoreCodes = $this->config()->get('IgnoreCodes');
139
-        if (is_array($ignoreCodes) && in_array($httpCode, $ignoreCodes)) {
140
-            return false;
141
-        }
142
-
143
-        // Check if code is outside valid range
144
-        return $httpCode < 200 || $httpCode > 302;
145
-    }
146
-
147
-    /**
148
-     * Runs the links checker and returns the track used
149
-     *
150
-     * @param int $limit Limit to number of pages to run, or null to run all
151
-     * @return BrokenExternalPageTrackStatus
152
-     */
153
-    public function runLinksCheck($limit = null)
154
-    {
155
-        // Check the current status
156
-        $status = BrokenExternalPageTrackStatus::get_or_create();
157
-
158
-        // Calculate pages to run
159
-        $pageTracks = $status->getIncompleteTracks();
160
-        if ($limit) {
161
-            $pageTracks = $pageTracks->limit($limit);
162
-        }
163
-
164
-        // Check each page
165
-        foreach ($pageTracks as $pageTrack) {
166
-            // Flag as complete
167
-            $pageTrack->Processed = 1;
168
-            $pageTrack->write();
169
-
170
-            // Check value of html area
171
-            $page = $pageTrack->Page();
172
-            $this->log("Checking {$page->Title}");
173
-            $htmlValue = Injector::inst()->create('HTMLValue', $page->Content);
174
-            if (!$htmlValue->isValid()) {
175
-                continue;
176
-            }
177
-
178
-            // Check each link
179
-            $links = $htmlValue->getElementsByTagName('a');
180
-            foreach ($links as $link) {
181
-                $this->checkPageLink($pageTrack, $link);
182
-            }
183
-
184
-            // Update content of page based on link fixes / breakages
185
-            $htmlValue->saveHTML();
186
-            $page->Content = $htmlValue->getContent();
187
-            $page->write();
188
-
189
-            // Once all links have been created for this page update HasBrokenLinks
190
-            $count = $pageTrack->BrokenLinks()->count();
191
-            $this->log("Found {$count} broken links");
192
-            if ($count) {
193
-                $siteTreeTable = DataObject::getSchema()->tableName(SiteTree::class);
194
-                // Bypass the ORM as syncLinkTracking does not allow you to update HasBrokenLink to true
195
-                DB::query(sprintf(
196
-                    'UPDATE "%s" SET "HasBrokenLink" = 1 WHERE "ID" = \'%d\'',
197
-                    $siteTreeTable,
198
-                    intval($pageTrack->ID)
199
-                ));
200
-            }
201
-        }
202
-
203
-        $status->updateJobInfo('Updating completed pages');
204
-        $status->updateStatus();
205
-        return $status;
206
-    }
207
-
208
-    private function updateCompletedPages($trackID = 0)
209
-    {
210
-        $noPages = BrokenExternalPageTrack::get()
211
-            ->filter(array(
212
-                'TrackID' => $trackID,
213
-                'Processed' => 1
214
-            ))
215
-            ->count();
216
-        $track = BrokenExternalPageTrackStatus::get_latest();
217
-        $track->CompletedPages = $noPages;
218
-        $track->write();
219
-        return $noPages;
220
-    }
221
-
222
-    private function updateJobInfo($message)
223
-    {
224
-        $track = BrokenExternalPageTrackStatus::get_latest();
225
-        if ($track) {
226
-            $track->JobInfo = $message;
227
-            $track->write();
228
-        }
229
-    }
21
+	private static $dependencies = [
22
+		'LinkChecker' => '%$' . LinkChecker::class
23
+	];
24
+
25
+	/**
26
+	 * @var bool
27
+	 */
28
+	protected $silent = false;
29
+
30
+	/**
31
+	 * @var LinkChecker
32
+	 */
33
+	protected $linkChecker;
34
+
35
+	protected $title = 'Checking broken External links in the SiteTree';
36
+
37
+	protected $description = 'A task that records external broken links in the SiteTree';
38
+
39
+	protected $enabled = true;
40
+
41
+	/**
42
+	 * Log a message
43
+	 *
44
+	 * @param string $message
45
+	 */
46
+	protected function log($message)
47
+	{
48
+		if (!$this->silent) {
49
+			Debug::message($message);
50
+		}
51
+	}
52
+
53
+	public function run($request)
54
+	{
55
+		$this->runLinksCheck();
56
+	}
57
+	/**
58
+	 * Turn on or off message output
59
+	 *
60
+	 * @param bool $silent
61
+	 */
62
+	public function setSilent($silent)
63
+	{
64
+		$this->silent = $silent;
65
+	}
66
+
67
+	/**
68
+	 * @param LinkChecker $linkChecker
69
+	 */
70
+	public function setLinkChecker(LinkChecker $linkChecker)
71
+	{
72
+		$this->linkChecker = $linkChecker;
73
+	}
74
+
75
+	/**
76
+	 * @return LinkChecker
77
+	 */
78
+	public function getLinkChecker()
79
+	{
80
+		return $this->linkChecker;
81
+	}
82
+
83
+	/**
84
+	 * Check the status of a single link on a page
85
+	 *
86
+	 * @param BrokenExternalPageTrack $pageTrack
87
+	 * @param DOMNode $link
88
+	 */
89
+	protected function checkPageLink(BrokenExternalPageTrack $pageTrack, DOMNode $link)
90
+	{
91
+		$class = $link->getAttribute('class');
92
+		$href = $link->getAttribute('href');
93
+		$markedBroken = preg_match('/\b(ss-broken)\b/', $class);
94
+
95
+		// Check link
96
+		$httpCode = $this->linkChecker->checkLink($href);
97
+		if ($httpCode === null) {
98
+			return; // Null link means uncheckable, such as an internal link
99
+		}
100
+
101
+		// If this code is broken then mark as such
102
+		if ($foundBroken = $this->isCodeBroken($httpCode)) {
103
+			// Create broken record
104
+			$brokenLink = new BrokenExternalLink();
105
+			$brokenLink->Link = $href;
106
+			$brokenLink->HTTPCode = $httpCode;
107
+			$brokenLink->TrackID = $pageTrack->ID;
108
+			$brokenLink->StatusID = $pageTrack->StatusID; // Slight denormalisation here for performance reasons
109
+			$brokenLink->write();
110
+		}
111
+
112
+		// Check if we need to update CSS class, otherwise return
113
+		if ($markedBroken == $foundBroken) {
114
+			return;
115
+		}
116
+		if ($foundBroken) {
117
+			$class .= ' ss-broken';
118
+		} else {
119
+			$class = preg_replace('/\s*\b(ss-broken)\b\s*/', ' ', $class);
120
+		}
121
+		$link->setAttribute('class', trim($class));
122
+	}
123
+
124
+	/**
125
+	 * Determine if the given HTTP code is "broken"
126
+	 *
127
+	 * @param int $httpCode
128
+	 * @return bool True if this is a broken code
129
+	 */
130
+	protected function isCodeBroken($httpCode)
131
+	{
132
+		// Null represents no request attempted
133
+		if ($httpCode === null) {
134
+			return false;
135
+		}
136
+
137
+		// do we have any whitelisted codes
138
+		$ignoreCodes = $this->config()->get('IgnoreCodes');
139
+		if (is_array($ignoreCodes) && in_array($httpCode, $ignoreCodes)) {
140
+			return false;
141
+		}
142
+
143
+		// Check if code is outside valid range
144
+		return $httpCode < 200 || $httpCode > 302;
145
+	}
146
+
147
+	/**
148
+	 * Runs the links checker and returns the track used
149
+	 *
150
+	 * @param int $limit Limit to number of pages to run, or null to run all
151
+	 * @return BrokenExternalPageTrackStatus
152
+	 */
153
+	public function runLinksCheck($limit = null)
154
+	{
155
+		// Check the current status
156
+		$status = BrokenExternalPageTrackStatus::get_or_create();
157
+
158
+		// Calculate pages to run
159
+		$pageTracks = $status->getIncompleteTracks();
160
+		if ($limit) {
161
+			$pageTracks = $pageTracks->limit($limit);
162
+		}
163
+
164
+		// Check each page
165
+		foreach ($pageTracks as $pageTrack) {
166
+			// Flag as complete
167
+			$pageTrack->Processed = 1;
168
+			$pageTrack->write();
169
+
170
+			// Check value of html area
171
+			$page = $pageTrack->Page();
172
+			$this->log("Checking {$page->Title}");
173
+			$htmlValue = Injector::inst()->create('HTMLValue', $page->Content);
174
+			if (!$htmlValue->isValid()) {
175
+				continue;
176
+			}
177
+
178
+			// Check each link
179
+			$links = $htmlValue->getElementsByTagName('a');
180
+			foreach ($links as $link) {
181
+				$this->checkPageLink($pageTrack, $link);
182
+			}
183
+
184
+			// Update content of page based on link fixes / breakages
185
+			$htmlValue->saveHTML();
186
+			$page->Content = $htmlValue->getContent();
187
+			$page->write();
188
+
189
+			// Once all links have been created for this page update HasBrokenLinks
190
+			$count = $pageTrack->BrokenLinks()->count();
191
+			$this->log("Found {$count} broken links");
192
+			if ($count) {
193
+				$siteTreeTable = DataObject::getSchema()->tableName(SiteTree::class);
194
+				// Bypass the ORM as syncLinkTracking does not allow you to update HasBrokenLink to true
195
+				DB::query(sprintf(
196
+					'UPDATE "%s" SET "HasBrokenLink" = 1 WHERE "ID" = \'%d\'',
197
+					$siteTreeTable,
198
+					intval($pageTrack->ID)
199
+				));
200
+			}
201
+		}
202
+
203
+		$status->updateJobInfo('Updating completed pages');
204
+		$status->updateStatus();
205
+		return $status;
206
+	}
207
+
208
+	private function updateCompletedPages($trackID = 0)
209
+	{
210
+		$noPages = BrokenExternalPageTrack::get()
211
+			->filter(array(
212
+				'TrackID' => $trackID,
213
+				'Processed' => 1
214
+			))
215
+			->count();
216
+		$track = BrokenExternalPageTrackStatus::get_latest();
217
+		$track->CompletedPages = $noPages;
218
+		$track->write();
219
+		return $noPages;
220
+	}
221
+
222
+	private function updateJobInfo($message)
223
+	{
224
+		$track = BrokenExternalPageTrackStatus::get_latest();
225
+		if ($track) {
226
+			$track->JobInfo = $message;
227
+			$track->write();
228
+		}
229
+	}
230 230
 }
Please login to merge, or discard this patch.