Version Description
- Added the ability to check scheduled, draft and private posts.
- Added a way to individually enable/disable the monitoring of posts, pages, comments, the blogroll, and so on.
- New "Status" column in the "Broken Links" table.
- Visible table columns and the number of links per page can now be selected in the "Screen Options" panel.
- Replaced the "Delete sources" action with "Move sources to Trash" (except on blogs where Trash is disabled).
- New URL editor interface, now more consistent with the look-n-feel of the inline editor for posts.
- New status icon to help distinguish "maybe broken" and "definitely broken" links.
- Tweaked table layout - links first, posts/etc last.
- Added "Compact" and "Detailed" table views (for now, the differences are quite minor).
- Split the settings page into several tabs.
- Removed the "Details" links as redundant. To display link details, click the contents of the "Status" or "Link text" columns instead.
- Added a way to individually enable/disable the monitoring of various link types, e.g. HTML links, images, etc.
Download this release
Release Info
Developer | whiteshadow |
Plugin | Broken Link Checker |
Version | 0.9.5 |
Comparing to | |
See all releases |
Code changes from version 0.9.4.4-last-non-modular to 0.9.5
- broken-link-checker.php +12 -388
- core.php → core/core.php +785 -1011
- core/init.php +337 -0
- css/links-page.css +189 -23
- css/options-page.css +107 -0
- css/{uservoice.css → screen-meta-links.css} +9 -2
- images/bullet_cross.png +0 -0
- images/bullet_error.png +0 -0
- images/bullet_warning.png +0 -0
- images/dailymotion-embed.png +0 -0
- images/vimeo-embed.png +0 -0
- images/youtube-embed.png +0 -0
- JSON.php → includes/JSON.php +0 -0
- includes/admin/db-schema.php +95 -0
- includes/admin/db-upgrade.php +577 -0
- includes/admin/links-page-js.php +229 -168
- includes/admin/options-page-js.php +122 -0
- includes/admin/search-form.php +30 -5
- includes/admin/table-printer.php +719 -0
- includes/any-post.php +732 -0
- includes/checkers.php +35 -51
- config-manager.php → includes/config-manager.php +0 -0
- includes/containers.php +402 -431
- includes/containers/post.php +0 -464
- includes/extra-strings.php +18 -0
- includes/instances.php +41 -45
- includes/link-query.php +764 -0
- includes/links.php +132 -623
- logger.php → includes/logger.php +0 -0
- includes/module-base.php +72 -0
- includes/module-manager.php +860 -0
- includes/modules.php +31 -0
- includes/parsers.php +96 -153
- includes/screen-options/screen-options.js +13 -0
- includes/screen-options/screen-options.php +282 -0
- utility-class.php → includes/utility-class.php +126 -141
- js/jquery.cookie.js +96 -0
- languages/broken-link-checker-pt_PT.po +404 -416
- languages/broken-link-checker.pot +796 -505
- {includes → modules}/checkers/http.php +116 -35
- {includes → modules}/containers/blogroll.php +28 -11
- {includes → modules}/containers/comment.php +117 -30
- {includes → modules}/containers/custom_field.php +125 -99
- {includes → modules}/containers/dummy.php +13 -2
- modules/extras/dailymotion-embed.php +17 -0
- modules/extras/mediafire.php +17 -0
- modules/extras/megaupload.php +17 -0
- modules/extras/plaintext-url.php +17 -0
- modules/extras/rapidshare.php +17 -0
- modules/extras/vimeo-embed.php +17 -0
- modules/extras/youtube-embed.php +17 -0
- modules/extras/youtube.php +17 -0
- {includes → modules}/parsers/html_link.php +15 -2
- {includes → modules}/parsers/image.php +16 -5
- {includes → modules}/parsers/metadata.php +39 -3
- {includes → modules}/parsers/url_field.php +14 -3
- readme.txt +37 -18
- uninstall.php +4 -3
broken-link-checker.php
CHANGED
@@ -1,403 +1,27 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
/*
|
4 |
Plugin Name: Broken Link Checker
|
5 |
Plugin URI: http://w-shadow.com/blog/2007/08/05/broken-link-checker-for-wordpress/
|
6 |
Description: Checks your blog for broken links and missing images and notifies you on the dashboard if any are found.
|
7 |
-
Version: 0.9.
|
8 |
Author: Janis Elsts
|
9 |
Author URI: http://w-shadow.com/blog/
|
10 |
Text Domain: broken-link-checker
|
11 |
*/
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
define('BLC_DEBUG', false);
|
23 |
-
|
24 |
-
|
25 |
-
/***********************************************
|
26 |
-
Constants
|
27 |
-
************************************************/
|
28 |
-
|
29 |
-
/*
|
30 |
-
For performance, some internal APIs used for retrieving multiple links, instances or containers
|
31 |
-
can take an optional "$purpose" argument. Those APIs will try to use this argument to pre-load
|
32 |
-
any DB data required for the specified purpose ahead of time.
|
33 |
-
|
34 |
-
For example, if you're loading a bunch of link containers for the purposes of parsing them and
|
35 |
-
thus set $purpose to BLC_FOR_PARSING, the relevant container managers will (if applicable) precache
|
36 |
-
the parse-able fields in each returned container object. Still, setting $purpose to any particular
|
37 |
-
value does not *guarantee* any data will be preloaded - it's only a suggestion that it should.
|
38 |
-
|
39 |
-
The currently supported values for the $purpose argument are :
|
40 |
-
*/
|
41 |
-
define('BLC_FOR_EDITING', 'edit');
|
42 |
-
define('BLC_FOR_PARSING', 'parse');
|
43 |
-
define('BLC_FOR_DISPLAY', 'display');
|
44 |
-
|
45 |
-
/***********************************************
|
46 |
-
Configuration
|
47 |
-
************************************************/
|
48 |
-
|
49 |
-
//Load and initialize the plugin's configuration
|
50 |
-
global $blc_directory;
|
51 |
-
$blc_directory = dirname(__FILE__);
|
52 |
-
require $blc_directory . '/config-manager.php';
|
53 |
-
|
54 |
-
global $blc_config_manager;
|
55 |
-
$blc_config_manager = new blcConfigurationManager(
|
56 |
-
//Save the plugin's configuration into this DB option
|
57 |
-
'wsblc_options',
|
58 |
-
//Initialize default settings
|
59 |
-
array(
|
60 |
-
'max_execution_time' => 5*60, //(in seconds) How long the worker instance may run, at most.
|
61 |
-
'check_threshold' => 72, //(in hours) Check each link every 72 hours.
|
62 |
-
|
63 |
-
'recheck_count' => 3, //How many times a broken link should be re-checked.
|
64 |
-
'recheck_threshold' => 20*60, //(in seconds) Re-check broken links after 20 minutes.
|
65 |
-
|
66 |
-
'run_in_dashboard' => true, //Run the link checker algo. continuously while the Dashboard is open.
|
67 |
-
'run_via_cron' => true, //Run it hourly via WordPress pseudo-cron.
|
68 |
-
|
69 |
-
'mark_broken_links' => true, //Whether to add the broken_link class to broken links in posts.
|
70 |
-
'broken_link_css' => ".broken_link, a.broken_link {\n\ttext-decoration: line-through;\n}",
|
71 |
-
'nofollow_broken_links' => false, //Whether to add rel="nofollow" to broken links in posts.
|
72 |
-
|
73 |
-
'mark_removed_links' => false, //Whether to add the removed_link class when un-linking a link.
|
74 |
-
'removed_link_css' => ".removed_link, a.removed_link {\n\ttext-decoration: line-through;\n}",
|
75 |
-
|
76 |
-
'exclusion_list' => array(), //Links that contain a substring listed in this array won't be checked.
|
77 |
-
|
78 |
-
'send_email_notifications' => false,//Whether to send email notifications about broken links
|
79 |
-
'notification_schedule' => 'daily', //How often (at most) notifications will be sent. Possible values : 'daily', 'weekly'
|
80 |
-
'last_notification_sent' => 0, //When the last email notification was send (Unix timestamp)
|
81 |
-
|
82 |
-
'server_load_limit' => 4, //Stop parsing stuff & checking links if the 1-minute load average
|
83 |
-
//goes over this value. Only works on Linux servers. 0 = no limit.
|
84 |
-
'enable_load_limit' => true, //Enable/disable load monitoring.
|
85 |
-
|
86 |
-
'custom_fields' => array(), //List of custom fields that can contain URLs and should be checked.
|
87 |
-
'check_comment_links' => true, //Whether to check links found in comments
|
88 |
-
|
89 |
-
'autoexpand_widget' => true, //Autoexpand the Dashboard widget if broken links are detected
|
90 |
-
'show_link_count_bubble' => true, //Display a notification bubble in the menu when broken links are found
|
91 |
-
|
92 |
-
'need_resynch' => false, //[Internal flag] True if there are unparsed items.
|
93 |
-
'current_db_version' => 0, //The currently set-up version of the plugin's tables
|
94 |
-
|
95 |
-
'custom_tmp_dir' => '', //The lockfile will be stored in this directory.
|
96 |
-
//If this option is not set, the plugin's own directory or the
|
97 |
-
//system-wide /tmp directory will be used instead.
|
98 |
-
|
99 |
-
'timeout' => 30, //(in seconds) Links that take longer than this to respond will be treated as broken.
|
100 |
-
|
101 |
-
'highlight_permanent_failures' => false,//Highlight links that have appear to be permanently broken (in Tools -> Broken Links).
|
102 |
-
'failure_duration_threshold' => 3, //(days) Assume a link is permanently broken if it still hasn't
|
103 |
-
//recovered after this many days.
|
104 |
-
|
105 |
-
'highlight_feedback_widget' => true, //Highlight the "Feedback" button in vivid orange
|
106 |
-
|
107 |
-
'installation_complete' => false,
|
108 |
-
'installation_failed' => false,
|
109 |
-
)
|
110 |
-
);
|
111 |
-
|
112 |
-
/***********************************************
|
113 |
-
Logging
|
114 |
-
************************************************/
|
115 |
-
|
116 |
-
include 'logger.php';
|
117 |
-
|
118 |
-
global $blclog;
|
119 |
-
$blclog = new blcDummyLogger;
|
120 |
-
|
121 |
-
|
122 |
-
/*
|
123 |
-
if ( defined('BLC_DEBUG') && constant('BLC_DEBUG') ){
|
124 |
-
//Load FirePHP for debug logging
|
125 |
-
if ( !class_exists('FB') ) {
|
126 |
-
require_once 'FirePHPCore/fb.php4';
|
127 |
-
}
|
128 |
-
//FB::setEnabled(false);
|
129 |
-
}
|
130 |
-
//to comment out all calls : (^[^\/]*)(FB::) -> $1\/\/$2
|
131 |
-
//to uncomment : \/\/(\s*FB::) -> $1
|
132 |
-
//*/
|
133 |
-
|
134 |
-
/***********************************************
|
135 |
-
Global functions
|
136 |
-
************************************************/
|
137 |
-
|
138 |
-
/**
|
139 |
-
* Initialize link containers.
|
140 |
-
*
|
141 |
-
* @uses do_action() on 'blc_init_containers' after all built-in link containers have been loaded.
|
142 |
-
* @see blcContainer
|
143 |
-
*
|
144 |
-
* @return void
|
145 |
-
*/
|
146 |
-
function blc_init_containers(){
|
147 |
-
global $blc_directory;
|
148 |
-
|
149 |
-
//Only init once.
|
150 |
-
static $done = false;
|
151 |
-
if ( $done ) return;
|
152 |
-
|
153 |
-
//Load the base container classes
|
154 |
-
require $blc_directory . '/includes/containers.php';
|
155 |
-
|
156 |
-
//Load built-in link containers
|
157 |
-
require $blc_directory . '/includes/containers/post.php';
|
158 |
-
require $blc_directory . '/includes/containers/blogroll.php';
|
159 |
-
require $blc_directory . '/includes/containers/custom_field.php';
|
160 |
-
require $blc_directory . '/includes/containers/dummy.php';
|
161 |
-
|
162 |
-
$conf = & blc_get_configuration();
|
163 |
-
if ( $conf->options['check_comment_links'] ){
|
164 |
-
require $blc_directory . '/includes/containers/comment.php';
|
165 |
-
}
|
166 |
-
|
167 |
-
|
168 |
-
//Notify other plugins that they may register their custom containers now.
|
169 |
-
do_action('blc_init_containers');
|
170 |
-
|
171 |
-
$done = true;
|
172 |
-
}
|
173 |
-
|
174 |
-
/**
|
175 |
-
* Initialize link parsers.
|
176 |
-
*
|
177 |
-
* @uses do_action() on 'blc_init_parsers' after all built-in parsers have been loaded.
|
178 |
-
*
|
179 |
-
* @return void
|
180 |
-
*/
|
181 |
-
function blc_init_parsers(){
|
182 |
-
global $blc_directory;
|
183 |
-
|
184 |
-
//Only init once.
|
185 |
-
static $done = false;
|
186 |
-
if ( $done ) return;
|
187 |
-
|
188 |
-
//Load the base parser classes
|
189 |
-
require $blc_directory . '/includes/parsers.php';
|
190 |
-
|
191 |
-
//Load built-in parsers
|
192 |
-
require $blc_directory . '/includes/parsers/html_link.php';
|
193 |
-
require $blc_directory . '/includes/parsers/image.php';
|
194 |
-
require $blc_directory . '/includes/parsers/metadata.php';
|
195 |
-
require $blc_directory . '/includes/parsers/url_field.php';
|
196 |
-
|
197 |
-
do_action('blc_init_parsers');
|
198 |
-
$done = true;
|
199 |
-
}
|
200 |
-
|
201 |
-
/**
|
202 |
-
* Initialize link checkers.
|
203 |
-
*
|
204 |
-
* @uses do_action() on 'blc_init_checkers' after all built-in checker implementations have been loaded.
|
205 |
-
*
|
206 |
-
* @return void
|
207 |
-
*/
|
208 |
-
function blc_init_checkers(){
|
209 |
-
global $blc_directory;
|
210 |
-
|
211 |
-
//Only init once.
|
212 |
-
static $done = false;
|
213 |
-
if ( $done ) return;
|
214 |
-
|
215 |
-
//Load the base classes for link checker algorithms
|
216 |
-
require $blc_directory . '/includes/checkers.php';
|
217 |
-
|
218 |
-
//Load built-in checker implementations (only HTTP at the time)
|
219 |
-
require $blc_directory . '/includes/checkers/http.php';
|
220 |
-
|
221 |
-
do_action('blc_init_checkers');
|
222 |
-
$done = true;
|
223 |
-
}
|
224 |
-
|
225 |
-
/**
|
226 |
-
* Load and register all containers, parsers and checkers.
|
227 |
-
*
|
228 |
-
* @return void
|
229 |
-
*/
|
230 |
-
function blc_init_all_components(){
|
231 |
-
blc_init_containers();
|
232 |
-
blc_init_parsers();
|
233 |
-
blc_init_checkers();
|
234 |
-
}
|
235 |
-
|
236 |
-
/**
|
237 |
-
* Get the configuration object used by Broken Link Checker.
|
238 |
-
*
|
239 |
-
* @return blcConfigurationManager
|
240 |
-
*/
|
241 |
-
function &blc_get_configuration(){
|
242 |
-
return $GLOBALS['blc_config_manager'];
|
243 |
-
}
|
244 |
-
|
245 |
-
/**
|
246 |
-
* Notify the link checker that there are unsynched items
|
247 |
-
* that might contain links (e.g. a new or edited post).
|
248 |
-
*
|
249 |
-
* @return void
|
250 |
-
*/
|
251 |
-
function blc_got_unsynched_items(){
|
252 |
-
$conf = & blc_get_configuration();
|
253 |
-
|
254 |
-
if ( !$conf->options['need_resynch'] ){
|
255 |
-
$conf->options['need_resynch'] = true;
|
256 |
-
$conf->save_options();
|
257 |
-
}
|
258 |
-
}
|
259 |
-
|
260 |
-
/**
|
261 |
-
* (Re)create synchronization records for all containers and mark them all as unparsed.
|
262 |
-
*
|
263 |
-
* @param bool $forced If true, the plugin will recreate all synch. records from scratch.
|
264 |
-
* @return void
|
265 |
-
*/
|
266 |
-
function blc_resynch( $forced = false ){
|
267 |
-
global $wpdb, $blclog;
|
268 |
-
|
269 |
-
if ( $forced ){
|
270 |
-
$blclog->info('... Forced resynchronization initiated');
|
271 |
-
|
272 |
-
//Drop all synchronization records
|
273 |
-
$wpdb->query("TRUNCATE {$wpdb->prefix}blc_synch");
|
274 |
-
} else {
|
275 |
-
$blclog->info('... Resynchronization initiated');
|
276 |
-
}
|
277 |
-
|
278 |
-
//Delete synch. records for container types that don't exist
|
279 |
-
$blclog->info('... Deleting invalid container records');
|
280 |
-
blc_cleanup_containers();
|
281 |
-
|
282 |
-
//(Re)create and update synch. records for all container types.
|
283 |
-
$blclog->info('... (Re)creating container records');
|
284 |
-
blc_resynch_containers($forced);
|
285 |
-
|
286 |
-
//Delete invalid instances
|
287 |
-
$blclog->info('... Deleting invalid link instances');
|
288 |
-
blc_cleanup_instances();
|
289 |
-
|
290 |
-
//Delete orphaned links
|
291 |
-
$blclog->info('... Deleting orphaned links');
|
292 |
-
blc_cleanup_links();
|
293 |
-
|
294 |
-
$blclog->info('... Setting resync. flags');
|
295 |
-
blc_got_unsynched_items();
|
296 |
-
|
297 |
-
//All done.
|
298 |
-
$blclog->info('Database resynchronization complete.');
|
299 |
-
}
|
300 |
-
|
301 |
-
/***********************************************
|
302 |
-
Utility hooks
|
303 |
-
************************************************/
|
304 |
-
|
305 |
-
/**
|
306 |
-
* Add a weekly Cron schedule for email notifications
|
307 |
-
* and a bimonthly schedule for database maintenance.
|
308 |
-
*
|
309 |
-
* @param array $schedules Existing Cron schedules.
|
310 |
-
* @return array
|
311 |
-
*/
|
312 |
-
function blc_cron_schedules($schedules){
|
313 |
-
if ( !isset($schedules['weekly']) ){
|
314 |
-
$schedules['weekly'] = array(
|
315 |
-
'interval' => 604800, //7 days
|
316 |
-
'display' => __('Once Weekly')
|
317 |
-
);
|
318 |
-
}
|
319 |
-
if ( !isset($schedules['bimonthly']) ){
|
320 |
-
$schedules['bimonthly'] = array(
|
321 |
-
'interval' => 15*24*2600, //15 days
|
322 |
-
'display' => __('Twice a Month')
|
323 |
-
);
|
324 |
-
}
|
325 |
-
|
326 |
-
return $schedules;
|
327 |
-
}
|
328 |
-
add_filter('cron_schedules', 'blc_cron_schedules');
|
329 |
-
|
330 |
-
/**
|
331 |
-
* Display installation errors (if any) on the Dashboard.
|
332 |
-
*
|
333 |
-
* @return void
|
334 |
-
*/
|
335 |
-
function blc_print_installation_errors(){
|
336 |
-
$conf = & blc_get_configuration();
|
337 |
-
if ( !$conf->options['installation_failed'] ){
|
338 |
-
return;
|
339 |
-
}
|
340 |
-
|
341 |
-
$logger = new blcOptionLogger('blc_installation_log');
|
342 |
-
$log = $logger->get_messages();
|
343 |
-
|
344 |
-
$message = array(
|
345 |
-
'<strong>' . __('Broken Link Checker installation failed', 'broken-link-checker') . '</strong>',
|
346 |
-
'',
|
347 |
-
'<em>Installation log follows :</em>',
|
348 |
-
);
|
349 |
-
foreach($log as $entry){
|
350 |
-
array_push($message, $entry);
|
351 |
-
}
|
352 |
-
$message = implode("<br>\n", $message);
|
353 |
-
|
354 |
-
echo "<div class='error'><p>$message</p></div>";
|
355 |
-
}
|
356 |
-
add_action('admin_notices', 'blc_print_installation_errors');
|
357 |
-
|
358 |
-
|
359 |
-
/***********************************************
|
360 |
-
Main functionality
|
361 |
-
************************************************/
|
362 |
-
|
363 |
-
//Load the base classes
|
364 |
-
require $blc_directory . '/includes/links.php';
|
365 |
-
require $blc_directory . '/includes/instances.php';
|
366 |
-
|
367 |
-
if ( is_admin() || defined('DOING_CRON') ){
|
368 |
-
|
369 |
-
//It's an admin-side or Cron request. Load all plugin components.
|
370 |
-
add_action('plugins_loaded', 'blc_init_all_components');
|
371 |
-
require $blc_directory . '/utility-class.php';
|
372 |
-
require $blc_directory . '/core.php';
|
373 |
-
$ws_link_checker = new wsBrokenLinkChecker( __FILE__ , $blc_config_manager );
|
374 |
-
|
375 |
-
} else {
|
376 |
-
|
377 |
-
//This is user-side request, so we don't need to load the core.
|
378 |
-
//We do need to load containers (for the purposes of catching
|
379 |
-
//new comments and such).
|
380 |
-
add_action('plugins_loaded', 'blc_init_containers');
|
381 |
-
|
382 |
-
//If broken links need to be marked, we also need to load parsers
|
383 |
-
//(used to find & modify links) and utilities (used by some parsers).
|
384 |
-
if ( $blc_config_manager->options['mark_broken_links'] || $blc_config_manager->options['nofollow_broken_links'] ){
|
385 |
-
require $blc_directory . '/utility-class.php';
|
386 |
-
add_action('plugins_loaded', 'blc_init_parsers');
|
387 |
-
}
|
388 |
-
|
389 |
-
//And possibly inject the CSS for removed links
|
390 |
-
if ( $blc_config_manager->options['mark_removed_links'] && !empty($blc_config_manager->options['removed_link_css']) ){
|
391 |
-
function blc_print_remove_link_css(){
|
392 |
-
global $blc_config_manager;
|
393 |
-
echo '<style type="text/css">',$blc_config_manager->options['removed_link_css'],'</style>';
|
394 |
-
}
|
395 |
-
add_action('wp_head', 'blc_print_remove_link_css');
|
396 |
}
|
397 |
}
|
398 |
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
|
403 |
?>
|
1 |
<?php
|
|
|
2 |
/*
|
3 |
Plugin Name: Broken Link Checker
|
4 |
Plugin URI: http://w-shadow.com/blog/2007/08/05/broken-link-checker-for-wordpress/
|
5 |
Description: Checks your blog for broken links and missing images and notifies you on the dashboard if any are found.
|
6 |
+
Version: 0.9.5
|
7 |
Author: Janis Elsts
|
8 |
Author URI: http://w-shadow.com/blog/
|
9 |
Text Domain: broken-link-checker
|
10 |
*/
|
11 |
|
12 |
+
if ( !function_exists('blc_get_plugin_file') ){
|
13 |
+
/**
|
14 |
+
* Retrieve the fully qualified filename of BLC's main PHP file.
|
15 |
+
*
|
16 |
+
* @return string
|
17 |
+
*/
|
18 |
+
function blc_get_plugin_file(){
|
19 |
+
//You'd be surprised on how useful this can be.
|
20 |
+
return __FILE__;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
}
|
22 |
}
|
23 |
|
24 |
+
//Load the actual plugin
|
25 |
+
require 'core/init.php';
|
|
|
26 |
|
27 |
?>
|
core.php → core/core.php
RENAMED
@@ -11,6 +11,8 @@ if ( !function_exists( 'microtime_float' ) ) {
|
|
11 |
}
|
12 |
}
|
13 |
|
|
|
|
|
14 |
if (!class_exists('wsBrokenLinkChecker')) {
|
15 |
|
16 |
class wsBrokenLinkChecker {
|
@@ -19,7 +21,7 @@ class wsBrokenLinkChecker {
|
|
19 |
var $loader;
|
20 |
var $my_basename = '';
|
21 |
|
22 |
-
var $db_version =
|
23 |
|
24 |
var $execution_start_time; //Used for a simple internal execution timer in start_timer()/execution_time()
|
25 |
var $lockfile_handle = null;
|
@@ -39,10 +41,12 @@ class wsBrokenLinkChecker {
|
|
39 |
$this->loader = $loader;
|
40 |
$this->my_basename = plugin_basename( $this->loader );
|
41 |
|
42 |
-
|
43 |
-
register_deactivation_hook($this->my_basename, array(&$this, 'deactivation'));
|
44 |
|
45 |
-
|
|
|
|
|
|
|
46 |
|
47 |
add_action('admin_menu', array(&$this,'admin_menu'));
|
48 |
|
@@ -61,7 +65,6 @@ class wsBrokenLinkChecker {
|
|
61 |
add_action( 'wp_ajax_blc_link_details', array(&$this,'ajax_link_details') );
|
62 |
add_action( 'wp_ajax_blc_unlink', array(&$this,'ajax_unlink') );
|
63 |
add_action( 'wp_ajax_blc_current_load', array(&$this,'ajax_current_load') );
|
64 |
-
add_action( 'wp_ajax_blc_save_highlight_settings', array(&$this,'ajax_save_highlight_settings') );
|
65 |
add_action( 'wp_ajax_blc_disable_widget_highlight', array(&$this,'ajax_disable_widget_highlight') );
|
66 |
|
67 |
//Check if it's possible to create a lockfile and nag the user about it if not.
|
@@ -81,6 +84,17 @@ class wsBrokenLinkChecker {
|
|
81 |
add_action('blc_cron_email_notifications', array( &$this, 'send_email_notifications' ));
|
82 |
add_action('blc_cron_check_links', array(&$this, 'cron_check_links'));
|
83 |
add_action('blc_cron_database_maintenance', array(&$this, 'database_maintenance'));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
}
|
85 |
|
86 |
/**
|
@@ -145,7 +159,8 @@ class wsBrokenLinkChecker {
|
|
145 |
$.getJSON(
|
146 |
"<?php echo admin_url('admin-ajax.php'); ?>",
|
147 |
{
|
148 |
-
'action' : 'blc_dashboard_status'
|
|
|
149 |
},
|
150 |
function (data, textStatus){
|
151 |
if ( data && ( typeof(data.text) != 'undefined' ) ) {
|
@@ -190,7 +205,7 @@ class wsBrokenLinkChecker {
|
|
190 |
}
|
191 |
|
192 |
function admin_print_scripts(){
|
193 |
-
//jQuery is used for AJAX
|
194 |
wp_enqueue_script('jquery');
|
195 |
}
|
196 |
|
@@ -198,6 +213,8 @@ class wsBrokenLinkChecker {
|
|
198 |
//jQuery UI is used on the settings page
|
199 |
wp_enqueue_script('jquery-ui-core'); //Used for background color animation
|
200 |
wp_enqueue_script('jquery-ui-dialog');
|
|
|
|
|
201 |
}
|
202 |
|
203 |
function enqueue_link_page_scripts(){
|
@@ -326,24 +343,40 @@ class wsBrokenLinkChecker {
|
|
326 |
$blclog = new blcOptionLogger('blc_installation_log');
|
327 |
$blclog->clear();
|
328 |
|
329 |
-
$blclog->info('Plugin activated.');
|
330 |
|
331 |
$this->conf->options['installation_complete'] = false;
|
332 |
$this->conf->options['installation_failed'] = true;
|
333 |
$this->conf->save_options();
|
334 |
$blclog->info('Installation/update begins.');
|
335 |
|
336 |
-
$
|
337 |
-
|
338 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
339 |
//Prepare the database.
|
340 |
$blclog->info('Upgrading the database...');
|
341 |
$this->upgrade_database();
|
|
|
|
|
|
|
|
|
342 |
|
343 |
-
//
|
344 |
-
|
345 |
-
|
346 |
-
|
|
|
|
|
347 |
//Turn off load limiting if it's not available on this server.
|
348 |
$blclog->info('Updating server load limit settings...');
|
349 |
$load = $this->get_server_load();
|
@@ -373,6 +406,7 @@ class wsBrokenLinkChecker {
|
|
373 |
wp_clear_scheduled_hook('blc_cron_check_links');
|
374 |
wp_clear_scheduled_hook('blc_cron_email_notifications');
|
375 |
wp_clear_scheduled_hook('blc_cron_database_maintenance');
|
|
|
376 |
}
|
377 |
|
378 |
/**
|
@@ -381,263 +415,8 @@ class wsBrokenLinkChecker {
|
|
381 |
* @return bool
|
382 |
*/
|
383 |
function upgrade_database($trigger_errors = true){
|
384 |
-
|
385 |
-
|
386 |
-
//Do we need to upgrade?
|
387 |
-
if ( $this->db_version == $this->conf->options['current_db_version'] ) {
|
388 |
-
//The DB is up to date, but lets make sure all the required tables are present
|
389 |
-
//in case the user has decided to delete some of them.
|
390 |
-
$blclog->info( sprintf(
|
391 |
-
'The database appears to be up to date (current version : %d).',
|
392 |
-
$this->conf->options['current_db_version']
|
393 |
-
));
|
394 |
-
return $this->maybe_create_tables();
|
395 |
-
}
|
396 |
-
|
397 |
-
//Upgrade to DB version 4
|
398 |
-
if ( $this->db_version == 4 ){
|
399 |
-
$blclog->info(sprintf(
|
400 |
-
'Upgrading the database to version %d',
|
401 |
-
$this->db_version
|
402 |
-
));
|
403 |
-
|
404 |
-
//The 4th version makes a lot of backwards-incompatible changes to the main
|
405 |
-
//BLC tables (in particular, it adds several required fields to blc_instances).
|
406 |
-
//While it would be possible to import data from an older version of the DB,
|
407 |
-
//some things - like link editing - wouldn't work with the old data.
|
408 |
-
|
409 |
-
//So we just drop, recreate and repopulate most tables.
|
410 |
-
$blclog->info('Deleting old tables');
|
411 |
-
$tables = array(
|
412 |
-
$wpdb->prefix . 'blc_linkdata',
|
413 |
-
$wpdb->prefix . 'blc_postdata',
|
414 |
-
$wpdb->prefix . 'blc_instances',
|
415 |
-
$wpdb->prefix . 'blc_synch',
|
416 |
-
$wpdb->prefix . 'blc_links',
|
417 |
-
);
|
418 |
-
|
419 |
-
$q = "DROP TABLE IF EXISTS " . implode(', ', $tables);
|
420 |
-
$rez = $wpdb->query( $q );
|
421 |
-
|
422 |
-
if ( $rez === false ){
|
423 |
-
$error = sprintf(
|
424 |
-
__("Failed to delete old DB tables. Database error : %s", 'broken-link-checker'),
|
425 |
-
$wpdb->last_error
|
426 |
-
);
|
427 |
-
|
428 |
-
$blclog->error($error);
|
429 |
-
/*//FIXME: In very rare cases, DROP TABLE IF EXISTS throws an error when the table(s) don't exist.
|
430 |
-
if ( $trigger_errors ){
|
431 |
-
trigger_error($error, E_USER_ERROR);
|
432 |
-
}
|
433 |
-
return false;
|
434 |
-
//*/
|
435 |
-
}
|
436 |
-
$blclog->info('Done.');
|
437 |
-
|
438 |
-
//Create new DB tables.
|
439 |
-
if ( !$this->maybe_create_tables($trigger_errors) ){
|
440 |
-
return false;
|
441 |
-
};
|
442 |
-
|
443 |
-
} else {
|
444 |
-
//This should never happen.
|
445 |
-
$error = sprintf(
|
446 |
-
__(
|
447 |
-
"Unexpected error: The plugin doesn't know how to upgrade its database to version '%d'.",
|
448 |
-
'broken-link-checker'
|
449 |
-
),
|
450 |
-
$this->db_version
|
451 |
-
);
|
452 |
-
|
453 |
-
$blclog->error($error);
|
454 |
-
if ( $trigger_errors ){
|
455 |
-
trigger_error($error, E_USER_ERROR);
|
456 |
-
}
|
457 |
-
return false;
|
458 |
-
}
|
459 |
-
|
460 |
-
//Upgrade was successful.
|
461 |
-
$this->conf->options['current_db_version'] = $this->db_version;
|
462 |
-
$this->conf->save_options();
|
463 |
-
|
464 |
-
$blclog->info('Database successfully upgraded.');
|
465 |
-
return true;
|
466 |
-
}
|
467 |
-
|
468 |
-
/**
|
469 |
-
* Create the plugin's DB tables, unless they already exist.
|
470 |
-
*
|
471 |
-
* @return bool
|
472 |
-
*/
|
473 |
-
function maybe_create_tables($trigger_errors = true){
|
474 |
-
global $wpdb, $blclog;
|
475 |
-
|
476 |
-
//Use the character set and collation that's configured for WP tables
|
477 |
-
$charset_collate = '';
|
478 |
-
if ( !empty($wpdb->charset) ){
|
479 |
-
//Some German installs use "utf-8" (invalid) instead of "utf8" (valid). None of
|
480 |
-
//the charset ids supported by MySQL contain dashes, so we can safely strip them.
|
481 |
-
//See http://dev.mysql.com/doc/refman/5.0/en/charset-charsets.html
|
482 |
-
$charset = str_replace('-', '', $wpdb->charset);
|
483 |
-
|
484 |
-
$charset_collate = "DEFAULT CHARACTER SET {$charset}";
|
485 |
-
}
|
486 |
-
if ( !empty($wpdb->collate) ){
|
487 |
-
$charset_collate = " COLLATE {$wpdb->collate}";
|
488 |
-
}
|
489 |
-
|
490 |
-
$blclog->info('Creating database tables');
|
491 |
-
|
492 |
-
//Search filters
|
493 |
-
$blclog->info('... Creating the search filter table');
|
494 |
-
$q = <<<EOD
|
495 |
-
CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}blc_filters` (
|
496 |
-
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
497 |
-
`name` varchar(100) NOT NULL,
|
498 |
-
`params` text NOT NULL,
|
499 |
-
PRIMARY KEY (`id`)
|
500 |
-
) {$charset_collate}
|
501 |
-
EOD;
|
502 |
-
if ( $wpdb->query($q) === false ){
|
503 |
-
$error = sprintf(
|
504 |
-
__("Failed to create table '%s'. Database error: %s", 'broken-link-checker'),
|
505 |
-
$wpdb->prefix . 'blc_filters',
|
506 |
-
$wpdb->last_error
|
507 |
-
);
|
508 |
-
|
509 |
-
$blclog->error($error);
|
510 |
-
if ( $trigger_errors ){
|
511 |
-
trigger_error(
|
512 |
-
$error,
|
513 |
-
E_USER_ERROR
|
514 |
-
);
|
515 |
-
}
|
516 |
-
return false;
|
517 |
-
}
|
518 |
-
|
519 |
-
//Link instances (i.e. link occurences inside posts and other items)
|
520 |
-
$blclog->info('... Creating the link instance table');
|
521 |
-
$q = <<<EOT
|
522 |
-
CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}blc_instances` (
|
523 |
-
`instance_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
524 |
-
`link_id` int(10) unsigned NOT NULL,
|
525 |
-
`container_id` int(10) unsigned NOT NULL,
|
526 |
-
`container_type` varchar(40) NOT NULL DEFAULT 'post',
|
527 |
-
`link_text` varchar(250) NOT NULL DEFAULT '',
|
528 |
-
`parser_type` varchar(40) NOT NULL DEFAULT 'link',
|
529 |
-
`container_field` varchar(250) NOT NULL DEFAULT '',
|
530 |
-
`link_context` varchar(250) NOT NULL DEFAULT '',
|
531 |
-
`raw_url` text NOT NULL,
|
532 |
-
|
533 |
-
PRIMARY KEY (`instance_id`),
|
534 |
-
KEY `link_id` (`link_id`),
|
535 |
-
KEY `source_id` (`container_type`, `container_id`),
|
536 |
-
KEY `parser_type` (`parser_type`)
|
537 |
-
) {$charset_collate};
|
538 |
-
EOT;
|
539 |
-
if ( $wpdb->query($q) === false ){
|
540 |
-
$error = sprintf(
|
541 |
-
__("Failed to create table '%s'. Database error: %s", 'broken-link-checker'),
|
542 |
-
$wpdb->prefix . 'blc_instances',
|
543 |
-
$wpdb->last_error
|
544 |
-
);
|
545 |
-
|
546 |
-
$blclog->error($error);
|
547 |
-
|
548 |
-
if ( $trigger_errors ){
|
549 |
-
trigger_error(
|
550 |
-
$error,
|
551 |
-
E_USER_ERROR
|
552 |
-
);
|
553 |
-
}
|
554 |
-
return false;
|
555 |
-
}
|
556 |
-
|
557 |
-
//Links themselves. Note : The 'url' and 'final_url' columns must be collated
|
558 |
-
//in a case-sensitive manner. This is because "http://a.b/cde" may be a page
|
559 |
-
//very different from "http://a.b/CDe".
|
560 |
-
$blclog->info('... Creating the link table');
|
561 |
-
$q = <<<EOS
|
562 |
-
CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}blc_links` (
|
563 |
-
`link_id` int(20) unsigned NOT NULL AUTO_INCREMENT,
|
564 |
-
`url` text CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,
|
565 |
-
`first_failure` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
566 |
-
`last_check` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
567 |
-
`last_success` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
568 |
-
`last_check_attempt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
569 |
-
`check_count` int(4) unsigned NOT NULL DEFAULT '0',
|
570 |
-
`final_url` text CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,
|
571 |
-
`redirect_count` smallint(5) unsigned NOT NULL DEFAULT '0',
|
572 |
-
`log` text NOT NULL,
|
573 |
-
`http_code` smallint(6) NOT NULL DEFAULT '0',
|
574 |
-
`request_duration` float NOT NULL DEFAULT '0',
|
575 |
-
`timeout` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
576 |
-
`broken` tinyint(1) NOT NULL DEFAULT '0',
|
577 |
-
`may_recheck` tinyint(1) NOT NULL DEFAULT '1',
|
578 |
-
`being_checked` tinyint(1) NOT NULL DEFAULT '0',
|
579 |
-
`result_hash` varchar(200) NOT NULL DEFAULT '',
|
580 |
-
`false_positive` tinyint(1) NOT NULL DEFAULT '0',
|
581 |
-
|
582 |
-
PRIMARY KEY (`link_id`),
|
583 |
-
KEY `url` (`url`(150)),
|
584 |
-
KEY `final_url` (`final_url`(150)),
|
585 |
-
KEY `http_code` (`http_code`),
|
586 |
-
KEY `broken` (`broken`)
|
587 |
-
) {$charset_collate};
|
588 |
-
EOS;
|
589 |
-
if ( $wpdb->query($q) === false ){
|
590 |
-
$error = sprintf(
|
591 |
-
__("Failed to create table '%s'. Database error: %s", 'broken-link-checker'),
|
592 |
-
$wpdb->prefix . 'blc_links',
|
593 |
-
$wpdb->last_error
|
594 |
-
);
|
595 |
-
|
596 |
-
$blclog->error($error);
|
597 |
-
if ( $trigger_errors ){
|
598 |
-
trigger_error(
|
599 |
-
$error,
|
600 |
-
E_USER_ERROR
|
601 |
-
);
|
602 |
-
}
|
603 |
-
return false;
|
604 |
-
}
|
605 |
-
|
606 |
-
//Synchronization records. This table is used to keep track of if and when various items
|
607 |
-
//(e.g. posts, comments, etc) were parsed.
|
608 |
-
$blclog->info('... Creating the synch. record table');
|
609 |
-
$q = <<<EOZ
|
610 |
-
CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}blc_synch` (
|
611 |
-
`container_id` int(20) unsigned NOT NULL,
|
612 |
-
`container_type` varchar(40) NOT NULL,
|
613 |
-
`synched` tinyint(3) unsigned NOT NULL,
|
614 |
-
`last_synch` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
615 |
-
|
616 |
-
PRIMARY KEY (`container_type`,`container_id`),
|
617 |
-
KEY `synched` (`synched`)
|
618 |
-
) {$charset_collate};
|
619 |
-
EOZ;
|
620 |
-
|
621 |
-
if ( $wpdb->query($q) === false ){
|
622 |
-
$error = sprintf(
|
623 |
-
__("Failed to create table '%s'. Database error: %s", 'broken-link-checker'),
|
624 |
-
$wpdb->prefix . 'blc_synch',
|
625 |
-
$wpdb->last_error
|
626 |
-
);
|
627 |
-
|
628 |
-
$blclog->error($error);
|
629 |
-
if ( $trigger_errors ){
|
630 |
-
trigger_error(
|
631 |
-
$error,
|
632 |
-
E_USER_ERROR
|
633 |
-
);
|
634 |
-
}
|
635 |
-
return false;
|
636 |
-
}
|
637 |
-
|
638 |
-
//All good.
|
639 |
-
$blclog->info('All database tables successfully created.');
|
640 |
-
return true;
|
641 |
}
|
642 |
|
643 |
/**
|
@@ -660,9 +439,7 @@ EOZ;
|
|
660 |
* @return void
|
661 |
*/
|
662 |
function database_maintenance(){
|
663 |
-
|
664 |
-
|
665 |
-
blc_cleanup_containers();
|
666 |
blc_cleanup_instances();
|
667 |
blc_cleanup_links();
|
668 |
|
@@ -717,21 +494,6 @@ EOZ;
|
|
717 |
//Add the UserVoice widget to the plugin's pages
|
718 |
add_action( 'admin_footer-' . $options_page_hook, array(&$this, 'uservoice_widget') );
|
719 |
add_action( 'admin_footer-' . $links_page_hook, array(&$this, 'uservoice_widget') );
|
720 |
-
|
721 |
-
/*
|
722 |
-
Display a checkbox in "Screen Options" that lets the user highlight links that
|
723 |
-
have been broken for a long time. The "Screen Options" panel isn't directly
|
724 |
-
customizable, so we must resort to ugly hacks using add_meta_box() and JavaScript.
|
725 |
-
*/
|
726 |
-
$input_html = sprintf(
|
727 |
-
'</label><input style="margin-left: -1em" type="text" name="failure_duration_threshold" id="failure_duration_threshold" value="%d" size="2">',
|
728 |
-
$this->conf->options['failure_duration_threshold']
|
729 |
-
);
|
730 |
-
$title_html = sprintf(
|
731 |
-
__('Highlight links broken for at least %s days', 'broken-link-checker'),
|
732 |
-
$input_html
|
733 |
-
);
|
734 |
-
add_meta_box('highlight_permanent_failures', $title_html, array(&$this, 'noop'), $links_page_hook);
|
735 |
}
|
736 |
|
737 |
/**
|
@@ -761,6 +523,8 @@ EOZ;
|
|
761 |
function options_page(){
|
762 |
global $blclog, $blc_directory;
|
763 |
|
|
|
|
|
764 |
//Sanity check : make sure the DB is all set up
|
765 |
if ( $this->db_version != $this->conf->options['current_db_version'] ) {
|
766 |
printf(
|
@@ -775,13 +539,37 @@ EOZ;
|
|
775 |
return;
|
776 |
}
|
777 |
|
778 |
-
if (isset($
|
779 |
$this->initiate_recheck();
|
|
|
|
|
|
|
|
|
|
|
780 |
}
|
781 |
|
782 |
if(isset($_POST['submit'])) {
|
783 |
check_admin_referer('link-checker-options');
|
784 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
785 |
//The execution time limit must be above zero
|
786 |
$new_execution_time = intval($_POST['max_execution_time']);
|
787 |
if( $new_execution_time > 0 ){
|
@@ -859,22 +647,6 @@ EOZ;
|
|
859 |
}
|
860 |
$this->conf->options['send_email_notifications'] = $email_notifications;
|
861 |
|
862 |
-
//Comment link checking on/off
|
863 |
-
$old_setting = $this->conf->options['check_comment_links'];
|
864 |
-
$this->conf->options['check_comment_links'] = !empty($_POST['check_comment_links']);
|
865 |
-
//If comment link checking was just turned on we need to load the comment manager
|
866 |
-
//and re-parse comments for new links. This is quite hack-y.
|
867 |
-
//TODO: More elegant handling of freshly enabled/disabled container types
|
868 |
-
if ( !$old_setting && $this->conf->options['check_comment_links'] ){
|
869 |
-
include $blc_directory . '/includes/containers/comment.php';
|
870 |
-
$containerRegistry = & blcContainerRegistry::getInstance();
|
871 |
-
$comment_manager = $containerRegistry->get_manager('comment');
|
872 |
-
if ( $comment_manager ){
|
873 |
-
$comment_manager->resynch();
|
874 |
-
blc_got_unsynched_items();
|
875 |
-
}
|
876 |
-
}
|
877 |
-
|
878 |
//Make settings that affect our Cron events take effect immediately
|
879 |
$this->setup_cron_events();
|
880 |
|
@@ -886,8 +658,7 @@ EOZ;
|
|
886 |
inefficient.
|
887 |
*/
|
888 |
if ( ( count($diff1) > 0 ) || ( count($diff2) > 0 ) ){
|
889 |
-
$
|
890 |
-
$manager = $containerRegistry->get_manager('custom_field');
|
891 |
if ( !is_null($manager) ){
|
892 |
$manager->resynch();
|
893 |
blc_got_unsynched_items();
|
@@ -905,20 +676,65 @@ EOZ;
|
|
905 |
|
906 |
}
|
907 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
908 |
$debug = $this->get_debug_info();
|
909 |
|
910 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
911 |
?>
|
912 |
|
913 |
-
<div class="wrap"
|
914 |
|
915 |
-
<form name="link_checker_options" method="post" action="<?php
|
916 |
echo admin_url('options-general.php?page=link-checker-settings&noheader=1');
|
917 |
?>">
|
918 |
<?php
|
919 |
wp_nonce_field('link-checker-options');
|
920 |
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
921 |
|
|
|
|
|
|
|
922 |
<table class="form-table">
|
923 |
|
924 |
<tr valign="top">
|
@@ -932,35 +748,6 @@ EOZ;
|
|
932 |
<div id='wsblc_full_status'>
|
933 |
<br/><br/><br/>
|
934 |
</div>
|
935 |
-
<script type='text/javascript'>
|
936 |
-
(function($){
|
937 |
-
|
938 |
-
function blcUpdateStatus(){
|
939 |
-
$.getJSON(
|
940 |
-
"<?php echo admin_url('admin-ajax.php'); ?>",
|
941 |
-
{
|
942 |
-
'action' : 'blc_full_status'
|
943 |
-
},
|
944 |
-
function (data, textStatus){
|
945 |
-
if ( data && ( typeof(data['text']) != 'undefined' ) ){
|
946 |
-
$('#wsblc_full_status').html(data.text);
|
947 |
-
} else {
|
948 |
-
$('#wsblc_full_status').html('<?php _e('[ Network error ]', 'broken-link-checker'); ?>');
|
949 |
-
}
|
950 |
-
|
951 |
-
setTimeout(blcUpdateStatus, 10000); //...update every 10 seconds
|
952 |
-
}
|
953 |
-
);
|
954 |
-
}
|
955 |
-
blcUpdateStatus();//Call it the first time
|
956 |
-
|
957 |
-
})(jQuery);
|
958 |
-
</script>
|
959 |
-
<?php //JHS: Recheck all posts link: ?>
|
960 |
-
<p><input class="button" type="button" name="recheckbutton"
|
961 |
-
value="<?php _e('Re-check all pages', 'broken-link-checker'); ?>"
|
962 |
-
onclick="location.replace('<?php echo basename($_SERVER['PHP_SELF']); ?>?page=link-checker-settings&recheck=true')" />
|
963 |
-
</p>
|
964 |
|
965 |
<table id="blc-debug-info">
|
966 |
<?php
|
@@ -1001,53 +788,157 @@ EOZ;
|
|
1001 |
|
1002 |
</td>
|
1003 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1004 |
|
1005 |
<tr valign="top">
|
1006 |
-
<th scope="row"><?php _e('
|
1007 |
<td>
|
|
|
1008 |
<label for='mark_broken_links'>
|
1009 |
<input type="checkbox" name="mark_broken_links" id="mark_broken_links"
|
1010 |
<?php if ($this->conf->options['mark_broken_links']) echo ' checked="checked"'; ?>/>
|
1011 |
-
<?php _e('Apply
|
1012 |
</label>
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1025 |
<label for='mark_removed_links'>
|
1026 |
<input type="checkbox" name="mark_removed_links" id="mark_removed_links"
|
1027 |
<?php if ($this->conf->options['mark_removed_links']) echo ' checked="checked"'; ?>/>
|
1028 |
-
<?php _e('Apply
|
1029 |
</label>
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1038 |
|
1039 |
-
|
1040 |
-
<th scope="row"><?php _e('Broken link SEO','broken-link-checker'); ?></th>
|
1041 |
-
<td>
|
1042 |
<label for='nofollow_broken_links'>
|
1043 |
<input type="checkbox" name="nofollow_broken_links" id="nofollow_broken_links"
|
1044 |
<?php if ($this->conf->options['nofollow_broken_links']) echo ' checked="checked"'; ?>/>
|
1045 |
-
<?php _e('
|
1046 |
</label>
|
|
|
|
|
1047 |
</td>
|
1048 |
</tr>
|
1049 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1050 |
<tr valign="top">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1051 |
<th scope="row"><?php _e('Exclusion list', 'broken-link-checker'); ?></th>
|
1052 |
<td><?php _e("Don't check links where the URL contains any of these words (one per line) :", 'broken-link-checker'); ?><br/>
|
1053 |
<textarea name="exclusion_list" id="exclusion_list" cols='45' rows='4' wrap='off'/><?php
|
@@ -1058,46 +949,30 @@ EOZ;
|
|
1058 |
</td>
|
1059 |
</tr>
|
1060 |
|
1061 |
-
|
1062 |
-
|
1063 |
-
<td><?php _e('Check URLs entered in these custom fields (one per line) :', 'broken-link-checker'); ?><br/>
|
1064 |
-
<textarea name="blc_custom_fields" id="blc_custom_fields" cols='45' rows='4' /><?php
|
1065 |
-
if( isset($this->conf->options['custom_fields']) )
|
1066 |
-
echo implode("\n", $this->conf->options['custom_fields']);
|
1067 |
-
?></textarea>
|
1068 |
-
|
1069 |
-
</td>
|
1070 |
-
</tr>
|
1071 |
|
1072 |
-
<
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
<label for='check_comment_links'>
|
1077 |
-
<input type="checkbox" name="check_comment_links" id="check_comment_links"
|
1078 |
-
<?php if ($this->conf->options['check_comment_links']) echo ' checked="checked"'; ?>/>
|
1079 |
-
<?php _e('Check comment links', 'broken-link-checker'); ?>
|
1080 |
-
</label><br>
|
1081 |
-
</p>
|
1082 |
-
</td>
|
1083 |
-
</tr>
|
1084 |
|
1085 |
<tr valign="top">
|
1086 |
-
<th scope="row"><?php _e('
|
1087 |
<td>
|
1088 |
-
|
1089 |
-
|
1090 |
-
|
1091 |
-
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
-
</td>
|
1096 |
-
</tr>
|
1097 |
|
1098 |
</table>
|
|
|
1099 |
|
1100 |
-
<
|
|
|
1101 |
|
1102 |
<table class="form-table">
|
1103 |
|
@@ -1126,21 +1001,23 @@ EOZ;
|
|
1126 |
<tr valign="top">
|
1127 |
<th scope="row"><?php _e('Link monitor', 'broken-link-checker'); ?></th>
|
1128 |
<td>
|
|
|
|
|
1129 |
<label for='run_in_dashboard'>
|
1130 |
-
|
1131 |
<input type="checkbox" name="run_in_dashboard" id="run_in_dashboard"
|
1132 |
<?php if ($this->conf->options['run_in_dashboard']) echo ' checked="checked"'; ?>/>
|
1133 |
<?php _e('Run continuously while the Dashboard is open', 'broken-link-checker'); ?>
|
1134 |
-
</p>
|
1135 |
</label>
|
|
|
1136 |
|
|
|
1137 |
<label for='run_via_cron'>
|
1138 |
-
<p>
|
1139 |
<input type="checkbox" name="run_via_cron" id="run_via_cron"
|
1140 |
<?php if ($this->conf->options['run_via_cron']) echo ' checked="checked"'; ?>/>
|
1141 |
<?php _e('Run hourly in the background', 'broken-link-checker'); ?>
|
1142 |
-
|
1143 |
-
</
|
1144 |
|
1145 |
</td>
|
1146 |
</tr>
|
@@ -1219,30 +1096,7 @@ EOZ;
|
|
1219 |
$value
|
1220 |
);
|
1221 |
|
1222 |
-
|
1223 |
-
Current load : <span id='wsblc_current_load'>...</span>
|
1224 |
-
<script type='text/javascript'>
|
1225 |
-
(function($){
|
1226 |
-
|
1227 |
-
function blcUpdateLoad(){
|
1228 |
-
$.get(
|
1229 |
-
"<?php echo admin_url('admin-ajax.php'); ?>",
|
1230 |
-
{
|
1231 |
-
'action' : 'blc_current_load'
|
1232 |
-
},
|
1233 |
-
function (data, textStatus){
|
1234 |
-
$('#wsblc_current_load').html(data);
|
1235 |
-
|
1236 |
-
setTimeout(blcUpdateLoad, 10000); //...update every 10 seconds
|
1237 |
-
}
|
1238 |
-
);
|
1239 |
-
}
|
1240 |
-
blcUpdateLoad();//Call it the first time
|
1241 |
-
|
1242 |
-
})(jQuery);
|
1243 |
-
</script>
|
1244 |
-
<?php
|
1245 |
-
|
1246 |
echo '<br/><span class="description">';
|
1247 |
printf(
|
1248 |
__(
|
@@ -1254,7 +1108,7 @@ EOZ;
|
|
1254 |
echo '</span>';
|
1255 |
|
1256 |
} else {
|
1257 |
-
echo '<input type="text" disabled="disabled" value="Not available" size="13"/><br>';
|
1258 |
echo '<span class="description">';
|
1259 |
_e('Load limiting only works on Linux-like systems where <code>/proc/loadavg</code> is present and accessible.', 'broken-link-checker');
|
1260 |
echo '</span>';
|
@@ -1263,40 +1117,194 @@ EOZ;
|
|
1263 |
</td>
|
1264 |
</tr>
|
1265 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1266 |
</table>
|
|
|
|
|
|
|
1267 |
|
1268 |
<p class="submit"><input type="submit" name="submit" class='button-primary' value="<?php _e('Save Changes') ?>" /></p>
|
1269 |
</form>
|
1270 |
</div>
|
1271 |
|
1272 |
-
<script type='text/javascript'>
|
1273 |
-
jQuery(function($){
|
1274 |
-
var toggleButton = $('#blc-debug-info-toggle');
|
1275 |
-
|
1276 |
-
toggleButton.click(function(){
|
1277 |
-
|
1278 |
-
var box = $('#blc-debug-info');
|
1279 |
-
box.toggle();
|
1280 |
-
if( box.is(':visible') ){
|
1281 |
-
toggleButton.text('<?php _e('Hide debug info', 'broken-link-checker'); ?>');
|
1282 |
-
} else {
|
1283 |
-
toggleButton.text('<?php _e('Show debug info', 'broken-link-checker'); ?>');
|
1284 |
-
}
|
1285 |
-
|
1286 |
-
});
|
1287 |
-
});
|
1288 |
-
</script>
|
1289 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1290 |
}
|
1291 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1292 |
function options_page_css(){
|
1293 |
-
wp_enqueue_style('blc-
|
1294 |
-
wp_enqueue_style('blc-
|
1295 |
}
|
1296 |
|
1297 |
|
|
|
|
|
|
|
|
|
|
|
1298 |
function links_page(){
|
1299 |
global $wpdb, $blclog;
|
|
|
1300 |
$blc_link_query = & blcLinkQuery::getInstance();
|
1301 |
|
1302 |
//Sanity check : Make sure the plugin's tables are all set up.
|
@@ -1313,6 +1321,17 @@ EOZ;
|
|
1313 |
echo '<p>', implode('<br>', $blclog->get_messages()), '</p>';
|
1314 |
return;
|
1315 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1316 |
|
1317 |
$action = !empty($_POST['action'])?$_POST['action']:'';
|
1318 |
if ( intval($action) == -1 ){
|
@@ -1333,371 +1352,115 @@ EOZ;
|
|
1333 |
$msg_class = 'updated';
|
1334 |
|
1335 |
//Run the selected bulk action, if any
|
1336 |
-
|
1337 |
-
|
1338 |
-
|
1339 |
-
|
1340 |
-
|
1341 |
-
|
1342 |
-
|
1343 |
-
|
1344 |
-
|
1345 |
-
|
1346 |
-
|
1347 |
-
|
1348 |
-
|
1349 |
-
|
1350 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1351 |
|
1352 |
if ( !empty($message) ){
|
1353 |
echo '<div id="message" class="'.$msg_class.' fade"><p>'.$message.'</p></div>';
|
1354 |
}
|
1355 |
|
|
|
|
|
1356 |
//Load custom filters, if any
|
1357 |
$blc_link_query->load_custom_filters();
|
1358 |
|
1359 |
//Calculate the number of links matching each filter
|
1360 |
$blc_link_query->count_filter_results();
|
1361 |
|
1362 |
-
|
1363 |
-
|
1364 |
-
|
1365 |
-
|
1366 |
-
|
1367 |
-
|
1368 |
-
|
1369 |
-
$current_filter = $blc_link_query->get_filter('broken');
|
1370 |
-
|
1371 |
-
}
|
1372 |
-
|
1373 |
-
//Get the desired page number (must be > 0)
|
1374 |
-
$page = isset($_GET['paged'])?intval($_GET['paged']):'1';
|
1375 |
-
if ($page < 1) $page = 1;
|
1376 |
-
|
1377 |
-
//Links per page [1 - 200]
|
1378 |
-
$per_page = isset($_GET['per_page'])?intval($_GET['per_page']):'30';
|
1379 |
-
if ($per_page < 1){
|
1380 |
-
$per_page = 30;
|
1381 |
-
} else if ($per_page > 200){
|
1382 |
-
$per_page = 200;
|
1383 |
-
}
|
1384 |
-
|
1385 |
-
//Calculate the maximum number of pages.
|
1386 |
-
$max_pages = ceil($current_filter['count'] / $per_page);
|
1387 |
-
|
1388 |
-
//Select the required links
|
1389 |
-
$extra_params = array(
|
1390 |
-
'offset' => ( ($page-1) * $per_page ),
|
1391 |
-
'max_results' => $per_page,
|
1392 |
-
'purpose' => BLC_FOR_DISPLAY,
|
1393 |
);
|
1394 |
-
|
|
|
|
|
1395 |
|
1396 |
//Error?
|
1397 |
-
if ( empty($links) && !empty($wpdb->last_error) ){
|
1398 |
printf( __('Database error : %s', 'broken-link-checker'), $wpdb->last_error);
|
1399 |
}
|
1400 |
|
1401 |
-
//If the current request is a user-initiated search query (either directly or
|
1402 |
-
//via a custom filter), save the search params. They can later be used to pre-fill
|
1403 |
-
//the search form or build a new/modified custom filter.
|
1404 |
-
if ( !empty($current_filter['custom']) || ($filter_id == 'search') ){
|
1405 |
-
$search_params = $blc_link_query->get_search_params($current_filter);
|
1406 |
-
}
|
1407 |
-
|
1408 |
-
//Figure out what the "safe" URL to acccess the current page would be.
|
1409 |
-
//This is used by the bulk action form.
|
1410 |
-
$special_args = array('_wpnonce', '_wp_http_referer', 'action', 'selected_links');
|
1411 |
-
$neutral_current_url = remove_query_arg($special_args);
|
1412 |
-
|
1413 |
//Add the "Feedback" widget to the screen meta bar
|
1414 |
$this->print_uservoice_widget();
|
|
|
1415 |
?>
|
1416 |
|
1417 |
<script type='text/javascript'>
|
1418 |
var blc_current_filter = '<?php echo $filter_id; ?>';
|
1419 |
-
var blc_is_broken_filter = <?php
|
1420 |
-
//TODO: Simplify this. Maybe overhaul the filter system to let us query the effective filter.
|
1421 |
-
$is_broken_filter =
|
1422 |
-
($filter_id == 'broken')
|
1423 |
-
|| ( isset($current_filter['params']['s_filter']) && ($current_filter['params']['s_filter'] == 'broken') )
|
1424 |
-
|| ( isset($_GET['s_filter']) && ($_GET['s_filter'] == 'broken') );
|
1425 |
-
echo $is_broken_filter ? 'true' : 'false';
|
1426 |
-
?>;
|
1427 |
</script>
|
1428 |
|
1429 |
-
<div class="wrap"
|
1430 |
-
|
1431 |
-
|
1432 |
-
|
1433 |
-
|
1434 |
-
} else {
|
1435 |
-
echo $current_filter['heading_zero'] . "<span class='current-link-count'></span>";
|
1436 |
-
}
|
1437 |
-
?>
|
1438 |
-
</h2>
|
1439 |
-
<ul class="subsubsub">
|
1440 |
-
<?php
|
1441 |
-
//Construct a submenu of filter types
|
1442 |
-
$items = array();
|
1443 |
-
foreach ($filters as $filter => $data){
|
1444 |
-
if ( !empty($data['hidden']) ) continue; //skip hidden filters
|
1445 |
-
|
1446 |
-
$class = $number_class = '';
|
1447 |
-
|
1448 |
-
if ( $filter_id == $filter ) {
|
1449 |
-
$class = 'class="current"';
|
1450 |
-
$number_class = 'current-link-count';
|
1451 |
-
}
|
1452 |
-
|
1453 |
-
$items[] = "<li><a href='tools.php?page=view-broken-links&filter_id=$filter' $class>
|
1454 |
-
{$data['name']}</a> <span class='count'>(<span class='$number_class'>{$data['count']}</span>)</span>";
|
1455 |
-
}
|
1456 |
-
echo implode(' |</li>', $items);
|
1457 |
-
unset($items);
|
1458 |
-
?>
|
1459 |
-
</ul>
|
1460 |
-
|
1461 |
-
<?php
|
1462 |
//Display the "Search" form and associated buttons.
|
1463 |
-
//The form requires the $filter_id and $
|
1464 |
include dirname($this->loader) . '/includes/admin/search-form.php';
|
1465 |
-
|
1466 |
-
|
1467 |
-
//Do we have any links to display?
|
1468 |
-
if( $links && ( count($links) > 0 ) ) {
|
1469 |
-
?>
|
1470 |
-
<!-- The link list -->
|
1471 |
-
<form id="blc-bulk-action-form" action="<?php echo $neutral_current_url; ?>" method="post">
|
1472 |
-
<?php
|
1473 |
-
wp_nonce_field('bulk-action');
|
1474 |
-
|
1475 |
-
$bulk_actions = array(
|
1476 |
-
'-1' => __('Bulk Actions', 'broken-link-checker'),
|
1477 |
-
"bulk-recheck" => __('Recheck', 'broken-link-checker'),
|
1478 |
-
"bulk-deredirect" => __('Fix redirects', 'broken-link-checker'),
|
1479 |
-
"bulk-not-broken" => __('Mark as not broken', 'broken-link-checker'),
|
1480 |
-
"bulk-unlink" => __('Unlink', 'broken-link-checker'),
|
1481 |
-
"bulk-delete-sources" => __('Delete sources', 'broken-link-checker'),
|
1482 |
-
);
|
1483 |
|
1484 |
-
|
1485 |
-
|
1486 |
-
|
1487 |
-
|
1488 |
-
|
1489 |
-
|
1490 |
-
<div class='tablenav'>
|
1491 |
-
<div class="alignleft actions">
|
1492 |
-
<select name="action" id="blc-bulk-action">
|
1493 |
-
<?php echo $bulk_actions_html; ?>
|
1494 |
-
</select>
|
1495 |
-
<input type="submit" name="doaction" id="doaction" value="<?php echo esc_attr(__('Apply', 'broken-link-checker')); ?>" class="button-secondary action">
|
1496 |
-
</div>
|
1497 |
-
<?php
|
1498 |
-
//Display pagination links
|
1499 |
-
$page_links = paginate_links( array(
|
1500 |
-
'base' => add_query_arg( 'paged', '%#%' ),
|
1501 |
-
'format' => '',
|
1502 |
-
'prev_text' => __('«'),
|
1503 |
-
'next_text' => __('»'),
|
1504 |
-
'total' => $max_pages,
|
1505 |
-
'current' => $page
|
1506 |
-
));
|
1507 |
-
|
1508 |
-
if ( $page_links ) {
|
1509 |
-
echo '<div class="tablenav-pages">';
|
1510 |
-
$page_links_text = sprintf( '<span class="displaying-num">' . __( 'Displaying %s–%s of <span class="current-link-count">%s</span>', 'broken-link-checker' ) . '</span>%s',
|
1511 |
-
number_format_i18n( ( $page - 1 ) * $per_page + 1 ),
|
1512 |
-
number_format_i18n( min( $page * $per_page, $current_filter['count'] ) ),
|
1513 |
-
number_format_i18n( $current_filter['count'] ),
|
1514 |
-
$page_links
|
1515 |
-
);
|
1516 |
-
echo $page_links_text;
|
1517 |
-
echo '</div>';
|
1518 |
-
}
|
1519 |
-
?>
|
1520 |
-
|
1521 |
-
</div>
|
1522 |
-
<table class="widefat" id="blc-links">
|
1523 |
-
<thead>
|
1524 |
-
<tr>
|
1525 |
-
|
1526 |
-
<th scope="col" id="cb" class="check-column">
|
1527 |
-
<input type="checkbox">
|
1528 |
-
</th>
|
1529 |
-
<th scope="col" class="column-title blc-column-source"><?php _e('Source', 'broken-link-checker'); ?></th>
|
1530 |
-
<th scope="col" class="blc-column-link-text"><?php _e('Link Text', 'broken-link-checker'); ?></th>
|
1531 |
-
<th scope="col" class="blc-column-url"><?php _e('URL', 'broken-link-checker'); ?></th>
|
1532 |
-
</tr>
|
1533 |
-
</thead>
|
1534 |
-
<tbody id="the-list">
|
1535 |
-
<?php
|
1536 |
-
$rowclass = ''; $rownum = 0;
|
1537 |
-
foreach ($links as $link) {
|
1538 |
-
$rownum++;
|
1539 |
-
|
1540 |
-
$rowclass = ($rownum % 2)? 'alternate' : '';
|
1541 |
-
$excluded = $this->is_excluded( $link->url );
|
1542 |
-
if ( $excluded ) $rowclass .= ' blc-excluded-link';
|
1543 |
-
|
1544 |
-
if ( $link->redirect_count > 0){
|
1545 |
-
$rowclass .= ' blc-redirect';
|
1546 |
-
}
|
1547 |
-
|
1548 |
-
$days_broken = 0;
|
1549 |
-
if ( $link->broken ){
|
1550 |
-
$rowclass .= ' blc-broken-link';
|
1551 |
-
|
1552 |
-
//Add a highlight to broken links that appear to be permanently broken
|
1553 |
-
$days_broken = intval( (time() - $link->first_failure) / (3600*24) );
|
1554 |
-
if ( $days_broken >= $this->conf->options['failure_duration_threshold'] ){
|
1555 |
-
$rowclass .= ' blc-permanently-broken';
|
1556 |
-
if ( $this->conf->options['highlight_permanent_failures'] ){
|
1557 |
-
$rowclass .= ' blc-permanently-broken-hl';
|
1558 |
-
}
|
1559 |
-
}
|
1560 |
-
}
|
1561 |
-
|
1562 |
-
|
1563 |
-
?>
|
1564 |
-
<tr id='<?php echo "blc-row-" . $link->link_id; ?>' class='blc-row <?php echo $rowclass; ?>' days_broken="<?php echo $days_broken; ?>">
|
1565 |
-
|
1566 |
-
<th class="check-column" scope="row">
|
1567 |
-
<input type="checkbox" name="selected_links[]" value="<?php echo $link->link_id; ?>">
|
1568 |
-
</th>
|
1569 |
-
|
1570 |
-
<td class='post-title column-title'>
|
1571 |
-
<span class='blc-link-id' style='display:none;'><?php echo $link->link_id; ?></span>
|
1572 |
-
<?php
|
1573 |
-
|
1574 |
-
//Pick one link instance to display in the table
|
1575 |
-
$instance = null;
|
1576 |
-
$instances = $link->get_instances();
|
1577 |
-
|
1578 |
-
if ( !empty($instances) ){
|
1579 |
-
//Try to find one that matches the selected link type, if any
|
1580 |
-
if( !empty($search_params['s_link_type']) ){
|
1581 |
-
foreach($instances as $candidate){
|
1582 |
-
if ( ($candidate->container_type == $search_params['s_link_type']) || ($candidate->parser_type == $search_params['s_link_type']) ){
|
1583 |
-
$instance = $candidate;
|
1584 |
-
break;
|
1585 |
-
}
|
1586 |
-
}
|
1587 |
-
}
|
1588 |
-
//If there's no specific link type set, or no suitable instances were found,
|
1589 |
-
//just use the first one.
|
1590 |
-
if ( is_null($instance) ){
|
1591 |
-
$instance = $instances[0];
|
1592 |
-
}
|
1593 |
-
|
1594 |
-
}
|
1595 |
-
|
1596 |
-
//Print the contents of the "Source" column
|
1597 |
-
if ( !is_null($instance) ){
|
1598 |
-
echo $instance->ui_get_source();
|
1599 |
-
|
1600 |
-
$actions = $instance->ui_get_action_links();
|
1601 |
-
|
1602 |
-
echo '<div class="row-actions">';
|
1603 |
-
echo implode(' | </span>', $actions);
|
1604 |
-
echo '</div>';
|
1605 |
-
|
1606 |
-
} else {
|
1607 |
-
_e("[An orphaned link! This is a bug.]", 'broken-link-checker');
|
1608 |
-
}
|
1609 |
-
|
1610 |
-
?>
|
1611 |
-
</td>
|
1612 |
-
<td class='blc-link-text'><?php
|
1613 |
-
//The "Link text" column
|
1614 |
-
if ( !is_null($instance) ){
|
1615 |
-
echo $instance->ui_get_link_text();
|
1616 |
-
} else {
|
1617 |
-
echo '<em>N/A</em>';
|
1618 |
-
}
|
1619 |
-
?>
|
1620 |
-
</td>
|
1621 |
-
<td class='column-url'>
|
1622 |
-
<a href="<?php print esc_attr($link->url); ?>" target='_blank' class='blc-link-url' title="<?php echo esc_attr($link->url); ?>">
|
1623 |
-
<?php print blcUtility::truncate($link->url, 50, ''); ?></a>
|
1624 |
-
<input type='text' id='link-editor-<?php print $rownum; ?>'
|
1625 |
-
value="<?php print esc_attr($link->url); ?>"
|
1626 |
-
class='blc-link-editor' style='display:none' />
|
1627 |
-
<?php
|
1628 |
-
//Output inline action links for the link/URL
|
1629 |
-
$actions = array();
|
1630 |
-
|
1631 |
-
$actions['details'] = "<span class='view'><a class='blc-details-button' href='javascript:void(0)' title='". esc_attr(__('Show more info about this link', 'broken-link-checker')) . "'>". __('Details', 'broken-link-checker') ."</a>";
|
1632 |
-
|
1633 |
-
$actions['delete'] = "<span class='delete'><a class='submitdelete blc-unlink-button' title='" . esc_attr( __('Remove this link from all posts', 'broken-link-checker') ). "' ".
|
1634 |
-
"id='unlink-button-$rownum' href='javascript:void(0);'>" . __('Unlink', 'broken-link-checker') . "</a>";
|
1635 |
-
|
1636 |
-
if ( $link->broken ){
|
1637 |
-
$actions['discard'] = sprintf(
|
1638 |
-
'<span><a href="#" title="%s" class="blc-discard-button">%s</a>',
|
1639 |
-
esc_attr(__('Remove this link from the list of broken links and mark it as valid', 'broken-link-checker')),
|
1640 |
-
__('Not broken', 'broken-link-checker')
|
1641 |
-
);
|
1642 |
-
}
|
1643 |
-
|
1644 |
-
$actions['edit'] = "<span class='edit'><a href='javascript:void(0)' class='blc-edit-button' title='" . esc_attr( __('Edit link URL' , 'broken-link-checker') ) . "'>". __('Edit URL' , 'broken-link-checker') ."</a>";
|
1645 |
-
|
1646 |
-
echo '<div class="row-actions">';
|
1647 |
-
echo implode(' | </span>', $actions);
|
1648 |
-
|
1649 |
-
echo "<span style='display:none' class='blc-cancel-button-container'> " .
|
1650 |
-
"| <a href='javascript:void(0)' class='blc-cancel-button' title='". esc_attr(__('Cancel URL editing' , 'broken-link-checker')) ."'>". __('Cancel' , 'broken-link-checker') ."</a></span>";
|
1651 |
-
|
1652 |
-
echo '</div>';
|
1653 |
-
?>
|
1654 |
-
</td>
|
1655 |
|
1656 |
-
|
1657 |
-
|
1658 |
-
|
1659 |
-
|
1660 |
-
|
1661 |
-
|
1662 |
-
|
1663 |
-
|
1664 |
-
|
1665 |
-
|
1666 |
-
|
1667 |
-
<?php echo $bulk_actions_html; ?>
|
1668 |
-
</select>
|
1669 |
-
<input type="submit" name="doaction2" id="doaction2" value="<?php echo esc_attr(__('Apply', 'broken-link-checker')); ?>" class="button-secondary action">
|
1670 |
-
</div><?php
|
1671 |
-
|
1672 |
-
//Also display pagination links at the bottom
|
1673 |
-
if ( $page_links ) {
|
1674 |
-
echo '<div class="tablenav-pages">';
|
1675 |
-
$page_links_text = sprintf( '<span class="displaying-num">' . __( 'Displaying %s–%s of <span class="current-link-count">%s</span>', 'broken-link-checker' ) . '</span>%s',
|
1676 |
-
number_format_i18n( ( $page - 1 ) * $per_page + 1 ),
|
1677 |
-
number_format_i18n( min( $page * $per_page, $current_filter['count'] ) ),
|
1678 |
-
number_format_i18n( $current_filter['count'] ),
|
1679 |
-
$page_links
|
1680 |
-
);
|
1681 |
-
echo $page_links_text;
|
1682 |
-
echo '</div>';
|
1683 |
-
}
|
1684 |
-
?>
|
1685 |
-
</div>
|
1686 |
-
|
1687 |
-
</form>
|
1688 |
-
<?php
|
1689 |
|
1690 |
-
};
|
|
|
1691 |
|
1692 |
-
|
1693 |
-
|
1694 |
-
|
1695 |
-
|
1696 |
-
|
1697 |
-
?>
|
1698 |
-
</div>
|
1699 |
-
<?php
|
1700 |
-
} //Function ends
|
1701 |
|
1702 |
/**
|
1703 |
* Create a custom link filter using params passed in $_POST.
|
@@ -1903,14 +1666,16 @@ EOZ;
|
|
1903 |
}
|
1904 |
|
1905 |
/**
|
1906 |
-
* Delete posts, bookmarks and other items that contain any of the specified links.
|
|
|
|
|
|
|
1907 |
*
|
1908 |
* @param array $selected_links An array of link IDs
|
|
|
1909 |
* @return array Confirmation message and its CSS class.
|
1910 |
*/
|
1911 |
-
function do_bulk_delete_sources($selected_links){
|
1912 |
-
$blc_container_registry = & blcContainerRegistry::getInstance();
|
1913 |
-
|
1914 |
$message = '';
|
1915 |
$msg_class = 'updated';
|
1916 |
|
@@ -1944,14 +1709,26 @@ EOZ;
|
|
1944 |
}
|
1945 |
|
1946 |
//Instantiate the containers
|
1947 |
-
$containers =
|
1948 |
|
1949 |
-
//Delete their associated entities
|
1950 |
$deleted = array();
|
|
|
1951 |
foreach($containers as $container){
|
1952 |
-
|
|
|
|
|
1953 |
|
1954 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1955 |
|
1956 |
if ( is_wp_error($rez) ){
|
1957 |
//Record error messages for later display
|
@@ -1959,6 +1736,7 @@ EOZ;
|
|
1959 |
$msg_class = 'error';
|
1960 |
} else {
|
1961 |
//Keep track of how many of each type were deleted.
|
|
|
1962 |
if ( isset($deleted[$container_type]) ){
|
1963 |
$deleted[$container_type]++;
|
1964 |
} else {
|
@@ -1969,11 +1747,38 @@ EOZ;
|
|
1969 |
|
1970 |
//Generate delete confirmation messages
|
1971 |
foreach($deleted as $container_type => $number){
|
1972 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1973 |
}
|
1974 |
|
1975 |
if ( count($messages) > 0 ){
|
1976 |
-
$message = implode('<
|
1977 |
} else {
|
1978 |
$message = __("Didn't find anything to delete!", 'broken-link-checker');
|
1979 |
$msg_class = 'error';
|
@@ -2079,194 +1884,123 @@ EOZ;
|
|
2079 |
}
|
2080 |
|
2081 |
|
|
|
|
|
|
|
|
|
|
|
2082 |
function links_page_css(){
|
2083 |
-
wp_enqueue_style('blc-links-page', plugin_dir_url($this->loader) . 'css/links-page.css' );
|
2084 |
-
wp_enqueue_style('blc-
|
2085 |
-
}
|
2086 |
-
|
2087 |
-
function link_details_row($link){
|
2088 |
-
?>
|
2089 |
-
<div class="blc-detail-container">
|
2090 |
-
<div class="blc-detail-block" style="float: left; width: 49%;">
|
2091 |
-
<ol style='list-style-type: none;'>
|
2092 |
-
<?php if ( !empty($link->post_date) ) { ?>
|
2093 |
-
<li><strong><?php _e('Post published on', 'broken-link-checker'); ?> :</strong>
|
2094 |
-
<span class='post_date'><?php
|
2095 |
-
echo date_i18n(get_option('date_format'),strtotime($link->post_date));
|
2096 |
-
?></span></li>
|
2097 |
-
<?php } ?>
|
2098 |
-
<li><strong><?php _e('Link last checked', 'broken-link-checker'); ?> :</strong>
|
2099 |
-
<span class='check_date'><?php
|
2100 |
-
$last_check = $link->last_check;
|
2101 |
-
if ( $last_check < strtotime('-10 years') ){
|
2102 |
-
_e('Never', 'broken-link-checker');
|
2103 |
-
} else {
|
2104 |
-
echo date_i18n(get_option('date_format'), $last_check);
|
2105 |
-
}
|
2106 |
-
?></span></li>
|
2107 |
-
|
2108 |
-
<li><strong><?php _e('HTTP code', 'broken-link-checker'); ?> :</strong>
|
2109 |
-
<span class='http_code'><?php
|
2110 |
-
print $link->http_code;
|
2111 |
-
?></span></li>
|
2112 |
-
|
2113 |
-
<li><strong><?php _e('Response time', 'broken-link-checker'); ?> :</strong>
|
2114 |
-
<span class='request_duration'><?php
|
2115 |
-
printf( __('%2.3f seconds', 'broken-link-checker'), $link->request_duration);
|
2116 |
-
?></span></li>
|
2117 |
-
|
2118 |
-
<li><strong><?php _e('Final URL', 'broken-link-checker'); ?> :</strong>
|
2119 |
-
<span class='final_url'><?php
|
2120 |
-
print $link->final_url;
|
2121 |
-
?></span></li>
|
2122 |
-
|
2123 |
-
<li><strong><?php _e('Redirect count', 'broken-link-checker'); ?> :</strong>
|
2124 |
-
<span class='redirect_count'><?php
|
2125 |
-
print $link->redirect_count;
|
2126 |
-
?></span></li>
|
2127 |
-
|
2128 |
-
<li><strong><?php _e('Instance count', 'broken-link-checker'); ?> :</strong>
|
2129 |
-
<span class='instance_count'><?php
|
2130 |
-
print count($link->get_instances());
|
2131 |
-
?></span></li>
|
2132 |
-
|
2133 |
-
<?php if ( $link->broken && (intval( $link->check_count ) > 0) ){ ?>
|
2134 |
-
<li><br/>
|
2135 |
-
<?php
|
2136 |
-
printf(
|
2137 |
-
_n('This link has failed %d time.', 'This link has failed %d times.', $link->check_count, 'broken-link-checker'),
|
2138 |
-
$link->check_count
|
2139 |
-
);
|
2140 |
-
|
2141 |
-
echo '<br>';
|
2142 |
-
|
2143 |
-
$delta = time() - $link->first_failure;
|
2144 |
-
printf(
|
2145 |
-
__('This link has been broken for %s.', 'broken-link-checker'),
|
2146 |
-
$this->fuzzy_delta($delta)
|
2147 |
-
);
|
2148 |
-
?>
|
2149 |
-
</li>
|
2150 |
-
<?php } ?>
|
2151 |
-
</ol>
|
2152 |
-
</div>
|
2153 |
-
|
2154 |
-
<div class="blc-detail-block" style="float: right; width: 50%;">
|
2155 |
-
<ol style='list-style-type: none;'>
|
2156 |
-
<li><strong><?php _e('Log', 'broken-link-checker'); ?> :</strong>
|
2157 |
-
<span class='blc_log'><?php
|
2158 |
-
print nl2br($link->log);
|
2159 |
-
?></span></li>
|
2160 |
-
</ol>
|
2161 |
-
</div>
|
2162 |
-
|
2163 |
-
<div style="clear:both;"> </div>
|
2164 |
-
</div>
|
2165 |
-
<?php
|
2166 |
}
|
2167 |
|
2168 |
-
|
2169 |
-
|
2170 |
-
|
2171 |
-
|
2172 |
-
|
2173 |
-
|
2174 |
-
|
2175 |
-
$
|
2176 |
-
|
2177 |
-
|
2178 |
-
|
2179 |
-
|
2180 |
-
|
2181 |
-
|
2182 |
-
return __('less than a minute', 'broken-link-checker');
|
2183 |
}
|
2184 |
|
2185 |
-
|
2186 |
-
|
2187 |
-
|
2188 |
-
return sprintf(
|
2189 |
-
_n(
|
2190 |
-
'%d minute',
|
2191 |
-
'%d minutes',
|
2192 |
-
$minutes,
|
2193 |
-
'broken-link-checker'
|
2194 |
-
),
|
2195 |
-
$minutes
|
2196 |
-
);
|
2197 |
-
}
|
2198 |
|
2199 |
-
|
2200 |
-
|
2201 |
-
|
2202 |
-
return sprintf(
|
2203 |
-
_n(
|
2204 |
-
'%d hour',
|
2205 |
-
'%d hours',
|
2206 |
-
$hours,
|
2207 |
-
'broken-link-checker'
|
2208 |
-
),
|
2209 |
-
$hours
|
2210 |
-
);
|
2211 |
-
}
|
2212 |
|
2213 |
-
|
2214 |
-
|
2215 |
-
|
2216 |
-
|
2217 |
-
|
2218 |
-
|
2219 |
-
|
2220 |
-
|
2221 |
-
$days,
|
2222 |
-
'broken-link-checker'
|
2223 |
-
),
|
2224 |
-
$days
|
2225 |
);
|
2226 |
-
|
2227 |
-
|
2228 |
-
if ( ($days < 2) && ($hours > 0) ){
|
2229 |
-
$ret .= ' ' . sprintf(
|
2230 |
-
_n(
|
2231 |
-
'%d hour',
|
2232 |
-
'%d hours',
|
2233 |
-
$hours,
|
2234 |
-
'broken-link-checker'
|
2235 |
-
),
|
2236 |
-
$hours
|
2237 |
-
);
|
2238 |
-
}
|
2239 |
-
|
2240 |
-
return $ret;
|
2241 |
-
}
|
2242 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2243 |
|
2244 |
-
$
|
2245 |
-
$
|
2246 |
-
|
2247 |
-
|
2248 |
-
|
2249 |
-
|
2250 |
-
|
2251 |
-
|
2252 |
-
|
2253 |
-
|
2254 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2255 |
);
|
|
|
2256 |
|
2257 |
-
|
2258 |
-
|
2259 |
-
|
2260 |
-
|
2261 |
-
|
2262 |
-
|
2263 |
-
|
2264 |
-
|
2265 |
-
|
2266 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2267 |
}
|
2268 |
|
2269 |
-
|
|
|
2270 |
}
|
2271 |
|
2272 |
function start_timer(){
|
@@ -2326,7 +2060,7 @@ EOZ;
|
|
2326 |
//This reduces resource usage and may solve the mysterious slowdowns certain users have
|
2327 |
//encountered when activating the plugin.
|
2328 |
//(Disable when debugging or you won't get the FirePHP output)
|
2329 |
-
if ( !
|
2330 |
@ob_end_clean(); //Discard the existing buffer, if any
|
2331 |
header("Connection: close");
|
2332 |
ob_start();
|
@@ -2337,18 +2071,23 @@ EOZ;
|
|
2337 |
flush(); // Unless both are called !
|
2338 |
}
|
2339 |
|
2340 |
-
|
2341 |
-
|
2342 |
-
|
|
|
|
|
2343 |
/*****************************************
|
2344 |
Parse posts and bookmarks
|
2345 |
******************************************/
|
2346 |
|
|
|
|
|
|
|
2347 |
if ( $still_need_resynch ) {
|
2348 |
|
2349 |
//FB::log("Looking for containers that need parsing...");
|
2350 |
|
2351 |
-
while( $containers =
|
2352 |
//FB::log($containers, 'Found containers');
|
2353 |
|
2354 |
foreach($containers as $container){
|
@@ -2489,15 +2228,9 @@ EOZ;
|
|
2489 |
|
2490 |
//Only check links that have at least one valid instance (i.e. an instance exists and
|
2491 |
//it corresponds to one of the currently loaded container/parser types).
|
2492 |
-
$
|
2493 |
-
$loaded_containers =
|
2494 |
-
$
|
2495 |
-
$loaded_containers = "'" . implode("', '", $loaded_containers) . "'";
|
2496 |
-
|
2497 |
-
$parserRegistry = & blcParserRegistry::getInstance();
|
2498 |
-
$loaded_parsers = array_keys($parserRegistry->get_registered_parsers());
|
2499 |
-
$loaded_parsers = array_map(array(&$wpdb, 'escape'), $loaded_parsers);
|
2500 |
-
$loaded_parsers = "'" . implode("', '", $loaded_parsers) . "'";
|
2501 |
|
2502 |
//Note : This is a slow query, but AFAIK there is no way to speed it up.
|
2503 |
//I could put an index on last_check_attempt, but that value is almost
|
@@ -2654,7 +2387,7 @@ EOZ;
|
|
2654 |
function ajax_current_load(){
|
2655 |
$load = $this->get_server_load();
|
2656 |
if ( empty($load) ){
|
2657 |
-
die('Unknown');
|
2658 |
}
|
2659 |
|
2660 |
$one_minute = reset($load);
|
@@ -2875,7 +2608,10 @@ EOZ;
|
|
2875 |
|
2876 |
if ( !$link->is_new ){
|
2877 |
//FB::info($link, 'Link loaded');
|
2878 |
-
|
|
|
|
|
|
|
2879 |
die();
|
2880 |
} else {
|
2881 |
printf( __('Failed to load link details (%s)', 'broken-link-checker'), $wpdb->last_error );
|
@@ -2883,29 +2619,6 @@ EOZ;
|
|
2883 |
}
|
2884 |
}
|
2885 |
|
2886 |
-
/**
|
2887 |
-
* AJAX hook for saving the settings from the "Screen Options" panel in Tools -> Broken Links.
|
2888 |
-
*
|
2889 |
-
* @return void
|
2890 |
-
*/
|
2891 |
-
function ajax_save_highlight_settings(){
|
2892 |
-
if (!current_user_can('edit_others_posts') || !check_ajax_referer('blc_save_highlight_settings', false, false)){
|
2893 |
-
die( json_encode( array(
|
2894 |
-
'error' => __("You're not allowed to do that!", 'broken-link-checker')
|
2895 |
-
)));
|
2896 |
-
}
|
2897 |
-
|
2898 |
-
$this->conf->options['highlight_permanent_failures'] = !empty($_POST['highlight_permanent_failures']);
|
2899 |
-
|
2900 |
-
$failure_duration_threshold = intval($_POST['failure_duration_threshold']);
|
2901 |
-
if ( $failure_duration_threshold >=1 ){
|
2902 |
-
$this->conf->options['failure_duration_threshold'] = $failure_duration_threshold;
|
2903 |
-
}
|
2904 |
-
|
2905 |
-
$this->conf->save_options();
|
2906 |
-
die('1');
|
2907 |
-
}
|
2908 |
-
|
2909 |
/**
|
2910 |
* Create and lock a temporary file.
|
2911 |
*
|
@@ -2981,8 +2694,8 @@ EOZ;
|
|
2981 |
}
|
2982 |
|
2983 |
//Try the plugin's own directory.
|
2984 |
-
if ( @is_writable( dirname(
|
2985 |
-
return dirname(
|
2986 |
} else {
|
2987 |
|
2988 |
//Try the system-wide temp directory
|
@@ -3071,7 +2784,7 @@ EOZ;
|
|
3071 |
}
|
3072 |
|
3073 |
function lockfile_warning(){
|
3074 |
-
$my_dir = '/plugins/' . basename(dirname(
|
3075 |
$settings_page = admin_url( 'options-general.php?page=link-checker-settings#lockfile_directory' );
|
3076 |
|
3077 |
//Make the notice customized to the current settings
|
@@ -3407,6 +3120,11 @@ EOZ;
|
|
3407 |
if ( !wp_next_scheduled('blc_cron_database_maintenance') ){
|
3408 |
wp_schedule_event(time(), 'bimonthly', 'blc_cron_database_maintenance');
|
3409 |
}
|
|
|
|
|
|
|
|
|
|
|
3410 |
}
|
3411 |
|
3412 |
/**
|
@@ -3417,6 +3135,62 @@ EOZ;
|
|
3417 |
function load_language(){
|
3418 |
load_plugin_textdomain( 'broken-link-checker', false, basename(dirname($this->loader)) . '/languages' );
|
3419 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3420 |
|
3421 |
}//class ends here
|
3422 |
|
11 |
}
|
12 |
}
|
13 |
|
14 |
+
require dirname(blc_get_plugin_file()) . '/includes/screen-options/screen-options.php';
|
15 |
+
|
16 |
if (!class_exists('wsBrokenLinkChecker')) {
|
17 |
|
18 |
class wsBrokenLinkChecker {
|
21 |
var $loader;
|
22 |
var $my_basename = '';
|
23 |
|
24 |
+
var $db_version = 5; //The required version of the plugin's DB schema.
|
25 |
|
26 |
var $execution_start_time; //Used for a simple internal execution timer in start_timer()/execution_time()
|
27 |
var $lockfile_handle = null;
|
41 |
$this->loader = $loader;
|
42 |
$this->my_basename = plugin_basename( $this->loader );
|
43 |
|
44 |
+
$this->load_language();
|
|
|
45 |
|
46 |
+
//Unlike the activation hook, the deactivation callback *can* be registered in this file
|
47 |
+
//because deactivation happens after this class has already been instantiated (durinng the
|
48 |
+
//'init' action).
|
49 |
+
register_deactivation_hook($loader, array(&$this, 'deactivation'));
|
50 |
|
51 |
add_action('admin_menu', array(&$this,'admin_menu'));
|
52 |
|
65 |
add_action( 'wp_ajax_blc_link_details', array(&$this,'ajax_link_details') );
|
66 |
add_action( 'wp_ajax_blc_unlink', array(&$this,'ajax_unlink') );
|
67 |
add_action( 'wp_ajax_blc_current_load', array(&$this,'ajax_current_load') );
|
|
|
68 |
add_action( 'wp_ajax_blc_disable_widget_highlight', array(&$this,'ajax_disable_widget_highlight') );
|
69 |
|
70 |
//Check if it's possible to create a lockfile and nag the user about it if not.
|
84 |
add_action('blc_cron_email_notifications', array( &$this, 'send_email_notifications' ));
|
85 |
add_action('blc_cron_check_links', array(&$this, 'cron_check_links'));
|
86 |
add_action('blc_cron_database_maintenance', array(&$this, 'database_maintenance'));
|
87 |
+
add_action('blc_cron_check_news', array(&$this, 'check_news'));
|
88 |
+
|
89 |
+
//Add a "Screen Options" panel to the "Broken Links" page
|
90 |
+
add_screen_options_panel(
|
91 |
+
'blc-screen-options',
|
92 |
+
'',
|
93 |
+
array(&$this, 'screen_options_html'),
|
94 |
+
'tools_page_view-broken-links',
|
95 |
+
array(&$this, 'ajax_save_screen_options'),
|
96 |
+
true
|
97 |
+
);
|
98 |
}
|
99 |
|
100 |
/**
|
159 |
$.getJSON(
|
160 |
"<?php echo admin_url('admin-ajax.php'); ?>",
|
161 |
{
|
162 |
+
'action' : 'blc_dashboard_status',
|
163 |
+
'random' : Math.random()
|
164 |
},
|
165 |
function (data, textStatus){
|
166 |
if ( data && ( typeof(data.text) != 'undefined' ) ) {
|
205 |
}
|
206 |
|
207 |
function admin_print_scripts(){
|
208 |
+
//jQuery is used for triggering the link monitor via AJAX when any admin page is open.
|
209 |
wp_enqueue_script('jquery');
|
210 |
}
|
211 |
|
213 |
//jQuery UI is used on the settings page
|
214 |
wp_enqueue_script('jquery-ui-core'); //Used for background color animation
|
215 |
wp_enqueue_script('jquery-ui-dialog');
|
216 |
+
wp_enqueue_script('jquery-ui-tabs');
|
217 |
+
wp_enqueue_script('jquery-cookie', WP_PLUGIN_URL . '/' . dirname($this->my_basename) . '/js/jquery.cookie.js'); //Used for storing last widget states, etc
|
218 |
}
|
219 |
|
220 |
function enqueue_link_page_scripts(){
|
343 |
$blclog = new blcOptionLogger('blc_installation_log');
|
344 |
$blclog->clear();
|
345 |
|
346 |
+
$blclog->info( sprintf('Plugin activated %s.', date('Y-m-d H:i:s')) );
|
347 |
|
348 |
$this->conf->options['installation_complete'] = false;
|
349 |
$this->conf->options['installation_failed'] = true;
|
350 |
$this->conf->save_options();
|
351 |
$blclog->info('Installation/update begins.');
|
352 |
|
353 |
+
$moduleManager = & blcModuleManager::getInstance();
|
354 |
+
|
355 |
+
//If upgrading, activate/deactivate custom field and comment containers based on old ver. settings
|
356 |
+
if ( isset($this->conf->options['check_comment_links']) ){
|
357 |
+
if ( !$this->conf->options['check_comment_links'] ){
|
358 |
+
$moduleManager->deactivate('comment');
|
359 |
+
}
|
360 |
+
unset($this->conf->options['check_comment_links']);
|
361 |
+
}
|
362 |
+
if ( empty($this->conf->options['custom_fields']) ){
|
363 |
+
$moduleManager->deactivate('custom_field');
|
364 |
+
}
|
365 |
+
|
366 |
//Prepare the database.
|
367 |
$blclog->info('Upgrading the database...');
|
368 |
$this->upgrade_database();
|
369 |
+
|
370 |
+
//Remove invalid DB entries
|
371 |
+
$blclog->info('Cleaning up the database...');
|
372 |
+
blc_cleanup_database();
|
373 |
|
374 |
+
//Notify modules that the plugin has been activated. This will cause container
|
375 |
+
//modules to create and update synch. records for all new/modified posts and other items.
|
376 |
+
$blclog->info('Notifying modules...');
|
377 |
+
$moduleManager->plugin_activated();
|
378 |
+
blc_got_unsynched_items();
|
379 |
+
|
380 |
//Turn off load limiting if it's not available on this server.
|
381 |
$blclog->info('Updating server load limit settings...');
|
382 |
$load = $this->get_server_load();
|
406 |
wp_clear_scheduled_hook('blc_cron_check_links');
|
407 |
wp_clear_scheduled_hook('blc_cron_email_notifications');
|
408 |
wp_clear_scheduled_hook('blc_cron_database_maintenance');
|
409 |
+
wp_clear_scheduled_hook('blc_cron_check_news');
|
410 |
}
|
411 |
|
412 |
/**
|
415 |
* @return bool
|
416 |
*/
|
417 |
function upgrade_database($trigger_errors = true){
|
418 |
+
require_once dirname($this->loader) . '/includes/admin/db-upgrade.php';
|
419 |
+
return blcDatabaseUpgrader::upgrade_database();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
420 |
}
|
421 |
|
422 |
/**
|
439 |
* @return void
|
440 |
*/
|
441 |
function database_maintenance(){
|
442 |
+
blcContainerHelper::cleanup_containers();
|
|
|
|
|
443 |
blc_cleanup_instances();
|
444 |
blc_cleanup_links();
|
445 |
|
494 |
//Add the UserVoice widget to the plugin's pages
|
495 |
add_action( 'admin_footer-' . $options_page_hook, array(&$this, 'uservoice_widget') );
|
496 |
add_action( 'admin_footer-' . $links_page_hook, array(&$this, 'uservoice_widget') );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
497 |
}
|
498 |
|
499 |
/**
|
523 |
function options_page(){
|
524 |
global $blclog, $blc_directory;
|
525 |
|
526 |
+
$moduleManager = &blcModuleManager::getInstance();
|
527 |
+
|
528 |
//Sanity check : make sure the DB is all set up
|
529 |
if ( $this->db_version != $this->conf->options['current_db_version'] ) {
|
530 |
printf(
|
539 |
return;
|
540 |
}
|
541 |
|
542 |
+
if (isset($_POST['recheck']) && !empty($_POST['recheck']) ){
|
543 |
$this->initiate_recheck();
|
544 |
+
|
545 |
+
//Redirect back to the settings page
|
546 |
+
$base_url = remove_query_arg( array('_wpnonce', 'noheader', 'updated', 'error', 'action', 'message') );
|
547 |
+
wp_redirect( add_query_arg( array( 'recheck-initiated' => true), $base_url ) );
|
548 |
+
die();
|
549 |
}
|
550 |
|
551 |
if(isset($_POST['submit'])) {
|
552 |
check_admin_referer('link-checker-options');
|
553 |
|
554 |
+
//Activate/deactivate modules
|
555 |
+
if ( !empty($_POST['module']) ){
|
556 |
+
$active = array_keys($_POST['module']);
|
557 |
+
$moduleManager->set_active_modules($active);
|
558 |
+
}
|
559 |
+
|
560 |
+
//Only post statuses that actually exist can be selected
|
561 |
+
if ( isset($_POST['enabled_post_statuses']) && is_array($_POST['enabled_post_statuses']) ){
|
562 |
+
$available_statuses = get_post_stati();
|
563 |
+
$enabled_post_statuses = array_intersect($_POST['enabled_post_statuses'], $available_statuses);
|
564 |
+
} else {
|
565 |
+
$enabled_post_statuses = array();
|
566 |
+
}
|
567 |
+
//At least one status must be enabled; defaults to "Published".
|
568 |
+
if ( empty($enabled_post_statuses) ){
|
569 |
+
$enabled_post_statuses = array('publish');
|
570 |
+
}
|
571 |
+
$this->conf->options['enabled_post_statuses'] = $enabled_post_statuses;
|
572 |
+
|
573 |
//The execution time limit must be above zero
|
574 |
$new_execution_time = intval($_POST['max_execution_time']);
|
575 |
if( $new_execution_time > 0 ){
|
647 |
}
|
648 |
$this->conf->options['send_email_notifications'] = $email_notifications;
|
649 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
650 |
//Make settings that affect our Cron events take effect immediately
|
651 |
$this->setup_cron_events();
|
652 |
|
658 |
inefficient.
|
659 |
*/
|
660 |
if ( ( count($diff1) > 0 ) || ( count($diff2) > 0 ) ){
|
661 |
+
$manager = & blcContainerHelper::get_manager('custom_field');
|
|
|
662 |
if ( !is_null($manager) ){
|
663 |
$manager->resynch();
|
664 |
blc_got_unsynched_items();
|
676 |
|
677 |
}
|
678 |
|
679 |
+
//Show one when recheck is started, too.
|
680 |
+
if ( !empty($_GET['recheck-initiated']) ){
|
681 |
+
echo '<div id="message" class="updated fade"><p><strong>',
|
682 |
+
__('Complete site recheck started.', 'broken-link-checker'), // -- Yoda
|
683 |
+
'</strong></p></div>';
|
684 |
+
}
|
685 |
+
|
686 |
+
//Cull invalid and missing modules
|
687 |
+
$moduleManager->validate_active_modules();
|
688 |
+
|
689 |
+
//Output the "Feedback" button that links to the plugin's UserVoice forum
|
690 |
+
$this->print_uservoice_widget();
|
691 |
+
|
692 |
$debug = $this->get_debug_info();
|
693 |
|
694 |
+
$details_text = __('Details', 'broken-link-checker');
|
695 |
+
add_filter('blc-module-settings-custom_field', array(&$this, 'make_custom_field_input'), 10, 2);
|
696 |
+
|
697 |
+
//Translate and markup-ify module headers for display
|
698 |
+
$modules = $moduleManager->get_modules_by_category('', true, true);
|
699 |
+
|
700 |
+
//Output the custom broken link/removed link styles for example links
|
701 |
+
printf(
|
702 |
+
'<style type="text/css">%s %s</style>',
|
703 |
+
$this->conf->options['broken_link_css'],
|
704 |
+
$this->conf->options['removed_link_css']
|
705 |
+
);
|
706 |
+
|
707 |
+
$section_names = array(
|
708 |
+
'general' => __('General', 'broken-link-checker'),
|
709 |
+
'where' => __('Look For Links In', 'broken-link-checker'),
|
710 |
+
'which' => __('Which Links To Check', 'broken-link-checker'),
|
711 |
+
'how' => __('Protocols & APIs', 'broken-link-checker'),
|
712 |
+
'advanced' => __('Advanced', 'broken-link-checker'),
|
713 |
+
);
|
714 |
?>
|
715 |
|
716 |
+
<div class="wrap"><?php screen_icon(); ?><h2><?php _e('Broken Link Checker Options', 'broken-link-checker'); ?></h2>
|
717 |
|
718 |
+
<form name="link_checker_options" id="link_checker_options" method="post" action="<?php
|
719 |
echo admin_url('options-general.php?page=link-checker-settings&noheader=1');
|
720 |
?>">
|
721 |
<?php
|
722 |
wp_nonce_field('link-checker-options');
|
723 |
?>
|
724 |
+
|
725 |
+
<div id="blc-tabs">
|
726 |
+
|
727 |
+
<ul class="hide-if-no-js">
|
728 |
+
<?php
|
729 |
+
foreach($section_names as $section_id => $section_name){
|
730 |
+
printf('<li><a href="#section-%s">%s</a></li>', esc_attr($section_id), $section_name);
|
731 |
+
}
|
732 |
+
?>
|
733 |
+
</ul>
|
734 |
|
735 |
+
<div id="section-general" class="blc-section">
|
736 |
+
<h3 class="hide-if-js"><?php echo $section_names['general']; ?></h3>
|
737 |
+
|
738 |
<table class="form-table">
|
739 |
|
740 |
<tr valign="top">
|
748 |
<div id='wsblc_full_status'>
|
749 |
<br/><br/><br/>
|
750 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
751 |
|
752 |
<table id="blc-debug-info">
|
753 |
<?php
|
788 |
|
789 |
</td>
|
790 |
</tr>
|
791 |
+
|
792 |
+
<tr valign="top">
|
793 |
+
<th scope="row"><?php _e('E-mail notifications', 'broken-link-checker'); ?></th>
|
794 |
+
<td>
|
795 |
+
<p style="margin-top: 0px;">
|
796 |
+
<label for='send_email_notifications'>
|
797 |
+
<input type="checkbox" name="send_email_notifications" id="send_email_notifications"
|
798 |
+
<?php if ($this->conf->options['send_email_notifications']) echo ' checked="checked"'; ?>/>
|
799 |
+
<?php _e('Send me e-mail notifications about newly detected broken links', 'broken-link-checker'); ?>
|
800 |
+
</label><br />
|
801 |
+
</p>
|
802 |
+
</td>
|
803 |
+
</tr>
|
804 |
|
805 |
<tr valign="top">
|
806 |
+
<th scope="row"><?php _e('Link tweaks','broken-link-checker'); ?></th>
|
807 |
<td>
|
808 |
+
<p style="margin-top: 0; margin-bottom: 0.5em;">
|
809 |
<label for='mark_broken_links'>
|
810 |
<input type="checkbox" name="mark_broken_links" id="mark_broken_links"
|
811 |
<?php if ($this->conf->options['mark_broken_links']) echo ' checked="checked"'; ?>/>
|
812 |
+
<?php _e('Apply custom formatting to broken links', 'broken-link-checker'); ?>
|
813 |
</label>
|
814 |
+
|
|
815 |
+
<a id="toggle-broken-link-css-editor" href="#" class="blc-toggle-link"><?php
|
816 |
+
_e('Edit CSS', 'broken-link-checker');
|
817 |
+
?></a>
|
818 |
+
</p>
|
819 |
+
|
820 |
+
<div id="broken-link-css-wrap"<?php
|
821 |
+
if ( !blcUtility::get_cookie('broken-link-css-wrap', false) ){
|
822 |
+
echo ' class="hidden"';
|
823 |
+
}
|
824 |
+
?>>
|
825 |
+
<textarea name="broken_link_css" id="broken_link_css" cols='45' rows='4'/><?php
|
826 |
+
if( isset($this->conf->options['broken_link_css']) )
|
827 |
+
echo $this->conf->options['broken_link_css'];
|
828 |
+
?></textarea>
|
829 |
+
<p class="description">
|
830 |
+
Example : Lorem ipsum <a href="#" class="broken_link" onclick="return false;">broken link</a>,
|
831 |
+
dolor sit amet.
|
832 |
+
Click "Save Changes" to update example output.
|
833 |
+
</p>
|
834 |
+
</div>
|
835 |
+
|
836 |
+
<p style="margin-bottom: 0.5em;">
|
837 |
<label for='mark_removed_links'>
|
838 |
<input type="checkbox" name="mark_removed_links" id="mark_removed_links"
|
839 |
<?php if ($this->conf->options['mark_removed_links']) echo ' checked="checked"'; ?>/>
|
840 |
+
<?php _e('Apply custom formatting to removed links', 'broken-link-checker'); ?>
|
841 |
</label>
|
842 |
+
|
|
843 |
+
<a id="toggle-removed-link-css-editor" href="#" class="blc-toggle-link"><?php
|
844 |
+
_e('Edit CSS', 'broken-link-checker');
|
845 |
+
?></a>
|
846 |
+
</p>
|
847 |
+
|
848 |
+
<div id="removed-link-css-wrap" <?php
|
849 |
+
if ( !blcUtility::get_cookie('removed-link-css-wrap', false) ){
|
850 |
+
echo ' class="hidden"';
|
851 |
+
}
|
852 |
+
?>>
|
853 |
+
<textarea name="removed_link_css" id="removed_link_css" cols='45' rows='4'/><?php
|
854 |
+
if( isset($this->conf->options['removed_link_css']) )
|
855 |
+
echo $this->conf->options['removed_link_css'];
|
856 |
+
?></textarea>
|
857 |
+
|
858 |
+
<p class="description">
|
859 |
+
Example : Lorem ipsum <span class="removed_link">removed link</span>, dolor sit amet.
|
860 |
+
Click "Save Changes" to update example output.
|
861 |
+
</p>
|
862 |
+
</div>
|
863 |
|
864 |
+
<p>
|
|
|
|
|
865 |
<label for='nofollow_broken_links'>
|
866 |
<input type="checkbox" name="nofollow_broken_links" id="nofollow_broken_links"
|
867 |
<?php if ($this->conf->options['nofollow_broken_links']) echo ' checked="checked"'; ?>/>
|
868 |
+
<?php _e('Stop search engines from following broken links', 'broken-link-checker'); ?>
|
869 |
</label>
|
870 |
+
</p>
|
871 |
+
|
872 |
</td>
|
873 |
</tr>
|
874 |
+
|
875 |
+
</table>
|
876 |
+
|
877 |
+
</div>
|
878 |
+
|
879 |
+
<div id="section-where" class="blc-section">
|
880 |
+
<h3 class="hide-if-js"><?php echo $section_names['where']; ?></h3>
|
881 |
+
|
882 |
+
<table class="form-table">
|
883 |
+
|
884 |
+
<tr valign="top">
|
885 |
+
<th scope="row"><?php _e('Look for links in', 'broken-link-checker'); ?></th>
|
886 |
+
<td>
|
887 |
+
<?php
|
888 |
+
if ( !empty($modules['container']) ){
|
889 |
+
uasort($modules['container'], create_function('$a, $b', 'return strcasecmp($a["Name"], $b["Name"]);'));
|
890 |
+
$this->print_module_list($modules['container'], $this->conf->options);
|
891 |
+
}
|
892 |
+
?>
|
893 |
+
</td></tr>
|
894 |
+
|
895 |
+
<tr valign="top">
|
896 |
+
<th scope="row"><?php _e('Post statuses', 'broken-link-checker'); ?></th>
|
897 |
+
<td>
|
898 |
+
<?php
|
899 |
+
$available_statuses = get_post_stati(array('internal' => false), 'objects');
|
900 |
+
|
901 |
+
if ( isset($this->conf->options['enabled_post_statuses']) ){
|
902 |
+
$enabled_post_statuses = $this->conf->options['enabled_post_statuses'];
|
903 |
+
} else {
|
904 |
+
$enabled_post_statuses = array();
|
905 |
+
}
|
906 |
+
|
907 |
+
foreach($available_statuses as $status => $status_object){
|
908 |
+
printf(
|
909 |
+
'<p><label><input type="checkbox" name="enabled_post_statuses[]" value="%s"%s> %s</label></p>',
|
910 |
+
esc_attr($status),
|
911 |
+
in_array($status, $enabled_post_statuses)?' checked="checked"':'',
|
912 |
+
$status_object->label
|
913 |
+
);
|
914 |
+
}
|
915 |
+
?>
|
916 |
+
</td></tr>
|
917 |
+
|
918 |
+
</table>
|
919 |
+
|
920 |
+
</div>
|
921 |
+
|
922 |
+
|
923 |
+
<div id="section-which" class="blc-section">
|
924 |
+
<h3 class="hide-if-js"><?php echo $section_names['which']; ?></h3>
|
925 |
+
|
926 |
+
<table class="form-table">
|
927 |
+
|
928 |
<tr valign="top">
|
929 |
+
<th scope="row"><?php _e('Link types', 'broken-link-checker'); ?></th>
|
930 |
+
<td>
|
931 |
+
<?php
|
932 |
+
if ( !empty($modules['parser']) ){
|
933 |
+
$this->print_module_list($modules['parser'], $this->conf->options);
|
934 |
+
} else {
|
935 |
+
echo __('Error : All link parsers missing!', 'broken-link-checker');
|
936 |
+
}
|
937 |
+
?>
|
938 |
+
</td>
|
939 |
+
</tr>
|
940 |
+
|
941 |
+
<tr valign="top">
|
942 |
<th scope="row"><?php _e('Exclusion list', 'broken-link-checker'); ?></th>
|
943 |
<td><?php _e("Don't check links where the URL contains any of these words (one per line) :", 'broken-link-checker'); ?><br/>
|
944 |
<textarea name="exclusion_list" id="exclusion_list" cols='45' rows='4' wrap='off'/><?php
|
949 |
</td>
|
950 |
</tr>
|
951 |
|
952 |
+
</table>
|
953 |
+
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
954 |
|
955 |
+
<div id="section-how" class="blc-section">
|
956 |
+
<h3 class="hide-if-js"><?php echo $section_names['how']; ?></h3>
|
957 |
+
|
958 |
+
<table class="form-table">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
959 |
|
960 |
<tr valign="top">
|
961 |
+
<th scope="row"><?php _e('Check links using', 'broken-link-checker'); ?></th>
|
962 |
<td>
|
963 |
+
<?php
|
964 |
+
if ( !empty($modules['checker']) ){
|
965 |
+
$modules['checker'] = array_reverse($modules['checker']);
|
966 |
+
$this->print_module_list($modules['checker'], $this->conf->options);
|
967 |
+
}
|
968 |
+
?>
|
969 |
+
</td></tr>
|
|
|
|
|
970 |
|
971 |
</table>
|
972 |
+
</div>
|
973 |
|
974 |
+
<div id="section-advanced" class="blc-section">
|
975 |
+
<h3 class="hide-if-js"><?php echo $section_names['advanced']; ?></h3>
|
976 |
|
977 |
<table class="form-table">
|
978 |
|
1001 |
<tr valign="top">
|
1002 |
<th scope="row"><?php _e('Link monitor', 'broken-link-checker'); ?></th>
|
1003 |
<td>
|
1004 |
+
|
1005 |
+
<p>
|
1006 |
<label for='run_in_dashboard'>
|
1007 |
+
|
1008 |
<input type="checkbox" name="run_in_dashboard" id="run_in_dashboard"
|
1009 |
<?php if ($this->conf->options['run_in_dashboard']) echo ' checked="checked"'; ?>/>
|
1010 |
<?php _e('Run continuously while the Dashboard is open', 'broken-link-checker'); ?>
|
|
|
1011 |
</label>
|
1012 |
+
</p>
|
1013 |
|
1014 |
+
<p>
|
1015 |
<label for='run_via_cron'>
|
|
|
1016 |
<input type="checkbox" name="run_via_cron" id="run_via_cron"
|
1017 |
<?php if ($this->conf->options['run_via_cron']) echo ' checked="checked"'; ?>/>
|
1018 |
<?php _e('Run hourly in the background', 'broken-link-checker'); ?>
|
1019 |
+
</label>
|
1020 |
+
</p>
|
1021 |
|
1022 |
</td>
|
1023 |
</tr>
|
1096 |
$value
|
1097 |
);
|
1098 |
|
1099 |
+
echo 'Current load : <span id="wsblc_current_load">...</span>';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1100 |
echo '<br/><span class="description">';
|
1101 |
printf(
|
1102 |
__(
|
1108 |
echo '</span>';
|
1109 |
|
1110 |
} else {
|
1111 |
+
echo '<input type="text" disabled="disabled" value="', esc_attr(__('Not available', 'broken-link-checker')), '" size="13"/><br>';
|
1112 |
echo '<span class="description">';
|
1113 |
_e('Load limiting only works on Linux-like systems where <code>/proc/loadavg</code> is present and accessible.', 'broken-link-checker');
|
1114 |
echo '</span>';
|
1117 |
</td>
|
1118 |
</tr>
|
1119 |
|
1120 |
+
<tr valign="top">
|
1121 |
+
<th scope="row"><?php _e('Forced recheck', 'broken-link-checker'); ?></th>
|
1122 |
+
<td>
|
1123 |
+
<input class="button" type="button" name="start-recheck" id="start-recheck"
|
1124 |
+
value="<?php _e('Re-check all pages', 'broken-link-checker'); ?>" />
|
1125 |
+
<input type="hidden" name="recheck" value="" id="recheck" />
|
1126 |
+
<br />
|
1127 |
+
<span class="description"><?php
|
1128 |
+
_e('The "Nuclear Option". Click this button to make the plugin empty its link database and recheck the entire site from scratch.', 'broken-link-checker');
|
1129 |
+
|
1130 |
+
?></span>
|
1131 |
+
</td>
|
1132 |
+
</tr>
|
1133 |
+
|
1134 |
</table>
|
1135 |
+
</div>
|
1136 |
+
|
1137 |
+
</div>
|
1138 |
|
1139 |
<p class="submit"><input type="submit" name="submit" class='button-primary' value="<?php _e('Save Changes') ?>" /></p>
|
1140 |
</form>
|
1141 |
</div>
|
1142 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1143 |
<?php
|
1144 |
+
//The various JS for this page is stored in a separate file for the purposes readability.
|
1145 |
+
include dirname($this->loader) . '/includes/admin/options-page-js.php';
|
1146 |
+
}
|
1147 |
+
|
1148 |
+
/**
|
1149 |
+
* Output a list of modules and their settings.
|
1150 |
+
*
|
1151 |
+
* Each list entry will contain a checkbox that is checked if the module is
|
1152 |
+
* currently active.
|
1153 |
+
*
|
1154 |
+
* @param array $modules Array of modules to display
|
1155 |
+
* @param array $current_settings
|
1156 |
+
* @return void
|
1157 |
+
*/
|
1158 |
+
function print_module_list($modules, $current_settings){
|
1159 |
+
$moduleManager = &blcModuleManager::getInstance();
|
1160 |
+
|
1161 |
+
foreach($modules as $module_id => $module_data){
|
1162 |
+
$module_id = $module_data['ModuleID'];
|
1163 |
+
|
1164 |
+
$style = $module_data['ModuleHidden']?' style="display:none;"':'';
|
1165 |
+
|
1166 |
+
printf(
|
1167 |
+
'<div class="module-container" id="module-container-%s"%s>',
|
1168 |
+
$module_id,
|
1169 |
+
$style
|
1170 |
+
);
|
1171 |
+
$this->print_module_checkbox($module_id, $module_data, $moduleManager->is_active($module_id));
|
1172 |
+
|
1173 |
+
$extra_settings = apply_filters(
|
1174 |
+
'blc-module-settings-'.$module_id,
|
1175 |
+
'',
|
1176 |
+
$current_settings
|
1177 |
+
);
|
1178 |
+
|
1179 |
+
if ( !empty($extra_settings) ){
|
1180 |
+
|
1181 |
+
printf(
|
1182 |
+
' | <a class="blc-toggle-link toggle-module-settings" id="toggle-module-settings-%s" href="#">%s</a>',
|
1183 |
+
$module_id,
|
1184 |
+
__('Configure', 'broken-link-checker')
|
1185 |
+
);
|
1186 |
+
|
1187 |
+
//The plugin remembers the last open/closed state of module configuration boxes
|
1188 |
+
$box_id = 'module-extra-settings-' . $module_id;
|
1189 |
+
$show = blcUtility::get_cookie(
|
1190 |
+
$box_id,
|
1191 |
+
$moduleManager->is_active($module_id)
|
1192 |
+
);
|
1193 |
+
|
1194 |
+
printf(
|
1195 |
+
'<div class="module-extra-settings%s" id="%s">%s</div>',
|
1196 |
+
$show?'':' hidden',
|
1197 |
+
$box_id,
|
1198 |
+
$extra_settings
|
1199 |
+
);
|
1200 |
+
}
|
1201 |
+
|
1202 |
+
echo '</div>';
|
1203 |
+
}
|
1204 |
+
}
|
1205 |
+
|
1206 |
+
/**
|
1207 |
+
* Output a checkbox for a module.
|
1208 |
+
*
|
1209 |
+
* Generates a simple checkbox that can be used to mark a module as active/inactive.
|
1210 |
+
* If the specified module can't be deactivated (ModuleAlwaysActive = true), the checkbox
|
1211 |
+
* will be displayed in a disabled state and a hidden field will be created to make
|
1212 |
+
* form submissions work correctly.
|
1213 |
+
*
|
1214 |
+
* @param string $module_id Module ID.
|
1215 |
+
* @param array $module_data Associative array of module data.
|
1216 |
+
* @param bool $active If true, the newly created checkbox will start out checked.
|
1217 |
+
* @return void
|
1218 |
+
*/
|
1219 |
+
function print_module_checkbox($module_id, $module_data, $active = false){
|
1220 |
+
$disabled = false;
|
1221 |
+
$name_prefix = 'module';
|
1222 |
+
$label_class = '';
|
1223 |
+
$active = $active || $module_data['ModuleAlwaysActive'];
|
1224 |
+
|
1225 |
+
if ( $module_data['ModuleRequiresPro'] && !defined('BLC_PRO_VERSION') ){
|
1226 |
+
$active = false;
|
1227 |
+
$disabled = true;
|
1228 |
+
$label_class .= ' module-requires-pro';
|
1229 |
+
}
|
1230 |
+
|
1231 |
+
if ( $module_data['ModuleAlwaysActive'] ){
|
1232 |
+
$disabled = true;
|
1233 |
+
$name_prefix = 'module-always-active';
|
1234 |
+
}
|
1235 |
+
|
1236 |
+
$checked = $active ? ' checked="checked"':'';
|
1237 |
+
if ( $disabled ){
|
1238 |
+
$checked .= ' disabled="disabled"';
|
1239 |
+
}
|
1240 |
+
|
1241 |
+
$pro_notice = sprintf(
|
1242 |
+
'<span class="pro-notice"><a href="%s" title="%s">Pro</a></span>',
|
1243 |
+
esc_attr('http://wpplugins.com/plugin/173/broken-link-checker-pro'),
|
1244 |
+
esc_attr(__('Upgrade to Pro to enable this feature', 'broken-link-checker'))
|
1245 |
+
);
|
1246 |
+
|
1247 |
+
printf(
|
1248 |
+
'<label class="%s">
|
1249 |
+
<input type="checkbox" name="%s[%s]" id="module-checkbox-%s"%s /> %s %s
|
1250 |
+
</label>',
|
1251 |
+
esc_attr($label_class),
|
1252 |
+
$name_prefix,
|
1253 |
+
esc_attr($module_id),
|
1254 |
+
esc_attr($module_id),
|
1255 |
+
$checked,
|
1256 |
+
$module_data['Name'],
|
1257 |
+
($module_data['ModuleRequiresPro'] && !defined('BLC_PRO_VERSION')) ? $pro_notice : ''
|
1258 |
+
);
|
1259 |
+
|
1260 |
+
if ( $module_data['ModuleAlwaysActive'] ){
|
1261 |
+
printf(
|
1262 |
+
'<input type="hidden" name="module[%s]" value="on">',
|
1263 |
+
esc_attr($module_id)
|
1264 |
+
);
|
1265 |
+
}
|
1266 |
}
|
1267 |
|
1268 |
+
/**
|
1269 |
+
* Add extra settings to the "Custom fields" entry on the plugin's config. page.
|
1270 |
+
*
|
1271 |
+
* Callback for the 'blc-module-settings-custom_field' filter.
|
1272 |
+
*
|
1273 |
+
* @param string $html Current extra HTML
|
1274 |
+
* @param array $current_settings The current plugin configuration.
|
1275 |
+
* @return string New extra HTML.
|
1276 |
+
*/
|
1277 |
+
function make_custom_field_input($html, $current_settings){
|
1278 |
+
$html .= '<span class="description">' .
|
1279 |
+
__('Check URLs entered in these custom fields (one per line) :', 'broken-link-checker') .
|
1280 |
+
'</span>';
|
1281 |
+
$html .= '<br><textarea name="blc_custom_fields" id="blc_custom_fields" cols="45" rows="4" />';
|
1282 |
+
if( isset($current_settings['custom_fields']) )
|
1283 |
+
$html .= implode("\n", $current_settings['custom_fields']);
|
1284 |
+
$html .= '</textarea>';
|
1285 |
+
|
1286 |
+
return $html;
|
1287 |
+
}
|
1288 |
+
|
1289 |
+
/**
|
1290 |
+
* Enqueue CSS file for the plugin's Settings page.
|
1291 |
+
*
|
1292 |
+
* @return void
|
1293 |
+
*/
|
1294 |
function options_page_css(){
|
1295 |
+
wp_enqueue_style('blc-options-page', plugin_dir_url($this->loader) . 'css/options-page.css', array(), '0.9.5' );
|
1296 |
+
wp_enqueue_style('blc-screen-meta-links', plugin_dir_url($this->loader) . 'css/screen-meta-links.css' );
|
1297 |
}
|
1298 |
|
1299 |
|
1300 |
+
/**
|
1301 |
+
* Display the "Broken Links" page, listing links detected by the plugin and their status.
|
1302 |
+
*
|
1303 |
+
* @return void
|
1304 |
+
*/
|
1305 |
function links_page(){
|
1306 |
global $wpdb, $blclog;
|
1307 |
+
|
1308 |
$blc_link_query = & blcLinkQuery::getInstance();
|
1309 |
|
1310 |
//Sanity check : Make sure the plugin's tables are all set up.
|
1321 |
echo '<p>', implode('<br>', $blclog->get_messages()), '</p>';
|
1322 |
return;
|
1323 |
}
|
1324 |
+
|
1325 |
+
//Cull invalid and missing modules so that we don't get dummy links/instances showing up.
|
1326 |
+
$moduleManager = &blcModuleManager::getInstance();
|
1327 |
+
$moduleManager->validate_active_modules();
|
1328 |
+
|
1329 |
+
if ( defined('BLC_DEBUG') && constant('BLC_DEBUG') ){
|
1330 |
+
//Make module headers translatable. They need to be formatted corrrectly and
|
1331 |
+
//placed in a .php file to be visible to the script(s) that generate .pot files.
|
1332 |
+
$code = $moduleManager->_build_header_translation_code();
|
1333 |
+
file_put_contents( dirname($this->loader) . '/includes/extra-strings.php', $code );
|
1334 |
+
}
|
1335 |
|
1336 |
$action = !empty($_POST['action'])?$_POST['action']:'';
|
1337 |
if ( intval($action) == -1 ){
|
1352 |
$msg_class = 'updated';
|
1353 |
|
1354 |
//Run the selected bulk action, if any
|
1355 |
+
$force_delete = false;
|
1356 |
+
switch ( $action ){
|
1357 |
+
case 'create-custom-filter':
|
1358 |
+
list($message, $msg_class) = $this->do_create_custom_filter();
|
1359 |
+
break;
|
1360 |
+
|
1361 |
+
case 'delete-custom-filter':
|
1362 |
+
list($message, $msg_class) = $this->do_delete_custom_filter();
|
1363 |
+
break;
|
1364 |
+
|
1365 |
+
case 'bulk-delete-sources':
|
1366 |
+
$force_delete = true;
|
1367 |
+
case 'bulk-trash-sources':
|
1368 |
+
list($message, $msg_class) = $this->do_bulk_delete_sources($selected_links, $force_delete);
|
1369 |
+
break;
|
1370 |
+
|
1371 |
+
case 'bulk-unlink':
|
1372 |
+
list($message, $msg_class) = $this->do_bulk_unlink($selected_links);
|
1373 |
+
break;
|
1374 |
+
|
1375 |
+
case 'bulk-deredirect':
|
1376 |
+
list($message, $msg_class) = $this->do_bulk_deredirect($selected_links);
|
1377 |
+
break;
|
1378 |
+
|
1379 |
+
case 'bulk-recheck':
|
1380 |
+
list($message, $msg_class) = $this->do_bulk_recheck($selected_links);
|
1381 |
+
break;
|
1382 |
+
|
1383 |
+
case 'bulk-not-broken':
|
1384 |
+
list($message, $msg_class) = $this->do_bulk_discard($selected_links);
|
1385 |
+
break;
|
1386 |
+
}
|
1387 |
+
|
1388 |
|
1389 |
if ( !empty($message) ){
|
1390 |
echo '<div id="message" class="'.$msg_class.' fade"><p>'.$message.'</p></div>';
|
1391 |
}
|
1392 |
|
1393 |
+
$start_time = microtime_float();
|
1394 |
+
|
1395 |
//Load custom filters, if any
|
1396 |
$blc_link_query->load_custom_filters();
|
1397 |
|
1398 |
//Calculate the number of links matching each filter
|
1399 |
$blc_link_query->count_filter_results();
|
1400 |
|
1401 |
+
//Run the selected filter (defaults to displaying broken links)
|
1402 |
+
$selected_filter_id = isset($_GET['filter_id'])?$_GET['filter_id']:'broken';
|
1403 |
+
$current_filter = $blc_link_query->exec_filter(
|
1404 |
+
$selected_filter_id,
|
1405 |
+
isset($_GET['paged']) ? intval($_GET['paged']) : 1,
|
1406 |
+
$this->conf->options['table_links_per_page'],
|
1407 |
+
'broken'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1408 |
);
|
1409 |
+
|
1410 |
+
//exec_filter() returns an array with filter data, including the actual filter ID that was used.
|
1411 |
+
$filter_id = $current_filter['filter_id'];
|
1412 |
|
1413 |
//Error?
|
1414 |
+
if ( empty($current_filter['links']) && !empty($wpdb->last_error) ){
|
1415 |
printf( __('Database error : %s', 'broken-link-checker'), $wpdb->last_error);
|
1416 |
}
|
1417 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1418 |
//Add the "Feedback" widget to the screen meta bar
|
1419 |
$this->print_uservoice_widget();
|
1420 |
+
$this->display_plugin_news_link();
|
1421 |
?>
|
1422 |
|
1423 |
<script type='text/javascript'>
|
1424 |
var blc_current_filter = '<?php echo $filter_id; ?>';
|
1425 |
+
var blc_is_broken_filter = <?php echo $current_filter['is_broken_filter'] ? 'true' : 'false'; ?>;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1426 |
</script>
|
1427 |
|
1428 |
+
<div class="wrap"><?php screen_icon(); ?>
|
1429 |
+
<?php
|
1430 |
+
$blc_link_query->print_filter_heading($current_filter);
|
1431 |
+
$blc_link_query->print_filter_menu($filter_id);
|
1432 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1433 |
//Display the "Search" form and associated buttons.
|
1434 |
+
//The form requires the $filter_id and $current_filter variables to be set.
|
1435 |
include dirname($this->loader) . '/includes/admin/search-form.php';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1436 |
|
1437 |
+
//If the user has decided to switch the table to a different mode (compact/full),
|
1438 |
+
//save the new setting.
|
1439 |
+
if ( isset($_GET['compact']) ){
|
1440 |
+
$this->conf->options['table_compact'] = (bool)$_GET['compact'];
|
1441 |
+
$this->conf->save_options();
|
1442 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1443 |
|
1444 |
+
//Display the links, if any
|
1445 |
+
if( $current_filter['links'] && ( count($current_filter['links']) > 0 ) ) {
|
1446 |
+
|
1447 |
+
include dirname($this->loader) . '/includes/admin/table-printer.php';
|
1448 |
+
$table = new blcTablePrinter($this);
|
1449 |
+
$table->print_table(
|
1450 |
+
$current_filter,
|
1451 |
+
$this->conf->options['table_layout'],
|
1452 |
+
$this->conf->options['table_visible_columns'],
|
1453 |
+
$this->conf->options['table_compact']
|
1454 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1455 |
|
1456 |
+
};
|
1457 |
+
printf('<!-- Total elapsed : %.4f seconds -->', microtime_float() - $start_time);
|
1458 |
|
1459 |
+
//Load assorted JS event handlers and other shinies
|
1460 |
+
include dirname($this->loader) . '/includes/admin/links-page-js.php';
|
1461 |
+
|
1462 |
+
?></div><?php
|
1463 |
+
}
|
|
|
|
|
|
|
|
|
1464 |
|
1465 |
/**
|
1466 |
* Create a custom link filter using params passed in $_POST.
|
1666 |
}
|
1667 |
|
1668 |
/**
|
1669 |
+
* Delete or trash posts, bookmarks and other items that contain any of the specified links.
|
1670 |
+
*
|
1671 |
+
* Will prefer moving stuff to trash to permanent deletion. If it encounters an item that
|
1672 |
+
* can't be moved to the trash, it will skip that item by default.
|
1673 |
*
|
1674 |
* @param array $selected_links An array of link IDs
|
1675 |
+
* @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false.
|
1676 |
* @return array Confirmation message and its CSS class.
|
1677 |
*/
|
1678 |
+
function do_bulk_delete_sources($selected_links, $force_delete = false){
|
|
|
|
|
1679 |
$message = '';
|
1680 |
$msg_class = 'updated';
|
1681 |
|
1709 |
}
|
1710 |
|
1711 |
//Instantiate the containers
|
1712 |
+
$containers = blcContainerHelper::get_containers($containers);
|
1713 |
|
1714 |
+
//Delete/trash their associated entities
|
1715 |
$deleted = array();
|
1716 |
+
$skipped = array();
|
1717 |
foreach($containers as $container){
|
1718 |
+
if ( !$container->current_user_can_delete() ){
|
1719 |
+
continue;
|
1720 |
+
}
|
1721 |
|
1722 |
+
if ( $force_delete ){
|
1723 |
+
$rez = $container->delete_wrapped_object();
|
1724 |
+
} else {
|
1725 |
+
if ( $container->can_be_trashed() ){
|
1726 |
+
$rez = $container->trash_wrapped_object();
|
1727 |
+
} else {
|
1728 |
+
$skipped[] = $container;
|
1729 |
+
continue;
|
1730 |
+
}
|
1731 |
+
}
|
1732 |
|
1733 |
if ( is_wp_error($rez) ){
|
1734 |
//Record error messages for later display
|
1736 |
$msg_class = 'error';
|
1737 |
} else {
|
1738 |
//Keep track of how many of each type were deleted.
|
1739 |
+
$container_type = $container->container_type;
|
1740 |
if ( isset($deleted[$container_type]) ){
|
1741 |
$deleted[$container_type]++;
|
1742 |
} else {
|
1747 |
|
1748 |
//Generate delete confirmation messages
|
1749 |
foreach($deleted as $container_type => $number){
|
1750 |
+
if ( $force_delete ){
|
1751 |
+
$messages[] = blcContainerHelper::ui_bulk_delete_message($container_type, $number);
|
1752 |
+
} else {
|
1753 |
+
$messages[] = blcContainerHelper::ui_bulk_trash_message($container_type, $number);
|
1754 |
+
}
|
1755 |
+
|
1756 |
+
}
|
1757 |
+
|
1758 |
+
//If some items couldn't be trashed, let the user know
|
1759 |
+
if ( count($skipped) > 0 ){
|
1760 |
+
$message = sprintf(
|
1761 |
+
_n(
|
1762 |
+
"%d item was skipped because it can't be moved to the Trash. You need to delete it manually.",
|
1763 |
+
"%d items were skipped because they can't be moved to the Trash. You need to delete them manually.",
|
1764 |
+
count($skipped)
|
1765 |
+
),
|
1766 |
+
count($skipped)
|
1767 |
+
);
|
1768 |
+
$message .= '<br><ul>';
|
1769 |
+
foreach($skipped as $container){
|
1770 |
+
$message .= sprintf(
|
1771 |
+
'<li>%s</li>',
|
1772 |
+
$container->ui_get_source()
|
1773 |
+
);
|
1774 |
+
}
|
1775 |
+
$message .= '</ul>';
|
1776 |
+
|
1777 |
+
$messages[] = $message;
|
1778 |
}
|
1779 |
|
1780 |
if ( count($messages) > 0 ){
|
1781 |
+
$message = implode('<p>', $messages);
|
1782 |
} else {
|
1783 |
$message = __("Didn't find anything to delete!", 'broken-link-checker');
|
1784 |
$msg_class = 'error';
|
1884 |
}
|
1885 |
|
1886 |
|
1887 |
+
/**
|
1888 |
+
* Enqueue CSS files for the "Broken Links" page
|
1889 |
+
*
|
1890 |
+
* @return void
|
1891 |
+
*/
|
1892 |
function links_page_css(){
|
1893 |
+
wp_enqueue_style('blc-links-page', plugin_dir_url($this->loader) . 'css/links-page.css', array(), '0.9.5' );
|
1894 |
+
wp_enqueue_style('blc-screen-meta-links', plugin_dir_url($this->loader) . 'css/screen-meta-links.css' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1895 |
}
|
1896 |
|
1897 |
+
/**
|
1898 |
+
* Generate the HTML for the plugin's Screen Options panel.
|
1899 |
+
*
|
1900 |
+
* @return string
|
1901 |
+
*/
|
1902 |
+
function screen_options_html(){
|
1903 |
+
//Update the links-per-page setting when "Apply" is clicked
|
1904 |
+
if ( isset($_POST['per_page']) && is_numeric($_POST['per_page']) ) {
|
1905 |
+
check_admin_referer( 'screen-options-nonce', 'screenoptionnonce' );
|
1906 |
+
$per_page = intval($_POST['per_page']);
|
1907 |
+
if ( ($per_page >= 1) && ($per_page <= 500) ){
|
1908 |
+
$this->conf->options['table_links_per_page'] = $per_page;
|
1909 |
+
$this->conf->save_options();
|
1910 |
+
}
|
|
|
1911 |
}
|
1912 |
|
1913 |
+
//Let the user show/hide individual table columns
|
1914 |
+
$html = '<h5>' . __('Table columns', 'broken-link-checker') . '</h5>';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1915 |
|
1916 |
+
include dirname($this->loader) . '/includes/admin/table-printer.php';
|
1917 |
+
$table = new blcTablePrinter($this);
|
1918 |
+
$available_columns = $table->get_layout_columns($this->conf->options['table_layout']);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1919 |
|
1920 |
+
$html .= '<div id="blc-column-selector" class="metabox-prefs">';
|
1921 |
+
|
1922 |
+
foreach( $available_columns as $column_id => $data ){
|
1923 |
+
$html .= sprintf(
|
1924 |
+
'<label><input type="checkbox" name="visible_columns[%s]"%s>%s</label>',
|
1925 |
+
esc_attr($column_id),
|
1926 |
+
in_array($column_id, $this->conf->options['table_visible_columns']) ? ' checked="checked"' : '',
|
1927 |
+
$data['heading']
|
|
|
|
|
|
|
|
|
1928 |
);
|
1929 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1930 |
|
1931 |
+
$html .= '</div>';
|
1932 |
+
|
1933 |
+
$html .= '<h5>' . __('Show on screen') . '</h5>';
|
1934 |
+
$html .= '<div class="screen-options">';
|
1935 |
+
$html .= sprintf(
|
1936 |
+
'<input type="text" name="per_page" maxlength="3" value="%d" class="screen-per-page" id="blc_links_per_page" />
|
1937 |
+
<label for="blc_links_per_page">%s</label>
|
1938 |
+
<input type="button" class="button" value="%s" id="blc-per-page-apply-button" /><br />',
|
1939 |
+
$this->conf->options['table_links_per_page'],
|
1940 |
+
__('links', 'broken-link-checker'),
|
1941 |
+
__('Apply')
|
1942 |
+
);
|
1943 |
+
$html .= '</div>';
|
1944 |
|
1945 |
+
$html .= '<h5>' . __('Misc', 'broken-link-checker') . '</h5>';
|
1946 |
+
$html .= '<div class="screen-options">';
|
1947 |
+
/*
|
1948 |
+
Display a checkbox in "Screen Options" that lets the user highlight links that
|
1949 |
+
have been broken for at least X days.
|
1950 |
+
*/
|
1951 |
+
$html .= sprintf(
|
1952 |
+
'<label><input type="checkbox" id="highlight_permanent_failures" name="highlight_permanent_failures"%s> ',
|
1953 |
+
$this->conf->options['highlight_permanent_failures'] ? ' checked="checked"' : ''
|
1954 |
+
);
|
1955 |
+
$input_box = sprintf(
|
1956 |
+
'</label><input type="text" name="failure_duration_threshold" id="failure_duration_threshold" value="%d" size="2"><label for="highlight_permanent_failures">',
|
1957 |
+
$this->conf->options['failure_duration_threshold']
|
1958 |
+
);
|
1959 |
+
$html .= sprintf(
|
1960 |
+
__('Highlight links broken for at least %s days', 'broken-link-checker'),
|
1961 |
+
$input_box
|
1962 |
);
|
1963 |
+
$html .= '</label>';
|
1964 |
|
1965 |
+
//Display a checkbox for turning colourful link status messages on/off
|
1966 |
+
$html .= sprintf(
|
1967 |
+
'<br/><label><input type="checkbox" id="table_color_code_status" name="table_color_code_status"%s> %s</label>',
|
1968 |
+
$this->conf->options['table_color_code_status'] ? ' checked="checked"' : '',
|
1969 |
+
__('Color-code status codes', 'broken-link-checker')
|
1970 |
+
);
|
1971 |
+
|
1972 |
+
$html .= '</div>';
|
1973 |
+
|
1974 |
+
return $html;
|
1975 |
+
}
|
1976 |
+
|
1977 |
+
/**
|
1978 |
+
* AJAX callback for saving the "Screen Options" panel settings
|
1979 |
+
*
|
1980 |
+
* @param array $form
|
1981 |
+
* @return void
|
1982 |
+
*/
|
1983 |
+
function ajax_save_screen_options($form){
|
1984 |
+
if ( !current_user_can('edit_others_posts') ){
|
1985 |
+
die( json_encode( array(
|
1986 |
+
'error' => __("You're not allowed to do that!", 'broken-link-checker')
|
1987 |
+
)));
|
1988 |
+
}
|
1989 |
+
|
1990 |
+
$this->conf->options['highlight_permanent_failures'] = !empty($form['highlight_permanent_failures']);
|
1991 |
+
$this->conf->options['table_color_code_status'] = !empty($form['table_color_code_status']);
|
1992 |
+
|
1993 |
+
$failure_duration_threshold = intval($form['failure_duration_threshold']);
|
1994 |
+
if ( $failure_duration_threshold >=1 ){
|
1995 |
+
$this->conf->options['failure_duration_threshold'] = $failure_duration_threshold;
|
1996 |
+
}
|
1997 |
+
|
1998 |
+
if ( isset($form['visible_columns']) && is_array($form['visible_columns']) ){
|
1999 |
+
$this->conf->options['table_visible_columns'] = array_keys($form['visible_columns']);
|
2000 |
}
|
2001 |
|
2002 |
+
$this->conf->save_options();
|
2003 |
+
die('1');
|
2004 |
}
|
2005 |
|
2006 |
function start_timer(){
|
2060 |
//This reduces resource usage and may solve the mysterious slowdowns certain users have
|
2061 |
//encountered when activating the plugin.
|
2062 |
//(Disable when debugging or you won't get the FirePHP output)
|
2063 |
+
if ( !defined('BLC_DEBUG') || !constant('BLC_DEBUG')){
|
2064 |
@ob_end_clean(); //Discard the existing buffer, if any
|
2065 |
header("Connection: close");
|
2066 |
ob_start();
|
2071 |
flush(); // Unless both are called !
|
2072 |
}
|
2073 |
|
2074 |
+
//Load modules for this context
|
2075 |
+
$moduleManager = & blcModuleManager::getInstance();
|
2076 |
+
$moduleManager->load_modules('work');
|
2077 |
+
|
2078 |
+
|
2079 |
/*****************************************
|
2080 |
Parse posts and bookmarks
|
2081 |
******************************************/
|
2082 |
|
2083 |
+
$orphans_possible = false;
|
2084 |
+
$still_need_resynch = $this->conf->options['need_resynch'];
|
2085 |
+
|
2086 |
if ( $still_need_resynch ) {
|
2087 |
|
2088 |
//FB::log("Looking for containers that need parsing...");
|
2089 |
|
2090 |
+
while( $containers = blcContainerHelper::get_unsynched_containers(50) ){
|
2091 |
//FB::log($containers, 'Found containers');
|
2092 |
|
2093 |
foreach($containers as $container){
|
2228 |
|
2229 |
//Only check links that have at least one valid instance (i.e. an instance exists and
|
2230 |
//it corresponds to one of the currently loaded container/parser types).
|
2231 |
+
$manager = & blcModuleManager::getInstance();
|
2232 |
+
$loaded_containers = $manager->get_escaped_ids('container');
|
2233 |
+
$loaded_parsers = $manager->get_escaped_ids('parser');
|
|
|
|
|
|
|
|
|
|
|
|
|
2234 |
|
2235 |
//Note : This is a slow query, but AFAIK there is no way to speed it up.
|
2236 |
//I could put an index on last_check_attempt, but that value is almost
|
2387 |
function ajax_current_load(){
|
2388 |
$load = $this->get_server_load();
|
2389 |
if ( empty($load) ){
|
2390 |
+
die( _x('Unknown', 'current load', 'broken-link-checker') );
|
2391 |
}
|
2392 |
|
2393 |
$one_minute = reset($load);
|
2608 |
|
2609 |
if ( !$link->is_new ){
|
2610 |
//FB::info($link, 'Link loaded');
|
2611 |
+
if ( !class_exists('blcTablePrinter') ){
|
2612 |
+
require dirname($this->loader) . '/includes/admin/table-printer.php';
|
2613 |
+
}
|
2614 |
+
blcTablePrinter::details_row_contents($link);
|
2615 |
die();
|
2616 |
} else {
|
2617 |
printf( __('Failed to load link details (%s)', 'broken-link-checker'), $wpdb->last_error );
|
2619 |
}
|
2620 |
}
|
2621 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2622 |
/**
|
2623 |
* Create and lock a temporary file.
|
2624 |
*
|
2694 |
}
|
2695 |
|
2696 |
//Try the plugin's own directory.
|
2697 |
+
if ( @is_writable( dirname( blc_get_plugin_file() ) ) ){
|
2698 |
+
return dirname( blc_get_plugin_file() ) . '/wp_blc_lock';
|
2699 |
} else {
|
2700 |
|
2701 |
//Try the system-wide temp directory
|
2784 |
}
|
2785 |
|
2786 |
function lockfile_warning(){
|
2787 |
+
$my_dir = '/plugins/' . basename(dirname(blc_get_plugin_file())) . '/';
|
2788 |
$settings_page = admin_url( 'options-general.php?page=link-checker-settings#lockfile_directory' );
|
2789 |
|
2790 |
//Make the notice customized to the current settings
|
3120 |
if ( !wp_next_scheduled('blc_cron_database_maintenance') ){
|
3121 |
wp_schedule_event(time(), 'bimonthly', 'blc_cron_database_maintenance');
|
3122 |
}
|
3123 |
+
|
3124 |
+
//Check for news notices related to this plugin
|
3125 |
+
if ( !wp_next_scheduled('blc_cron_check_news') ){
|
3126 |
+
wp_schedule_event(time(), 'daily', 'blc_cron_check_news');
|
3127 |
+
}
|
3128 |
}
|
3129 |
|
3130 |
/**
|
3135 |
function load_language(){
|
3136 |
load_plugin_textdomain( 'broken-link-checker', false, basename(dirname($this->loader)) . '/languages' );
|
3137 |
}
|
3138 |
+
|
3139 |
+
/**
|
3140 |
+
* Check if there's a "news" link to display on the plugin's pages.
|
3141 |
+
*
|
3142 |
+
* @return void
|
3143 |
+
*/
|
3144 |
+
function check_news(){
|
3145 |
+
$url = 'http://w-shadow.com/plugin-news/';
|
3146 |
+
if ( defined('BLC_PRO_VERSION') && BLC_PRO_VERSION ){
|
3147 |
+
$url .= 'broken-link-checker-pro-news.txt';
|
3148 |
+
} else {
|
3149 |
+
$url .= 'broken-link-checker-news.txt';
|
3150 |
+
}
|
3151 |
+
|
3152 |
+
//Retrieve the appropriate "news" file
|
3153 |
+
$res = wp_remote_get($url);
|
3154 |
+
if ( is_wp_error($res) ){
|
3155 |
+
return;
|
3156 |
+
}
|
3157 |
+
|
3158 |
+
//Anything there?
|
3159 |
+
if ( isset($res['response']['code']) && ($res['response']['code'] == 200) && isset($res['body']) ) {
|
3160 |
+
//The file should contain two lines - a title and an URL
|
3161 |
+
$news = explode("\n", trim($res['body']));
|
3162 |
+
if ( count($news) == 2 ){
|
3163 |
+
//Save for later.
|
3164 |
+
$this->conf->options['plugin_news'] = $news;
|
3165 |
+
} else {
|
3166 |
+
$this->conf->options['plugin_news'] = null;
|
3167 |
+
}
|
3168 |
+
$this->conf->save_options();
|
3169 |
+
}
|
3170 |
+
}
|
3171 |
+
|
3172 |
+
/**
|
3173 |
+
* Display a link to the latest blog post/whatever about this plugin, if any.
|
3174 |
+
*
|
3175 |
+
* @return void
|
3176 |
+
*/
|
3177 |
+
function display_plugin_news_link(){
|
3178 |
+
if ( !isset($this->conf->options['plugin_news']) || empty($this->conf->options['plugin_news']) ){
|
3179 |
+
return;
|
3180 |
+
}
|
3181 |
+
$news = $this->conf->options['plugin_news'];
|
3182 |
+
?>
|
3183 |
+
<script type="text/javascript">
|
3184 |
+
(function($){
|
3185 |
+
var wrapper = $('<div id="blc-news-link-wrap" class="hide-if-no-js screen-meta-toggle"></div>').appendTo('#screen-meta-links');
|
3186 |
+
$('<a id="blc-plugin-news-link" class="show-settings"></a>')
|
3187 |
+
.attr('href', '<?php echo esc_js($news[1]); ?>')
|
3188 |
+
.html('<?php echo esc_js($news[0]) ?>')
|
3189 |
+
.appendTo(wrapper);
|
3190 |
+
})(jQuery);
|
3191 |
+
</script>
|
3192 |
+
<?php
|
3193 |
+
}
|
3194 |
|
3195 |
}//class ends here
|
3196 |
|
core/init.php
ADDED
@@ -0,0 +1,337 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
//To prevent conflicts, only one version of the plugin can be activated at any given time.
|
3 |
+
if ( defined('BLC_ACTIVE') ){
|
4 |
+
trigger_error(
|
5 |
+
'Another version of Broken Link Checker is already active. Please deactivate it before activating this one.',
|
6 |
+
E_USER_ERROR
|
7 |
+
);
|
8 |
+
} else {
|
9 |
+
|
10 |
+
define('BLC_ACTIVE', true);
|
11 |
+
|
12 |
+
/***********************************************
|
13 |
+
Debugging stuff
|
14 |
+
************************************************/
|
15 |
+
|
16 |
+
//define('BLC_DEBUG', true);
|
17 |
+
|
18 |
+
|
19 |
+
|
20 |
+
/***********************************************
|
21 |
+
Constants
|
22 |
+
************************************************/
|
23 |
+
|
24 |
+
/*
|
25 |
+
For performance, some internal APIs used for retrieving multiple links, instances or containers
|
26 |
+
can take an optional "$purpose" argument. Those APIs will try to use this argument to pre-load
|
27 |
+
any DB data required for the specified purpose ahead of time.
|
28 |
+
|
29 |
+
For example, if you're loading a bunch of link containers for the purposes of parsing them and
|
30 |
+
thus set $purpose to BLC_FOR_PARSING, the relevant container managers will (if applicable) precache
|
31 |
+
the parse-able fields in each returned container object. Still, setting $purpose to any particular
|
32 |
+
value does not *guarantee* any data will be preloaded - it's only a suggestion that it should.
|
33 |
+
|
34 |
+
The currently supported values for the $purpose argument are :
|
35 |
+
*/
|
36 |
+
define('BLC_FOR_EDITING', 'edit');
|
37 |
+
define('BLC_FOR_PARSING', 'parse');
|
38 |
+
define('BLC_FOR_DISPLAY', 'display');
|
39 |
+
|
40 |
+
/***********************************************
|
41 |
+
Configuration
|
42 |
+
************************************************/
|
43 |
+
|
44 |
+
//Load and initialize the plugin's configuration
|
45 |
+
global $blc_directory;
|
46 |
+
$blc_directory = dirname( blc_get_plugin_file() );
|
47 |
+
require $blc_directory . '/includes/config-manager.php';
|
48 |
+
|
49 |
+
global $blc_config_manager;
|
50 |
+
$blc_config_manager = new blcConfigurationManager(
|
51 |
+
//Save the plugin's configuration into this DB option
|
52 |
+
'wsblc_options',
|
53 |
+
//Initialize default settings
|
54 |
+
array(
|
55 |
+
'max_execution_time' => 5*60, //(in seconds) How long the worker instance may run, at most.
|
56 |
+
'check_threshold' => 72, //(in hours) Check each link every 72 hours.
|
57 |
+
|
58 |
+
'recheck_count' => 3, //How many times a broken link should be re-checked.
|
59 |
+
'recheck_threshold' => 30*60, //(in seconds) Re-check broken links after 30 minutes.
|
60 |
+
|
61 |
+
'run_in_dashboard' => true, //Run the link checker algo. continuously while the Dashboard is open.
|
62 |
+
'run_via_cron' => true, //Run it hourly via WordPress pseudo-cron.
|
63 |
+
|
64 |
+
'mark_broken_links' => true, //Whether to add the broken_link class to broken links in posts.
|
65 |
+
'broken_link_css' => ".broken_link, a.broken_link {\n\ttext-decoration: line-through;\n}",
|
66 |
+
'nofollow_broken_links' => false, //Whether to add rel="nofollow" to broken links in posts.
|
67 |
+
|
68 |
+
'mark_removed_links' => false, //Whether to add the removed_link class when un-linking a link.
|
69 |
+
'removed_link_css' => ".removed_link, a.removed_link {\n\ttext-decoration: line-through;\n}",
|
70 |
+
|
71 |
+
'exclusion_list' => array(), //Links that contain a substring listed in this array won't be checked.
|
72 |
+
|
73 |
+
'send_email_notifications' => false,//Whether to send email notifications about broken links
|
74 |
+
'notification_schedule' => 'daily', //How often (at most) notifications will be sent. Possible values : 'daily', 'weekly'
|
75 |
+
'last_notification_sent' => 0, //When the last email notification was send (Unix timestamp)
|
76 |
+
|
77 |
+
'server_load_limit' => 4, //Stop parsing stuff & checking links if the 1-minute load average
|
78 |
+
//goes over this value. Only works on Linux servers. 0 = no limit.
|
79 |
+
'enable_load_limit' => true, //Enable/disable load monitoring.
|
80 |
+
|
81 |
+
'custom_fields' => array(), //List of custom fields that can contain URLs and should be checked.
|
82 |
+
'enabled_post_statuses' => array('publish'), //Only check posts that match one of these statuses
|
83 |
+
|
84 |
+
'autoexpand_widget' => true, //Autoexpand the Dashboard widget if broken links are detected
|
85 |
+
'show_link_count_bubble' => true, //Display a notification bubble in the menu when broken links are found
|
86 |
+
|
87 |
+
'table_layout' => 'flexible', //The layout of the link table. Possible values : 'classic', 'flexible'
|
88 |
+
'table_compact' => true, //Compact table mode on/off
|
89 |
+
'table_visible_columns' => array('new-url', 'status', 'used-in', 'new-link-text',),
|
90 |
+
'table_links_per_page' => 30,
|
91 |
+
'table_color_code_status' => true, //Color-code link status text
|
92 |
+
|
93 |
+
'need_resynch' => false, //[Internal flag] True if there are unparsed items.
|
94 |
+
'current_db_version' => 0, //The currently set-up version of the plugin's tables
|
95 |
+
|
96 |
+
'custom_tmp_dir' => '', //The lockfile will be stored in this directory.
|
97 |
+
//If this option is not set, the plugin's own directory or the
|
98 |
+
//system-wide /tmp directory will be used instead.
|
99 |
+
|
100 |
+
'timeout' => 30, //(in seconds) Links that take longer than this to respond will be treated as broken.
|
101 |
+
|
102 |
+
'highlight_permanent_failures' => false,//Highlight links that have appear to be permanently broken (in Tools -> Broken Links).
|
103 |
+
'failure_duration_threshold' => 3, //(days) Assume a link is permanently broken if it still hasn't
|
104 |
+
//recovered after this many days.
|
105 |
+
|
106 |
+
'highlight_feedback_widget' => true, //Highlight the "Feedback" button in vivid orange
|
107 |
+
|
108 |
+
'installation_complete' => false,
|
109 |
+
'installation_failed' => false,
|
110 |
+
)
|
111 |
+
);
|
112 |
+
|
113 |
+
/***********************************************
|
114 |
+
Logging
|
115 |
+
************************************************/
|
116 |
+
|
117 |
+
include $blc_directory . '/includes/logger.php';
|
118 |
+
|
119 |
+
global $blclog;
|
120 |
+
$blclog = new blcDummyLogger;
|
121 |
+
|
122 |
+
//*
|
123 |
+
if ( defined('BLC_DEBUG') && constant('BLC_DEBUG') ){
|
124 |
+
//Load FirePHP for debug logging
|
125 |
+
if ( !class_exists('FB') && file_exists($blc_directory . '/FirePHPCore/fb.php4') ) {
|
126 |
+
require_once $blc_directory . '/FirePHPCore/fb.php4';
|
127 |
+
}
|
128 |
+
//FB::setEnabled(false);
|
129 |
+
}
|
130 |
+
//to comment out all calls : (^[^\/]*)(FB::) -> $1\/\/$2
|
131 |
+
//to uncomment : \/\/(\s*FB::) -> $1
|
132 |
+
//*/
|
133 |
+
|
134 |
+
/***********************************************
|
135 |
+
Global functions
|
136 |
+
************************************************/
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Get the configuration object used by Broken Link Checker.
|
140 |
+
*
|
141 |
+
* @return blcConfigurationManager
|
142 |
+
*/
|
143 |
+
function &blc_get_configuration(){
|
144 |
+
return $GLOBALS['blc_config_manager'];
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Notify the link checker that there are unsynched items
|
149 |
+
* that might contain links (e.g. a new or edited post).
|
150 |
+
*
|
151 |
+
* @return void
|
152 |
+
*/
|
153 |
+
function blc_got_unsynched_items(){
|
154 |
+
$conf = & blc_get_configuration();
|
155 |
+
|
156 |
+
if ( !$conf->options['need_resynch'] ){
|
157 |
+
$conf->options['need_resynch'] = true;
|
158 |
+
$conf->save_options();
|
159 |
+
}
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* (Re)create synchronization records for all containers and mark them all as unparsed.
|
164 |
+
*
|
165 |
+
* @param bool $forced If true, the plugin will recreate all synch. records from scratch.
|
166 |
+
* @return void
|
167 |
+
*/
|
168 |
+
function blc_resynch( $forced = false ){
|
169 |
+
global $wpdb, $blclog;
|
170 |
+
|
171 |
+
if ( $forced ){
|
172 |
+
$blclog->info('... Forced resynchronization initiated');
|
173 |
+
|
174 |
+
//Drop all synchronization records
|
175 |
+
$wpdb->query("TRUNCATE {$wpdb->prefix}blc_synch");
|
176 |
+
} else {
|
177 |
+
$blclog->info('... Resynchronization initiated');
|
178 |
+
}
|
179 |
+
|
180 |
+
//Remove invalid DB entries
|
181 |
+
blc_cleanup_database();
|
182 |
+
|
183 |
+
//(Re)create and update synch. records for all container types.
|
184 |
+
$blclog->info('... (Re)creating container records');
|
185 |
+
blcContainerHelper::resynch($forced);
|
186 |
+
|
187 |
+
$blclog->info('... Setting resync. flags');
|
188 |
+
blc_got_unsynched_items();
|
189 |
+
|
190 |
+
//All done.
|
191 |
+
$blclog->info('Database resynchronization complete.');
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Delete synch. records, instances and links that refer to missing or invalid items.
|
196 |
+
*
|
197 |
+
* @return void
|
198 |
+
*/
|
199 |
+
function blc_cleanup_database(){
|
200 |
+
global $blclog;
|
201 |
+
|
202 |
+
//Delete synch. records for container types that don't exist
|
203 |
+
$blclog->info('... Deleting invalid container records');
|
204 |
+
blcContainerHelper::cleanup_containers();
|
205 |
+
|
206 |
+
//Delete invalid instances
|
207 |
+
$blclog->info('... Deleting invalid link instances');
|
208 |
+
blc_cleanup_instances();
|
209 |
+
|
210 |
+
//Delete orphaned links
|
211 |
+
$blclog->info('... Deleting orphaned links');
|
212 |
+
blc_cleanup_links();
|
213 |
+
}
|
214 |
+
|
215 |
+
/***********************************************
|
216 |
+
Utility hooks
|
217 |
+
************************************************/
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Add a weekly Cron schedule for email notifications
|
221 |
+
* and a bimonthly schedule for database maintenance.
|
222 |
+
*
|
223 |
+
* @param array $schedules Existing Cron schedules.
|
224 |
+
* @return array
|
225 |
+
*/
|
226 |
+
function blc_cron_schedules($schedules){
|
227 |
+
if ( !isset($schedules['weekly']) ){
|
228 |
+
$schedules['weekly'] = array(
|
229 |
+
'interval' => 604800, //7 days
|
230 |
+
'display' => __('Once Weekly')
|
231 |
+
);
|
232 |
+
}
|
233 |
+
if ( !isset($schedules['bimonthly']) ){
|
234 |
+
$schedules['bimonthly'] = array(
|
235 |
+
'interval' => 15*24*2600, //15 days
|
236 |
+
'display' => __('Twice a Month')
|
237 |
+
);
|
238 |
+
}
|
239 |
+
|
240 |
+
return $schedules;
|
241 |
+
}
|
242 |
+
add_filter('cron_schedules', 'blc_cron_schedules');
|
243 |
+
|
244 |
+
/**
|
245 |
+
* Display installation errors (if any) on the Dashboard.
|
246 |
+
*
|
247 |
+
* @return void
|
248 |
+
*/
|
249 |
+
function blc_print_installation_errors(){
|
250 |
+
$conf = & blc_get_configuration();
|
251 |
+
if ( !$conf->options['installation_failed'] ){
|
252 |
+
return;
|
253 |
+
}
|
254 |
+
|
255 |
+
$logger = new blcOptionLogger('blc_installation_log');
|
256 |
+
$log = $logger->get_messages();
|
257 |
+
|
258 |
+
$message = array(
|
259 |
+
'<strong>' . __('Broken Link Checker installation failed', 'broken-link-checker') . '</strong>',
|
260 |
+
'',
|
261 |
+
'<em>Installation log follows :</em>',
|
262 |
+
);
|
263 |
+
foreach($log as $entry){
|
264 |
+
array_push($message, $entry);
|
265 |
+
}
|
266 |
+
$message = implode("<br>\n", $message);
|
267 |
+
|
268 |
+
echo "<div class='error'><p>$message</p></div>";
|
269 |
+
}
|
270 |
+
add_action('admin_notices', 'blc_print_installation_errors');
|
271 |
+
|
272 |
+
/**
|
273 |
+
* A stub function that calls the real activation hook.
|
274 |
+
*
|
275 |
+
* @return void
|
276 |
+
*/
|
277 |
+
function blc_activation_hook(){
|
278 |
+
global $ws_link_checker;
|
279 |
+
blc_init();
|
280 |
+
$ws_link_checker->activation();
|
281 |
+
}
|
282 |
+
|
283 |
+
//Since the main plugin files load during the 'init' action, any activation hooks
|
284 |
+
//set therein would never be executed ('init' runs before activation happens). Instead,
|
285 |
+
//we must register the hook(s) immediately after our main plugin file is loaded.
|
286 |
+
register_activation_hook(plugin_basename(blc_get_plugin_file()), 'blc_activation_hook');
|
287 |
+
|
288 |
+
|
289 |
+
/***********************************************
|
290 |
+
Main functionality
|
291 |
+
************************************************/
|
292 |
+
|
293 |
+
function blc_init(){
|
294 |
+
global $blc_directory, $blc_module_manager, $blc_config_manager, $ws_link_checker;
|
295 |
+
|
296 |
+
static $init_done = false;
|
297 |
+
if ( $init_done ){
|
298 |
+
return;
|
299 |
+
}
|
300 |
+
$init_done = true;
|
301 |
+
|
302 |
+
//Load the base classes and utilities
|
303 |
+
require $blc_directory . '/includes/links.php';
|
304 |
+
require $blc_directory . '/includes/link-query.php';
|
305 |
+
require $blc_directory . '/includes/instances.php';
|
306 |
+
require $blc_directory . '/includes/utility-class.php';
|
307 |
+
|
308 |
+
//Load the module subsystem
|
309 |
+
require $blc_directory . '/includes/modules.php';
|
310 |
+
|
311 |
+
//Load the modules that want to be executed in all contexts
|
312 |
+
$blc_module_manager->load_modules();
|
313 |
+
|
314 |
+
if ( is_admin() || defined('DOING_CRON') ){
|
315 |
+
|
316 |
+
//It's an admin-side or Cron request. Load the core.
|
317 |
+
require $blc_directory . '/core/core.php';
|
318 |
+
$ws_link_checker = new wsBrokenLinkChecker( blc_get_plugin_file() , $blc_config_manager );
|
319 |
+
|
320 |
+
} else {
|
321 |
+
|
322 |
+
//This is user-side request, so we don't need to load the core.
|
323 |
+
//We might need to inject the CSS for removed links, though.
|
324 |
+
if ( $blc_config_manager->options['mark_removed_links'] && !empty($blc_config_manager->options['removed_link_css']) ){
|
325 |
+
function blc_print_removed_link_css(){
|
326 |
+
global $blc_config_manager;
|
327 |
+
echo '<style type="text/css">',$blc_config_manager->options['removed_link_css'],'</style>';
|
328 |
+
}
|
329 |
+
add_action('wp_head', 'blc_print_removed_link_css');
|
330 |
+
}
|
331 |
+
}
|
332 |
+
}
|
333 |
+
|
334 |
+
add_action('init', 'blc_init', 2000);
|
335 |
+
|
336 |
+
}
|
337 |
+
?>
|
css/links-page.css
CHANGED
@@ -5,8 +5,8 @@ table#blc-links {
|
|
5 |
table-layout: fixed;
|
6 |
}
|
7 |
|
8 |
-
|
9 |
-
|
10 |
}
|
11 |
|
12 |
.blc-detail-container {
|
@@ -18,34 +18,84 @@ td.blc-link-details {
|
|
18 |
width: 50%;
|
19 |
}
|
20 |
|
21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
width: 33%;
|
23 |
}
|
24 |
|
25 |
-
.
|
26 |
width: 24%;
|
27 |
}
|
28 |
|
29 |
-
.
|
30 |
-
|
31 |
}
|
32 |
|
33 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
|
35 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
|
37 |
.blc-redirect .blc-link-url {
|
38 |
background-image: url("../images/bullet_blue.png");
|
39 |
-
background-position: left center;
|
40 |
-
background-repeat: no-repeat;
|
41 |
}
|
42 |
|
43 |
-
.blc-
|
44 |
-
|
45 |
-
.blc-broken-link .blc-link-url {
|
46 |
background-image: url("../images/bullet_error.png");
|
47 |
-
|
48 |
-
|
|
|
|
|
49 |
}
|
50 |
|
51 |
.blc-excluded-link {
|
@@ -61,26 +111,135 @@ td.blc-link-details {
|
|
61 |
}
|
62 |
|
63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
/* Misc table styles */
|
65 |
|
66 |
.blc-link-url {
|
67 |
padding-left: 16px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
}
|
69 |
|
70 |
.blc-link-editor {
|
71 |
font-size: 1em;
|
72 |
width: 95%;
|
73 |
margin-left: 12px;
|
|
|
74 |
}
|
75 |
|
76 |
-
.
|
77 |
-
margin-left:
|
|
|
|
|
|
|
78 |
}
|
79 |
|
80 |
-
.
|
81 |
-
|
|
|
|
|
82 |
}
|
83 |
|
|
|
|
|
|
|
84 |
|
85 |
.blc-small-image {
|
86 |
vertical-align: middle;
|
@@ -92,6 +251,10 @@ td.blc-link-details {
|
|
92 |
background : white !important;
|
93 |
border: 3px solid #EEEEEE;
|
94 |
padding: 12px;
|
|
|
|
|
|
|
|
|
95 |
}
|
96 |
|
97 |
.blc-search-container .ui-dialog-titlebar {
|
@@ -131,8 +294,11 @@ div.search-box{
|
|
131 |
margin-left: 0pt;
|
132 |
}
|
133 |
|
134 |
-
|
|
|
|
|
|
|
135 |
|
136 |
-
|
137 |
-
|
138 |
-
}
|
5 |
table-layout: fixed;
|
6 |
}
|
7 |
|
8 |
+
tr.blc-link-details {
|
9 |
+
display: none;
|
10 |
}
|
11 |
|
12 |
.blc-detail-container {
|
18 |
width: 50%;
|
19 |
}
|
20 |
|
21 |
+
/* Column headers */
|
22 |
+
|
23 |
+
th.column-new-url {
|
24 |
+
width: 33%;
|
25 |
+
}
|
26 |
+
|
27 |
+
th.column-status {
|
28 |
+
width: 16em;
|
29 |
+
}
|
30 |
+
|
31 |
+
th.column-new-link-text {
|
32 |
+
|
33 |
+
}
|
34 |
+
|
35 |
+
th.column-used-in {
|
36 |
+
|
37 |
+
}
|
38 |
+
|
39 |
+
th.column-source {
|
40 |
width: 33%;
|
41 |
}
|
42 |
|
43 |
+
th.column-link-text {
|
44 |
width: 24%;
|
45 |
}
|
46 |
|
47 |
+
th.column-url {
|
48 |
+
width: 35%;
|
49 |
}
|
50 |
|
51 |
+
th.column-last-checked {
|
52 |
+
width: 10em;
|
53 |
+
}
|
54 |
+
|
55 |
+
th.column-broken-for {
|
56 |
+
width: 10em;
|
57 |
+
}
|
58 |
+
|
59 |
+
th.column-instance-count {
|
60 |
+
width: 10em;
|
61 |
+
}
|
62 |
|
63 |
+
/* Cells */
|
64 |
+
|
65 |
+
td.column-new-url,
|
66 |
+
td.column-used-in
|
67 |
+
{
|
68 |
+
/*
|
69 |
+
overflow: hidden;
|
70 |
+
white-space: nowrap;
|
71 |
+
text-overflow: ellipsis;
|
72 |
+
-o-text-overflow: ellipsis;
|
73 |
+
*/
|
74 |
+
}
|
75 |
+
|
76 |
+
td.column-new-url .row-actions,
|
77 |
+
td.column-url .row-actions
|
78 |
+
{
|
79 |
+
margin-left: 16px;
|
80 |
+
}
|
81 |
+
|
82 |
+
td.column-new-url .mini-status {
|
83 |
+
margin-left: 16px;
|
84 |
+
color: black;
|
85 |
+
}
|
86 |
+
|
87 |
+
/* Styles for broken links, redirects and other link states or types */
|
88 |
|
89 |
.blc-redirect .blc-link-url {
|
90 |
background-image: url("../images/bullet_blue.png");
|
|
|
|
|
91 |
}
|
92 |
|
93 |
+
.link-status-error .blc-link-url {
|
|
|
|
|
94 |
background-image: url("../images/bullet_error.png");
|
95 |
+
}
|
96 |
+
|
97 |
+
.link-status-warning .blc-link-url {
|
98 |
+
background-image: url("../images/bullet_warning.png");
|
99 |
}
|
100 |
|
101 |
.blc-excluded-link {
|
111 |
}
|
112 |
|
113 |
|
114 |
+
/* The "Status" column */
|
115 |
+
td.column-status {
|
116 |
+
cursor: pointer;
|
117 |
+
}
|
118 |
+
|
119 |
+
.mini-status, .mini-status th, .mini-status td {
|
120 |
+
border: 0;
|
121 |
+
font-size: 1em;
|
122 |
+
padding: 0;
|
123 |
+
color: gray;
|
124 |
+
}
|
125 |
+
|
126 |
+
.mini-status div {
|
127 |
+
display: inline-block;
|
128 |
+
}
|
129 |
+
|
130 |
+
.mini-status .status-text {
|
131 |
+
color: black;
|
132 |
+
}
|
133 |
+
|
134 |
+
.link-status-unknown td.column-status .http-code {
|
135 |
+
display: none;
|
136 |
+
}
|
137 |
+
|
138 |
+
|
139 |
+
/* Status colors */
|
140 |
+
.color-code-link-status .mini-status .http-code,
|
141 |
+
.color-code-link-status .mini-status .status-text
|
142 |
+
{
|
143 |
+
font-weight: bold;
|
144 |
+
}
|
145 |
+
|
146 |
+
.color-code-link-status .link-status-unknown td.column-status .status-text,
|
147 |
+
.color-code-link-status .link-status-unknown td.column-status .http-code
|
148 |
+
{
|
149 |
+
color: gray;
|
150 |
+
font-weight: normal;
|
151 |
+
}
|
152 |
+
|
153 |
+
.color-code-link-status .link-status-ok td.column-status .status-text,
|
154 |
+
.color-code-link-status .link-status-ok td.column-status .http-code
|
155 |
+
{
|
156 |
+
color: green;
|
157 |
+
}
|
158 |
+
|
159 |
+
.color-code-link-status .link-status-info td.column-status .status-text,
|
160 |
+
.color-code-link-status .link-status-info td.column-status .http-code
|
161 |
+
{
|
162 |
+
color: blue;
|
163 |
+
}
|
164 |
+
|
165 |
+
.color-code-link-status .link-status-warning td.column-status .status-text,
|
166 |
+
.color-code-link-status .link-status-warning td.column-status .http-code
|
167 |
+
{
|
168 |
+
color: #FF8C00; /*#FFA500*/
|
169 |
+
}
|
170 |
+
|
171 |
+
.color-code-link-status .link-status-error td.column-status .status-text,
|
172 |
+
.color-code-link-status .link-status-error td.column-status .http-code
|
173 |
+
{
|
174 |
+
color: red;
|
175 |
+
}
|
176 |
+
|
177 |
+
|
178 |
+
/* "Compact" view */
|
179 |
+
|
180 |
+
.compact td.column-url,
|
181 |
+
.compact td.column-status,
|
182 |
+
.compact td.column-link-text,
|
183 |
+
.compact td.column-used-in,
|
184 |
+
.compact td.column-new-url,
|
185 |
+
.compact td.column-source,
|
186 |
+
.compact td.column-new-link-text
|
187 |
+
{
|
188 |
+
overflow: hidden;
|
189 |
+
text-overflow: ellipsis;
|
190 |
+
-o-text-overflow: ellipsis;
|
191 |
+
white-space: nowrap;
|
192 |
+
word-wrap: normal;
|
193 |
+
}
|
194 |
+
|
195 |
+
.compact .link-last-checked,
|
196 |
+
.compact .link-broken-for,
|
197 |
+
.compact .link-text
|
198 |
+
{
|
199 |
+
display: none;
|
200 |
+
}
|
201 |
+
|
202 |
/* Misc table styles */
|
203 |
|
204 |
.blc-link-url {
|
205 |
padding-left: 16px;
|
206 |
+
overflow: hidden;
|
207 |
+
|
208 |
+
background-image: none;
|
209 |
+
background-position: left center;
|
210 |
+
background-repeat: no-repeat;
|
211 |
+
}
|
212 |
+
|
213 |
+
td.column-new-url { /* The URL never wraps */
|
214 |
+
word-wrap: normal;
|
215 |
+
white-space: nowrap;
|
216 |
+
text-overflow: ellipsis;
|
217 |
+
-o-text-overflow: ellipsis;
|
218 |
}
|
219 |
|
220 |
.blc-link-editor {
|
221 |
font-size: 1em;
|
222 |
width: 95%;
|
223 |
margin-left: 12px;
|
224 |
+
margin-top: -1px;
|
225 |
}
|
226 |
|
227 |
+
.blc-url-editor-buttons {
|
228 |
+
margin-left: 12px;
|
229 |
+
margin-top: 2px;
|
230 |
+
display: none;
|
231 |
+
width: 95%;
|
232 |
}
|
233 |
|
234 |
+
img.waiting {
|
235 |
+
float:right;
|
236 |
+
padding:4px 8px 0;
|
237 |
+
vertical-align:top;
|
238 |
}
|
239 |
|
240 |
+
td.column-link-text, td.column-new-link-text {
|
241 |
+
cursor: pointer;
|
242 |
+
}
|
243 |
|
244 |
.blc-small-image {
|
245 |
vertical-align: middle;
|
251 |
background : white !important;
|
252 |
border: 3px solid #EEEEEE;
|
253 |
padding: 12px;
|
254 |
+
|
255 |
+
border-radius: 6px;
|
256 |
+
-moz-border-radius: 6px;
|
257 |
+
-webkit-border-radius: 6px;
|
258 |
}
|
259 |
|
260 |
.blc-search-container .ui-dialog-titlebar {
|
294 |
margin-left: 0pt;
|
295 |
}
|
296 |
|
297 |
+
#s_link_type optgroup {
|
298 |
+
font-style: normal;
|
299 |
+
font-size: 13px;
|
300 |
+
}
|
301 |
|
302 |
+
#s_link_type optgroup option {
|
303 |
+
margin-left: 1em;
|
304 |
+
}
|
css/options-page.css
CHANGED
@@ -35,4 +35,111 @@
|
|
35 |
border-style: solid;
|
36 |
|
37 |
border-collapse: collapse;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
}
|
35 |
border-style: solid;
|
36 |
|
37 |
border-collapse: collapse;
|
38 |
+
}
|
39 |
+
|
40 |
+
.blc-toggle-link {
|
41 |
+
/*padding-left: 20px; */
|
42 |
+
}
|
43 |
+
|
44 |
+
.module-container {
|
45 |
+
margin: 1em 0;
|
46 |
+
font-size: 12px;
|
47 |
+
line-height: 140%;
|
48 |
+
}
|
49 |
+
|
50 |
+
.module-extra-settings {
|
51 |
+
margin-top: 0.5em;
|
52 |
+
}
|
53 |
+
|
54 |
+
.form-table td p:first-child, .form-table td .module-container:first-child {
|
55 |
+
margin-top: 0.2em;
|
56 |
+
}
|
57 |
+
|
58 |
+
.module-requires-pro {
|
59 |
+
color: gray;
|
60 |
+
}
|
61 |
+
|
62 |
+
#blc-tabs {
|
63 |
+
margin-top: 0.5em;
|
64 |
+
}
|
65 |
+
|
66 |
+
/* Tab navigation */
|
67 |
+
ul.ui-tabs-nav {
|
68 |
+
margin-bottom: -1px;
|
69 |
+
padding-left: 1.5em;
|
70 |
+
}
|
71 |
+
|
72 |
+
ul.ui-tabs-nav li {
|
73 |
+
display: inline-block;
|
74 |
+
margin: 0 0.5em 0 0;
|
75 |
+
|
76 |
+
border: 1px solid #DFDFDF;
|
77 |
+
|
78 |
+
background: none repeat scroll 0 0 #F4F4F4;
|
79 |
+
|
80 |
+
border-top-right-radius: 6px;
|
81 |
+
border-top-left-radius: 6px;
|
82 |
+
|
83 |
+
-moz-border-radius-topright: 6px;
|
84 |
+
-moz-border-radius-topleft: 6px;
|
85 |
+
|
86 |
+
-webkit-border-top-right-radius: 6px;
|
87 |
+
-webkit-border-top-left-radius: 6px;
|
88 |
+
|
89 |
+
font-weight: bold;
|
90 |
+
text-shadow: 0 1px 0 #FFFFFF;
|
91 |
+
}
|
92 |
+
|
93 |
+
ul.ui-tabs-nav li.ui-tabs-selected {
|
94 |
+
background: white;
|
95 |
+
color: black;
|
96 |
+
border-bottom-color: white;
|
97 |
+
}
|
98 |
+
|
99 |
+
ul.ui-tabs-nav li a {
|
100 |
+
display: inline-block;
|
101 |
+
padding: 0.5em 1em 0.6em 1em;
|
102 |
+
text-decoration: none;
|
103 |
+
color: #C1C1C1;
|
104 |
+
}
|
105 |
+
|
106 |
+
ul.ui-tabs-nav li.ui-tabs-selected a {
|
107 |
+
color: black;
|
108 |
+
}
|
109 |
+
|
110 |
+
/* Tab panels */
|
111 |
+
|
112 |
+
.ui-tabs .blc-section {
|
113 |
+
border: 1px solid #DFDFDF;
|
114 |
+
border-top-width: 1px;
|
115 |
+
|
116 |
+
padding-bottom: 1em;
|
117 |
+
|
118 |
+
background: white;
|
119 |
+
|
120 |
+
border-radius: 6px;
|
121 |
+
-moz-border-radius: 6px;
|
122 |
+
-webkit-border-radius: 6px;
|
123 |
+
|
124 |
+
border-top-right-radius: 6px;
|
125 |
+
border-bottom-right-radius: 6px;
|
126 |
+
border-bottom-left-radius: 6px;
|
127 |
+
|
128 |
+
-moz-border-radius-topright: 6px;
|
129 |
+
-moz-border-radius-bottomright: 6px;
|
130 |
+
-moz-border-radius-bottomleft: 6px;
|
131 |
+
|
132 |
+
-webkit-border-top-right-radius: 6px;
|
133 |
+
-webkit-border-bottom-right-radius: 6px;
|
134 |
+
-webkit-border-bottom-left-radius: 6px;
|
135 |
+
}
|
136 |
+
|
137 |
+
/* "Upgrade to Pro" stuff */
|
138 |
+
|
139 |
+
.pro-notice {
|
140 |
+
|
141 |
+
}
|
142 |
+
|
143 |
+
.pro-notice a {
|
144 |
+
font-style: italic;
|
145 |
}
|
css/{uservoice.css → screen-meta-links.css}
RENAMED
@@ -1,4 +1,6 @@
|
|
1 |
-
#blc-feedback-widget-wrap
|
|
|
|
|
2 |
float: right;
|
3 |
height: 22px;
|
4 |
padding: 0;
|
@@ -18,9 +20,14 @@
|
|
18 |
-webkit-border-bottom-right-radius: 3px;
|
19 |
}
|
20 |
|
21 |
-
#blc-feedback-widget-wrap a.show-settings
|
|
|
|
|
22 |
background-image: none;
|
23 |
padding:0 6px 0 6px;
|
|
|
|
|
|
|
24 |
font-weight: bold;
|
25 |
}
|
26 |
|
1 |
+
#blc-feedback-widget-wrap,
|
2 |
+
#blc-news-link-wrap
|
3 |
+
{
|
4 |
float: right;
|
5 |
height: 22px;
|
6 |
padding: 0;
|
20 |
-webkit-border-bottom-right-radius: 3px;
|
21 |
}
|
22 |
|
23 |
+
#blc-feedback-widget-wrap a.show-settings,
|
24 |
+
#blc-news-link-wrap a.show-settings
|
25 |
+
{
|
26 |
background-image: none;
|
27 |
padding:0 6px 0 6px;
|
28 |
+
}
|
29 |
+
|
30 |
+
#blc-feedback-widget-wrap a.show-settings {
|
31 |
font-weight: bold;
|
32 |
}
|
33 |
|
images/bullet_cross.png
ADDED
Binary file
|
images/bullet_error.png
CHANGED
Binary file
|
images/bullet_warning.png
ADDED
Binary file
|
images/dailymotion-embed.png
ADDED
Binary file
|
images/vimeo-embed.png
ADDED
Binary file
|
images/youtube-embed.png
ADDED
Binary file
|
JSON.php → includes/JSON.php
RENAMED
File without changes
|
includes/admin/db-schema.php
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if( !function_exists('blc_get_db_schema') ){
|
4 |
+
|
5 |
+
function blc_get_db_schema(){
|
6 |
+
global $wpdb;
|
7 |
+
|
8 |
+
//Use the character set and collation that's configured for WP tables
|
9 |
+
$charset_collate = '';
|
10 |
+
if ( !empty($wpdb->charset) ){
|
11 |
+
//Some German installs use "utf-8" (invalid) instead of "utf8" (valid). None of
|
12 |
+
//the charset ids supported by MySQL contain dashes, so we can safely strip them.
|
13 |
+
//See http://dev.mysql.com/doc/refman/5.0/en/charset-charsets.html
|
14 |
+
$charset = str_replace('-', '', $wpdb->charset);
|
15 |
+
|
16 |
+
$charset_collate = "DEFAULT CHARACTER SET {$charset}";
|
17 |
+
}
|
18 |
+
if ( !empty($wpdb->collate) ){
|
19 |
+
$charset_collate = " COLLATE {$wpdb->collate}";
|
20 |
+
}
|
21 |
+
|
22 |
+
$blc_db_schema = <<<EOM
|
23 |
+
|
24 |
+
CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}blc_filters` (
|
25 |
+
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
26 |
+
`name` varchar(100) NOT NULL,
|
27 |
+
`params` text NOT NULL,
|
28 |
+
|
29 |
+
PRIMARY KEY (`id`)
|
30 |
+
) {$charset_collate};
|
31 |
+
|
32 |
+
CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}blc_instances` (
|
33 |
+
`instance_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
34 |
+
`link_id` int(10) unsigned NOT NULL,
|
35 |
+
`container_id` int(10) unsigned NOT NULL,
|
36 |
+
`container_type` varchar(40) NOT NULL DEFAULT 'post',
|
37 |
+
`link_text` varchar(250) NOT NULL DEFAULT '',
|
38 |
+
`parser_type` varchar(40) NOT NULL DEFAULT 'link',
|
39 |
+
`container_field` varchar(250) NOT NULL DEFAULT '',
|
40 |
+
`link_context` varchar(250) NOT NULL DEFAULT '',
|
41 |
+
`raw_url` text NOT NULL,
|
42 |
+
|
43 |
+
PRIMARY KEY (`instance_id`),
|
44 |
+
KEY `link_id` (`link_id`),
|
45 |
+
KEY `source_id` (`container_type`, `container_id`),
|
46 |
+
KEY `parser_type` (`parser_type`)
|
47 |
+
) {$charset_collate};
|
48 |
+
|
49 |
+
CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}blc_links` (
|
50 |
+
`link_id` int(20) unsigned NOT NULL AUTO_INCREMENT,
|
51 |
+
`url` text CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,
|
52 |
+
`first_failure` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
53 |
+
`last_check` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
54 |
+
`last_success` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
55 |
+
`last_check_attempt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
56 |
+
`check_count` int(4) unsigned NOT NULL DEFAULT '0',
|
57 |
+
`final_url` text CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,
|
58 |
+
`redirect_count` smallint(5) unsigned NOT NULL DEFAULT '0',
|
59 |
+
`log` text NOT NULL,
|
60 |
+
`http_code` smallint(6) NOT NULL DEFAULT '0',
|
61 |
+
`status_code` varchar(100) DEFAULT '',
|
62 |
+
`status_text` varchar(250) DEFAULT '',
|
63 |
+
`request_duration` float NOT NULL DEFAULT '0',
|
64 |
+
`timeout` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
65 |
+
`broken` tinyint(1) NOT NULL DEFAULT '0',
|
66 |
+
`may_recheck` tinyint(1) NOT NULL DEFAULT '1',
|
67 |
+
`being_checked` tinyint(1) NOT NULL DEFAULT '0',
|
68 |
+
`result_hash` varchar(200) NOT NULL DEFAULT '',
|
69 |
+
`false_positive` tinyint(1) NOT NULL DEFAULT '0',
|
70 |
+
|
71 |
+
PRIMARY KEY (`link_id`),
|
72 |
+
KEY `url` (`url`(150)),
|
73 |
+
KEY `final_url` (`final_url`(150)),
|
74 |
+
KEY `http_code` (`http_code`),
|
75 |
+
KEY `broken` (`broken`)
|
76 |
+
) {$charset_collate};
|
77 |
+
|
78 |
+
CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}blc_synch` (
|
79 |
+
`container_id` int(20) unsigned NOT NULL,
|
80 |
+
`container_type` varchar(40) NOT NULL,
|
81 |
+
`synched` tinyint(3) unsigned NOT NULL,
|
82 |
+
`last_synch` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
83 |
+
|
84 |
+
PRIMARY KEY (`container_type`,`container_id`),
|
85 |
+
KEY `synched` (`synched`)
|
86 |
+
) {$charset_collate};
|
87 |
+
|
88 |
+
EOM;
|
89 |
+
|
90 |
+
return $blc_db_schema;
|
91 |
+
}
|
92 |
+
|
93 |
+
}
|
94 |
+
|
95 |
+
?>
|
includes/admin/db-upgrade.php
ADDED
@@ -0,0 +1,577 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class blcDatabaseUpgrader {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Create and/or upgrade the plugin's database tables.
|
7 |
+
*
|
8 |
+
* @return bool
|
9 |
+
*/
|
10 |
+
function upgrade_database(){
|
11 |
+
global $wpdb, $blclog;
|
12 |
+
|
13 |
+
$conf = &blc_get_configuration();
|
14 |
+
$current = $conf->options['current_db_version'];
|
15 |
+
|
16 |
+
if ( ($current != 0) && ( $current < 4 ) ){
|
17 |
+
//The 4th DB version makes a lot of backwards-incompatible changes to the main
|
18 |
+
//BLC tables, so instead of upgrading we just throw them away and recreate.
|
19 |
+
if ( !blcDatabaseUpgrader::drop_tables() ){
|
20 |
+
return false;
|
21 |
+
};
|
22 |
+
$current = 0;
|
23 |
+
}
|
24 |
+
|
25 |
+
//Create/update the plugin's tables
|
26 |
+
if ( !blcDatabaseUpgrader::make_schema_current() ) {
|
27 |
+
return false;
|
28 |
+
}
|
29 |
+
|
30 |
+
if ( $current != 0 ){
|
31 |
+
|
32 |
+
if ( $current < 5 ){
|
33 |
+
blcDatabaseUpgrader::upgrade_095();
|
34 |
+
}
|
35 |
+
|
36 |
+
}
|
37 |
+
|
38 |
+
$conf->options['current_db_version'] = 5;
|
39 |
+
$conf->save_options();
|
40 |
+
$blclog->info('Database successfully upgraded.');
|
41 |
+
|
42 |
+
return true;
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Create or update the plugin's DB tables.
|
47 |
+
*
|
48 |
+
* @return bool
|
49 |
+
*/
|
50 |
+
function make_schema_current(){
|
51 |
+
global $blclog;
|
52 |
+
|
53 |
+
if ( !function_exists('blc_get_db_schema') ){
|
54 |
+
require 'db-schema.php';
|
55 |
+
}
|
56 |
+
list($dummy, $query_log) = blcTableDelta::delta(blc_get_db_schema());
|
57 |
+
|
58 |
+
$have_errors = false;
|
59 |
+
foreach($query_log as $item){
|
60 |
+
if ( $item['success'] ){
|
61 |
+
$blclog->info(' [OK] ' . $item['query']);
|
62 |
+
} else {
|
63 |
+
$blclog->error(' [ ] ' . $item['query']);
|
64 |
+
$blclog->error(' Database error : ' . $item['error_message']);
|
65 |
+
$have_errors = true;
|
66 |
+
}
|
67 |
+
}
|
68 |
+
|
69 |
+
$blclog->info('Database schema updated.');
|
70 |
+
return !$have_errors;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Drop the plugin's tables.
|
75 |
+
*
|
76 |
+
* @return bool
|
77 |
+
*/
|
78 |
+
function drop_tables(){
|
79 |
+
global $wpdb, $blclog;
|
80 |
+
|
81 |
+
$blclog->info('Deleting the plugin\'s database tables');
|
82 |
+
$tables = array(
|
83 |
+
$wpdb->prefix . 'blc_linkdata',
|
84 |
+
$wpdb->prefix . 'blc_postdata',
|
85 |
+
$wpdb->prefix . 'blc_instances',
|
86 |
+
$wpdb->prefix . 'blc_synch',
|
87 |
+
$wpdb->prefix . 'blc_links',
|
88 |
+
);
|
89 |
+
|
90 |
+
$q = "DROP TABLE IF EXISTS " . implode(', ', $tables);
|
91 |
+
$rez = $wpdb->query( $q );
|
92 |
+
|
93 |
+
if ( $rez === false ){
|
94 |
+
$error = sprintf(
|
95 |
+
__("Failed to delete old DB tables. Database error : %s", 'broken-link-checker'),
|
96 |
+
$wpdb->last_error
|
97 |
+
);
|
98 |
+
|
99 |
+
$blclog->error($error);
|
100 |
+
/*
|
101 |
+
//FIXME: In very rare cases, DROP TABLE IF EXISTS throws an error when the table(s) don't exist.
|
102 |
+
return false;
|
103 |
+
//*/
|
104 |
+
}
|
105 |
+
$blclog->info('Done.');
|
106 |
+
|
107 |
+
return true;
|
108 |
+
}
|
109 |
+
|
110 |
+
function upgrade_095($trigger_errors = false){
|
111 |
+
global $wpdb;
|
112 |
+
|
113 |
+
//Prior to 0.9.5 all supported post types were internally represented using
|
114 |
+
//a common 'post' container type. The current version creates a unique container
|
115 |
+
//type to each post type.
|
116 |
+
|
117 |
+
//Update synch records and instances to reflect this change
|
118 |
+
$q = "
|
119 |
+
UPDATE
|
120 |
+
{$wpdb->prefix}blc_synch AS synch
|
121 |
+
LEFT JOIN {$wpdb->posts} AS posts ON (posts.ID = synch.container_id)
|
122 |
+
SET
|
123 |
+
synch.container_type = posts.post_type
|
124 |
+
WHERE
|
125 |
+
synch.container_type == 'post' AND posts.post_type IS NOT NULL";
|
126 |
+
$wpdb->query($q);
|
127 |
+
|
128 |
+
$q = "
|
129 |
+
UPDATE
|
130 |
+
{$wpdb->prefix}blc_instances AS instances
|
131 |
+
LEFT JOIN {$wpdb->posts} AS posts ON (posts.ID = instances.container_id)
|
132 |
+
SET
|
133 |
+
instances.container_type = posts.post_type
|
134 |
+
WHERE
|
135 |
+
instances.container_type == 'post' AND posts.post_type IS NOT NULL";
|
136 |
+
$wpdb->query($q);
|
137 |
+
}
|
138 |
+
|
139 |
+
}
|
140 |
+
|
141 |
+
class blcTableDelta {
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Parse one or more CREATE TABLE queries and generate a list of SQL queries that need
|
145 |
+
* to be executed to make the current database schema match those queries. Will also
|
146 |
+
* execute those queries by default.
|
147 |
+
*
|
148 |
+
* This function returns an array with two items. The first is a list of human-readable
|
149 |
+
* messages explaining what database changes were/would be made. The second array item
|
150 |
+
* is an array of the generated SQL queries and (if $execute was True) their results.
|
151 |
+
*
|
152 |
+
* Each item of this second array is itself an associative array with these keys :
|
153 |
+
* 'query' - the generated query.
|
154 |
+
* 'success' - True if the query was executed successfully, False if it caused an error.
|
155 |
+
* 'error_message' - the MySQL error message (only meaningful when 'success' = false).
|
156 |
+
*
|
157 |
+
* The 'success' and 'error_message' keys will only be present if $execute was set to True.
|
158 |
+
*
|
159 |
+
* @param string $queries One or more CREATE TABLE queries separated by a semicolon.
|
160 |
+
* @param bool $execute Whether to apply the schema changes. Defaults to true.
|
161 |
+
* @param bool $drop_columns Whether to drop columns not present in the input. Defaults to true.
|
162 |
+
* @param bool $drop_indexes Whether to drop indexes not present in the input. Defaults to true.
|
163 |
+
* @return array
|
164 |
+
*/
|
165 |
+
function delta($queries, $execute = true, $drop_columns = true, $drop_indexes = true){
|
166 |
+
global $wpdb;
|
167 |
+
|
168 |
+
// Separate individual queries into an array
|
169 |
+
if ( !is_array($queries) ) {
|
170 |
+
$queries = explode( ';', $queries );
|
171 |
+
if ('' == $queries[count($queries) - 1]) array_pop($queries);
|
172 |
+
}
|
173 |
+
|
174 |
+
$cqueries = array(); // Creation Queries
|
175 |
+
$for_update = array();
|
176 |
+
|
177 |
+
// Create a tablename index for an array ($cqueries) of queries
|
178 |
+
foreach($queries as $qry) {
|
179 |
+
if (preg_match("|CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?([^\s(]+)|i", $qry, $matches)) {
|
180 |
+
$table = trim( strtolower($matches[1]), '`' );
|
181 |
+
$cqueries[$table] = $qry;
|
182 |
+
$for_update[$table] = 'Create table `'.$table.'`';
|
183 |
+
}
|
184 |
+
}
|
185 |
+
|
186 |
+
// Check to see which tables and fields exist
|
187 |
+
if ($tables = $wpdb->get_col('SHOW TABLES;')) {
|
188 |
+
// For every table in the database
|
189 |
+
foreach ($tables as $table) {
|
190 |
+
$table = strtolower($table);
|
191 |
+
|
192 |
+
// If a table query exists for the database table...
|
193 |
+
if ( array_key_exists($table, $cqueries) ) {
|
194 |
+
|
195 |
+
// Clear the field and index arrays
|
196 |
+
$cfields = $indices = array();
|
197 |
+
|
198 |
+
// Get all of the field names in the query from between the parens
|
199 |
+
preg_match("|\((.*)\)|ms", $cqueries[$table], $match2);
|
200 |
+
$qryline = trim($match2[1]);
|
201 |
+
|
202 |
+
// Separate field lines into an array
|
203 |
+
$flds = preg_split('@[\r\n]+@', $qryline);
|
204 |
+
|
205 |
+
//echo "<hr/><pre>\n".print_r(strtolower($table), true).":\n".print_r($flds, true)."</pre><hr/>";
|
206 |
+
|
207 |
+
// For every field line specified in the query
|
208 |
+
foreach ($flds as $fld) {
|
209 |
+
$definition = blcTableDelta::parse_create_definition($fld);
|
210 |
+
|
211 |
+
if ( $definition ){
|
212 |
+
if ( $definition['index'] ){
|
213 |
+
$indices[ $definition['index_definition'] ] = $definition; //Index
|
214 |
+
} else {
|
215 |
+
$cfields[ $definition['name'] ] = $definition; //Column
|
216 |
+
}
|
217 |
+
}
|
218 |
+
}
|
219 |
+
|
220 |
+
//echo "Detected fields : <br>"; print_r($cfields);
|
221 |
+
|
222 |
+
// Fetch the table column structure from the database
|
223 |
+
$tablefields = $wpdb->get_results("SHOW FULL COLUMNS FROM {$table};");
|
224 |
+
|
225 |
+
// For every field in the table
|
226 |
+
foreach ($tablefields as $tablefield) {
|
227 |
+
$field_name = strtolower($tablefield->Field); //Field names are case-insensitive in MySQL
|
228 |
+
|
229 |
+
// If the table field exists in the field array...
|
230 |
+
if (array_key_exists($field_name, $cfields)) {
|
231 |
+
$definition = $cfields[$field_name];
|
232 |
+
|
233 |
+
// Is actual field definition different from that in the query?
|
234 |
+
$different =
|
235 |
+
( $tablefield->Type != $definition['data_type'] ) ||
|
236 |
+
( $definition['collation'] && ($tablefield->Collation != $definition['collation']) ) ||
|
237 |
+
( $definition['null_allowed'] && ($tablefield->Null == 'NO') ) ||
|
238 |
+
( !$definition['null_allowed'] && ($tablefield->Null == 'YES') ) ||
|
239 |
+
( $tablefield->Default !== $definition['default'] );
|
240 |
+
|
241 |
+
// Add a query to change the column type
|
242 |
+
if ( $different ) {
|
243 |
+
$cqueries[] = "ALTER TABLE `{$table}` MODIFY COLUMN `{$field_name}` {$definition['column_definition']}";
|
244 |
+
$for_update[$table.'.'.$field_name] = "Changed type of {$table}.{$field_name} from {$tablefield->Type} to {$definition['column_definition']}";
|
245 |
+
}
|
246 |
+
|
247 |
+
// Remove the field from the array (so it's not added)
|
248 |
+
unset($cfields[$field_name]);
|
249 |
+
} else {
|
250 |
+
// This field exists in the table, but not in the creation queries? Drop it.
|
251 |
+
if ( $drop_columns ){
|
252 |
+
$cqueries[] = "ALTER TABLE `{$table}` DROP COLUMN `$field_name`";
|
253 |
+
$for_update[$table.'.'.$field_name] = 'Removed column '.$table.'.'.$field_name;
|
254 |
+
}
|
255 |
+
}
|
256 |
+
}
|
257 |
+
|
258 |
+
// For every remaining field specified for the table
|
259 |
+
foreach ($cfields as $field_name => $definition) {
|
260 |
+
// Push a query line into $cqueries that adds the field to that table
|
261 |
+
$cqueries[] = "ALTER TABLE `{$table}` ADD COLUMN `$field_name` {$definition['column_definition']}";
|
262 |
+
$for_update[$table.'.'.$field_name] = 'Added column '.$table.'.'.$field_name;
|
263 |
+
}
|
264 |
+
|
265 |
+
// Index stuff goes here
|
266 |
+
//echo 'Detected indexes : <br>'; print_r($indices);
|
267 |
+
|
268 |
+
// Fetch the table index structure from the database
|
269 |
+
$tableindices = $wpdb->get_results("SHOW INDEX FROM `{$table}`;");
|
270 |
+
|
271 |
+
if ($tableindices) {
|
272 |
+
// Clear the index array
|
273 |
+
unset($index_ary);
|
274 |
+
|
275 |
+
// For every index in the table
|
276 |
+
foreach ($tableindices as $tableindex) {
|
277 |
+
// Add the index to the index data array
|
278 |
+
$keyname = strtolower($tableindex->Key_name);
|
279 |
+
$index_ary[$keyname]['name'] = $keyname;
|
280 |
+
|
281 |
+
$index_ary[$keyname]['columns'][] = array(
|
282 |
+
'column_name' => strtolower($tableindex->Column_name),
|
283 |
+
'length' => $tableindex->Sub_part
|
284 |
+
);
|
285 |
+
|
286 |
+
if ( !isset($index_ary[$keyname]['index_modifier']) ){
|
287 |
+
if ( $keyname == 'primary' ){
|
288 |
+
$index_ary[$keyname]['index_modifier'] = 'primary';
|
289 |
+
} else if ( $tableindex->Non_unique == 0 ){
|
290 |
+
$index_ary[$keyname]['index_modifier'] = 'unique';
|
291 |
+
}
|
292 |
+
}
|
293 |
+
}
|
294 |
+
|
295 |
+
// For each actual index in the index array
|
296 |
+
foreach ($index_ary as $index_name => $index_data) {
|
297 |
+
// Build a create string to compare to the query
|
298 |
+
$index_string = blcTableDelta::generate_index_string($index_data);
|
299 |
+
if ( array_key_exists($index_string, $indices) ){
|
300 |
+
//echo "Found index $index_string<br>";
|
301 |
+
unset($indices[$index_string]);
|
302 |
+
} else {
|
303 |
+
//echo "Didn't find index $index_string<br>";
|
304 |
+
if ( $drop_indexes ){
|
305 |
+
if ( $index_name == 'primary' ){
|
306 |
+
$cqueries[] = "ALTER TABLE `{$table}` DROP PRIMARY KEY";
|
307 |
+
} else {
|
308 |
+
$cqueries[] = "ALTER TABLE `{$table}` DROP KEY `$index_name`";
|
309 |
+
}
|
310 |
+
$for_update[$table.'.'.$index_name] = 'Removed index '.$table.'.'.$index_name;
|
311 |
+
}
|
312 |
+
}
|
313 |
+
}
|
314 |
+
}
|
315 |
+
|
316 |
+
// For every remaining index specified for the table
|
317 |
+
foreach ( $indices as $index ) {
|
318 |
+
// Push a query line into $cqueries that adds the index to that table
|
319 |
+
$cqueries[] = "ALTER TABLE `{$table}` ADD {$index['index_definition']}";
|
320 |
+
$for_update[$table.'.'.$index['name']] = 'Added index '.$table.' '.$index['index_definition'];
|
321 |
+
}
|
322 |
+
|
323 |
+
// Remove the original table creation query from processing
|
324 |
+
unset($cqueries[strtolower($table)]);
|
325 |
+
unset($for_update[strtolower($table)]);
|
326 |
+
} else {
|
327 |
+
// This table exists in the database, but not in the creation queries?
|
328 |
+
}
|
329 |
+
}
|
330 |
+
}
|
331 |
+
|
332 |
+
//echo "Execute queries : <br>"; print_r($cqueries);
|
333 |
+
$query_log = array();
|
334 |
+
foreach ($cqueries as $query) {
|
335 |
+
$log_item = array('query' => $query,);
|
336 |
+
if ( $execute ) {
|
337 |
+
$log_item['success'] = ($wpdb->query($query) !== false);
|
338 |
+
$log_item['error_message'] = $wpdb->last_error;
|
339 |
+
}
|
340 |
+
$query_log[] = $log_item;
|
341 |
+
}
|
342 |
+
|
343 |
+
return array($for_update, $query_log);
|
344 |
+
}
|
345 |
+
|
346 |
+
/**
|
347 |
+
* Parse a a single column or index definition.
|
348 |
+
*
|
349 |
+
* This function can parse many (but not all) types of syntax used to define columns
|
350 |
+
* and indexes in a "CREATE TABLE" query.
|
351 |
+
*
|
352 |
+
* @param string $line
|
353 |
+
* @return array
|
354 |
+
*/
|
355 |
+
function parse_create_definition($line){
|
356 |
+
$line = preg_replace('@[,\r\n\s]+$@', '', $line); //Strip the ", " line separator
|
357 |
+
|
358 |
+
$pieces = preg_split('@\s+|(?=\()@', $line, -1, PREG_SPLIT_NO_EMPTY);
|
359 |
+
if ( empty($pieces) ){
|
360 |
+
return null;
|
361 |
+
}
|
362 |
+
|
363 |
+
$token = strtolower(array_shift($pieces));
|
364 |
+
|
365 |
+
$index_modifier = '';
|
366 |
+
$index = false;
|
367 |
+
|
368 |
+
//Determine if this line defines an index
|
369 |
+
if ( in_array($token, array('primary', 'unique', 'fulltext')) ){
|
370 |
+
$index_modifier = $token;
|
371 |
+
$index = true;
|
372 |
+
$token = strtolower(array_shift($pieces));
|
373 |
+
}
|
374 |
+
|
375 |
+
if ( in_array($token, array('index', 'key')) ){
|
376 |
+
$index = true;
|
377 |
+
$token = strtolower(array_shift($pieces));
|
378 |
+
}
|
379 |
+
|
380 |
+
//Determine column/index name
|
381 |
+
$name = '';
|
382 |
+
if ( $index ){
|
383 |
+
//Names are optional for indexes; the INDEX/etc keyword can be immediately
|
384 |
+
//followed by a column list (or index_type, but we're ignoring that possibility).
|
385 |
+
if ( strpos($token, '(') === false ){
|
386 |
+
$name = $token;
|
387 |
+
} else {
|
388 |
+
if ( $index_modifier == 'primary' ){
|
389 |
+
$name = 'primary';
|
390 |
+
}
|
391 |
+
array_unshift($pieces, $token);
|
392 |
+
}
|
393 |
+
} else {
|
394 |
+
$name = $token;
|
395 |
+
}
|
396 |
+
$name = strtolower(trim($name, '`'));
|
397 |
+
|
398 |
+
$definition = compact('name', 'index', 'index_modifier');
|
399 |
+
|
400 |
+
//Parse the rest of the line
|
401 |
+
$remainder = implode(' ', $pieces);
|
402 |
+
if ( $index ){
|
403 |
+
$definition['columns'] = blcTableDelta::parse_index_column_list($remainder);
|
404 |
+
|
405 |
+
//If the index doesn't have a name, use the name of the first column
|
406 |
+
//(this is what MySQL does, but only when there isn't already an index with that name).
|
407 |
+
if ( empty($definition['name']) ){
|
408 |
+
$definition['name'] = $definition['columns'][0]['column_name'];
|
409 |
+
}
|
410 |
+
//Rebuild the index def. in a normalized form
|
411 |
+
$definition['index_definition'] = blcTableDelta::generate_index_string($definition);
|
412 |
+
|
413 |
+
} else {
|
414 |
+
$column_def = blcTableDelta::parse_column_definition($remainder);
|
415 |
+
$definition = array_merge($definition, $column_def);
|
416 |
+
}
|
417 |
+
|
418 |
+
return $definition;
|
419 |
+
}
|
420 |
+
|
421 |
+
/**
|
422 |
+
* Parse the list of columns included in an index.
|
423 |
+
*
|
424 |
+
* This function returns a list of column descriptors. Each descriptor is
|
425 |
+
* an associative array with the keys 'column_name', 'length' and 'order'.
|
426 |
+
*
|
427 |
+
* @param string $line
|
428 |
+
* @return array Array of index columns
|
429 |
+
*/
|
430 |
+
function parse_index_column_list($line){
|
431 |
+
$line = preg_replace('@^\s*\(|\)\s*$@', '', $line); //Strip the braces that surround the column list
|
432 |
+
$pieces = preg_split('@\s*,\s*@', $line);
|
433 |
+
|
434 |
+
$columns = array();
|
435 |
+
foreach($pieces as $piece){
|
436 |
+
if ( preg_match('@`?(?P<column_name>[^\s`]+)`?(?:\s*\(\s*(?P<length>\d+)\s*\))?(?:\s+(?P<order>ASC|DESC))?@i', $piece, $matches) ){
|
437 |
+
|
438 |
+
$column = array(
|
439 |
+
'column_name' => strtolower($matches['column_name']),
|
440 |
+
'length' => null,
|
441 |
+
'order' => null //unused; included for completeness
|
442 |
+
);
|
443 |
+
|
444 |
+
if ( isset($matches['length']) && is_numeric($matches['length']) ){
|
445 |
+
$column['length'] = intval($matches['length']);
|
446 |
+
}
|
447 |
+
if ( isset($matches['order']) && !empty($matches['order']) ){
|
448 |
+
$column['order'] = strtolower($matches['order']);
|
449 |
+
}
|
450 |
+
|
451 |
+
$columns[] = $column;
|
452 |
+
};
|
453 |
+
}
|
454 |
+
|
455 |
+
return $columns;
|
456 |
+
}
|
457 |
+
|
458 |
+
/**
|
459 |
+
* Parse column datatype and flags.
|
460 |
+
*
|
461 |
+
*
|
462 |
+
* @param string $line
|
463 |
+
* @return array
|
464 |
+
*/
|
465 |
+
function parse_column_definition($line){
|
466 |
+
$line = trim($line);
|
467 |
+
|
468 |
+
//Extract datatype. This regexp is not entirely reliable - for example, it won't work
|
469 |
+
//with enum fields where one of values contains brackets "()".
|
470 |
+
$data_type = '';
|
471 |
+
$regexp = '
|
472 |
+
@
|
473 |
+
(?P<type_name>^\w+)
|
474 |
+
|
475 |
+
# followed by an optional length or a list of enum values
|
476 |
+
(?:\s*
|
477 |
+
\(
|
478 |
+
\s* (?P<length>[^()]+) \s*
|
479 |
+
\)
|
480 |
+
)?
|
481 |
+
|
482 |
+
# various type modifiers/keywords
|
483 |
+
(?P<keywords>
|
484 |
+
(?:\s+
|
485 |
+
(?: BINARY | UNSIGNED | ZEROFILL )
|
486 |
+
)*
|
487 |
+
)?
|
488 |
+
@xi';
|
489 |
+
|
490 |
+
if ( preg_match($regexp, $line, $matches) ){
|
491 |
+
$data_type = strtolower($matches['type_name']);
|
492 |
+
if ( !empty($matches['length']) ){
|
493 |
+
$data_type .= '(' . trim($matches['length']) . ')';
|
494 |
+
}
|
495 |
+
if ( !empty($matches['keywords']) ){
|
496 |
+
$data_type .= preg_replace('@\s+@', ' ', $matches['keywords']); //Collapse spaces
|
497 |
+
}
|
498 |
+
$line = substr($line, strlen($data_type));
|
499 |
+
}
|
500 |
+
|
501 |
+
//Extract flags
|
502 |
+
$null_allowed = !preg_match('@\sNOT\s+NULL\b@i', $line);
|
503 |
+
$auto_increment = preg_match('@\sAUTO_INCREMENT\b@i', $line);
|
504 |
+
|
505 |
+
//Got a default value?
|
506 |
+
$default = null;
|
507 |
+
if ( preg_match("@\sDEFAULT\s+('[^']*'|\"[^\"]*\"|\d+)@i", $line, $matches) ){
|
508 |
+
$default = trim($matches[1], '"\'');
|
509 |
+
}
|
510 |
+
|
511 |
+
//Custom character set and/or collation?
|
512 |
+
$charset = $collation = null;
|
513 |
+
if ( preg_match('@ (?:\s CHARACTER \s+ SET \s+ (?P<charset>[^\s()]+) )? (?:\s COLLATE \s+ (?P<collation>[^\s()]+) )? @xi', $line, $matches) ){
|
514 |
+
if ( isset($matches['charset']) ){
|
515 |
+
$charset = $matches['charset'];
|
516 |
+
}
|
517 |
+
if ( isset($matches['collation']) ){
|
518 |
+
$collation = $matches['collation'];
|
519 |
+
}
|
520 |
+
}
|
521 |
+
|
522 |
+
//Generate the normalized column definition
|
523 |
+
$column_definition = $data_type;
|
524 |
+
if ( !empty($charset) ){
|
525 |
+
$column_definition .= " CHARACTER SET {$charset}";
|
526 |
+
}
|
527 |
+
if ( !empty($collation) ){
|
528 |
+
$column_definition .= " COLLATE {$collation}";
|
529 |
+
}
|
530 |
+
if ( !$null_allowed ){
|
531 |
+
$column_definition .= " NOT NULL";
|
532 |
+
}
|
533 |
+
if ( !is_null($default) ){
|
534 |
+
$column_definition .= " DEFAULT '{$default}'";
|
535 |
+
}
|
536 |
+
if ( $auto_increment ){
|
537 |
+
$column_definition .= " AUTO_INCREMENT";
|
538 |
+
}
|
539 |
+
|
540 |
+
return compact('data_type', 'null_allowed', 'auto_increment', 'default', 'charset', 'collation', 'column_definition');
|
541 |
+
}
|
542 |
+
|
543 |
+
/**
|
544 |
+
* Generate an index's definition string from its parsed representation.
|
545 |
+
*
|
546 |
+
* @param array $definition The return value of blcTableDelta::parse_create_definition()
|
547 |
+
* @return string
|
548 |
+
*/
|
549 |
+
function generate_index_string($definition){
|
550 |
+
|
551 |
+
//Rebuild the index def. in a normalized form
|
552 |
+
$index_definition = '';
|
553 |
+
if ( !empty($definition['index_modifier']) ){
|
554 |
+
$index_definition .= strtoupper($definition['index_modifier']) . ' ';
|
555 |
+
}
|
556 |
+
$index_definition .= 'KEY';
|
557 |
+
if ( $definition['index_modifier'] != 'primary' ){
|
558 |
+
$index_definition .= ' `' . $definition['name'].'`';
|
559 |
+
}
|
560 |
+
|
561 |
+
$column_strings = array();
|
562 |
+
foreach($definition['columns'] as $column){
|
563 |
+
$c = '`' . $column['column_name'] . '`';
|
564 |
+
if ( $column['length'] ){
|
565 |
+
$c .= '('.$column['length'].')';
|
566 |
+
}
|
567 |
+
$column_strings[] = $c;
|
568 |
+
}
|
569 |
+
|
570 |
+
$index_definition .= ' (' . implode(', ', $column_strings) . ')';
|
571 |
+
return $index_definition;
|
572 |
+
}
|
573 |
+
|
574 |
+
}
|
575 |
+
|
576 |
+
|
577 |
+
?>
|
includes/admin/links-page-js.php
CHANGED
@@ -23,16 +23,18 @@ function alterLinkCounter(factor){
|
|
23 |
function replaceLinkId(old_id, new_id){
|
24 |
var master = jQuery('#blc-row-'+old_id);
|
25 |
|
26 |
-
//Save the new ID
|
27 |
master.attr('id', 'blc-row-'+new_id);
|
28 |
master.find('.blc-link-id').html(new_id);
|
|
|
|
|
|
|
29 |
}
|
30 |
|
31 |
function reloadDetailsRow(link_id){
|
32 |
-
var
|
33 |
|
34 |
//Load up the new link info (so sue me)
|
35 |
-
|
36 |
"<?php echo admin_url('admin-ajax.php'); ?>",
|
37 |
{
|
38 |
'action' : 'blc_link_details',
|
@@ -44,16 +46,19 @@ function reloadDetailsRow(link_id){
|
|
44 |
jQuery(function($){
|
45 |
|
46 |
//The details button - display/hide detailed info about a link
|
47 |
-
$(".blc-details-button, .
|
48 |
-
$(this).parents('.blc-row')
|
|
|
|
|
49 |
});
|
50 |
|
51 |
-
//The
|
52 |
$(".blc-discard-button").click(function () {
|
53 |
var me = $(this);
|
54 |
me.html('<?php echo esc_js(__('Wait...', 'broken-link-checker')); ?>');
|
55 |
|
56 |
-
var
|
|
|
57 |
|
58 |
$.post(
|
59 |
"<?php echo admin_url('admin-ajax.php'); ?>",
|
@@ -64,13 +69,15 @@ jQuery(function($){
|
|
64 |
},
|
65 |
function (data, textStatus){
|
66 |
if (data == 'OK'){
|
67 |
-
var
|
68 |
-
var details = master.next('.blc-link-details');
|
69 |
|
70 |
-
//Remove the "Not broken"
|
71 |
me.parent().remove();
|
72 |
|
73 |
-
|
|
|
|
|
|
|
74 |
|
75 |
//Flash the main row green to indicate success, then remove it if the current view
|
76 |
//is supposed to show only broken links.
|
@@ -89,7 +96,7 @@ jQuery(function($){
|
|
89 |
alterLinkCounter(-1);
|
90 |
}
|
91 |
} else {
|
92 |
-
|
93 |
alert(data);
|
94 |
}
|
95 |
}
|
@@ -98,126 +105,180 @@ jQuery(function($){
|
|
98 |
return false;
|
99 |
});
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
$(".blc-edit-button").click(function () {
|
103 |
var edit_button = $(this);
|
104 |
var master = $(edit_button).parents('.blc-row');
|
105 |
-
var editor = $(master).find('.blc-link-editor');
|
106 |
var url_el = $(master).find('.blc-link-url');
|
107 |
-
var cancel_button_container = $(master).find('.blc-cancel-button-container');
|
108 |
|
109 |
//Find the current/original URL
|
110 |
var orig_url = url_el.attr('href');
|
111 |
//Find the link ID
|
112 |
-
var link_id =
|
113 |
|
114 |
-
if (
|
115 |
-
|
116 |
-
url_el.hide();
|
117 |
-
//Reset the edit box to the actual URL value in case the user has already tried and failed to edit this link.
|
118 |
-
editor.val( url_el.attr('href') );
|
119 |
-
editor.show();
|
120 |
-
cancel_button_container.show();
|
121 |
-
editor.focus();
|
122 |
-
editor.select();
|
123 |
-
edit_button.html('<?php echo esc_js(__('Save URL' , 'broken-link-checker')); ?>');
|
124 |
} else {
|
125 |
-
|
126 |
-
editor.hide();
|
127 |
-
cancel_button_container.hide();
|
128 |
-
url_el.show();
|
129 |
-
|
130 |
-
new_url = editor.val();
|
131 |
-
|
132 |
-
if (new_url != orig_url){
|
133 |
-
//Save the changed link
|
134 |
-
url_el.html('<?php echo esc_js(__('Saving changes...' , 'broken-link-checker')); ?>');
|
135 |
-
|
136 |
-
$.getJSON(
|
137 |
-
"<?php echo admin_url('admin-ajax.php'); ?>",
|
138 |
-
{
|
139 |
-
'action' : 'blc_edit',
|
140 |
-
'link_id' : link_id,
|
141 |
-
'new_url' : new_url,
|
142 |
-
'_ajax_nonce' : '<?php echo esc_js(wp_create_nonce('blc_edit')); ?>'
|
143 |
-
},
|
144 |
-
function (data, textStatus){
|
145 |
-
var display_url = '';
|
146 |
-
|
147 |
-
if ( data && (typeof(data['error']) != 'undefined') ){
|
148 |
-
//An internal error occured before the link could be edited.
|
149 |
-
//data.error is an error message.
|
150 |
-
alert(data.error);
|
151 |
-
display_url = orig_url;
|
152 |
-
} else {
|
153 |
-
//data contains info about the performed edit
|
154 |
-
if ( data.errors.length == 0 ){
|
155 |
-
//Everything went well.
|
156 |
-
|
157 |
-
//Replace the displayed link URL with the new one.
|
158 |
-
display_url = new_url;
|
159 |
-
url_el.attr('href', new_url);
|
160 |
-
|
161 |
-
//Save the new ID
|
162 |
-
replaceLinkId(link_id, data.new_link_id);
|
163 |
-
//Load up the new link info
|
164 |
-
reloadDetailsRow(data.new_link_id);
|
165 |
-
//Remove classes indicating link state - they're probably wrong by now
|
166 |
-
master.removeClass('blc-broken-link').removeClass('blc-redirect');
|
167 |
-
|
168 |
-
//Flash the row green to indicate success
|
169 |
-
var oldColor = master.css('background-color');
|
170 |
-
master.animate({ backgroundColor: "#E0FFB3" }, 200).animate({ backgroundColor: oldColor }, 300);
|
171 |
-
|
172 |
-
} else {
|
173 |
-
display_url = orig_url;
|
174 |
-
|
175 |
-
//Build and display an error message.
|
176 |
-
var msg = '';
|
177 |
-
|
178 |
-
if ( data.cnt_okay > 0 ){
|
179 |
-
var msgpiece = sprintf(
|
180 |
-
'<?php echo esc_js(__('%d instances of the link were successfully modified.', 'broken-link-checker')); ?>',
|
181 |
-
data.cnt_okay
|
182 |
-
);
|
183 |
-
msg = msg + msgpiece + '\n';
|
184 |
-
if ( data.cnt_error > 0 ){
|
185 |
-
msgpiece = sprintf(
|
186 |
-
'<?php echo esc_js(__("However, %d instances couldn't be edited and still point to the old URL.", 'broken-link-checker')); ?>',
|
187 |
-
data.cnt_error
|
188 |
-
);
|
189 |
-
msg = msg + msgpiece + "\n";
|
190 |
-
}
|
191 |
-
} else {
|
192 |
-
msg = msg + '<?php echo esc_js(__('The link could not be modified.', 'broken-link-checker')); ?>\n';
|
193 |
-
}
|
194 |
-
|
195 |
-
msg = msg + '\n<?php echo esc_js(__("The following error(s) occured :", 'broken-link-checker')); ?>\n* ';
|
196 |
-
msg = msg + data.errors.join('\n* ');
|
197 |
-
|
198 |
-
alert(msg);
|
199 |
-
}
|
200 |
-
};
|
201 |
-
|
202 |
-
//Shorten the displayed URL if it's > 50 characters
|
203 |
-
if ( display_url.length > 50 ){
|
204 |
-
display_url = display_url.substr(0, 47) + '...';
|
205 |
-
}
|
206 |
-
url_el.html(display_url);
|
207 |
-
}
|
208 |
-
);
|
209 |
-
|
210 |
-
} else {
|
211 |
-
//It's the same URL, so do nothing.
|
212 |
-
}
|
213 |
-
edit_button.html('<?php echo esc_js(__('Edit URL', 'broken-link-checker')); ?>');
|
214 |
}
|
215 |
});
|
216 |
|
217 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
218 |
$('input.blc-link-editor').keypress(function (e) {
|
219 |
if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
|
220 |
-
$(this).parents('.blc-row').find('.blc-
|
221 |
return false;
|
222 |
} else if ((e.which && e.which == 27) || (e.keyCode && e.keyCode == 27)) {
|
223 |
$(this).parents('.blc-row').find('.blc-cancel-button').click();
|
@@ -227,27 +288,20 @@ jQuery(function($){
|
|
227 |
}
|
228 |
});
|
229 |
|
|
|
230 |
$(".blc-cancel-button").click(function () {
|
231 |
var master = $(this).parents('.blc-row');
|
232 |
-
|
233 |
-
|
234 |
-
//Hide the cancel button
|
235 |
-
$(this).parent().hide();
|
236 |
-
//Show the un-editable URL again
|
237 |
-
url_el.show();
|
238 |
-
//reset and hide the editor
|
239 |
-
master.find('.blc-link-editor').hide().val(url_el.attr('href'));
|
240 |
-
//Set the edit button to say "Edit URL"
|
241 |
-
master.find('.blc-edit-button').html('<?php echo esc_js(__('Edit URL' , 'broken-link-checker')); ?>');
|
242 |
});
|
243 |
|
244 |
-
//The
|
245 |
$(".blc-unlink-button").click(function () {
|
246 |
var me = this;
|
247 |
var master = $(me).parents('.blc-row');
|
248 |
$(me).html('<?php echo esc_js(__('Wait...' , 'broken-link-checker')); ?>');
|
249 |
|
250 |
-
|
|
|
251 |
|
252 |
$.post(
|
253 |
"<?php echo admin_url('admin-ajax.php'); ?>",
|
@@ -266,7 +320,7 @@ jQuery(function($){
|
|
266 |
} else {
|
267 |
if ( data.errors.length == 0 ){
|
268 |
//The link was successfully removed. Hide its details.
|
269 |
-
|
270 |
//Flash the main row green to indicate success, then hide it.
|
271 |
var oldColor = master.css('background-color');
|
272 |
master.animate({ backgroundColor: "#E0FFB3" }, 200).animate({ backgroundColor: oldColor }, 300, function(){
|
@@ -388,28 +442,27 @@ jQuery(function($){
|
|
388 |
if ( !confirm(message) ){
|
389 |
return false;
|
390 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
391 |
}
|
392 |
});
|
393 |
|
394 |
//------------------------------------------------------------
|
395 |
// Manipulate highlight settings for permanently broken links
|
396 |
//------------------------------------------------------------
|
397 |
-
var highlight_permanent_failures_checkbox = $('#highlight_permanent_failures
|
398 |
var failure_duration_threshold_input = $('#failure_duration_threshold');
|
399 |
|
400 |
-
//Update the checkbox depending on current settings.
|
401 |
-
<?php
|
402 |
-
$conf = & blc_get_configuration();
|
403 |
-
if ( $conf->options['highlight_permanent_failures'] ){
|
404 |
-
echo 'highlight_permanent_failures_checkbox.attr("checked", "checked");';
|
405 |
-
} else {
|
406 |
-
echo 'highlight_permanent_failures_checkbox.removeAttr("checked");';
|
407 |
-
}
|
408 |
-
?>;
|
409 |
-
|
410 |
//Apply/remove highlights when the checkbox is (un)checked
|
411 |
highlight_permanent_failures_checkbox.change(function(){
|
412 |
-
save_highlight_settings();
|
413 |
|
414 |
if ( this.checked ){
|
415 |
$('#blc-links tr.blc-permanently-broken').addClass('blc-permanently-broken-hl');
|
@@ -421,7 +474,7 @@ jQuery(function($){
|
|
421 |
//Apply/remove highlights when the duration threshold is changed.
|
422 |
failure_duration_threshold_input.change(function(){
|
423 |
var new_threshold = parseInt($(this).val());
|
424 |
-
save_highlight_settings();
|
425 |
if (isNaN(new_threshold) || (new_threshold < 1)) {
|
426 |
return;
|
427 |
}
|
@@ -441,37 +494,45 @@ jQuery(function($){
|
|
441 |
});
|
442 |
});
|
443 |
|
444 |
-
//
|
445 |
-
$('#
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
var highlight_permanent_failures = highlight_permanent_failures_checkbox.is(':checked');
|
454 |
-
var failure_duration_threshold = parseInt(failure_duration_threshold_input.val());
|
455 |
-
|
456 |
-
if ( isNaN(failure_duration_threshold) || ( failure_duration_threshold < 1 ) ){
|
457 |
-
failure_duration_threshold = 1;
|
458 |
}
|
459 |
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
'action' : 'blc_save_highlight_settings',
|
466 |
-
'failure_duration_threshold' : failure_duration_threshold,
|
467 |
-
'highlight_permanent_failures' : highlight_permanent_failures?1:0,
|
468 |
-
'_ajax_nonce' : '<?php echo esc_js(wp_create_nonce('blc_save_highlight_settings')); ?>'
|
469 |
-
}
|
470 |
);
|
471 |
-
}
|
472 |
|
|
|
|
|
|
|
|
|
|
|
473 |
|
|
|
|
|
|
|
|
|
|
|
474 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
475 |
});
|
476 |
|
477 |
</script>
|
23 |
function replaceLinkId(old_id, new_id){
|
24 |
var master = jQuery('#blc-row-'+old_id);
|
25 |
|
|
|
26 |
master.attr('id', 'blc-row-'+new_id);
|
27 |
master.find('.blc-link-id').html(new_id);
|
28 |
+
|
29 |
+
var details_row = jQuery('#link-details-'+old_id);
|
30 |
+
details_row.attr('id', 'link-details-'+new_id);
|
31 |
}
|
32 |
|
33 |
function reloadDetailsRow(link_id){
|
34 |
+
var details_row = jQuery('#link-details-'+link_id);
|
35 |
|
36 |
//Load up the new link info (so sue me)
|
37 |
+
details_row.find('td').html('<center><?php echo esc_js(__('Loading...' , 'broken-link-checker')); ?></center>').load(
|
38 |
"<?php echo admin_url('admin-ajax.php'); ?>",
|
39 |
{
|
40 |
'action' : 'blc_link_details',
|
46 |
jQuery(function($){
|
47 |
|
48 |
//The details button - display/hide detailed info about a link
|
49 |
+
$(".blc-details-button, td.column-link-text, td.column-status, td.column-new-link-text").click(function () {
|
50 |
+
var master = $(this).parents('.blc-row');
|
51 |
+
var link_id = master.attr('id').split('-')[2];
|
52 |
+
$('#link-details-'+link_id).toggle();
|
53 |
});
|
54 |
|
55 |
+
//The "Not broken" button - manually mark the link as valid. The link will be checked again later.
|
56 |
$(".blc-discard-button").click(function () {
|
57 |
var me = $(this);
|
58 |
me.html('<?php echo esc_js(__('Wait...', 'broken-link-checker')); ?>');
|
59 |
|
60 |
+
var master = me.parents('.blc-row');
|
61 |
+
var link_id = master.attr('id').split('-')[2];
|
62 |
|
63 |
$.post(
|
64 |
"<?php echo admin_url('admin-ajax.php'); ?>",
|
69 |
},
|
70 |
function (data, textStatus){
|
71 |
if (data == 'OK'){
|
72 |
+
var details = $('#link-details-'+link_id);
|
|
|
73 |
|
74 |
+
//Remove the "Not broken" action
|
75 |
me.parent().remove();
|
76 |
|
77 |
+
//Set the displayed link status to OK
|
78 |
+
var classNames = master.attr('class');
|
79 |
+
classNames = classNames.replace(/(^|\s)link-status-[^\s]+(\s|$)/, ' ') + ' link-status-ok';
|
80 |
+
master.attr('class', classNames);
|
81 |
|
82 |
//Flash the main row green to indicate success, then remove it if the current view
|
83 |
//is supposed to show only broken links.
|
96 |
alterLinkCounter(-1);
|
97 |
}
|
98 |
} else {
|
99 |
+
me.html('<?php echo esc_js(__('Not broken' , 'broken-link-checker')); ?>');
|
100 |
alert(data);
|
101 |
}
|
102 |
}
|
105 |
return false;
|
106 |
});
|
107 |
|
108 |
+
/**
|
109 |
+
* Display the inline URL editor for a particular link (that's present in the current view).
|
110 |
+
*
|
111 |
+
* @param link_id Either a link ID (int), or a jQuery object representing the link row.
|
112 |
+
*/
|
113 |
+
function showUrlEditor(link_id){
|
114 |
+
if ( isNaN(link_id) ){
|
115 |
+
var master = link_id;
|
116 |
+
} else {
|
117 |
+
var master = $('#blc-row-' + link_id);
|
118 |
+
}
|
119 |
+
|
120 |
+
var url_el = master.find('a.blc-link-url').hide();
|
121 |
+
|
122 |
+
master.find('div.blc-url-editor-buttons').show();
|
123 |
+
master.find('input.blc-link-editor')
|
124 |
+
.val( url_el.attr('href') ).show().focus().select()
|
125 |
+
.parents('td').find('div.row-actions').hide();
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Hide the URL editor of a particular link.
|
130 |
+
*
|
131 |
+
* @param link_id Either a link ID (int), or a jQuery object representing the link row.
|
132 |
+
*/
|
133 |
+
function hideUrlEditor(link_id){
|
134 |
+
if ( isNaN(link_id) ){
|
135 |
+
var master = link_id;
|
136 |
+
} else {
|
137 |
+
var master = $('#blc-row-' + link_id);
|
138 |
+
}
|
139 |
+
|
140 |
+
master.find('div.blc-url-editor-buttons').hide();
|
141 |
+
master.find('input.blc-link-editor').hide();
|
142 |
+
master.find('a.blc-link-url').show();
|
143 |
+
master.find('div.row-actions').show();
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Call our PHP backend and tell it to edit all occurences of particular link so that they
|
148 |
+
* point to a different URL. Updates UI with the new link info and displays any error messages
|
149 |
+
* that might be generated.
|
150 |
+
*
|
151 |
+
* @param link_id Either a link ID (int), or a jQuery object representing the link row.
|
152 |
+
* @param new_url The new URL for the link.
|
153 |
+
*/
|
154 |
+
function updateLinkUrl(link_id, new_url){
|
155 |
+
if ( isNaN(link_id) ){
|
156 |
+
var master = link_id;
|
157 |
+
link_id = master.attr('id').split("-")[2]; //id="blc-row-$linkid"
|
158 |
+
} else {
|
159 |
+
var master = $('#blc-row-' + link_id);
|
160 |
+
}
|
161 |
+
var url_el = master.find('a.blc-link-url');
|
162 |
+
var orig_url = url_el.attr('href');
|
163 |
+
var progress_indicator = master.find('.waiting');
|
164 |
+
|
165 |
+
progress_indicator.show();
|
166 |
+
|
167 |
+
$.getJSON(
|
168 |
+
"<?php echo admin_url('admin-ajax.php'); ?>",
|
169 |
+
{
|
170 |
+
'action' : 'blc_edit',
|
171 |
+
'link_id' : link_id,
|
172 |
+
'new_url' : new_url,
|
173 |
+
'_ajax_nonce' : '<?php echo esc_js(wp_create_nonce('blc_edit')); ?>'
|
174 |
+
},
|
175 |
+
function (data, textStatus){
|
176 |
+
var display_url = '';
|
177 |
+
|
178 |
+
if ( data && (typeof(data['error']) != 'undefined') ){
|
179 |
+
//An internal error occured before the link could be edited.
|
180 |
+
//data.error is an error message.
|
181 |
+
alert(data.error);
|
182 |
+
display_url = orig_url;
|
183 |
+
} else {
|
184 |
+
//data contains info about the performed edit
|
185 |
+
if ( data.errors.length == 0 ){
|
186 |
+
//Everything went well.
|
187 |
+
|
188 |
+
//Replace the displayed link URL with the new one.
|
189 |
+
display_url = new_url;
|
190 |
+
url_el.attr('href', new_url);
|
191 |
+
|
192 |
+
//Save the new ID
|
193 |
+
replaceLinkId(link_id, data.new_link_id);
|
194 |
+
//Load up the new link info
|
195 |
+
reloadDetailsRow(data.new_link_id);
|
196 |
+
//Remove classes indicating link state - they're probably wrong by now
|
197 |
+
var classNames = master.attr('class').replace(/(^|\s)link-status-[^\s]+(\s|$)/, ' ')+' link-status-unknown';
|
198 |
+
master.attr('class', classNames);
|
199 |
+
master.removeClass('blc-redirect');
|
200 |
+
|
201 |
+
//Flash the row green to indicate success
|
202 |
+
var oldColor = master.css('background-color');
|
203 |
+
master.animate({ backgroundColor: "#E0FFB3" }, 200).animate({ backgroundColor: oldColor }, 300);
|
204 |
+
|
205 |
+
} else {
|
206 |
+
display_url = orig_url;
|
207 |
+
|
208 |
+
//Build and display an error message.
|
209 |
+
var msg = '';
|
210 |
+
|
211 |
+
if ( data.cnt_okay > 0 ){
|
212 |
+
var msgpiece = sprintf(
|
213 |
+
'<?php echo esc_js(__('%d instances of the link were successfully modified.', 'broken-link-checker')); ?>',
|
214 |
+
data.cnt_okay
|
215 |
+
);
|
216 |
+
msg = msg + msgpiece + '\n';
|
217 |
+
if ( data.cnt_error > 0 ){
|
218 |
+
msgpiece = sprintf(
|
219 |
+
'<?php echo esc_js(__("However, %d instances couldn't be edited and still point to the old URL.", 'broken-link-checker')); ?>',
|
220 |
+
data.cnt_error
|
221 |
+
);
|
222 |
+
msg = msg + msgpiece + "\n";
|
223 |
+
}
|
224 |
+
} else {
|
225 |
+
msg = msg + '<?php echo esc_js(__('The link could not be modified.', 'broken-link-checker')); ?>\n';
|
226 |
+
}
|
227 |
+
|
228 |
+
msg = msg + '\n<?php echo esc_js(__("The following error(s) occured :", 'broken-link-checker')); ?>\n* ';
|
229 |
+
msg = msg + data.errors.join('\n* ');
|
230 |
+
|
231 |
+
alert(msg);
|
232 |
+
}
|
233 |
+
};
|
234 |
+
|
235 |
+
url_el.text(display_url);
|
236 |
+
|
237 |
+
progress_indicator.hide();
|
238 |
+
hideUrlEditor(master);
|
239 |
+
}
|
240 |
+
);
|
241 |
+
}
|
242 |
+
|
243 |
+
//The "Edit URL" button - displays the inline editor
|
244 |
$(".blc-edit-button").click(function () {
|
245 |
var edit_button = $(this);
|
246 |
var master = $(edit_button).parents('.blc-row');
|
247 |
+
var editor = $(master).find('input.blc-link-editor');
|
248 |
var url_el = $(master).find('.blc-link-url');
|
|
|
249 |
|
250 |
//Find the current/original URL
|
251 |
var orig_url = url_el.attr('href');
|
252 |
//Find the link ID
|
253 |
+
var link_id = master.attr('id').split('-')[2];
|
254 |
|
255 |
+
if ( !editor.is(':visible') ){
|
256 |
+
showUrlEditor(link_id);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
257 |
} else {
|
258 |
+
hideUrlEditor(link_id);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
259 |
}
|
260 |
});
|
261 |
|
262 |
+
//The "Update URL" button in the inline editor
|
263 |
+
$('.blc-update-url-button').click(function(){
|
264 |
+
var master = $(this).parents('tr.blc-row');
|
265 |
+
var url_el = master.find('.blc-link-url');
|
266 |
+
var editor = master.find('input.blc-link-editor');
|
267 |
+
|
268 |
+
var old_url = url_el.attr('href');
|
269 |
+
var new_url = editor.val();
|
270 |
+
|
271 |
+
if ( (new_url == old_url) || ($.trim(new_url) == '') ){
|
272 |
+
hideUrlEditor(master);
|
273 |
+
} else {
|
274 |
+
updateLinkUrl(master, new_url);
|
275 |
+
}
|
276 |
+
});
|
277 |
+
|
278 |
+
//Let the user use Enter and Esc as shortcuts for "Update URL" and "Cancel"
|
279 |
$('input.blc-link-editor').keypress(function (e) {
|
280 |
if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
|
281 |
+
$(this).parents('.blc-row').find('.blc-update-url-button').click();
|
282 |
return false;
|
283 |
} else if ((e.which && e.which == 27) || (e.keyCode && e.keyCode == 27)) {
|
284 |
$(this).parents('.blc-row').find('.blc-cancel-button').click();
|
288 |
}
|
289 |
});
|
290 |
|
291 |
+
//The "Cancel" in the inline editor
|
292 |
$(".blc-cancel-button").click(function () {
|
293 |
var master = $(this).parents('.blc-row');
|
294 |
+
hideUrlEditor(master);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
295 |
});
|
296 |
|
297 |
+
//The "Unlink" button - remove the link/image from all posts, custom fields, etc.
|
298 |
$(".blc-unlink-button").click(function () {
|
299 |
var me = this;
|
300 |
var master = $(me).parents('.blc-row');
|
301 |
$(me).html('<?php echo esc_js(__('Wait...' , 'broken-link-checker')); ?>');
|
302 |
|
303 |
+
//Find the link ID
|
304 |
+
var link_id = master.attr('id').split('-')[2];
|
305 |
|
306 |
$.post(
|
307 |
"<?php echo admin_url('admin-ajax.php'); ?>",
|
320 |
} else {
|
321 |
if ( data.errors.length == 0 ){
|
322 |
//The link was successfully removed. Hide its details.
|
323 |
+
$('#link-details-'+link_id).hide();
|
324 |
//Flash the main row green to indicate success, then hide it.
|
325 |
var oldColor = master.css('background-color');
|
326 |
master.animate({ backgroundColor: "#E0FFB3" }, 200).animate({ backgroundColor: oldColor }, 300, function(){
|
442 |
if ( !confirm(message) ){
|
443 |
return false;
|
444 |
}
|
445 |
+
} else if ( action == 'bulk-unlink' ){
|
446 |
+
var message = '<?php
|
447 |
+
echo esc_js(
|
448 |
+
__("Are you sure you want to remove the selected links? This action can't be undone.\n'Cancel' to stop, 'OK' to remove", 'broken-link-checker')
|
449 |
+
);
|
450 |
+
?>';
|
451 |
+
if ( !confirm(message) ){
|
452 |
+
return false;
|
453 |
+
}
|
454 |
}
|
455 |
});
|
456 |
|
457 |
//------------------------------------------------------------
|
458 |
// Manipulate highlight settings for permanently broken links
|
459 |
//------------------------------------------------------------
|
460 |
+
var highlight_permanent_failures_checkbox = $('#highlight_permanent_failures');
|
461 |
var failure_duration_threshold_input = $('#failure_duration_threshold');
|
462 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
463 |
//Apply/remove highlights when the checkbox is (un)checked
|
464 |
highlight_permanent_failures_checkbox.change(function(){
|
465 |
+
//save_highlight_settings();
|
466 |
|
467 |
if ( this.checked ){
|
468 |
$('#blc-links tr.blc-permanently-broken').addClass('blc-permanently-broken-hl');
|
474 |
//Apply/remove highlights when the duration threshold is changed.
|
475 |
failure_duration_threshold_input.change(function(){
|
476 |
var new_threshold = parseInt($(this).val());
|
477 |
+
//save_highlight_settings();
|
478 |
if (isNaN(new_threshold) || (new_threshold < 1)) {
|
479 |
return;
|
480 |
}
|
494 |
});
|
495 |
});
|
496 |
|
497 |
+
//Show/hide table columns dynamically
|
498 |
+
$('#blc-column-selector input[type="checkbox"]').change(function(){
|
499 |
+
var checkbox = $(this);
|
500 |
+
var column_id = checkbox.attr('name').split(/\[|\]/)[1];
|
501 |
+
if (checkbox.is(':checked')){
|
502 |
+
$('td.column-'+column_id+', th.column-'+column_id, '#blc-links').removeClass('hidden');
|
503 |
+
} else {
|
504 |
+
$('td.column-'+column_id+', th.column-'+column_id, '#blc-links').addClass('hidden');
|
|
|
|
|
|
|
|
|
|
|
|
|
505 |
}
|
506 |
|
507 |
+
//Recalculate colspan's for detail rows to take into account the changed number of
|
508 |
+
//visible columns. Otherwise you can get some ugly layout glitches.
|
509 |
+
$('#blc-links tr.blc-link-details td').attr(
|
510 |
+
'colspan',
|
511 |
+
$('#blc-column-selector input[type="checkbox"]:checked').length+1
|
|
|
|
|
|
|
|
|
|
|
512 |
);
|
513 |
+
});
|
514 |
|
515 |
+
//Unlike other fields in "Screen Options", the links-per-page setting
|
516 |
+
//is handled using straight form submission (POST), not AJAX.
|
517 |
+
$('#blc-per-page-apply-button').click(function(){
|
518 |
+
$('#adv-settings').submit();
|
519 |
+
});
|
520 |
|
521 |
+
$('#blc_links_per_page').keypress(function(e){
|
522 |
+
if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
|
523 |
+
$('#adv-settings').submit();
|
524 |
+
}
|
525 |
+
});
|
526 |
|
527 |
+
//Toggle status code colors when the corresponding checkbox is toggled
|
528 |
+
$('#table_color_code_status').click(function(){
|
529 |
+
if ( $(this).is(':checked') ){
|
530 |
+
$('#blc-links').addClass('color-code-link-status');
|
531 |
+
} else {
|
532 |
+
$('#blc-links').removeClass('color-code-link-status');
|
533 |
+
}
|
534 |
+
});
|
535 |
+
|
536 |
});
|
537 |
|
538 |
</script>
|
includes/admin/options-page-js.php
ADDED
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script type="text/javascript">
|
2 |
+
|
3 |
+
jQuery(function($){
|
4 |
+
$('#blc-tabs').tabs();
|
5 |
+
|
6 |
+
//Refresh the "Status" box every 10 seconds
|
7 |
+
function blcUpdateStatus(){
|
8 |
+
$.getJSON(
|
9 |
+
"<?php echo admin_url('admin-ajax.php'); ?>",
|
10 |
+
{
|
11 |
+
'action' : 'blc_full_status',
|
12 |
+
'random' : Math.random()
|
13 |
+
},
|
14 |
+
function (data, textStatus){
|
15 |
+
if ( data && ( typeof(data['text']) != 'undefined' ) ){
|
16 |
+
$('#wsblc_full_status').html(data.text);
|
17 |
+
} else {
|
18 |
+
$('#wsblc_full_status').html('<?php _e('[ Network error ]', 'broken-link-checker'); ?>');
|
19 |
+
}
|
20 |
+
|
21 |
+
setTimeout(blcUpdateStatus, 10000);
|
22 |
+
}
|
23 |
+
);
|
24 |
+
}
|
25 |
+
blcUpdateStatus();
|
26 |
+
|
27 |
+
//Refresh the avg. load display every 10 seconds
|
28 |
+
function blcUpdateLoad(){
|
29 |
+
$.get(
|
30 |
+
"<?php echo admin_url('admin-ajax.php'); ?>",
|
31 |
+
{
|
32 |
+
'action' : 'blc_current_load'
|
33 |
+
},
|
34 |
+
function (data, textStatus){
|
35 |
+
$('#wsblc_current_load').html(data);
|
36 |
+
|
37 |
+
setTimeout(blcUpdateLoad, 10000); //...update every 10 seconds
|
38 |
+
}
|
39 |
+
);
|
40 |
+
}
|
41 |
+
//Only do it if load limiting is available on this server, though.
|
42 |
+
if ( $('#wsblc_current_load').length > 0 ){
|
43 |
+
blcUpdateLoad();
|
44 |
+
}
|
45 |
+
|
46 |
+
|
47 |
+
var toggleButton = $('#blc-debug-info-toggle');
|
48 |
+
|
49 |
+
toggleButton.click(function(){
|
50 |
+
|
51 |
+
var box = $('#blc-debug-info');
|
52 |
+
box.toggle();
|
53 |
+
if( box.is(':visible') ){
|
54 |
+
toggleButton.text('<?php _e('Hide debug info', 'broken-link-checker'); ?>');
|
55 |
+
} else {
|
56 |
+
toggleButton.text('<?php _e('Show debug info', 'broken-link-checker'); ?>');
|
57 |
+
}
|
58 |
+
|
59 |
+
});
|
60 |
+
|
61 |
+
$('#toggle-broken-link-css-editor').click(function(){
|
62 |
+
var box = $('#broken-link-css-wrap').toggleClass('hidden');
|
63 |
+
|
64 |
+
$.cookie(
|
65 |
+
box.attr('id'),
|
66 |
+
box.hasClass('hidden')?'0':'1',
|
67 |
+
{
|
68 |
+
expires : 365
|
69 |
+
}
|
70 |
+
);
|
71 |
+
|
72 |
+
return false;
|
73 |
+
});
|
74 |
+
|
75 |
+
$('#toggle-removed-link-css-editor').click(function(){
|
76 |
+
var box = $('#removed-link-css-wrap').toggleClass('hidden');
|
77 |
+
|
78 |
+
$.cookie(
|
79 |
+
box.attr('id'),
|
80 |
+
box.hasClass('hidden')?'0':'1',
|
81 |
+
{
|
82 |
+
expires : 365
|
83 |
+
}
|
84 |
+
);
|
85 |
+
|
86 |
+
return false;
|
87 |
+
});
|
88 |
+
|
89 |
+
//Show/hide per-module settings
|
90 |
+
$('.toggle-module-settings').click(function(){
|
91 |
+
var settingsBox = $(this).parent().find('.module-extra-settings');
|
92 |
+
if ( settingsBox.length > 0 ){
|
93 |
+
settingsBox.toggleClass('hidden');
|
94 |
+
$.cookie(
|
95 |
+
settingsBox.attr('id'),
|
96 |
+
settingsBox.hasClass('hidden')?'0':'1',
|
97 |
+
{
|
98 |
+
expires : 365
|
99 |
+
}
|
100 |
+
);
|
101 |
+
}
|
102 |
+
return false;
|
103 |
+
});
|
104 |
+
|
105 |
+
//When the user ticks the "Custom fields" box, display the field list input
|
106 |
+
//so that they notice that they need to enter the field names.
|
107 |
+
$('#module-checkbox-custom_field').click(function(){
|
108 |
+
var box = $(this);
|
109 |
+
var fieldList = $('#blc_custom_fields');
|
110 |
+
if ( box.is(':checked') && ( $.trim(fieldList.val()) == '' ) ){
|
111 |
+
$('#module-extra-settings-custom_field').removeClass('hidden');
|
112 |
+
}
|
113 |
+
});
|
114 |
+
|
115 |
+
//Handle the "Recheck" button
|
116 |
+
$('#start-recheck').click(function(){
|
117 |
+
$('#recheck').val('1'); //populate the hidden field
|
118 |
+
$('#link_checker_options input[name="submit"]').click(); //.submit() didn't work for some reason
|
119 |
+
});
|
120 |
+
});
|
121 |
+
|
122 |
+
</script>
|
includes/admin/search-form.php
CHANGED
@@ -1,3 +1,6 @@
|
|
|
|
|
|
|
|
1 |
<div class="search-box">
|
2 |
|
3 |
<?php
|
@@ -64,7 +67,33 @@
|
|
64 |
|
65 |
<label for="s_link_type"><?php _e('Link type', 'broken-link-checker'); ?></label>
|
66 |
<select name="s_link_type" id="s_link_type">
|
|
|
67 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
$link_types = array(
|
69 |
__('Any', 'broken-link-checker') => '',
|
70 |
__('Normal link', 'broken-link-checker') => 'link',
|
@@ -73,11 +102,7 @@
|
|
73 |
__('Bookmark', 'broken-link-checker') => 'blogroll',
|
74 |
__('Comment', 'broken-link-checker') => 'comment',
|
75 |
);
|
76 |
-
|
77 |
-
foreach ($link_types as $name => $value){
|
78 |
-
$selected = ( isset($search_params['s_link_type']) && $search_params['s_link_type'] == $value )?' selected="selected"':'';
|
79 |
-
printf('<option value="%s"%s>%s</option>', $value, $selected, $name);
|
80 |
-
}
|
81 |
?>
|
82 |
</select>
|
83 |
|
1 |
+
<?php
|
2 |
+
$search_params = $current_filter['search_params'];
|
3 |
+
?>
|
4 |
<div class="search-box">
|
5 |
|
6 |
<?php
|
67 |
|
68 |
<label for="s_link_type"><?php _e('Link type', 'broken-link-checker'); ?></label>
|
69 |
<select name="s_link_type" id="s_link_type">
|
70 |
+
<option value=""><?php _e('Any', 'broken-link-checker'); ?></option>
|
71 |
<?php
|
72 |
+
$moduleManager = &blcModuleManager::getInstance();
|
73 |
+
|
74 |
+
printf('<optgroup label="%s">', esc_attr(__('Links used in', 'broken-link-checker')));
|
75 |
+
$containers = $moduleManager->get_modules_by_category('container', false, true);
|
76 |
+
foreach($containers as $container_type => $module_data){
|
77 |
+
if ( !empty($module_data['ModuleHidden']) || !$moduleManager->is_active($container_type) ){
|
78 |
+
continue;
|
79 |
+
}
|
80 |
+
$selected = ( isset($search_params['s_link_type']) && $search_params['s_link_type'] == $container_type )?' selected="selected"':'';
|
81 |
+
printf('<option value="%s"%s>%s</option>', $container_type, $selected, $module_data['Name']);
|
82 |
+
}
|
83 |
+
echo '</optgroup>';
|
84 |
+
//TODO: Better group labels
|
85 |
+
printf('<optgroup label="%s">', esc_attr(__('Link type', 'broken-link-checker')));
|
86 |
+
$parsers = $moduleManager->get_modules_by_category('parser', false, true);
|
87 |
+
foreach($parsers as $parser_type => $module_data){
|
88 |
+
if ( !empty($module_data['ModuleHidden']) || !$moduleManager->is_active($parser_type) ){
|
89 |
+
continue;
|
90 |
+
}
|
91 |
+
$selected = ( isset($search_params['s_link_type']) && $search_params['s_link_type'] == $parser_type )?' selected="selected"':'';
|
92 |
+
printf('<option value="%s"%s>%s</option>', $parser_type, $selected, $module_data['Name']);
|
93 |
+
}
|
94 |
+
echo '</optgroup>';
|
95 |
+
|
96 |
+
/*
|
97 |
$link_types = array(
|
98 |
__('Any', 'broken-link-checker') => '',
|
99 |
__('Normal link', 'broken-link-checker') => 'link',
|
102 |
__('Bookmark', 'broken-link-checker') => 'blogroll',
|
103 |
__('Comment', 'broken-link-checker') => 'comment',
|
104 |
);
|
105 |
+
*/
|
|
|
|
|
|
|
|
|
106 |
?>
|
107 |
</select>
|
108 |
|
includes/admin/table-printer.php
ADDED
@@ -0,0 +1,719 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( !class_exists('blcTablePrinter') ) {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Utility class for printing the link listing table.
|
7 |
+
*
|
8 |
+
* @package Broken Link Checker
|
9 |
+
* @access public
|
10 |
+
*/
|
11 |
+
class blcTablePrinter {
|
12 |
+
|
13 |
+
var $current_filter; //The current search filter. Also contains the list of links to display.
|
14 |
+
var $page; //The current page number
|
15 |
+
var $per_page; //Max links per page
|
16 |
+
var $core; //A reference to the main plugin object
|
17 |
+
var $neutral_current_url; //The "safe" version of the current URL, for use in the bulk action form.
|
18 |
+
|
19 |
+
var $bulk_actions_html = '';
|
20 |
+
var $pagination_html = '';
|
21 |
+
var $searched_link_type = '';
|
22 |
+
|
23 |
+
var $columns;
|
24 |
+
var $layouts;
|
25 |
+
|
26 |
+
|
27 |
+
function blcTablePrinter(&$core){
|
28 |
+
$this->core = &$core;
|
29 |
+
|
30 |
+
//Initialize layout and column definitions
|
31 |
+
$this->setup_columns();
|
32 |
+
$this->setup_layouts();
|
33 |
+
|
34 |
+
//Figure out what the "safe" URL to acccess the current page would be.
|
35 |
+
//This is used by the bulk action form.
|
36 |
+
$special_args = array('_wpnonce', '_wp_http_referer', 'action', 'selected_links');
|
37 |
+
$this->neutral_current_url = remove_query_arg($special_args);
|
38 |
+
}
|
39 |
+
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Print the entire link table and associated navigation elements.
|
43 |
+
*
|
44 |
+
* @param array $current_filter
|
45 |
+
* @param string $layout
|
46 |
+
* @param array $visible_columns
|
47 |
+
* @param bool $compact
|
48 |
+
* @return void
|
49 |
+
*/
|
50 |
+
function print_table($current_filter, $layout = 'flexible', $visible_columns = null, $compact = false){
|
51 |
+
$this->current_filter = $current_filter;
|
52 |
+
$this->page = $current_filter['page'];
|
53 |
+
$this->per_page = $current_filter['per_page'];
|
54 |
+
|
55 |
+
$layout = $this->layouts[$layout];
|
56 |
+
if ( empty($visible_columns) ){
|
57 |
+
$visible_columns = $layout;
|
58 |
+
}
|
59 |
+
//Only allow columns actually present in this layout
|
60 |
+
$visible_columns = array_intersect($visible_columns, $layout);
|
61 |
+
|
62 |
+
echo '<form id="blc-bulk-action-form" action="', $this->neutral_current_url, '" method="post">';
|
63 |
+
wp_nonce_field('bulk-action');
|
64 |
+
|
65 |
+
//Top navigation
|
66 |
+
$this->prepare_nav_html();
|
67 |
+
$this->navigation($compact);
|
68 |
+
|
69 |
+
//Table header
|
70 |
+
$table_classes = array('widefat');
|
71 |
+
if ( $compact ) {
|
72 |
+
$table_classes[] = 'compact';
|
73 |
+
};
|
74 |
+
if ( $this->core->conf->options['table_color_code_status'] ) {
|
75 |
+
$table_classes[] = 'color-code-link-status';
|
76 |
+
};
|
77 |
+
printf(
|
78 |
+
'<table class="%s" id="blc-links"><thead><tr>',
|
79 |
+
implode(' ', $table_classes)
|
80 |
+
);
|
81 |
+
|
82 |
+
//The select-all checkbox
|
83 |
+
echo '<th scope="col" class="column-checkbox check-column" id="cb"><input type="checkbox" /></th>';
|
84 |
+
|
85 |
+
foreach($layout as $column_id){
|
86 |
+
$column = $this->columns[$column_id];
|
87 |
+
|
88 |
+
$column_classes = array('column-'.$column_id);
|
89 |
+
if ( isset($column['class']) ){
|
90 |
+
$column_classes[] = $column['class'];
|
91 |
+
}
|
92 |
+
if ( !in_array($column_id, $visible_columns) ) {
|
93 |
+
$column_classes[] = 'hidden';
|
94 |
+
}
|
95 |
+
|
96 |
+
printf(
|
97 |
+
'<th scope="col" class="%s"%s>%s</th>',
|
98 |
+
implode(' ', $column_classes),
|
99 |
+
isset($column['id']) ? ' id="' . $column['id'] . '"' : '',
|
100 |
+
$column['heading']
|
101 |
+
);
|
102 |
+
}
|
103 |
+
echo '</tr></thead>';
|
104 |
+
|
105 |
+
//Table body
|
106 |
+
echo '<tbody id="the-list">';
|
107 |
+
$rownum = 0;
|
108 |
+
foreach ($this->current_filter['links'] as $link) {
|
109 |
+
$rownum++;
|
110 |
+
$this->link_row($link, $layout, $visible_columns, $rownum);
|
111 |
+
$this->link_details_row($link, $visible_columns, $rownum);
|
112 |
+
}
|
113 |
+
echo '</tbody></table>';
|
114 |
+
|
115 |
+
//Bottom navigation
|
116 |
+
$this->navigation($compact, '2');
|
117 |
+
echo '</form>';
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Print the "Bulk Actions" dropdown and navigation links
|
122 |
+
*
|
123 |
+
* @param string $suffix Optional. Appended to ID and name attributes of the bulk action dropdown.
|
124 |
+
* @return void
|
125 |
+
*/
|
126 |
+
function navigation($table_compact = false, $suffix = ''){
|
127 |
+
//Display the "Bulk Actions" dropdown
|
128 |
+
echo '<div class="tablenav">',
|
129 |
+
'<div class="alignleft actions">',
|
130 |
+
'<select name="action', $suffix ,'" id="blc-bulk-action', $suffix ,'">',
|
131 |
+
$this->bulk_actions_html,
|
132 |
+
'</select>',
|
133 |
+
' <input type="submit" name="doaction', $suffix ,'" id="doaction',$suffix,'" value="',
|
134 |
+
esc_attr(__('Apply', 'broken-link-checker')),
|
135 |
+
'" class="button-secondary action">',
|
136 |
+
'</div>';
|
137 |
+
|
138 |
+
//Display pagination links
|
139 |
+
if ( !empty($this->pagination_html) ){
|
140 |
+
echo $this->pagination_html;
|
141 |
+
}
|
142 |
+
|
143 |
+
//Display the view switch (only in the top nav. area)
|
144 |
+
if ( empty($suffix) ){
|
145 |
+
?>
|
146 |
+
|
147 |
+
<div class="view-switch">
|
148 |
+
<a href="<?php echo esc_url(add_query_arg('compact', '1', $_SERVER['REQUEST_URI'])) ?>"><img <?php if ( $table_compact ) echo 'class="current"'; ?> id="view-switch-list" src="<?php echo esc_url( includes_url( 'images/blank.gif' ) ); ?>" width="20" height="20" title="<?php _e('Compact View', 'broken-link-checker') ?>" alt="<?php _e('Compact View', 'broken-link-checker') ?>" /></a>
|
149 |
+
<a href="<?php echo esc_url(add_query_arg('compact', '0', $_SERVER['REQUEST_URI'])) ?>"><img <?php if ( !$table_compact ) echo 'class="current"'; ?> id="view-switch-excerpt" src="<?php echo esc_url( includes_url( 'images/blank.gif' ) ); ?>" width="20" height="20" title="<?php _e('Detailed View', 'broken-link-checker') ?>" alt="<?php _e('Detailed View', 'broken-link-checker') ?>" /></a>
|
150 |
+
</div>
|
151 |
+
|
152 |
+
<?php
|
153 |
+
}
|
154 |
+
|
155 |
+
echo '</div>';
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Initialize the internal list of available table columns.
|
160 |
+
*
|
161 |
+
* @return void
|
162 |
+
*/
|
163 |
+
function setup_columns(){
|
164 |
+
$this->columns = array(
|
165 |
+
'source' => array(
|
166 |
+
'heading' => __('Source', 'broken-link-checker'),
|
167 |
+
'class' => 'column-title',
|
168 |
+
'content' => array(&$this, 'column_source'),
|
169 |
+
),
|
170 |
+
|
171 |
+
'link-text' => array(
|
172 |
+
'heading' => __('Link Text', 'broken-link-checker'),
|
173 |
+
'content' => array(&$this, 'column_link_text'),
|
174 |
+
),
|
175 |
+
|
176 |
+
'url' => array(
|
177 |
+
'heading' => __('URL', 'broken-link-checker'),
|
178 |
+
'content' => array(&$this, 'column_url'),
|
179 |
+
),
|
180 |
+
|
181 |
+
'status' => array(
|
182 |
+
'heading' => __('Status', 'broken-link-checker'),
|
183 |
+
'content' => array(&$this, 'column_status'),
|
184 |
+
),
|
185 |
+
|
186 |
+
'new-url' => array(
|
187 |
+
'heading' => __('URL', 'broken-link-checker'),
|
188 |
+
'content' => array(&$this, 'column_new_url'),
|
189 |
+
),
|
190 |
+
|
191 |
+
'used-in' => array(
|
192 |
+
'heading' => __('Source', 'broken-link-checker'),
|
193 |
+
'class' => 'column-title',
|
194 |
+
'content' => array(&$this, 'column_used_in'),
|
195 |
+
),
|
196 |
+
|
197 |
+
'new-link-text' => array(
|
198 |
+
'heading' => __('Link Text', 'broken-link-checker'),
|
199 |
+
'content' => array(&$this, 'column_new_link_text'),
|
200 |
+
),
|
201 |
+
);
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Initialize the list of available layouts
|
206 |
+
*
|
207 |
+
* @return void
|
208 |
+
*/
|
209 |
+
function setup_layouts(){
|
210 |
+
$this->layouts = array(
|
211 |
+
'classic' => array('used-in', 'new-link-text', 'new-url'),
|
212 |
+
'flexible' => array('new-url', 'status', 'new-link-text', 'used-in',),
|
213 |
+
);
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Get a list of columns available in a specific table layout.
|
218 |
+
*
|
219 |
+
* @param string $layout Layout ID.
|
220 |
+
* @return array Associative array of column data indexed by column ID.
|
221 |
+
*/
|
222 |
+
function get_layout_columns($layout){
|
223 |
+
if ( isset($this->layouts[$layout]) ){
|
224 |
+
|
225 |
+
$result = array();
|
226 |
+
foreach($this->layouts[$layout] as $column_id){
|
227 |
+
if ( isset($this->columns[$column_id]) )
|
228 |
+
$result[$column_id] = $this->columns[$column_id];
|
229 |
+
}
|
230 |
+
return $result;
|
231 |
+
|
232 |
+
} else {
|
233 |
+
return null;
|
234 |
+
}
|
235 |
+
}
|
236 |
+
|
237 |
+
/**
|
238 |
+
* Pre-generate some HTML fragments used for both the top and bottom navigation/bulk action boxes.
|
239 |
+
*
|
240 |
+
* @return void
|
241 |
+
*/
|
242 |
+
function prepare_nav_html(){
|
243 |
+
//Generate an <option> element for each possible bulk action. The list doesn't change,
|
244 |
+
//so we can do it once and reuse the generated HTML.
|
245 |
+
$bulk_actions = array(
|
246 |
+
'-1' => __('Bulk Actions', 'broken-link-checker'),
|
247 |
+
"bulk-recheck" => __('Recheck', 'broken-link-checker'),
|
248 |
+
"bulk-deredirect" => __('Fix redirects', 'broken-link-checker'),
|
249 |
+
"bulk-not-broken" => __('Mark as not broken', 'broken-link-checker'),
|
250 |
+
"bulk-unlink" => __('Unlink', 'broken-link-checker'),
|
251 |
+
);
|
252 |
+
if ( EMPTY_TRASH_DAYS ){
|
253 |
+
$bulk_actions["bulk-trash-sources"] = __('Move sources to Trash', 'broken-link-checker');
|
254 |
+
} else {
|
255 |
+
$bulk_actions["bulk-delete-sources"] = __('Delete sources', 'broken-link-checker');
|
256 |
+
}
|
257 |
+
|
258 |
+
$bulk_actions_html = '';
|
259 |
+
foreach($bulk_actions as $value => $name){
|
260 |
+
$bulk_actions_html .= sprintf('<option value="%s">%s</option>', $value, $name);
|
261 |
+
}
|
262 |
+
|
263 |
+
$this->bulk_actions_html = $bulk_actions_html;
|
264 |
+
|
265 |
+
//Pagination links can also be pre-generated.
|
266 |
+
//WP has a built-in function for pagination :)
|
267 |
+
$page_links = paginate_links( array(
|
268 |
+
'base' => add_query_arg( 'paged', '%#%' ),
|
269 |
+
'format' => '',
|
270 |
+
'prev_text' => __('«'),
|
271 |
+
'next_text' => __('»'),
|
272 |
+
'total' => $this->current_filter['max_pages'],
|
273 |
+
'current' => $this->page
|
274 |
+
));
|
275 |
+
|
276 |
+
if ( $page_links ) {
|
277 |
+
$this->pagination_html = '<div class="tablenav-pages">';
|
278 |
+
$this->pagination_html .= sprintf(
|
279 |
+
'<span class="displaying-num">' . __( 'Displaying %s–%s of <span class="current-link-count">%s</span>', 'broken-link-checker' ) . '</span>%s',
|
280 |
+
number_format_i18n( ( $this->page - 1 ) * $this->per_page + 1 ),
|
281 |
+
number_format_i18n( min( $this->page * $this->per_page, $this->current_filter['count'] ) ),
|
282 |
+
number_format_i18n( $this->current_filter['count'] ),
|
283 |
+
$page_links
|
284 |
+
);
|
285 |
+
$this->pagination_html .= '</div>';
|
286 |
+
} else {
|
287 |
+
$this->pagination_html = '';
|
288 |
+
}
|
289 |
+
}
|
290 |
+
|
291 |
+
/**
|
292 |
+
* Print the link row.
|
293 |
+
*
|
294 |
+
* @param object $link The link to display.
|
295 |
+
* @param array $layout List of columns to output.
|
296 |
+
* @param array $visible_columns List of visible columns.
|
297 |
+
* @param integer $rownum Table row number.
|
298 |
+
* @return void
|
299 |
+
*/
|
300 |
+
function link_row(&$link, $layout, $visible_columns, $rownum = 0){
|
301 |
+
|
302 |
+
//Figure out what CSS classes the link row should have
|
303 |
+
$rowclass = ($rownum % 2)? 'alternate' : '';
|
304 |
+
|
305 |
+
$excluded = $this->core->is_excluded( $link->url );
|
306 |
+
if ( $excluded ) $rowclass .= ' blc-excluded-link';
|
307 |
+
|
308 |
+
if ( $link->redirect_count > 0){
|
309 |
+
$rowclass .= ' blc-redirect';
|
310 |
+
}
|
311 |
+
|
312 |
+
$days_broken = 0;
|
313 |
+
if ( $link->broken ){
|
314 |
+
//Add a highlight to broken links that appear to be permanently broken
|
315 |
+
$days_broken = intval( (time() - $link->first_failure) / (3600*24) );
|
316 |
+
if ( $days_broken >= $this->core->conf->options['failure_duration_threshold'] ){
|
317 |
+
$rowclass .= ' blc-permanently-broken';
|
318 |
+
if ( $this->core->conf->options['highlight_permanent_failures'] ){
|
319 |
+
$rowclass .= ' blc-permanently-broken-hl';
|
320 |
+
}
|
321 |
+
}
|
322 |
+
}
|
323 |
+
|
324 |
+
$status = $link->analyse_status();
|
325 |
+
$rowclass .= ' link-status-' . $status['code'];
|
326 |
+
|
327 |
+
//Retrieve link instances to display in the table
|
328 |
+
$instances = $link->get_instances();
|
329 |
+
|
330 |
+
if ( !empty($instances) ){
|
331 |
+
//Put instances that match the selected link type at the top. Makes search results look better.
|
332 |
+
if ( !empty($this->current_filter['search_params']['s_link_type']) ){
|
333 |
+
$s_link_type = $this->current_filter['search_params']['s_link_type'];
|
334 |
+
} else {
|
335 |
+
$s_link_type = '';
|
336 |
+
}
|
337 |
+
$instances = $this->sort_instances_for_display($instances, $s_link_type);
|
338 |
+
}
|
339 |
+
|
340 |
+
printf(
|
341 |
+
'<tr id="blc-row-%s" class="blc-row %s" days_broken="%d">',
|
342 |
+
$link->link_id,
|
343 |
+
$rowclass,
|
344 |
+
$days_broken
|
345 |
+
);
|
346 |
+
|
347 |
+
//The checkbox used to select links is automatically printed in all layouts
|
348 |
+
//and can't be disabled. Without it, bulk actions wouldn't work.
|
349 |
+
$this->column_checkbox($link);
|
350 |
+
|
351 |
+
foreach($layout as $column_id){
|
352 |
+
$column = $this->columns[$column_id];
|
353 |
+
|
354 |
+
printf(
|
355 |
+
'<td class="column-%s%s">',
|
356 |
+
$column_id,
|
357 |
+
in_array($column_id, $visible_columns) ? '' : ' hidden'
|
358 |
+
);
|
359 |
+
|
360 |
+
if ( isset($column['content']) ){
|
361 |
+
if ( is_callable($column['content']) ){
|
362 |
+
call_user_func($column['content'], $link, $instances);
|
363 |
+
} else {
|
364 |
+
echo $column['content'];
|
365 |
+
}
|
366 |
+
} else {
|
367 |
+
echo '[', $column_id, ']';
|
368 |
+
}
|
369 |
+
|
370 |
+
echo '</td>';
|
371 |
+
}
|
372 |
+
|
373 |
+
echo '</tr>';
|
374 |
+
}
|
375 |
+
|
376 |
+
/**
|
377 |
+
* Print the details row for a specific link.
|
378 |
+
*
|
379 |
+
* @uses blcTablePrinter::details_row_contents()
|
380 |
+
*
|
381 |
+
* @param object $link The link to display.
|
382 |
+
* @param array $visible_columns List of visible columns.
|
383 |
+
* @param integer $rownum Table row number.
|
384 |
+
* @return void
|
385 |
+
*/
|
386 |
+
function link_details_row(&$link, $visible_columns, $rownum = 0){
|
387 |
+
printf(
|
388 |
+
'<tr id="link-details-%d" class="blc-link-details"><td colspan="%d">',
|
389 |
+
$link->link_id,
|
390 |
+
count($visible_columns)+1
|
391 |
+
);
|
392 |
+
$this->details_row_contents($link);
|
393 |
+
echo '</td></tr>';
|
394 |
+
}
|
395 |
+
|
396 |
+
/**
|
397 |
+
* Print the contents of the details row for a specific link.
|
398 |
+
*
|
399 |
+
* @param object $link
|
400 |
+
* @return void
|
401 |
+
*/
|
402 |
+
function details_row_contents(&$link){
|
403 |
+
?>
|
404 |
+
<div class="blc-detail-container">
|
405 |
+
<div class="blc-detail-block" style="float: left; width: 49%;">
|
406 |
+
<ol style='list-style-type: none;'>
|
407 |
+
<?php if ( !empty($link->post_date) ) { ?>
|
408 |
+
<li><strong><?php _e('Post published on', 'broken-link-checker'); ?> :</strong>
|
409 |
+
<span class='post_date'><?php
|
410 |
+
echo date_i18n(get_option('date_format'),strtotime($link->post_date));
|
411 |
+
?></span></li>
|
412 |
+
<?php } ?>
|
413 |
+
<li><strong><?php _e('Link last checked', 'broken-link-checker'); ?> :</strong>
|
414 |
+
<span class='check_date'><?php
|
415 |
+
$last_check = $link->last_check;
|
416 |
+
if ( $last_check < strtotime('-10 years') ){
|
417 |
+
_e('Never', 'broken-link-checker');
|
418 |
+
} else {
|
419 |
+
echo date_i18n(get_option('date_format'), $last_check);
|
420 |
+
}
|
421 |
+
?></span></li>
|
422 |
+
|
423 |
+
<li><strong><?php _e('HTTP code', 'broken-link-checker'); ?> :</strong>
|
424 |
+
<span class='http_code'><?php
|
425 |
+
print $link->http_code;
|
426 |
+
?></span></li>
|
427 |
+
|
428 |
+
<li><strong><?php _e('Response time', 'broken-link-checker'); ?> :</strong>
|
429 |
+
<span class='request_duration'><?php
|
430 |
+
printf( __('%2.3f seconds', 'broken-link-checker'), $link->request_duration);
|
431 |
+
?></span></li>
|
432 |
+
|
433 |
+
<li><strong><?php _e('Final URL', 'broken-link-checker'); ?> :</strong>
|
434 |
+
<span class='final_url'><?php
|
435 |
+
print $link->final_url;
|
436 |
+
?></span></li>
|
437 |
+
|
438 |
+
<li><strong><?php _e('Redirect count', 'broken-link-checker'); ?> :</strong>
|
439 |
+
<span class='redirect_count'><?php
|
440 |
+
print $link->redirect_count;
|
441 |
+
?></span></li>
|
442 |
+
|
443 |
+
<li><strong><?php _e('Instance count', 'broken-link-checker'); ?> :</strong>
|
444 |
+
<span class='instance_count'><?php
|
445 |
+
print count($link->get_instances());
|
446 |
+
?></span></li>
|
447 |
+
|
448 |
+
<?php if ( $link->broken && (intval( $link->check_count ) > 0) ){ ?>
|
449 |
+
<li><br/>
|
450 |
+
<?php
|
451 |
+
printf(
|
452 |
+
_n('This link has failed %d time.', 'This link has failed %d times.', $link->check_count, 'broken-link-checker'),
|
453 |
+
$link->check_count
|
454 |
+
);
|
455 |
+
|
456 |
+
echo '<br>';
|
457 |
+
|
458 |
+
$delta = time() - $link->first_failure;
|
459 |
+
printf(
|
460 |
+
__('This link has been broken for %s.', 'broken-link-checker'),
|
461 |
+
blcUtility::fuzzy_delta($delta)
|
462 |
+
);
|
463 |
+
?>
|
464 |
+
</li>
|
465 |
+
<?php } ?>
|
466 |
+
</ol>
|
467 |
+
</div>
|
468 |
+
|
469 |
+
<div class="blc-detail-block" style="float: right; width: 50%;">
|
470 |
+
<ol style='list-style-type: none;'>
|
471 |
+
<li><strong><?php _e('Log', 'broken-link-checker'); ?> :</strong>
|
472 |
+
<span class='blc_log'><?php
|
473 |
+
print nl2br($link->log);
|
474 |
+
?></span></li>
|
475 |
+
</ol>
|
476 |
+
</div>
|
477 |
+
|
478 |
+
<div style="clear:both;"> </div>
|
479 |
+
</div>
|
480 |
+
<?php
|
481 |
+
}
|
482 |
+
|
483 |
+
function column_checkbox(&$link){
|
484 |
+
?>
|
485 |
+
<th scope="row" class="check-column"><input type="checkbox" name="selected_links[]" value="<?php echo $link->link_id; ?>" /></th>
|
486 |
+
<?php
|
487 |
+
}
|
488 |
+
|
489 |
+
function column_source(&$link, $instances){
|
490 |
+
echo '<span class="blc-link-id" style="display:none;">',
|
491 |
+
$link->link_id,
|
492 |
+
'</span>';
|
493 |
+
|
494 |
+
//Print the contents of the "Source" column
|
495 |
+
if ( !empty($instances) ){
|
496 |
+
$instance = reset($instances);
|
497 |
+
|
498 |
+
echo $instance->ui_get_source();
|
499 |
+
|
500 |
+
$actions = $instance->ui_get_action_links();
|
501 |
+
|
502 |
+
echo '<div class="row-actions">';
|
503 |
+
echo implode(' | </span>', $actions);
|
504 |
+
echo '</div>';
|
505 |
+
|
506 |
+
} else {
|
507 |
+
_e("[An orphaned link! This is a bug.]", 'broken-link-checker');
|
508 |
+
}
|
509 |
+
}
|
510 |
+
|
511 |
+
function column_url(&$link){
|
512 |
+
?>
|
513 |
+
<a href="<?php print esc_attr($link->url); ?>" target='_blank' class='blc-link-url' title="<?php echo esc_attr($link->url); ?>">
|
514 |
+
<?php print $link->url; ?></a>
|
515 |
+
<input type='text' id='link-editor-<?php print $link->link_id; ?>'
|
516 |
+
value="<?php print esc_attr($link->url); ?>"
|
517 |
+
class='blc-link-editor' style='display:none' />
|
518 |
+
<?php
|
519 |
+
//Output inline action links for the link/URL
|
520 |
+
$actions = array();
|
521 |
+
|
522 |
+
$actions['details'] = "<span class='view'><a class='blc-details-button' href='javascript:void(0)' title='". esc_attr(__('Show more info about this link', 'broken-link-checker')) . "'>". __('Details', 'broken-link-checker') ."</a>";
|
523 |
+
|
524 |
+
$actions['delete'] = "<span class='delete'><a class='submitdelete blc-unlink-button' title='" . esc_attr( __('Remove this link from all posts', 'broken-link-checker') ). "' ".
|
525 |
+
"id='unlink-button-$rownum' href='javascript:void(0);'>" . __('Unlink', 'broken-link-checker') . "</a>";
|
526 |
+
|
527 |
+
if ( $link->broken ){
|
528 |
+
$actions['discard'] = sprintf(
|
529 |
+
'<span><a href="#" title="%s" class="blc-discard-button">%s</a>',
|
530 |
+
esc_attr(__('Remove this link from the list of broken links and mark it as valid', 'broken-link-checker')),
|
531 |
+
__('Not broken', 'broken-link-checker')
|
532 |
+
);
|
533 |
+
}
|
534 |
+
|
535 |
+
$actions['edit'] = "<span class='edit'><a href='javascript:void(0)' class='blc-edit-button' title='" . esc_attr( __('Edit link URL' , 'broken-link-checker') ) . "'>". __('Edit URL' , 'broken-link-checker') ."</a>";
|
536 |
+
|
537 |
+
echo '<div class="row-actions">';
|
538 |
+
echo implode(' | </span>', $actions);
|
539 |
+
|
540 |
+
echo "<span style='display:none' class='blc-cancel-button-container'> " .
|
541 |
+
"| <a href='javascript:void(0)' class='blc-cancel-button' title='". esc_attr(__('Cancel URL editing' , 'broken-link-checker')) ."'>". __('Cancel' , 'broken-link-checker') ."</a></span>";
|
542 |
+
|
543 |
+
echo '</div>';
|
544 |
+
}
|
545 |
+
|
546 |
+
function column_link_text(&$link, $instances){
|
547 |
+
if ( empty($instances) ){
|
548 |
+
echo '<em>N/A</em>';
|
549 |
+
} else {
|
550 |
+
$instance = reset($instances);
|
551 |
+
echo $instance->ui_get_link_text();
|
552 |
+
}
|
553 |
+
}
|
554 |
+
|
555 |
+
function column_status(&$link, $instances){
|
556 |
+
printf(
|
557 |
+
'<table class="mini-status" title="%s">',
|
558 |
+
esc_attr(__('Show more info about this link', 'broken-link-checker'))
|
559 |
+
);
|
560 |
+
|
561 |
+
$status = $link->analyse_status();
|
562 |
+
|
563 |
+
printf(
|
564 |
+
'<tr class="link-status-row link-status-%s">
|
565 |
+
<td>
|
566 |
+
<span class="http-code">%s</span> <span class="status-text">%s</span>
|
567 |
+
</td>
|
568 |
+
</tr>',
|
569 |
+
$status['code'],
|
570 |
+
empty($link->http_code)?'':$link->http_code,
|
571 |
+
$status['text']
|
572 |
+
);
|
573 |
+
|
574 |
+
//Last checked...
|
575 |
+
if ( $link->last_check != 0 ){
|
576 |
+
$last_check = _x('Checked', 'checked how long ago', 'broken-link-checker') . ' ';
|
577 |
+
$last_check .= blcUtility::fuzzy_delta(time() - $link->last_check, 'ago');
|
578 |
+
|
579 |
+
printf(
|
580 |
+
'<tr class="link-last-checked"><td>%s</td></tr>',
|
581 |
+
$last_check
|
582 |
+
);
|
583 |
+
}
|
584 |
+
|
585 |
+
|
586 |
+
//Broken for...
|
587 |
+
if ( $link->broken ){
|
588 |
+
$delta = time() - $link->first_failure;
|
589 |
+
$broken_for = blcUtility::fuzzy_delta($delta);
|
590 |
+
printf(
|
591 |
+
'<tr class="link-broken-for"><td>%s %s</td></tr>',
|
592 |
+
__('Broken for', 'broken-link-checker'),
|
593 |
+
$broken_for
|
594 |
+
);
|
595 |
+
}
|
596 |
+
|
597 |
+
echo '</table>';
|
598 |
+
}
|
599 |
+
|
600 |
+
|
601 |
+
function column_new_url(&$link){
|
602 |
+
?>
|
603 |
+
<a href="<?php print esc_attr($link->url); ?>" target='_blank' class='blc-link-url' title="<?php echo esc_attr($link->url); ?>">
|
604 |
+
<?php print $link->url; ?></a>
|
605 |
+
<input type='text' id='link-editor-<?php print $link->link_id; ?>'
|
606 |
+
value="<?php print esc_attr($link->url); ?>"
|
607 |
+
class='blc-link-editor' style='display:none' />
|
608 |
+
<?php
|
609 |
+
//Output inline action links for the link/URL
|
610 |
+
$actions = array();
|
611 |
+
|
612 |
+
$actions['edit'] = "<span class='edit'><a href='javascript:void(0)' class='blc-edit-button' title='" . esc_attr( __('Edit link URL' , 'broken-link-checker') ) . "'>". __('Edit URL' , 'broken-link-checker') ."</a>";
|
613 |
+
|
614 |
+
$actions['delete'] = "<span class='delete'><a class='submitdelete blc-unlink-button' title='" . esc_attr( __('Remove this link from all posts', 'broken-link-checker') ). "' ".
|
615 |
+
"id='unlink-button-$rownum' href='javascript:void(0);'>" . __('Unlink', 'broken-link-checker') . "</a>";
|
616 |
+
|
617 |
+
if ( $link->broken ){
|
618 |
+
$actions['discard'] = sprintf(
|
619 |
+
'<span><a href="#" title="%s" class="blc-discard-button">%s</a>',
|
620 |
+
esc_attr(__('Remove this link from the list of broken links and mark it as valid', 'broken-link-checker')),
|
621 |
+
__('Not broken', 'broken-link-checker')
|
622 |
+
);
|
623 |
+
}
|
624 |
+
|
625 |
+
echo '<div class="row-actions">';
|
626 |
+
echo implode(' | </span>', $actions) .'</span>';
|
627 |
+
|
628 |
+
echo "<span style='display:none' class='blc-cancel-button-container'> " .
|
629 |
+
"| <a href='javascript:void(0)' class='blc-cancel-button' title='". esc_attr(__('Cancel URL editing' , 'broken-link-checker')) ."'>". __('Cancel' , 'broken-link-checker') ."</a></span>";
|
630 |
+
|
631 |
+
echo '</div>';
|
632 |
+
|
633 |
+
?>
|
634 |
+
<div class="blc-url-editor-buttons">
|
635 |
+
<input type="button" class="button-secondary cancel alignleft blc-cancel-button" value="<?php echo esc_attr(__('Cancel', 'broken-link-checker')); ?>" />
|
636 |
+
<input type="button" class="button-primary save alignright blc-update-url-button" value="<?php echo esc_attr(__('Update URL', 'broken-link-checker')); ?>" />
|
637 |
+
<img class="waiting" style="display:none;" src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" />
|
638 |
+
</div>
|
639 |
+
<?php
|
640 |
+
}
|
641 |
+
|
642 |
+
function column_used_in(&$link, $instances){
|
643 |
+
echo '<span class="blc-link-id" style="display:none;">',
|
644 |
+
$link->link_id,
|
645 |
+
'</span>';
|
646 |
+
|
647 |
+
if ( !empty($instances) ){
|
648 |
+
$instance = reset($instances);
|
649 |
+
echo $instance->ui_get_source();
|
650 |
+
|
651 |
+
$actions = $instance->ui_get_action_links();
|
652 |
+
|
653 |
+
echo '<div class="row-actions">';
|
654 |
+
echo implode(' | </span>', $actions);
|
655 |
+
echo '</div>';
|
656 |
+
|
657 |
+
} else {
|
658 |
+
_e("[An orphaned link! This is a bug.]", 'broken-link-checker');
|
659 |
+
}
|
660 |
+
}
|
661 |
+
|
662 |
+
function column_new_link_text(&$link, $instances){
|
663 |
+
if ( empty($instances) ){
|
664 |
+
echo '<em>N/A</em>';
|
665 |
+
} else {
|
666 |
+
$instance = reset($instances);
|
667 |
+
echo $instance->ui_get_link_text();
|
668 |
+
}
|
669 |
+
}
|
670 |
+
|
671 |
+
/**
|
672 |
+
* Sort a list of link instances to be displayed in the "Broken Links" page.
|
673 |
+
*
|
674 |
+
* Groups instances by container type and, if $search_link_type is specified,
|
675 |
+
* puts instances that have a matching container type or parser type at the
|
676 |
+
* beginning.
|
677 |
+
*
|
678 |
+
* @param array $instances An array of blcLinkInstance objects.
|
679 |
+
* @param string $searched_link_type Optional. The required container/parser type.
|
680 |
+
* @return array Sorted array.
|
681 |
+
*/
|
682 |
+
function sort_instances_for_display($instances, $searched_link_type = ''){
|
683 |
+
$this->searched_link_type = $searched_link_type;
|
684 |
+
usort($instances, array(&$this, 'compare_link_instances'));
|
685 |
+
return $instances;
|
686 |
+
}
|
687 |
+
|
688 |
+
/**
|
689 |
+
* Callback function for sorting link instances.
|
690 |
+
*
|
691 |
+
* @see blcTablePrinter::sort_instances_for_display()
|
692 |
+
*
|
693 |
+
* @param blcLinkInstance $a
|
694 |
+
* @param blcLinkInstance $b
|
695 |
+
* @return int
|
696 |
+
*/
|
697 |
+
function compare_link_instances($a, $b){
|
698 |
+
if ( !empty($this->searched_link_type) ){
|
699 |
+
if ( ($a->container_type == $this->searched_link_type) || ($a->parser_type == $this->searched_link_type) ){
|
700 |
+
if ( ($b->container_type == $this->searched_link_type) || ($b->parser_type == $this->searched_link_type) ){
|
701 |
+
return 0;
|
702 |
+
} else {
|
703 |
+
return -1;
|
704 |
+
}
|
705 |
+
} else {
|
706 |
+
if ( ($b->container_type == $this->searched_link_type) || ($b->parser_type == $this->searched_link_type) ){
|
707 |
+
return 1;
|
708 |
+
}
|
709 |
+
}
|
710 |
+
}
|
711 |
+
|
712 |
+
return strcmp($a->container_type, $b->container_type);
|
713 |
+
}
|
714 |
+
|
715 |
+
}
|
716 |
+
|
717 |
+
}//class_exists
|
718 |
+
|
719 |
+
?>
|
includes/any-post.php
ADDED
@@ -0,0 +1,732 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* The manager to rule all (post) managers.
|
5 |
+
*
|
6 |
+
* This class dynamically registers container modules for the available post types
|
7 |
+
* (including custom post types) and does stuff that pertain to all of them, such
|
8 |
+
* as handling save/delete hooks and (re)creating synch records.
|
9 |
+
*
|
10 |
+
* @package Broken Link Checker
|
11 |
+
* @author Janis Elsts
|
12 |
+
* @access private
|
13 |
+
*/
|
14 |
+
class blcPostTypeOverlord {
|
15 |
+
var $enabled_post_types = array(); //Post types currently selected for link checking
|
16 |
+
var $enabled_post_statuses = array('publish'); //Only posts that have one of these statuses shall be checked
|
17 |
+
|
18 |
+
var $plugin_conf;
|
19 |
+
var $resynch_already_done = false;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Class "constructor". Can't use an actual constructor due to how PHP4 handles object references.
|
23 |
+
*
|
24 |
+
* Specifically, this class is a singleton. The function needs to pass $this to several other
|
25 |
+
* functions (to set up hooks), which will store the reference for later use. However, it appears
|
26 |
+
* that in PHP4 the actual value of $this is thrown away right after the constructor finishes, and
|
27 |
+
* `new` returns a *copy* of $this. The result is that means getInstance() won't be returning a ref.
|
28 |
+
* to the same object as is used for hook callbacks. And that's horrible.
|
29 |
+
*
|
30 |
+
* Sets up hooks that monitor added/modified/deleted posts and registers
|
31 |
+
* virtual modules for all post types.
|
32 |
+
*
|
33 |
+
* @return void
|
34 |
+
*/
|
35 |
+
function init(){
|
36 |
+
$this->plugin_conf = &blc_get_configuration();
|
37 |
+
|
38 |
+
if ( isset($this->plugin_conf->options['enabled_post_statuses']) ){
|
39 |
+
$this->enabled_post_statuses = $this->plugin_conf->options['enabled_post_statuses'];
|
40 |
+
}
|
41 |
+
|
42 |
+
//Register a virtual container module for each enabled post type
|
43 |
+
$module_manager = &blcModuleManager::getInstance();
|
44 |
+
|
45 |
+
$post_types = get_post_types(array(), 'objects');
|
46 |
+
$exceptions = array('revision', 'nav_menu_item', 'attachment');
|
47 |
+
$built_in = array('post', 'page');
|
48 |
+
|
49 |
+
foreach($post_types as $post_type => $data){
|
50 |
+
if ( in_array($post_type, $exceptions) ){
|
51 |
+
continue;
|
52 |
+
}
|
53 |
+
|
54 |
+
$module_manager->register_virtual_module(
|
55 |
+
$post_type,
|
56 |
+
array(
|
57 |
+
'Name' => $data->labels->name,
|
58 |
+
'ModuleCategory' => 'container',
|
59 |
+
'ModuleContext' => 'all',
|
60 |
+
'ModuleClassName' => 'blcAnyPostContainerManager',
|
61 |
+
'ModuleRequiresPro' => in_array($post_type, $built_in) ? 'false' : 'true',
|
62 |
+
)
|
63 |
+
);
|
64 |
+
}
|
65 |
+
|
66 |
+
//These hooks update the synch & instance records when posts are added, deleted or modified.
|
67 |
+
add_action('delete_post', array(&$this,'post_deleted'));
|
68 |
+
add_action('save_post', array(&$this,'post_saved'));
|
69 |
+
//We also treat post trashing/untrashing as delete/save.
|
70 |
+
add_action('trash_post', array(&$this,'post_deleted'));
|
71 |
+
add_action('untrash_post', array(&$this,'post_saved'));
|
72 |
+
|
73 |
+
//Highlight and nofollow broken links in posts & pages
|
74 |
+
if ( $this->plugin_conf->options['mark_broken_links'] || $this->plugin_conf->options['nofollow_broken_links'] ){
|
75 |
+
add_filter( 'the_content', array(&$this, 'hook_the_content') );
|
76 |
+
if ( $this->plugin_conf->options['mark_broken_links'] && !empty( $this->plugin_conf->options['broken_link_css'] ) ){
|
77 |
+
add_action( 'wp_head', array(&$this,'hook_wp_head') );
|
78 |
+
}
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Retrieve an instance of the overlord class.
|
84 |
+
*
|
85 |
+
* @return blcPostTypeOverlord
|
86 |
+
*/
|
87 |
+
function &getInstance(){
|
88 |
+
static $instance = null;
|
89 |
+
if ( is_null($instance) ){
|
90 |
+
$instance = new blcPostTypeOverlord;
|
91 |
+
$instance->init();
|
92 |
+
}
|
93 |
+
return $instance;
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Notify the overlord that a post type is active.
|
98 |
+
*
|
99 |
+
* Called by individual instances of blcAnyPostContainerManager to let
|
100 |
+
* the overlord know that they've been created. Since a module instance
|
101 |
+
* is only created if the module is active, this event indicates that
|
102 |
+
* the user has enabled the corresponding post type for link checking.
|
103 |
+
*
|
104 |
+
* @param string $post_type
|
105 |
+
* @return void
|
106 |
+
*/
|
107 |
+
function post_type_enabled($post_type){
|
108 |
+
if ( !in_array($post_type, $this->enabled_post_types) ){
|
109 |
+
$this->enabled_post_types[] = $post_type;
|
110 |
+
}
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Remove the synch. record and link instances associated with a post when it's deleted
|
115 |
+
*
|
116 |
+
* @param int $post_id
|
117 |
+
* @return void
|
118 |
+
*/
|
119 |
+
function post_deleted($post_id){
|
120 |
+
//Get the container type matching the type of the deleted post
|
121 |
+
$post = &get_post($post_id);
|
122 |
+
if ( !$post ){
|
123 |
+
return;
|
124 |
+
}
|
125 |
+
//Get the associated container object
|
126 |
+
$post_container = & blcContainerHelper::get_container( array($post->post_type, intval($post_id)) );
|
127 |
+
|
128 |
+
if ( $post_container ){
|
129 |
+
//Delete it
|
130 |
+
$post_container->delete();
|
131 |
+
//Clean up any dangling links
|
132 |
+
blc_cleanup_links();
|
133 |
+
}
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* When a post is saved or modified, mark it as unparsed.
|
138 |
+
*
|
139 |
+
* @param int $post_id
|
140 |
+
* @return void
|
141 |
+
*/
|
142 |
+
function post_saved($post_id){
|
143 |
+
//Get the container type matching the type of the deleted post
|
144 |
+
$post = &get_post($post_id);
|
145 |
+
if ( !$post ){
|
146 |
+
return;
|
147 |
+
}
|
148 |
+
|
149 |
+
//Only check links in currently enabled post types
|
150 |
+
if ( !in_array($post->post_type, $this->enabled_post_types) ) return;
|
151 |
+
|
152 |
+
//Only check posts that have one of the allowed statuses
|
153 |
+
if ( !in_array($post->post_status, $this->enabled_post_statuses) ) return;
|
154 |
+
|
155 |
+
//Get the container & mark it as unparsed
|
156 |
+
$args = array($post->post_type, intval($post_id));
|
157 |
+
$post_container = & blcContainerHelper::get_container( $args );
|
158 |
+
|
159 |
+
$post_container->mark_as_unsynched();
|
160 |
+
}
|
161 |
+
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Create or update synchronization records for all posts.
|
165 |
+
*
|
166 |
+
* @param bool $forced If true, assume that all synch. records are gone and will need to be recreated from scratch.
|
167 |
+
* @return void
|
168 |
+
*/
|
169 |
+
function resynch($container_type = '', $forced = false){
|
170 |
+
global $wpdb;
|
171 |
+
//Resynch is expensive in terms of DB performance. Thus we only do it once, processing
|
172 |
+
//all post types in one go and ignoring any further resynch requests during this pageload.
|
173 |
+
//BUG: This might be a problem if there ever is an actual need to run resynch twice or
|
174 |
+
//more per pageload.
|
175 |
+
if ( $this->resynch_already_done ){
|
176 |
+
return;
|
177 |
+
}
|
178 |
+
|
179 |
+
if ( empty($this->enabled_post_types) ){
|
180 |
+
return;
|
181 |
+
}
|
182 |
+
|
183 |
+
$escaped_post_types = array_map(array(&$wpdb, 'escape'), $this->enabled_post_types);
|
184 |
+
$escaped_post_statuses = array_map(array(&$wpdb, 'escape'), $this->enabled_post_statuses);
|
185 |
+
|
186 |
+
if ( $forced ){
|
187 |
+
//Create new synchronization records for all posts.
|
188 |
+
$q = "INSERT INTO {$wpdb->prefix}blc_synch(container_id, container_type, synched)
|
189 |
+
SELECT posts.id, posts.post_type, 0
|
190 |
+
FROM {$wpdb->posts} AS posts
|
191 |
+
WHERE
|
192 |
+
posts.post_status IN (%s)
|
193 |
+
AND posts.post_type IN (%s)";
|
194 |
+
$q = sprintf(
|
195 |
+
$q,
|
196 |
+
"'" . implode("', '", $escaped_post_statuses) . "'",
|
197 |
+
"'" . implode("', '", $escaped_post_types) . "'"
|
198 |
+
);
|
199 |
+
$wpdb->query( $q );
|
200 |
+
} else {
|
201 |
+
//Delete synch records corresponding to posts that no longer exist.
|
202 |
+
$q = "DELETE synch.*
|
203 |
+
FROM
|
204 |
+
{$wpdb->prefix}blc_synch AS synch LEFT JOIN {$wpdb->posts} AS posts
|
205 |
+
ON posts.ID = synch.container_id
|
206 |
+
WHERE
|
207 |
+
synch.container_type IN (%s) AND posts.ID IS NULL";
|
208 |
+
$q = sprintf(
|
209 |
+
$q,
|
210 |
+
"'" . implode("', '", $escaped_post_types) . "'"
|
211 |
+
);
|
212 |
+
$wpdb->query( $q );
|
213 |
+
|
214 |
+
//Remove the 'synched' flag from all posts that have been updated
|
215 |
+
//since the last time they were parsed/synchronized.
|
216 |
+
$q = "UPDATE
|
217 |
+
{$wpdb->prefix}blc_synch AS synch
|
218 |
+
JOIN {$wpdb->posts} AS posts ON (synch.container_id = posts.ID and synch.container_type=posts.post_type)
|
219 |
+
SET
|
220 |
+
synched = 0
|
221 |
+
WHERE
|
222 |
+
synch.last_synch < posts.post_modified";
|
223 |
+
$wpdb->query( $q );
|
224 |
+
|
225 |
+
//Create synch. records for posts that don't have them.
|
226 |
+
$q = "INSERT INTO {$wpdb->prefix}blc_synch(container_id, container_type, synched)
|
227 |
+
SELECT posts.id, posts.post_type, 0
|
228 |
+
FROM
|
229 |
+
{$wpdb->posts} AS posts LEFT JOIN {$wpdb->prefix}blc_synch AS synch
|
230 |
+
ON (synch.container_id = posts.ID and synch.container_type=posts.post_type)
|
231 |
+
WHERE
|
232 |
+
posts.post_status IN (%s)
|
233 |
+
AND posts.post_type IN (%s)
|
234 |
+
AND synch.container_id IS NULL";
|
235 |
+
$q = sprintf(
|
236 |
+
$q,
|
237 |
+
"'" . implode("', '", $escaped_post_statuses) . "'",
|
238 |
+
"'" . implode("', '", $escaped_post_types) . "'"
|
239 |
+
);
|
240 |
+
$wpdb->query($q);
|
241 |
+
}
|
242 |
+
|
243 |
+
$this->resynch_already_done = true;
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* Hook for the 'the_content' filter. Scans the current post and adds the 'broken_link'
|
248 |
+
* CSS class to all links that are known to be broken. Currently works only on standard
|
249 |
+
* HTML links (i.e. the '<a href=...' kind).
|
250 |
+
*
|
251 |
+
* @param string $content Post content
|
252 |
+
* @return string Modified post content.
|
253 |
+
*/
|
254 |
+
function hook_the_content($content){
|
255 |
+
global $post, $wpdb;
|
256 |
+
if ( empty($post) || !in_array($post->post_type, $this->enabled_post_types)) {
|
257 |
+
return $content;
|
258 |
+
}
|
259 |
+
|
260 |
+
//Retrieve info about all occurences of broken links in the current post
|
261 |
+
$q = "
|
262 |
+
SELECT instances.raw_url
|
263 |
+
FROM {$wpdb->prefix}blc_instances AS instances JOIN {$wpdb->prefix}blc_links AS links
|
264 |
+
ON instances.link_id = links.link_id
|
265 |
+
WHERE
|
266 |
+
instances.container_type = %s
|
267 |
+
AND instances.container_id = %d
|
268 |
+
AND links.broken = 1
|
269 |
+
AND parser_type = 'link'
|
270 |
+
";
|
271 |
+
$q = $wpdb->prepare($q, $post->post_type, $post->ID);
|
272 |
+
$links = $wpdb->get_results($q, ARRAY_A);
|
273 |
+
|
274 |
+
//Return the content unmodified if there are no broken links in this post.
|
275 |
+
if ( empty($links) || !is_array($links) ){
|
276 |
+
return $content;
|
277 |
+
}
|
278 |
+
|
279 |
+
//Put the broken link URLs in an array
|
280 |
+
$broken_link_urls = array();
|
281 |
+
foreach($links as $link){
|
282 |
+
$broken_link_urls[] = $link['raw_url'];
|
283 |
+
}
|
284 |
+
|
285 |
+
//Iterate over all HTML links and modify the broken ones
|
286 |
+
if ( $parser = & blcParserHelper::get_parser('link') ){
|
287 |
+
$content = $parser->multi_edit($content, array(&$this, 'highlight_broken_link'), $broken_link_urls);
|
288 |
+
}
|
289 |
+
|
290 |
+
return $content;
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* Analyse a link and add 'broken_link' CSS class if the link is broken.
|
295 |
+
*
|
296 |
+
* @see blcHtmlLink::multi_edit()
|
297 |
+
*
|
298 |
+
* @param array $link Associative array of link data.
|
299 |
+
* @param array $broken_link_urls List of broken link URLs present in the current post.
|
300 |
+
* @return array|string The modified link
|
301 |
+
*/
|
302 |
+
function highlight_broken_link($link, $broken_link_urls){
|
303 |
+
if ( !in_array($link['href'], $broken_link_urls) ){
|
304 |
+
//Link not broken = return the original link tag
|
305 |
+
return $link['#raw'];
|
306 |
+
}
|
307 |
+
|
308 |
+
//Add 'broken_link' to the 'class' attribute (unless already present).
|
309 |
+
if ( $this->plugin_conf->options['mark_broken_links'] ){
|
310 |
+
if ( isset($link['class']) ){
|
311 |
+
$classes = explode(' ', $link['class']);
|
312 |
+
if ( !in_array('broken_link', $classes) ){
|
313 |
+
$classes[] = 'broken_link';
|
314 |
+
$link['class'] = implode(' ', $classes);
|
315 |
+
}
|
316 |
+
} else {
|
317 |
+
$link['class'] = 'broken_link';
|
318 |
+
}
|
319 |
+
}
|
320 |
+
|
321 |
+
//Nofollow the link (unless it's already nofollow'ed)
|
322 |
+
if ( $this->plugin_conf->options['nofollow_broken_links'] ){
|
323 |
+
if ( isset($link['rel']) ){
|
324 |
+
$relations = explode(' ', $link['rel']);
|
325 |
+
if ( !in_array('nofollow', $relations) ){
|
326 |
+
$relations[] = 'nofollow';
|
327 |
+
$link['rel'] = implode(' ', $relations);
|
328 |
+
}
|
329 |
+
} else {
|
330 |
+
$link['rel'] = 'nofollow';
|
331 |
+
}
|
332 |
+
}
|
333 |
+
|
334 |
+
return $link;
|
335 |
+
}
|
336 |
+
|
337 |
+
/**
|
338 |
+
* A hook for the 'wp_head' action. Outputs the user-defined broken link CSS.
|
339 |
+
*
|
340 |
+
* @return void
|
341 |
+
*/
|
342 |
+
function hook_wp_head(){
|
343 |
+
echo '<style type="text/css">',$this->plugin_conf->options['broken_link_css'],'</style>';
|
344 |
+
}
|
345 |
+
}
|
346 |
+
|
347 |
+
//Start up the post overlord
|
348 |
+
blcPostTypeOverlord::getInstance();
|
349 |
+
|
350 |
+
|
351 |
+
/**
|
352 |
+
* Universal container item class used for all post types.
|
353 |
+
*
|
354 |
+
* @package Broken Link Checker
|
355 |
+
* @author Janis Elsts
|
356 |
+
* @access public
|
357 |
+
*/
|
358 |
+
class blcAnyPostContainer extends blcContainer {
|
359 |
+
var $default_field = 'post_content';
|
360 |
+
|
361 |
+
/**
|
362 |
+
* Get action links for this post.
|
363 |
+
*
|
364 |
+
* @param string $container_field Ignored.
|
365 |
+
* @return array of action link HTML.
|
366 |
+
*/
|
367 |
+
function ui_get_action_links($container_field = ''){
|
368 |
+
$actions = array();
|
369 |
+
|
370 |
+
//Fetch the post (it should be cached already)
|
371 |
+
$post = &$this->get_wrapped_object();
|
372 |
+
if ( !$post ){
|
373 |
+
return $actions;
|
374 |
+
}
|
375 |
+
|
376 |
+
$post_type_object = get_post_type_object($post->post_type);
|
377 |
+
|
378 |
+
//Each post type can have its own cap requirements
|
379 |
+
if ( current_user_can( $post_type_object->cap->edit_post, $this->container_id ) ){
|
380 |
+
$actions['edit'] = sprintf(
|
381 |
+
'<span class="edit"><a href="%s" title="%s">%s</a>',
|
382 |
+
$this->get_edit_url(),
|
383 |
+
$post_type_object->labels->edit_item,
|
384 |
+
__('Edit')
|
385 |
+
);
|
386 |
+
|
387 |
+
//Trash/Delete link
|
388 |
+
if ( current_user_can( $post_type_object->cap->delete_post, $this->container_id ) ){
|
389 |
+
if ( $this->can_be_trashed() ) {
|
390 |
+
$actions['trash'] = sprintf(
|
391 |
+
"<span class='trash'><a class='submitdelete' title='%s' href='%s'>%s</a>",
|
392 |
+
esc_attr(__('Move this item to the Trash')),
|
393 |
+
get_delete_post_link($this->container_id, '', false),
|
394 |
+
__('Trash')
|
395 |
+
);
|
396 |
+
} else {
|
397 |
+
$actions['delete'] = sprintf(
|
398 |
+
"<span><a class='submitdelete' title='%s' href='%s'>%s</a>",
|
399 |
+
esc_attr(__('Delete this item permanently')),
|
400 |
+
get_delete_post_link($this->container_id, '', true),
|
401 |
+
__('Delete')
|
402 |
+
);
|
403 |
+
}
|
404 |
+
}
|
405 |
+
}
|
406 |
+
|
407 |
+
//View/Preview link
|
408 |
+
$title = get_the_title($this->container_id);
|
409 |
+
if ( in_array($post->post_status, array('pending', 'draft')) ) {
|
410 |
+
if ( current_user_can($post_type_object->cap->edit_post, $this->container_id) ){
|
411 |
+
$actions['view'] = sprintf(
|
412 |
+
'<span class="view"><a href="%s" title="%s" rel="permalink">%s</a>',
|
413 |
+
esc_url( add_query_arg( 'preview', 'true', get_permalink($this->container_id) ) ),
|
414 |
+
esc_attr(sprintf(__('Preview “%s”'), $title)),
|
415 |
+
__('Preview')
|
416 |
+
);
|
417 |
+
}
|
418 |
+
} elseif ( 'trash' != $post->post_status ) {
|
419 |
+
$actions['view'] = sprintf(
|
420 |
+
'<span class="view"><a href="%s" title="%s" rel="permalink">%s</a>',
|
421 |
+
esc_url( get_permalink($this->container_id) ),
|
422 |
+
esc_attr(sprintf(__('View “%s”'), $title)),
|
423 |
+
__('View')
|
424 |
+
);
|
425 |
+
}
|
426 |
+
|
427 |
+
return $actions;
|
428 |
+
}
|
429 |
+
|
430 |
+
/**
|
431 |
+
* Get the HTML for displaying the post title in the "Source" column.
|
432 |
+
*
|
433 |
+
* @param string $container_field Ignored.
|
434 |
+
* @param string $context How to filter the output. Optional, defaults to 'display'.
|
435 |
+
* @return string HTML
|
436 |
+
*/
|
437 |
+
function ui_get_source($container_field = '', $context = 'display'){
|
438 |
+
$source = '<a class="row-title" href="%s" title="%s">%s</a>';
|
439 |
+
$source = sprintf(
|
440 |
+
$source,
|
441 |
+
$this->get_edit_url(),
|
442 |
+
esc_attr(__('Edit this item')),
|
443 |
+
get_the_title($this->container_id)
|
444 |
+
);
|
445 |
+
|
446 |
+
return $source;
|
447 |
+
}
|
448 |
+
|
449 |
+
/**
|
450 |
+
* Get edit URL for this container. Returns the URL of the Dashboard page where the item
|
451 |
+
* associated with this container can be edited.
|
452 |
+
*
|
453 |
+
* @access protected
|
454 |
+
*
|
455 |
+
* @return string
|
456 |
+
*/
|
457 |
+
function get_edit_url(){
|
458 |
+
/*
|
459 |
+
The below is a near-exact copy of the get_post_edit_link() function.
|
460 |
+
Unfortunately we can't just call that function because it has a hardcoded
|
461 |
+
caps-check which fails when called from the email notification script
|
462 |
+
executed by Cron.
|
463 |
+
*/
|
464 |
+
|
465 |
+
if ( !$post = &$this->get_wrapped_object() ){
|
466 |
+
return '';
|
467 |
+
}
|
468 |
+
|
469 |
+
$context = 'display';
|
470 |
+
$action = '&action=edit';
|
471 |
+
|
472 |
+
$post_type_object = get_post_type_object( $post->post_type );
|
473 |
+
if ( !$post_type_object ){
|
474 |
+
return '';
|
475 |
+
}
|
476 |
+
|
477 |
+
return apply_filters( 'get_edit_post_link', admin_url( sprintf($post_type_object->_edit_link . $action, $post->ID) ), $post->ID, $context );
|
478 |
+
}
|
479 |
+
|
480 |
+
/**
|
481 |
+
* Retrieve the post associated with this container.
|
482 |
+
*
|
483 |
+
* @access protected
|
484 |
+
*
|
485 |
+
* @param bool $ensure_consistency Set this to true to ignore the cached $wrapped_object value and retrieve an up-to-date copy of the wrapped object from the DB (or WP's internal cache).
|
486 |
+
* @return object Post data.
|
487 |
+
*/
|
488 |
+
function &get_wrapped_object($ensure_consistency = false){
|
489 |
+
if( $ensure_consistency || is_null($this->wrapped_object) ){
|
490 |
+
$this->wrapped_object = &get_post($this->container_id);
|
491 |
+
}
|
492 |
+
return $this->wrapped_object;
|
493 |
+
}
|
494 |
+
|
495 |
+
/**
|
496 |
+
* Update the post associated with this container.
|
497 |
+
*
|
498 |
+
* @access protected
|
499 |
+
*
|
500 |
+
* @return bool|WP_Error True on success, an error if something went wrong.
|
501 |
+
*/
|
502 |
+
function update_wrapped_object(){
|
503 |
+
if ( is_null($this->wrapped_object) ){
|
504 |
+
return new WP_Error(
|
505 |
+
'no_wrapped_object',
|
506 |
+
__('Nothing to update', 'broken-link-checker')
|
507 |
+
);
|
508 |
+
}
|
509 |
+
|
510 |
+
$id = wp_update_post($this->wrapped_object);
|
511 |
+
if ( $id != 0 ){
|
512 |
+
return true;
|
513 |
+
} else {
|
514 |
+
return new WP_Error(
|
515 |
+
'update_failed',
|
516 |
+
sprintf(__('Updating post %d failed', 'broken-link-checker'), $this->container_id)
|
517 |
+
);
|
518 |
+
}
|
519 |
+
}
|
520 |
+
|
521 |
+
/**
|
522 |
+
* Get the base URL of the container. For posts, the post permalink is used
|
523 |
+
* as the base URL when normalizing relative links.
|
524 |
+
*
|
525 |
+
* @return string
|
526 |
+
*/
|
527 |
+
function base_url(){
|
528 |
+
return get_permalink($this->container_id);
|
529 |
+
}
|
530 |
+
|
531 |
+
/**
|
532 |
+
* Delete or trash the post corresponding to this container.
|
533 |
+
* Will always move to trash instead of deleting if trash is enabled.
|
534 |
+
*
|
535 |
+
* @return bool|WP_error
|
536 |
+
*/
|
537 |
+
function delete_wrapped_object(){
|
538 |
+
//Note that we don't need to delete the synch record and instances here -
|
539 |
+
//wp_delete_post()/wp_trash_post() will run the post_delete/trash hook,
|
540 |
+
//which will be caught by blcPostContainerManager, which will in turn
|
541 |
+
//delete anything that needs to be deleted.
|
542 |
+
if ( EMPTY_TRASH_DAYS ){
|
543 |
+
return $this->trash_wrapped_object();
|
544 |
+
} else {
|
545 |
+
if ( wp_delete_post($this->container_id, true) ){
|
546 |
+
return true;
|
547 |
+
} else {
|
548 |
+
return new WP_Error(
|
549 |
+
'delete_failed',
|
550 |
+
sprintf(
|
551 |
+
__('Failed to delete post "%s" (%d)', 'broken-link-checker'),
|
552 |
+
get_the_title($this->container_id),
|
553 |
+
$this->container_id
|
554 |
+
)
|
555 |
+
);
|
556 |
+
};
|
557 |
+
}
|
558 |
+
}
|
559 |
+
|
560 |
+
/**
|
561 |
+
* Move the post corresponding to this container to the Trash.
|
562 |
+
*
|
563 |
+
* @return bool|WP_Error
|
564 |
+
*/
|
565 |
+
function trash_wrapped_object(){
|
566 |
+
if ( !EMPTY_TRASH_DAYS ){
|
567 |
+
return new WP_Error(
|
568 |
+
'trash_disabled',
|
569 |
+
sprintf(
|
570 |
+
__('Can\'t move post "%s" (%d) to the trash because the trash feature is disabled', 'broken-link-checker'),
|
571 |
+
get_the_title($this->container_id),
|
572 |
+
$this->container_id
|
573 |
+
)
|
574 |
+
);
|
575 |
+
}
|
576 |
+
|
577 |
+
$post = &get_post($this->container_id);
|
578 |
+
if ( $post->post_status == 'trash' ){
|
579 |
+
//Prevent conflicts between post and custom field containers trying to trash the same post.
|
580 |
+
//BUG: Post and custom field containers shouldn't wrap the same object
|
581 |
+
return true;
|
582 |
+
}
|
583 |
+
|
584 |
+
if ( wp_trash_post($this->container_id) ){
|
585 |
+
return true;
|
586 |
+
} else {
|
587 |
+
return new WP_Error(
|
588 |
+
'trash_failed',
|
589 |
+
sprintf(
|
590 |
+
__('Failed to move post "%s" (%d) to the trash', 'broken-link-checker'),
|
591 |
+
get_the_title($this->container_id),
|
592 |
+
$this->container_id
|
593 |
+
)
|
594 |
+
);
|
595 |
+
};
|
596 |
+
}
|
597 |
+
|
598 |
+
/**
|
599 |
+
* Check if the current user can delete/trash this post.
|
600 |
+
*
|
601 |
+
* @return bool
|
602 |
+
*/
|
603 |
+
function current_user_can_delete(){
|
604 |
+
$post = &$this->get_wrapped_object();
|
605 |
+
$post_type_object = get_post_type_object($post->post_type);
|
606 |
+
return current_user_can( $post_type_object->cap->delete_post, $this->container_id );
|
607 |
+
}
|
608 |
+
|
609 |
+
function can_be_trashed(){
|
610 |
+
return defined('EMPTY_TRASH_DAYS') && EMPTY_TRASH_DAYS;
|
611 |
+
}
|
612 |
+
}
|
613 |
+
|
614 |
+
|
615 |
+
|
616 |
+
/**
|
617 |
+
* Universal manager usable for most post types.
|
618 |
+
*
|
619 |
+
* @package Broken Link Checker
|
620 |
+
* @access public
|
621 |
+
*/
|
622 |
+
class blcAnyPostContainerManager extends blcContainerManager {
|
623 |
+
var $container_class_name = 'blcAnyPostContainer';
|
624 |
+
var $fields = array('post_content' => 'html');
|
625 |
+
|
626 |
+
function init(){
|
627 |
+
parent::init();
|
628 |
+
|
629 |
+
//Notify the overlord that the post/container type that this instance is
|
630 |
+
//responsible for is enabled.
|
631 |
+
$overlord = &blcPostTypeOverlord::getInstance();
|
632 |
+
$overlord->post_type_enabled($this->container_type);
|
633 |
+
}
|
634 |
+
|
635 |
+
/**
|
636 |
+
* Instantiate multiple containers of the container type managed by this class.
|
637 |
+
*
|
638 |
+
* @param array $containers Array of assoc. arrays containing container data.
|
639 |
+
* @param string $purpose An optional code indicating how the retrieved containers will be used.
|
640 |
+
* @param bool $load_wrapped_objects Preload wrapped objects regardless of purpose.
|
641 |
+
*
|
642 |
+
* @return array of blcPostContainer indexed by "container_type|container_id"
|
643 |
+
*/
|
644 |
+
function get_containers($containers, $purpose = '', $load_wrapped_objects = false){
|
645 |
+
$containers = $this->make_containers($containers);
|
646 |
+
|
647 |
+
//Preload post data if it is likely to be useful later
|
648 |
+
$preload = $load_wrapped_objects || in_array($purpose, array(BLC_FOR_DISPLAY, BLC_FOR_PARSING));
|
649 |
+
if ( $preload ){
|
650 |
+
$post_ids = array();
|
651 |
+
foreach($containers as $container){
|
652 |
+
$post_ids[] = $container->container_id;
|
653 |
+
}
|
654 |
+
|
655 |
+
$args = array('include' => implode(',', $post_ids));
|
656 |
+
$posts = get_posts($args);
|
657 |
+
|
658 |
+
foreach($posts as $post){
|
659 |
+
$key = $this->container_type . '|' . $post->ID;
|
660 |
+
if ( isset($containers[$key]) ){
|
661 |
+
$containers[$key]->wrapped_object = $post;
|
662 |
+
}
|
663 |
+
}
|
664 |
+
}
|
665 |
+
|
666 |
+
return $containers;
|
667 |
+
}
|
668 |
+
|
669 |
+
/**
|
670 |
+
* Create or update synchronization records for all posts.
|
671 |
+
*
|
672 |
+
* @param bool $forced If true, assume that all synch. records are gone and will need to be recreated from scratch.
|
673 |
+
* @return void
|
674 |
+
*/
|
675 |
+
function resynch($forced = false){
|
676 |
+
$overlord = &blcPostTypeOverlord::getInstance();
|
677 |
+
$overlord->resynch($this->container_type, $forced);
|
678 |
+
}
|
679 |
+
|
680 |
+
/**
|
681 |
+
* Get the message to display after $n posts have been deleted.
|
682 |
+
*
|
683 |
+
* @param int $n Number of deleted posts.
|
684 |
+
* @return string A delete confirmation message, e.g. "5 posts were moved deleted"
|
685 |
+
*/
|
686 |
+
function ui_bulk_delete_message($n){
|
687 |
+
//Since the "Trash" feature has been introduced, calling wp_delete_post
|
688 |
+
//doesn't actually delete the post (unless you set force_delete to True),
|
689 |
+
//just moves it to the trash. So we pick the message accordingly.
|
690 |
+
//(If possible, BLC *always* moves to trash instead of deleting permanently.)
|
691 |
+
if ( function_exists('wp_trash_post') && EMPTY_TRASH_DAYS ){
|
692 |
+
return blcAnyPostContainerManager::ui_bulk_trash_message($n);
|
693 |
+
} else {
|
694 |
+
$post_type_object = get_post_type_object($this->container_type);
|
695 |
+
$type_name = '';
|
696 |
+
|
697 |
+
if ( $this->container_type == 'post' || is_null($post_type_object) ){
|
698 |
+
$delete_msg = _n("%d post deleted.", "%d posts deleted.", $n, 'broken-link-checker');
|
699 |
+
} elseif ( $this->container_type == 'page' ){
|
700 |
+
$delete_msg = _n("%d page deleted.", "%d pages deleted.", $n, 'broken-link-checker');
|
701 |
+
} else {
|
702 |
+
$delete_msg = _n('%d "%s" deleted.', '%d "%s" deleted.', $n, 'broken-link-checker');
|
703 |
+
$type_name = ($n == 1 ? $post_type_object->labels->singular_name : $post_type_object->labels->name);
|
704 |
+
}
|
705 |
+
return sprintf($delete_msg, $n, $type_name);
|
706 |
+
}
|
707 |
+
}
|
708 |
+
|
709 |
+
|
710 |
+
/**
|
711 |
+
* Get the message to display after $n posts have been trashed.
|
712 |
+
*
|
713 |
+
* @param int $n Number of deleted posts.
|
714 |
+
* @return string A confirmation message, e.g. "5 posts were moved to trash"
|
715 |
+
*/
|
716 |
+
function ui_bulk_trash_message($n){
|
717 |
+
$post_type_object = get_post_type_object($this->container_type);
|
718 |
+
$type_name = '';
|
719 |
+
|
720 |
+
if ( $this->container_type == 'post' || is_null($post_type_object) ){
|
721 |
+
$delete_msg = _n("%d post moved to the Trash.", "%d posts moved to the Trash.", $n, 'broken-link-checker');
|
722 |
+
} elseif ( $this->container_type == 'page' ){
|
723 |
+
$delete_msg = _n("%d page moved to the Trash.", "%d pages moved to the Trash.", $n, 'broken-link-checker');
|
724 |
+
} else {
|
725 |
+
$delete_msg = _n('%d "%s" moved to the Trash.', '%d "%s" moved to the Trash.', $n, 'broken-link-checker');
|
726 |
+
$type_name = ($n == 1 ? $post_type_object->labels->singular_name : $post_type_object->labels->name);
|
727 |
+
}
|
728 |
+
return sprintf($delete_msg, $n, $type_name);
|
729 |
+
}
|
730 |
+
}
|
731 |
+
|
732 |
+
?>
|
includes/checkers.php
CHANGED
@@ -8,7 +8,7 @@
|
|
8 |
* @package Broken Link Checker
|
9 |
* @access public
|
10 |
*/
|
11 |
-
class blcChecker {
|
12 |
|
13 |
/**
|
14 |
* Priority determines the order in which the plugin will try all registered checkers
|
@@ -63,33 +63,19 @@ class blcChecker {
|
|
63 |
}
|
64 |
}
|
65 |
|
66 |
-
class
|
67 |
-
var $registered_checkers = array();
|
68 |
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
}
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Callback for sorting checkers by priority.
|
84 |
-
*
|
85 |
-
* @access private
|
86 |
-
*
|
87 |
-
* @param blcChecker $a
|
88 |
-
* @param blcChecker $b
|
89 |
-
* @return int
|
90 |
-
*/
|
91 |
-
function compare_checkers($a, $b){
|
92 |
-
return $b->priority - $a->priority;
|
93 |
}
|
94 |
|
95 |
/**
|
@@ -101,7 +87,27 @@ class blcCheckerRegistry {
|
|
101 |
function &get_checker_for($url){
|
102 |
$parsed = @parse_url($url);
|
103 |
|
104 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
if ( $checker->can_check($url, $parsed) ){
|
106 |
return $checker;
|
107 |
}
|
@@ -110,27 +116,5 @@ class blcCheckerRegistry {
|
|
110 |
return null;
|
111 |
}
|
112 |
}
|
113 |
-
|
114 |
-
$GLOBALS['blc_checker_registry'] = new blcCheckerRegistry();
|
115 |
-
|
116 |
-
/**
|
117 |
-
* Register a new link checker.
|
118 |
-
*
|
119 |
-
* @param string $class_name
|
120 |
-
* @return void
|
121 |
-
*/
|
122 |
-
function blc_register_checker($class_name){
|
123 |
-
return $GLOBALS['blc_checker_registry']->register_checker($class_name);
|
124 |
-
}
|
125 |
-
|
126 |
-
/**
|
127 |
-
* Get the checker algo. implementation that knows how to check a specific URL.
|
128 |
-
*
|
129 |
-
* @param string $url The URL that needs to be checked.
|
130 |
-
* @return blcChecker|null
|
131 |
-
*/
|
132 |
-
function &blc_get_checker_for($url){
|
133 |
-
return $GLOBALS['blc_checker_registry']->get_checker_for($url);
|
134 |
-
}
|
135 |
-
|
136 |
?>
|
8 |
* @package Broken Link Checker
|
9 |
* @access public
|
10 |
*/
|
11 |
+
class blcChecker extends blcModule {
|
12 |
|
13 |
/**
|
14 |
* Priority determines the order in which the plugin will try all registered checkers
|
63 |
}
|
64 |
}
|
65 |
|
66 |
+
class blcCheckerHelper {
|
|
|
67 |
|
68 |
+
/**
|
69 |
+
* Get a reference to a specific checker.
|
70 |
+
*
|
71 |
+
* @uses blcModuleManager::get_module()
|
72 |
+
*
|
73 |
+
* @param string $checker_id
|
74 |
+
* @return blcChecker
|
75 |
+
*/
|
76 |
+
function &get_checker($checker_id){
|
77 |
+
$manager = & blcModuleManager::getInstance();
|
78 |
+
return $manager->get_module($checker_id, true, 'checker');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
}
|
80 |
|
81 |
/**
|
87 |
function &get_checker_for($url){
|
88 |
$parsed = @parse_url($url);
|
89 |
|
90 |
+
$manager = & blcModuleManager::getInstance();
|
91 |
+
$active_checkers = $manager->get_active_by_category('checker');
|
92 |
+
|
93 |
+
foreach($active_checkers as $module_id => $module_data){
|
94 |
+
//Try the URL pattern in the header first. If it doesn't match,
|
95 |
+
//we can avoid loading the module altogether.
|
96 |
+
if ( !empty($module_data['ModuleCheckerUrlPattern']) ){
|
97 |
+
if ( !preg_match($module_data['ModuleCheckerUrlPattern'], $url) ){
|
98 |
+
continue;
|
99 |
+
}
|
100 |
+
}
|
101 |
+
|
102 |
+
$checker = & $manager->get_module($module_id);
|
103 |
+
|
104 |
+
if ( !$checker ){
|
105 |
+
continue;
|
106 |
+
}
|
107 |
+
|
108 |
+
//The can_check() method can perform more sophisticated filtering,
|
109 |
+
//or just return true if the checker thinks matching the URL regex
|
110 |
+
//is sufficient.
|
111 |
if ( $checker->can_check($url, $parsed) ){
|
112 |
return $checker;
|
113 |
}
|
116 |
return null;
|
117 |
}
|
118 |
}
|
119 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
?>
|
config-manager.php → includes/config-manager.php
RENAMED
File without changes
|
includes/containers.php
CHANGED
@@ -1,298 +1,145 @@
|
|
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
-
*
|
5 |
-
*
|
6 |
-
*
|
7 |
-
* instantiate container objects. Mostly acts as a proxy between various container managers
|
8 |
-
* and the rest of plugin code. It does't know anything about how individual containers are
|
9 |
-
* implemented.
|
10 |
-
*
|
11 |
-
* Used as a singleton.
|
12 |
*
|
13 |
* @package Broken Link Checker
|
|
|
14 |
*/
|
15 |
-
class
|
16 |
|
17 |
-
var $
|
|
|
|
|
18 |
|
19 |
/**
|
20 |
-
*
|
21 |
*
|
|
|
|
|
|
|
22 |
* @return void
|
23 |
*/
|
24 |
-
function
|
25 |
-
|
|
|
|
|
26 |
}
|
27 |
|
28 |
/**
|
29 |
-
*
|
30 |
-
* Old-style class constructor
|
31 |
*
|
32 |
-
* @
|
|
|
33 |
*/
|
34 |
-
function
|
35 |
-
$this->
|
36 |
-
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Return a singleton instance of this class.
|
40 |
-
*
|
41 |
-
* @return blcContainerRegistry
|
42 |
-
*/
|
43 |
-
function &getInstance(){
|
44 |
-
static $instance = null;
|
45 |
-
if ( is_null($instance) ){
|
46 |
-
$instance = new blcContainerRegistry;
|
47 |
-
}
|
48 |
-
return $instance;
|
49 |
}
|
50 |
|
51 |
/**
|
52 |
-
*
|
53 |
-
*
|
54 |
-
* A "container type" comprises three things :
|
55 |
-
* - An alphanumeric container type name, e.g. "post"
|
56 |
-
* - A class representing an individual container. Must inherit from blcContainer.
|
57 |
-
* - A "manager" class that builds container objects, knows how to retrieve multiple
|
58 |
-
* containers and their associated data from the database, and handles all other
|
59 |
-
* ancillary tasks associated with the particular container type (e.g. WP hooks).
|
60 |
*
|
61 |
-
*
|
62 |
-
*
|
|
|
|
|
63 |
*
|
64 |
-
* @see blcContainer
|
65 |
-
* @see
|
|
|
66 |
*
|
67 |
-
* @param
|
68 |
-
* @param string $
|
69 |
-
* @
|
|
|
|
|
70 |
*/
|
71 |
-
function
|
72 |
-
|
73 |
-
return false;
|
74 |
-
}
|
75 |
-
|
76 |
-
$this->registered_managers[$container_type] = new $manager_class($container_type);
|
77 |
-
|
78 |
-
return true;
|
79 |
-
}
|
80 |
-
|
81 |
-
/**
|
82 |
-
* Retrieve a list of all registered container types and their managers.
|
83 |
-
*
|
84 |
-
* @return array An associative array of container manager objects indexed by container type.
|
85 |
-
*/
|
86 |
-
function get_registered_containers(){
|
87 |
-
return $this->registered_managers;
|
88 |
}
|
89 |
|
90 |
/**
|
91 |
-
*
|
92 |
*
|
93 |
-
* @param
|
94 |
-
* @
|
95 |
-
* @return blcContainerManager|null
|
96 |
*/
|
97 |
-
function
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
} else {
|
103 |
-
return null;
|
104 |
}
|
|
|
105 |
}
|
106 |
|
107 |
/**
|
108 |
-
*
|
109 |
*
|
110 |
-
*
|
111 |
-
* from the database. Alternatively, pass an associative array to create a new container object
|
112 |
-
* from the data in the array.
|
113 |
*
|
114 |
-
* @param
|
115 |
-
* @return
|
116 |
*/
|
117 |
-
function
|
118 |
-
|
119 |
-
|
120 |
-
if ( !is_array($container) || ( count($container) < 2 ) ){
|
121 |
-
return null;
|
122 |
-
}
|
123 |
-
|
124 |
-
if ( is_string($container[0]) && is_numeric($container[1]) ){
|
125 |
-
//The argument is in the [container_type, id] format
|
126 |
-
//Fetch the container's synch record.
|
127 |
-
$q = "SELECT * FROM {$wpdb->prefix}blc_synch WHERE container_type = %s AND container_id = %d";
|
128 |
-
$q = $wpdb->prepare($q, $container[0], $container[1]);
|
129 |
-
$rez = $wpdb->get_row($q, ARRAY_A);
|
130 |
-
|
131 |
-
if ( empty($rez) ){
|
132 |
-
//The container wasn't found, so we'll create a new one.
|
133 |
-
$container = array(
|
134 |
-
'container_type' => $container[0],
|
135 |
-
'container_id' => $container[1],
|
136 |
-
);
|
137 |
-
} else {
|
138 |
-
$container = $rez;
|
139 |
-
}
|
140 |
-
}
|
141 |
-
|
142 |
-
if ( !isset($this->registered_managers[$container['container_type']]) ){
|
143 |
-
return null;
|
144 |
-
}
|
145 |
-
|
146 |
-
$manager = $this->registered_managers[$container['container_type']];
|
147 |
-
|
148 |
-
return $manager->get_container($container);
|
149 |
}
|
150 |
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
* @param string $purpose Optional code indicating how the retrieved containers will be used.
|
162 |
-
* @param string $fallback The fallback container type to use for unrecognized containers.
|
163 |
-
* @param bool $load_wrapped_objects Preload wrapped objects regardless of purpose.
|
164 |
-
* @return array of blcContainer indexed by "container_type|container_id"
|
165 |
-
*/
|
166 |
-
function get_containers( $containers, $purpose = '', $fallback = '', $load_wrapped_objects = false ){
|
167 |
-
global $wpdb;
|
168 |
-
|
169 |
-
//If the input is invalid or empty, return an empty array.
|
170 |
-
if ( !is_array($containers) || (count($containers) < 1) ) {
|
171 |
-
return array();
|
172 |
-
}
|
173 |
-
|
174 |
-
$first = reset($containers);
|
175 |
-
if ( !is_array($first) ){
|
176 |
-
return array();
|
177 |
-
}
|
178 |
-
|
179 |
-
if ( isset($first[0]) && is_string($first[0]) && is_numeric($first[1]) ){
|
180 |
-
//The argument is an array of [container_type, id].
|
181 |
-
//Divide the container IDs by container type.
|
182 |
-
$by_type = array();
|
183 |
-
|
184 |
-
foreach($containers as $container){
|
185 |
-
if ( isset($by_type[$container[0]]) ){
|
186 |
-
array_push($by_type[$container[0]], intval($container[1]));
|
187 |
-
} else {
|
188 |
-
$by_type[$container[0]] = array( intval($container[1]) );
|
189 |
-
}
|
190 |
-
}
|
191 |
-
|
192 |
-
//Build the SQL to fetch all the specified containers
|
193 |
-
$q = "SELECT *
|
194 |
-
FROM {$wpdb->prefix}blc_synch
|
195 |
-
WHERE";
|
196 |
-
|
197 |
-
$pieces = array();
|
198 |
-
foreach($by_type as $container_type => $container_ids){
|
199 |
-
$pieces[] = '( container_type = "'. $wpdb->escape($container_type) .'" AND container_id IN ('. implode(', ', $container_ids) .') )';
|
200 |
-
}
|
201 |
-
|
202 |
-
$q .= implode("\n\t OR ", $pieces);
|
203 |
-
|
204 |
-
//Fetch the container synch. records from the DB.
|
205 |
-
$containers = $wpdb->get_results($q, ARRAY_A);
|
206 |
-
}
|
207 |
-
|
208 |
-
/*
|
209 |
-
Divide the inputs into separate arrays by container type (again), then invoke
|
210 |
-
the appropriate manager for each type to instantiate the container objects.
|
211 |
-
*/
|
212 |
-
|
213 |
-
//At this point, $containers is an array of assoc. arrays comprising container data.
|
214 |
-
$by_type = array();
|
215 |
-
foreach($containers as $container){
|
216 |
-
if ( isset($by_type[$container['container_type']]) ){
|
217 |
-
array_push($by_type[$container['container_type']], $container);
|
218 |
-
} else {
|
219 |
-
$by_type[$container['container_type']] = array($container);
|
220 |
-
}
|
221 |
-
}
|
222 |
-
|
223 |
-
$results = array();
|
224 |
-
foreach($by_type as $container_type => $entries){
|
225 |
-
$manager = & $this->get_manager($container_type, $fallback);
|
226 |
-
if ( !is_null($manager) ){
|
227 |
-
$partial_results = $manager->get_containers($entries, $purpose, $load_wrapped_objects);
|
228 |
-
$results = array_merge($results, $partial_results);
|
229 |
-
}
|
230 |
-
}
|
231 |
-
|
232 |
-
return $results;
|
233 |
}
|
234 |
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
global $wpdb;
|
243 |
-
|
244 |
-
$q = "SELECT * FROM {$wpdb->prefix}blc_synch WHERE synched = 0";
|
245 |
-
if ( $max_results > 0 ){
|
246 |
-
$q .= " LIMIT $max_results";
|
247 |
-
}
|
248 |
-
|
249 |
-
$container_data = $wpdb->get_results($q, ARRAY_A);
|
250 |
-
//FB::log($container_data, "Unsynched containers");
|
251 |
-
if( empty($container_data) ){
|
252 |
-
return array();
|
253 |
-
}
|
254 |
-
|
255 |
-
$containers = $this->get_containers($container_data, BLC_FOR_PARSING, 'dummy');
|
256 |
-
return $containers;
|
257 |
}
|
258 |
|
259 |
/**
|
260 |
-
*
|
261 |
-
* Calls the resynch() method of all registered managers.
|
262 |
*
|
263 |
-
* @param
|
264 |
-
* @return
|
265 |
*/
|
266 |
-
function
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
|
|
|
|
|
|
|
|
|
|
272 |
}
|
273 |
|
274 |
/**
|
275 |
-
* Get the message to display after $n containers
|
276 |
*
|
277 |
-
* @param
|
278 |
-
* @param int $n Number of deleted containers.
|
279 |
* @return string A delete confirmation message, e.g. "5 posts were moved to trash"
|
280 |
*/
|
281 |
-
function
|
282 |
-
|
283 |
-
if ( is_null($manager) ){
|
284 |
-
return sprintf(__("Container type '%s' not recognized", 'broken-link-checker'), $container_type);
|
285 |
-
} else {
|
286 |
-
return $manager->ui_bulk_delete_message($n);
|
287 |
-
}
|
288 |
}
|
289 |
}
|
290 |
|
291 |
-
//Init the container registry & make it global
|
292 |
-
$GLOBALS['blc_container_registry'] = & blcContainerRegistry::getInstance();
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
/**
|
297 |
* The base class for link containers. All containers should extend this class.
|
298 |
*
|
@@ -423,7 +270,7 @@ class blcContainer {
|
|
423 |
//FB::log($name, "Parsing field");
|
424 |
|
425 |
//Get all parsers applicable to this field
|
426 |
-
$parsers =
|
427 |
//FB::log($parsers, "Applicable parsers");
|
428 |
|
429 |
if ( empty($parsers) ) continue;
|
@@ -562,7 +409,7 @@ class blcContainer {
|
|
562 |
}
|
563 |
|
564 |
/**
|
565 |
-
* Delete the WP entity corresponding to this container.
|
566 |
* Also remove the synch. record of the container and all associated instances.
|
567 |
*
|
568 |
* Must be over-ridden in a sub-class.
|
@@ -571,10 +418,43 @@ class blcContainer {
|
|
571 |
*/
|
572 |
function delete_wrapped_object(){
|
573 |
trigger_error('Function blcContainer::delete_wrapped_object() must be over-ridden in a sub-class', E_USER_ERROR);
|
574 |
-
}
|
575 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
576 |
|
577 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
578 |
* Change all links with the specified URL to a new URL.
|
579 |
*
|
580 |
* @param string $field_name
|
@@ -582,7 +462,7 @@ class blcContainer {
|
|
582 |
* @param string $new_url
|
583 |
* @param string $old_url
|
584 |
* @param string $old_raw_url
|
585 |
-
* @return
|
586 |
*/
|
587 |
function edit_link($field_name, $parser, $new_url, $old_url = '', $old_raw_url = ''){
|
588 |
//Ensure we're operating on a consistent copy of the wrapped object.
|
@@ -614,15 +494,16 @@ class blcContainer {
|
|
614 |
if ( is_wp_error($edit_result) ){
|
615 |
return $edit_result;
|
616 |
}
|
617 |
-
|
618 |
//Update the field with the new value returned by the parser.
|
619 |
$update_result = $this->update_field( $field_name, $edit_result['content'], $old_value );
|
620 |
if ( is_wp_error($update_result) ){
|
621 |
return $update_result;
|
622 |
}
|
623 |
|
624 |
-
//Return the new
|
625 |
-
|
|
|
626 |
}
|
627 |
|
628 |
/**
|
@@ -634,7 +515,7 @@ class blcContainer {
|
|
634 |
* @param string $raw_url
|
635 |
* @return bool|WP_Error True on success, or an error object if something went wrong.
|
636 |
*/
|
637 |
-
function unlink($field_name,
|
638 |
//Ensure we're operating on a consistent copy of the wrapped object.
|
639 |
$this->get_wrapped_object(true);
|
640 |
|
@@ -699,232 +580,322 @@ class blcContainer {
|
|
699 |
//Should be over-ridden in a sub-class.
|
700 |
return '';
|
701 |
}
|
|
|
702 |
}
|
703 |
|
|
|
704 |
/**
|
705 |
-
*
|
706 |
-
*
|
707 |
-
*
|
708 |
-
*
|
709 |
* @package Broken Link Checker
|
710 |
-
* @access public
|
711 |
*/
|
712 |
-
class
|
713 |
-
|
714 |
-
var $container_type = '';
|
715 |
-
var $container_class_name = 'blcContainer';
|
716 |
-
|
717 |
-
function __construct($container_type){
|
718 |
-
$this->container_type = $container_type;
|
719 |
-
$this->init();
|
720 |
-
}
|
721 |
|
722 |
/**
|
723 |
-
*
|
724 |
-
* Old-style class constructor
|
725 |
*
|
726 |
-
* @
|
|
|
|
|
727 |
*/
|
728 |
-
function
|
729 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
730 |
}
|
731 |
|
732 |
/**
|
733 |
-
*
|
734 |
*
|
735 |
-
*
|
736 |
-
*
|
737 |
-
*
|
738 |
-
*
|
739 |
-
* @return void
|
740 |
-
*/
|
741 |
-
function init(){
|
742 |
-
//Do nothing. Sub-classes might use it to set up hooks, etc.
|
743 |
-
}
|
744 |
-
|
745 |
-
/**
|
746 |
-
* Instantiate a link container.
|
747 |
*
|
748 |
-
* @param array $container
|
749 |
-
* @return blcContainer
|
750 |
*/
|
751 |
-
function get_container($container){
|
752 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
753 |
}
|
754 |
|
755 |
/**
|
756 |
-
*
|
757 |
-
* pre-load container data used for display/parsing.
|
758 |
*
|
759 |
-
*
|
760 |
-
*
|
761 |
-
*
|
762 |
-
* container will need in blcContainer::ui_get_source().
|
763 |
*
|
764 |
-
* @see
|
765 |
-
* @see blcContainer::ui_get_source()
|
766 |
-
* @see blcContainer::ui_get_action_links()
|
767 |
*
|
768 |
-
* @param array $containers
|
769 |
-
* @param string $purpose
|
770 |
-
* @param
|
771 |
-
*
|
772 |
* @return array of blcContainer indexed by "container_type|container_id"
|
773 |
*/
|
774 |
-
function get_containers($containers, $purpose = '', $load_wrapped_objects = false){
|
775 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
776 |
}
|
777 |
|
778 |
/**
|
779 |
-
*
|
780 |
*
|
781 |
-
* @param
|
782 |
-
* @return array of blcContainer
|
783 |
*/
|
784 |
-
function
|
785 |
-
$
|
786 |
-
|
787 |
-
|
788 |
-
|
|
|
789 |
}
|
790 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
791 |
}
|
792 |
|
793 |
/**
|
794 |
-
*
|
795 |
-
*
|
796 |
-
* Must be over-ridden in subclasses.
|
797 |
*
|
798 |
-
* @param bool $forced If true, assume that
|
799 |
* @return void
|
800 |
*/
|
801 |
function resynch($forced = false){
|
802 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
803 |
}
|
804 |
|
805 |
/**
|
806 |
-
* Get the message to display after $n containers have been deleted.
|
807 |
*
|
|
|
808 |
* @param int $n Number of deleted containers.
|
809 |
* @return string A delete confirmation message, e.g. "5 posts were moved to trash"
|
810 |
*/
|
811 |
-
function ui_bulk_delete_message($n){
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
),
|
819 |
-
$n,
|
820 |
-
$this->container_type
|
821 |
-
);
|
822 |
}
|
823 |
-
}
|
824 |
-
|
825 |
-
/**
|
826 |
-
* Register a new link container.
|
827 |
-
*
|
828 |
-
* Each container type is implemented by two related classes - the container manager class, and the
|
829 |
-
* container class itself. The container manager handles tasks like creating new instances of the container
|
830 |
-
* class, loading & filtering them to the database, handling WordPress hooks relevant to the container
|
831 |
-
* type, and so on. The container class handles the synchronization, parsing and modification of
|
832 |
-
* individual link containers (e.g. posts or comments).
|
833 |
-
*
|
834 |
-
* @see blcContainer
|
835 |
-
* @see blcContainerManager
|
836 |
-
*
|
837 |
-
* @param string $container_type A unique string identifying the container, e.g. "post" or "comment".
|
838 |
-
* @param string $manager_class Class name of the container manager corresponding to the container type you want to register.
|
839 |
-
* @return bool True if the container was successfully registered, false otherwise.
|
840 |
-
*/
|
841 |
-
function blc_register_container( $container_type, $manager_class ){
|
842 |
-
$instance = & blcContainerRegistry::getInstance();
|
843 |
-
return $instance->register_container($container_type, $manager_class);
|
844 |
-
}
|
845 |
-
|
846 |
-
/**
|
847 |
-
* Retrieve or create a link container.
|
848 |
-
*
|
849 |
-
* @param array $container Either (container type, id), or an assoc. array of container data.
|
850 |
-
* @return blcContainer|null Returns null if the container type is unrecognized.
|
851 |
-
*/
|
852 |
-
function blc_get_container($container){
|
853 |
-
$instance = & blcContainerRegistry::getInstance();
|
854 |
-
return $instance->get_container($container);
|
855 |
-
}
|
856 |
-
|
857 |
-
/**
|
858 |
-
* Retrieve multiple link containers.
|
859 |
-
*
|
860 |
-
* If you specify the optional $purpose argument, the relevant container managers might be
|
861 |
-
* able to use it to (pre)load container data more efficiently - e.g. loading all posts associated
|
862 |
-
* with the selected batch of containers in one go, instead of running a separate DB query for
|
863 |
-
* each individual container later.
|
864 |
-
*
|
865 |
-
* There are several predefined constants that can be used for the $purpose argument :
|
866 |
-
* BLC_FOR_EDITING, BLC_FOR_PARSING, BLC_FOR_DISPLAY
|
867 |
-
*
|
868 |
-
* For containers not found in the DB, the behaviour of this function depends on the format
|
869 |
-
* of the $containers argument. If $containers is an array of [container_type, container_id] pairs,
|
870 |
-
* only existing containers will be returned. If it's an array of assoc. arrays specifying container
|
871 |
-
* data, the function will create and return container objects for all specified containers.
|
872 |
-
*
|
873 |
-
* @see blc_get_container()
|
874 |
-
*
|
875 |
-
* @param array $containers Array of (container_type, id) pairs, or assoc. arrays with container data.
|
876 |
-
* @param string $purpose Optional code indicating how the retrieved containers are going to be used.
|
877 |
-
* @param bool $load_wrapped_objects Preload wrapped objects regardless of purpose.
|
878 |
-
* @return array of blcContainer indexed by 'container_type|container_id'
|
879 |
-
*/
|
880 |
-
function blc_get_containers( $containers, $purpose = '', $load_wrapped_objects = false ){
|
881 |
-
$instance = & blcContainerRegistry::getInstance();
|
882 |
-
return $instance->get_containers($containers, $purpose, '', $load_wrapped_objects);
|
883 |
-
}
|
884 |
-
|
885 |
-
/**
|
886 |
-
* Retrieve link containers that need to be synchronized (parsed).
|
887 |
-
*
|
888 |
-
* @param integer $max_results The maximum number of containers to return. Defaults to returning all unsynched containers.
|
889 |
-
* @return array of blcContainer
|
890 |
-
*/
|
891 |
-
function blc_get_unsynched_containers($max_results = 0){
|
892 |
-
$instance = & blcContainerRegistry::getInstance();
|
893 |
-
return $instance->get_unsynched_containers($max_results);
|
894 |
-
}
|
895 |
-
|
896 |
-
/**
|
897 |
-
* (Re)create and update synchronization records for all supported containers.
|
898 |
-
* Calls the resynch() method of all registered managers.
|
899 |
-
*
|
900 |
-
* @param bool $forced If true, assume that no synch. records exist and build all of them from scratch.
|
901 |
-
* @return void
|
902 |
-
*/
|
903 |
-
function blc_resynch_containers($forced = false){
|
904 |
-
$instance = & blcContainerRegistry::getInstance();
|
905 |
-
$instance->resynch($forced);
|
906 |
-
}
|
907 |
-
|
908 |
-
/**
|
909 |
-
* Remove synch. records that reference container types not currently loaded
|
910 |
-
*
|
911 |
-
* @return bool
|
912 |
-
*/
|
913 |
-
function blc_cleanup_containers(){
|
914 |
-
global $wpdb;
|
915 |
-
|
916 |
-
$containerRegistry = & blcContainerRegistry::getInstance();
|
917 |
-
$loaded_containers = array_keys($containerRegistry->get_registered_containers());
|
918 |
-
$loaded_containers = array_map(array(&$wpdb, 'escape'), $loaded_containers);
|
919 |
-
$loaded_containers = "'" . implode("', '", $loaded_containers) . "'";
|
920 |
-
|
921 |
-
$q = "DELETE synch.*
|
922 |
-
FROM {$wpdb->prefix}blc_synch AS synch
|
923 |
-
WHERE
|
924 |
-
synch.container_type NOT IN ({$loaded_containers})";
|
925 |
-
$rez = $wpdb->query($q);
|
926 |
|
927 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
928 |
}
|
929 |
|
930 |
?>
|
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
+
* The base class for link container managers.
|
5 |
+
*
|
6 |
+
* Sub-classes should override at least the get_containers() and resynch() methods.
|
|
|
|
|
|
|
|
|
|
|
7 |
*
|
8 |
* @package Broken Link Checker
|
9 |
+
* @access public
|
10 |
*/
|
11 |
+
class blcContainerManager extends blcModule {
|
12 |
|
13 |
+
var $container_type = '';
|
14 |
+
var $fields = array();
|
15 |
+
var $container_class_name = 'blcContainer';
|
16 |
|
17 |
/**
|
18 |
+
* Do whatever setup necessary that wasn't already done in the constructor.
|
19 |
*
|
20 |
+
* This method was added so that sub-classes would have something "safe" to
|
21 |
+
* over-ride without having to deal with PHP4/5 constructors.
|
22 |
+
*
|
23 |
* @return void
|
24 |
*/
|
25 |
+
function init(){
|
26 |
+
parent::init();
|
27 |
+
$this->container_type = $this->module_id;
|
28 |
+
//Sub-classes might also use it to set up hooks, etc.
|
29 |
}
|
30 |
|
31 |
/**
|
32 |
+
* Instantiate a link container.
|
|
|
33 |
*
|
34 |
+
* @param array $container An associative array of container data.
|
35 |
+
* @return blcContainer
|
36 |
*/
|
37 |
+
function &get_container($container){
|
38 |
+
$container['fields'] = $this->get_parseable_fields();
|
39 |
+
return new $this->container_class_name($container);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
}
|
41 |
|
42 |
/**
|
43 |
+
* Instantiate multiple containers of the container type managed by this class and optionally
|
44 |
+
* pre-load container data used for display/parsing.
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
*
|
46 |
+
* Sub-classes should, if possible, use the $purpose argument to pre-load any extra data required for
|
47 |
+
* the specified task right away, instead of making multiple DB roundtrips later. For example, if
|
48 |
+
* $purpose is set to the BLC_FOR_DISPLAY constant, you might want to preload any DB data that the
|
49 |
+
* container will need in blcContainer::ui_get_source().
|
50 |
*
|
51 |
+
* @see blcContainer::make_containers()
|
52 |
+
* @see blcContainer::ui_get_source()
|
53 |
+
* @see blcContainer::ui_get_action_links()
|
54 |
*
|
55 |
+
* @param array $containers Array of assoc. arrays containing container data.
|
56 |
+
* @param string $purpose An optional code indicating how the retrieved containers will be used.
|
57 |
+
* @param bool $load_wrapped_objects Preload wrapped objects regardless of purpose.
|
58 |
+
*
|
59 |
+
* @return array of blcContainer indexed by "container_type|container_id"
|
60 |
*/
|
61 |
+
function get_containers($containers, $purpose = '', $load_wrapped_objects = false){
|
62 |
+
return $this->make_containers($containers);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
}
|
64 |
|
65 |
/**
|
66 |
+
* Instantiate multiple containers of the container type managed by this class
|
67 |
*
|
68 |
+
* @param array $containers Array of assoc. arrays containing container data.
|
69 |
+
* @return array of blcContainer indexed by "container_type|container_id"
|
|
|
70 |
*/
|
71 |
+
function make_containers($containers){
|
72 |
+
$results = array();
|
73 |
+
foreach($containers as $container){
|
74 |
+
$key = $container['container_type'] . '|' . $container['container_id'];
|
75 |
+
$results[ $key ] = & $this->get_container($container);
|
|
|
|
|
76 |
}
|
77 |
+
return $results;
|
78 |
}
|
79 |
|
80 |
/**
|
81 |
+
* Create or update synchronization records for all containers managed by this class.
|
82 |
*
|
83 |
+
* Must be over-ridden in subclasses.
|
|
|
|
|
84 |
*
|
85 |
+
* @param bool $forced If true, assume that all synch. records are gone and will need to be recreated from scratch.
|
86 |
+
* @return void
|
87 |
*/
|
88 |
+
function resynch($forced = false){
|
89 |
+
trigger_error('Function blcContainerManager::resynch() must be over-ridden in a sub-class', E_USER_ERROR);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
}
|
91 |
|
92 |
+
/**
|
93 |
+
* Resynch when activated.
|
94 |
+
*
|
95 |
+
* @uses blcContainerManager::resynch()
|
96 |
+
*
|
97 |
+
* @return void
|
98 |
+
*/
|
99 |
+
function activated(){
|
100 |
+
$this->resynch();
|
101 |
+
blc_got_unsynched_items();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
}
|
103 |
|
104 |
+
/**
|
105 |
+
* Get a list of the parseable fields and their formats common to all containers of this type.
|
106 |
+
*
|
107 |
+
* @return array Associative array of formats indexed by field name.
|
108 |
+
*/
|
109 |
+
function get_parseable_fields(){
|
110 |
+
return $this->fields;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
}
|
112 |
|
113 |
/**
|
114 |
+
* Get the message to display after $n containers have been deleted.
|
|
|
115 |
*
|
116 |
+
* @param int $n Number of deleted containers.
|
117 |
+
* @return string A delete confirmation message, e.g. "5 posts were moved to trash"
|
118 |
*/
|
119 |
+
function ui_bulk_delete_message($n){
|
120 |
+
return sprintf(
|
121 |
+
_n(
|
122 |
+
"%d '%s' has been deleted",
|
123 |
+
"%d '%s' have been deleted",
|
124 |
+
$n,
|
125 |
+
'broken-link-checker'
|
126 |
+
),
|
127 |
+
$n,
|
128 |
+
$this->container_type
|
129 |
+
);
|
130 |
}
|
131 |
|
132 |
/**
|
133 |
+
* Get the message to display after $n containers have been moved to the trash.
|
134 |
*
|
135 |
+
* @param int $n Number of trashed containers.
|
|
|
136 |
* @return string A delete confirmation message, e.g. "5 posts were moved to trash"
|
137 |
*/
|
138 |
+
function ui_bulk_trash_message($n){
|
139 |
+
return $this->ui_bulk_delete_message($n);
|
|
|
|
|
|
|
|
|
|
|
140 |
}
|
141 |
}
|
142 |
|
|
|
|
|
|
|
|
|
|
|
143 |
/**
|
144 |
* The base class for link containers. All containers should extend this class.
|
145 |
*
|
270 |
//FB::log($name, "Parsing field");
|
271 |
|
272 |
//Get all parsers applicable to this field
|
273 |
+
$parsers = blcParserHelper::get_parsers( $format, $this->container_type );
|
274 |
//FB::log($parsers, "Applicable parsers");
|
275 |
|
276 |
if ( empty($parsers) ) continue;
|
409 |
}
|
410 |
|
411 |
/**
|
412 |
+
* Delete or trash the WP entity corresponding to this container. Should prefer moving to trash, if possible.
|
413 |
* Also remove the synch. record of the container and all associated instances.
|
414 |
*
|
415 |
* Must be over-ridden in a sub-class.
|
418 |
*/
|
419 |
function delete_wrapped_object(){
|
420 |
trigger_error('Function blcContainer::delete_wrapped_object() must be over-ridden in a sub-class', E_USER_ERROR);
|
421 |
+
}
|
422 |
|
423 |
+
/**
|
424 |
+
* Move the WP entity corresponding to this container to the Trash.
|
425 |
+
*
|
426 |
+
* Must be over-riden in a subclass.
|
427 |
+
*
|
428 |
+
* @return bool|WP_Error
|
429 |
+
*/
|
430 |
+
function trash_wrapped_object(){
|
431 |
+
trigger_error('Function blcContainer::trash_wrapped_object() must be over-ridden in a sub-class', E_USER_ERROR);
|
432 |
+
}
|
433 |
|
434 |
+
/**
|
435 |
+
* Check if the current user can delete/trash this container.
|
436 |
+
*
|
437 |
+
* Should be over-ridden in a subclass.
|
438 |
+
*
|
439 |
+
* @return bool
|
440 |
+
*/
|
441 |
+
function current_user_can_delete(){
|
442 |
+
return false;
|
443 |
+
}
|
444 |
+
|
445 |
+
/**
|
446 |
+
* Determine if this container can be moved to the trash.
|
447 |
+
*
|
448 |
+
* Should be over-ridden in a subclass.
|
449 |
+
*
|
450 |
+
* @return bool
|
451 |
+
*/
|
452 |
+
function can_be_trashed(){
|
453 |
+
return false;
|
454 |
+
}
|
455 |
+
|
456 |
+
|
457 |
+
/**
|
458 |
* Change all links with the specified URL to a new URL.
|
459 |
*
|
460 |
* @param string $field_name
|
462 |
* @param string $new_url
|
463 |
* @param string $old_url
|
464 |
* @param string $old_raw_url
|
465 |
+
* @return array|WP_Error The new value of raw_url on success, or an error object if something went wrong.
|
466 |
*/
|
467 |
function edit_link($field_name, $parser, $new_url, $old_url = '', $old_raw_url = ''){
|
468 |
//Ensure we're operating on a consistent copy of the wrapped object.
|
494 |
if ( is_wp_error($edit_result) ){
|
495 |
return $edit_result;
|
496 |
}
|
497 |
+
|
498 |
//Update the field with the new value returned by the parser.
|
499 |
$update_result = $this->update_field( $field_name, $edit_result['content'], $old_value );
|
500 |
if ( is_wp_error($update_result) ){
|
501 |
return $update_result;
|
502 |
}
|
503 |
|
504 |
+
//Return the new values to the instance.
|
505 |
+
unset($edit_result['content']); //(Except content, which it doesn't need.)
|
506 |
+
return $edit_result;
|
507 |
}
|
508 |
|
509 |
/**
|
515 |
* @param string $raw_url
|
516 |
* @return bool|WP_Error True on success, or an error object if something went wrong.
|
517 |
*/
|
518 |
+
function unlink($field_name, &$parser, $url, $raw_url =''){
|
519 |
//Ensure we're operating on a consistent copy of the wrapped object.
|
520 |
$this->get_wrapped_object(true);
|
521 |
|
580 |
//Should be over-ridden in a sub-class.
|
581 |
return '';
|
582 |
}
|
583 |
+
|
584 |
}
|
585 |
|
586 |
+
|
587 |
/**
|
588 |
+
* An utility class for working with link container types.
|
589 |
+
* All methods of this class should be called statically.
|
590 |
+
*
|
|
|
591 |
* @package Broken Link Checker
|
|
|
592 |
*/
|
593 |
+
class blcContainerHelper {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
594 |
|
595 |
/**
|
596 |
+
* Get the manager associated with a container type.
|
|
|
597 |
*
|
598 |
+
* @param string $container_type
|
599 |
+
* @param string $fallback If there is no manager associated with $container_type, return the manager of this container type instead.
|
600 |
+
* @return blcContainerManager|null
|
601 |
*/
|
602 |
+
function &get_manager( $container_type, $fallback = '' ){
|
603 |
+
$module_manager = & blcModuleManager::getInstance();
|
604 |
+
$container_manager = null;
|
605 |
+
|
606 |
+
if ( $container_manager = & $module_manager->get_module($container_type, true, 'container') ){
|
607 |
+
return $container_manager;
|
608 |
+
} elseif ( !empty($fallback) && ( $container_manager = & $module_manager->get_module($fallback, true, 'container') ) ) {
|
609 |
+
return $container_manager;
|
610 |
+
} else {
|
611 |
+
return null;
|
612 |
+
}
|
613 |
}
|
614 |
|
615 |
/**
|
616 |
+
* Retrieve or instantiate a container object.
|
617 |
*
|
618 |
+
* Pass an array containing the container type (string) and ID (int) to retrieve the container
|
619 |
+
* from the database. Alternatively, pass an associative array to create a new container object
|
620 |
+
* from the data in the array.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
621 |
*
|
622 |
+
* @param array $container Either [container_type, container_id], or an assoc. array of container data.
|
623 |
+
* @return blcContainer|null
|
624 |
*/
|
625 |
+
function &get_container( $container ){
|
626 |
+
global $wpdb;
|
627 |
+
|
628 |
+
if ( !is_array($container) || ( count($container) < 2 ) ){
|
629 |
+
return null;
|
630 |
+
}
|
631 |
+
|
632 |
+
if ( is_string($container[0]) && is_numeric($container[1]) ){
|
633 |
+
//The argument is in the [container_type, id] format
|
634 |
+
//Fetch the container's synch record.
|
635 |
+
$q = "SELECT * FROM {$wpdb->prefix}blc_synch WHERE container_type = %s AND container_id = %d";
|
636 |
+
$q = $wpdb->prepare($q, $container[0], $container[1]);
|
637 |
+
$rez = $wpdb->get_row($q, ARRAY_A);
|
638 |
+
|
639 |
+
if ( empty($rez) ){
|
640 |
+
//The container wasn't found, so we'll create a new one.
|
641 |
+
$container = array(
|
642 |
+
'container_type' => $container[0],
|
643 |
+
'container_id' => $container[1],
|
644 |
+
);
|
645 |
+
} else {
|
646 |
+
$container = $rez;
|
647 |
+
}
|
648 |
+
}
|
649 |
+
|
650 |
+
if ( !($manager = & blcContainerHelper::get_manager($container['container_type'])) ){
|
651 |
+
return null;
|
652 |
+
}
|
653 |
+
|
654 |
+
return $manager->get_container($container);
|
655 |
}
|
656 |
|
657 |
/**
|
658 |
+
* Retrieve or instantiate multiple link containers.
|
|
|
659 |
*
|
660 |
+
* Takes an array of container specifications and returns an array of container objects.
|
661 |
+
* Each input array entry should be an array and consist either of a container type (string)
|
662 |
+
* and container ID (int), or name => value pairs describing a container object.
|
|
|
663 |
*
|
664 |
+
* @see blcContainerHelper::get_container()
|
|
|
|
|
665 |
*
|
666 |
+
* @param array $containers
|
667 |
+
* @param string $purpose Optional code indicating how the retrieved containers will be used.
|
668 |
+
* @param string $fallback The fallback container type to use for unrecognized containers.
|
669 |
+
* @param bool $load_wrapped_objects Preload wrapped objects regardless of purpose.
|
670 |
* @return array of blcContainer indexed by "container_type|container_id"
|
671 |
*/
|
672 |
+
function get_containers( $containers, $purpose = '', $fallback = '', $load_wrapped_objects = false ){
|
673 |
+
global $wpdb;
|
674 |
+
|
675 |
+
//If the input is invalid or empty, return an empty array.
|
676 |
+
if ( !is_array($containers) || (count($containers) < 1) ) {
|
677 |
+
return array();
|
678 |
+
}
|
679 |
+
|
680 |
+
$first = reset($containers);
|
681 |
+
if ( !is_array($first) ){
|
682 |
+
return array();
|
683 |
+
}
|
684 |
+
|
685 |
+
if ( isset($first[0]) && is_string($first[0]) && is_numeric($first[1]) ){
|
686 |
+
//The argument is an array of [container_type, id].
|
687 |
+
//Divide the container IDs by container type.
|
688 |
+
$by_type = array();
|
689 |
+
|
690 |
+
foreach($containers as $container){
|
691 |
+
if ( isset($by_type[$container[0]]) ){
|
692 |
+
array_push($by_type[$container[0]], intval($container[1]));
|
693 |
+
} else {
|
694 |
+
$by_type[$container[0]] = array( intval($container[1]) );
|
695 |
+
}
|
696 |
+
}
|
697 |
+
|
698 |
+
//Build the SQL to fetch all the specified containers
|
699 |
+
$q = "SELECT *
|
700 |
+
FROM {$wpdb->prefix}blc_synch
|
701 |
+
WHERE";
|
702 |
+
|
703 |
+
$pieces = array();
|
704 |
+
foreach($by_type as $container_type => $container_ids){
|
705 |
+
$pieces[] = '( container_type = "'. $wpdb->escape($container_type) .'" AND container_id IN ('. implode(', ', $container_ids) .') )';
|
706 |
+
}
|
707 |
+
|
708 |
+
$q .= implode("\n\t OR ", $pieces);
|
709 |
+
|
710 |
+
//Fetch the container synch. records from the DB.
|
711 |
+
$containers = $wpdb->get_results($q, ARRAY_A);
|
712 |
+
}
|
713 |
+
|
714 |
+
/*
|
715 |
+
Divide the inputs into separate arrays by container type (again), then invoke
|
716 |
+
the appropriate manager for each type to instantiate the container objects.
|
717 |
+
*/
|
718 |
+
|
719 |
+
//At this point, $containers is an array of assoc. arrays comprising container data.
|
720 |
+
$by_type = array();
|
721 |
+
foreach($containers as $container){
|
722 |
+
if ( isset($by_type[$container['container_type']]) ){
|
723 |
+
array_push($by_type[$container['container_type']], $container);
|
724 |
+
} else {
|
725 |
+
$by_type[$container['container_type']] = array($container);
|
726 |
+
}
|
727 |
+
}
|
728 |
+
|
729 |
+
$results = array();
|
730 |
+
foreach($by_type as $container_type => $entries){
|
731 |
+
$manager = & blcContainerHelper::get_manager($container_type, $fallback);
|
732 |
+
if ( !is_null($manager) ){
|
733 |
+
$partial_results = $manager->get_containers($entries, $purpose, $load_wrapped_objects);
|
734 |
+
$results = array_merge($results, $partial_results);
|
735 |
+
}
|
736 |
+
}
|
737 |
+
|
738 |
+
return $results;
|
739 |
}
|
740 |
|
741 |
/**
|
742 |
+
* Retrieve link containers that need to be synchronized (parsed).
|
743 |
*
|
744 |
+
* @param integer $max_results The maximum number of containers to return. Defaults to returning all unsynched containers.
|
745 |
+
* @return array of blcContainer
|
746 |
*/
|
747 |
+
function get_unsynched_containers($max_results = 0){
|
748 |
+
global $wpdb;
|
749 |
+
|
750 |
+
$q = "SELECT * FROM {$wpdb->prefix}blc_synch WHERE synched = 0";
|
751 |
+
if ( $max_results > 0 ){
|
752 |
+
$q .= " LIMIT $max_results";
|
753 |
}
|
754 |
+
|
755 |
+
$container_data = $wpdb->get_results($q, ARRAY_A);
|
756 |
+
//FB::log($container_data, "Unsynched containers");
|
757 |
+
if( empty($container_data) ){
|
758 |
+
return array();
|
759 |
+
}
|
760 |
+
|
761 |
+
$containers = blcContainerHelper::get_containers($container_data, BLC_FOR_PARSING, 'dummy');
|
762 |
+
return $containers;
|
763 |
}
|
764 |
|
765 |
/**
|
766 |
+
* (Re)create and update synchronization records for all supported containers.
|
767 |
+
* Calls the resynch() method of all registered managers.
|
|
|
768 |
*
|
769 |
+
* @param bool $forced If true, assume that no synch. records exist and build all of them from scratch.
|
770 |
* @return void
|
771 |
*/
|
772 |
function resynch($forced = false){
|
773 |
+
global $wpdb;
|
774 |
+
|
775 |
+
$module_manager = & blcModuleManager::getInstance();
|
776 |
+
$active_managers = $module_manager->get_active_by_category('container');
|
777 |
+
foreach($active_managers as $module_id => $module_data){
|
778 |
+
$manager = & $module_manager->get_module($module_id);
|
779 |
+
if ( $manager ){
|
780 |
+
$manager->resynch($forced);
|
781 |
+
}
|
782 |
+
}
|
783 |
+
}
|
784 |
+
|
785 |
+
/**
|
786 |
+
* Mark as unparsed all containers that match one of the the specified formats or
|
787 |
+
* container types and that were last parsed after a specific timestamp.
|
788 |
+
*
|
789 |
+
* Used by newly activated parsers to force the containers they're interested in
|
790 |
+
* to resynchronize and thus let the parser process them.
|
791 |
+
*
|
792 |
+
* @param array $formats Associative array of timestamps, indexed by format IDs.
|
793 |
+
* @param array $container_types Associative array of timestamps, indexed by container types.
|
794 |
+
* @return bool
|
795 |
+
*/
|
796 |
+
function mark_as_unsynched_where($formats, $container_types){
|
797 |
+
global $wpdb;
|
798 |
+
|
799 |
+
//Find containers that match any of the specified formats and add them to
|
800 |
+
//the list of container types that need to be marked as unsynched.
|
801 |
+
$module_manager = &blcModuleManager::getInstance();
|
802 |
+
$containers = $module_manager->get_active_by_category('container');
|
803 |
+
|
804 |
+
foreach($containers as $module_id => $module_data){
|
805 |
+
if ( $container_manager = &$module_manager->get_module($module_id) ){
|
806 |
+
$fields = $container_manager->get_parseable_fields();
|
807 |
+
$container_type = $container_manager->container_type;
|
808 |
+
foreach($formats as $format => $timestamp){
|
809 |
+
if ( in_array($format, $fields) ){
|
810 |
+
//Choose the earliest timestamp
|
811 |
+
if ( isset($container_types[$container_type]) ){
|
812 |
+
$container_types[$container_type] = min($timestamp, $container_types[$container_type]);
|
813 |
+
} else {
|
814 |
+
$container_types[$container_type] = $timestamp;
|
815 |
+
}
|
816 |
+
}
|
817 |
+
}
|
818 |
+
};
|
819 |
+
}
|
820 |
+
|
821 |
+
if ( empty($container_types) ){
|
822 |
+
return true;
|
823 |
+
}
|
824 |
+
|
825 |
+
//Build the query to update all synch. records that match one of the specified
|
826 |
+
//container types and have been parsed after the specified time.
|
827 |
+
$q = "UPDATE {$wpdb->prefix}blc_synch SET synched = 0 WHERE ";
|
828 |
+
|
829 |
+
$pieces = array();
|
830 |
+
foreach($container_types as $container_type => $timestamp){
|
831 |
+
$pieces[] = $wpdb->prepare(
|
832 |
+
'(container_type = %s AND last_synch >= %s)',
|
833 |
+
$container_type,
|
834 |
+
date('Y-m-d H:i:s', $timestamp)
|
835 |
+
);
|
836 |
+
}
|
837 |
+
|
838 |
+
$q .= implode(' OR ', $pieces);
|
839 |
+
|
840 |
+
$rez = ($wpdb->query($q) !== false);
|
841 |
+
blc_got_unsynched_items();
|
842 |
+
|
843 |
+
return $rez;
|
844 |
+
}
|
845 |
+
|
846 |
+
/**
|
847 |
+
* Remove synch. records that reference container types not currently loaded
|
848 |
+
*
|
849 |
+
* @return bool
|
850 |
+
*/
|
851 |
+
function cleanup_containers(){
|
852 |
+
global $wpdb;
|
853 |
+
|
854 |
+
$module_manager = & blcModuleManager::getInstance();
|
855 |
+
$active_containers = $module_manager->get_escaped_ids('container');
|
856 |
+
|
857 |
+
$q = "DELETE synch.*
|
858 |
+
FROM {$wpdb->prefix}blc_synch AS synch
|
859 |
+
WHERE
|
860 |
+
synch.container_type NOT IN ({$active_containers})";
|
861 |
+
$rez = $wpdb->query($q);
|
862 |
+
|
863 |
+
return $rez !== false;
|
864 |
}
|
865 |
|
866 |
/**
|
867 |
+
* Get the message to display after $n containers of a specific type have been deleted.
|
868 |
*
|
869 |
+
* @param string $container_type
|
870 |
* @param int $n Number of deleted containers.
|
871 |
* @return string A delete confirmation message, e.g. "5 posts were moved to trash"
|
872 |
*/
|
873 |
+
function ui_bulk_delete_message($container_type, $n){
|
874 |
+
$manager = & blcContainerHelper::get_manager($container_type);
|
875 |
+
if ( is_null($manager) ){
|
876 |
+
return sprintf(__("Container type '%s' not recognized", 'broken-link-checker'), $container_type);
|
877 |
+
} else {
|
878 |
+
return $manager->ui_bulk_delete_message($n);
|
879 |
+
}
|
|
|
|
|
|
|
|
|
880 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
881 |
|
882 |
+
/**
|
883 |
+
* Get the message to display after $n containers of a specific type have been moved to the trash.
|
884 |
+
*
|
885 |
+
* @see blcContainerHelper::ui_bulk_delete_message()
|
886 |
+
*
|
887 |
+
* @param string $container_type
|
888 |
+
* @param int $n
|
889 |
+
* @return string
|
890 |
+
*/
|
891 |
+
function ui_bulk_trash_message($container_type, $n){
|
892 |
+
$manager = & blcContainerHelper::get_manager($container_type);
|
893 |
+
if ( is_null($manager) ){
|
894 |
+
return sprintf(__("Container type '%s' not recognized", 'broken-link-checker'), $container_type);
|
895 |
+
} else {
|
896 |
+
return $manager->ui_bulk_trash_message($n);
|
897 |
+
}
|
898 |
+
}
|
899 |
}
|
900 |
|
901 |
?>
|
includes/containers/post.php
DELETED
@@ -1,464 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class blcPostContainer extends blcContainer {
|
4 |
-
var $fields = array('post_content' => 'html');
|
5 |
-
var $default_field = 'post_content';
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Get action links for this post.
|
9 |
-
*
|
10 |
-
* @param string $container_field Ignored.
|
11 |
-
* @return array of action link HTML.
|
12 |
-
*/
|
13 |
-
function ui_get_action_links($container_field = ''){
|
14 |
-
$actions = array();
|
15 |
-
if ( current_user_can('edit_post', $this->container_id) ) {
|
16 |
-
$actions['edit'] = '<span class="edit"><a href="' . $this->get_edit_url() . '" title="' . esc_attr(__('Edit this post')) . '">' . __('Edit') . '</a>';
|
17 |
-
|
18 |
-
if ( constant('EMPTY_TRASH_DAYS') ) {
|
19 |
-
$actions['trash'] = "<a class='submitdelete' title='" . esc_attr(__('Move this post to the Trash')) . "' href='" . get_delete_post_link($this->container_id) . "'>" . __('Trash') . "</a>";
|
20 |
-
} else {
|
21 |
-
$actions['delete'] = "<a class='submitdelete' title='" . esc_attr(__('Delete this post permanently')) . "' href='" . wp_nonce_url( admin_url("post.php?action=delete&post=".$this->container_id), 'delete-post_' . $this->container_id) . "' onclick=\"if ( confirm('" . esc_js(sprintf( __("You are about to delete this post '%s'\n 'Cancel' to stop, 'OK' to delete."), get_the_title($this->container_id) )) . "') ) { return true;}return false;\">" . __('Delete') . "</a>";
|
22 |
-
}
|
23 |
-
}
|
24 |
-
$actions['view'] = '<span class="view"><a href="' . get_permalink($this->container_id) . '" title="' . esc_attr(sprintf(__('View "%s"', 'broken-link-checker'), get_the_title($this->container_id))) . '" rel="permalink">' . __('View') . '</a>';
|
25 |
-
|
26 |
-
return $actions;
|
27 |
-
}
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Get the HTML for displaying the post title in the "Source" column.
|
31 |
-
*
|
32 |
-
* @param string $container_field Ignored.
|
33 |
-
* @param string $context How to filter the output. Optional, defaults to 'display'.
|
34 |
-
* @return string HTML
|
35 |
-
*/
|
36 |
-
function ui_get_source($container_field = '', $context = 'display'){
|
37 |
-
$source = '<a class="row-title" href="%s" title="%s">%s</a>';
|
38 |
-
$source = sprintf(
|
39 |
-
$source,
|
40 |
-
$this->get_edit_url(),
|
41 |
-
esc_attr(__('Edit this post')),
|
42 |
-
get_the_title($this->container_id)
|
43 |
-
);
|
44 |
-
|
45 |
-
return $source;
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Get edit URL for this container. Returns the URL of the Dashboard page where the item
|
50 |
-
* associated with this container can be edited.
|
51 |
-
*
|
52 |
-
* @access protected
|
53 |
-
*
|
54 |
-
* @return string
|
55 |
-
*/
|
56 |
-
function get_edit_url(){
|
57 |
-
/*
|
58 |
-
The below is a near-exact copy of the get_post_edit_link() function.
|
59 |
-
Unfortunately we can't just call that function because it has a hardcoded
|
60 |
-
caps-check which fails when called from the email notification script
|
61 |
-
executed by Cron.
|
62 |
-
*/
|
63 |
-
|
64 |
-
if ( !$post = &get_post( $this->container_id ) ){
|
65 |
-
return '';
|
66 |
-
}
|
67 |
-
|
68 |
-
$context = 'display';
|
69 |
-
|
70 |
-
if ( function_exists('get_post_type_object') ){
|
71 |
-
//WP 3.0
|
72 |
-
if ( 'display' == $context )
|
73 |
-
$action = '&action=edit';
|
74 |
-
else
|
75 |
-
$action = '&action=edit';
|
76 |
-
|
77 |
-
$post_type_object = get_post_type_object( $post->post_type );
|
78 |
-
if ( !$post_type_object ){
|
79 |
-
return '';
|
80 |
-
}
|
81 |
-
|
82 |
-
return apply_filters( 'get_edit_post_link', admin_url( sprintf($post_type_object->_edit_link . $action, $post->ID) ), $post->ID, $context );
|
83 |
-
|
84 |
-
} else {
|
85 |
-
//WP 2.9.x
|
86 |
-
if ( 'display' == $context )
|
87 |
-
$action = 'action=edit&';
|
88 |
-
else
|
89 |
-
$action = 'action=edit&';
|
90 |
-
|
91 |
-
switch ( $post->post_type ) :
|
92 |
-
case 'page' :
|
93 |
-
$file = 'page';
|
94 |
-
$var = 'post';
|
95 |
-
break;
|
96 |
-
case 'attachment' :
|
97 |
-
$file = 'media';
|
98 |
-
$var = 'attachment_id';
|
99 |
-
break;
|
100 |
-
case 'revision' :
|
101 |
-
$file = 'revision';
|
102 |
-
$var = 'revision';
|
103 |
-
$action = '';
|
104 |
-
break;
|
105 |
-
default :
|
106 |
-
$file = 'post';
|
107 |
-
$var = 'post';
|
108 |
-
break;
|
109 |
-
endswitch;
|
110 |
-
|
111 |
-
return apply_filters( 'get_edit_post_link', admin_url("$file.php?{$action}$var=$post->ID"), $post->ID, $context );
|
112 |
-
|
113 |
-
}
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* Retrieve the post associated with this container.
|
118 |
-
*
|
119 |
-
* @access protected
|
120 |
-
*
|
121 |
-
* @param bool $ensure_consistency Set this to true to ignore the cached $wrapped_object value and retrieve an up-to-date copy of the wrapped object from the DB (or WP's internal cache).
|
122 |
-
* @return object Post data.
|
123 |
-
*/
|
124 |
-
function &get_wrapped_object($ensure_consistency = false){
|
125 |
-
if( $ensure_consistency || is_null($this->wrapped_object) ){
|
126 |
-
$this->wrapped_object = &get_post($this->container_id);
|
127 |
-
}
|
128 |
-
return $this->wrapped_object;
|
129 |
-
}
|
130 |
-
|
131 |
-
/**
|
132 |
-
* Update the post associated with this container.
|
133 |
-
*
|
134 |
-
* @access protected
|
135 |
-
*
|
136 |
-
* @return bool|WP_Error True on success, an error if something went wrong.
|
137 |
-
*/
|
138 |
-
function update_wrapped_object(){
|
139 |
-
if ( is_null($this->wrapped_object) ){
|
140 |
-
return new WP_Error(
|
141 |
-
'no_wrapped_object',
|
142 |
-
__('Nothing to update', 'broken-link-checker')
|
143 |
-
);
|
144 |
-
}
|
145 |
-
|
146 |
-
$id = wp_update_post($this->wrapped_object);
|
147 |
-
if ( $id != 0 ){
|
148 |
-
return true;
|
149 |
-
} else {
|
150 |
-
return new WP_Error(
|
151 |
-
'update_failed',
|
152 |
-
sprintf(__('Updating post %d failed', 'broken-link-checker'), $this->container_id)
|
153 |
-
);
|
154 |
-
}
|
155 |
-
}
|
156 |
-
|
157 |
-
/**
|
158 |
-
* Get the base URL of the container. For posts, the post permalink is used
|
159 |
-
* as the base URL when normalizing relative links.
|
160 |
-
*
|
161 |
-
* @return string
|
162 |
-
*/
|
163 |
-
function base_url(){
|
164 |
-
return get_permalink($this->container_id);
|
165 |
-
}
|
166 |
-
|
167 |
-
/**
|
168 |
-
* Delete the post corresponding to this container.
|
169 |
-
*
|
170 |
-
* @return bool|WP_error
|
171 |
-
*/
|
172 |
-
function delete_wrapped_object(){
|
173 |
-
if ( wp_delete_post($this->container_id) ){
|
174 |
-
//Note that we don't need to delete the synch record and instances here -
|
175 |
-
//wp_delete_post() will run the post_delete hook, which will be caught
|
176 |
-
//by blcPostContainerManager, which will delete anything that needs to be
|
177 |
-
//deleted.
|
178 |
-
return true;
|
179 |
-
} else {
|
180 |
-
return new WP_Error(
|
181 |
-
'delete_failed',
|
182 |
-
sprintf(
|
183 |
-
__('Failed to delete post "%s" (%d)', 'broken-link-checker'),
|
184 |
-
get_the_title($this->container_id),
|
185 |
-
$this->container_id
|
186 |
-
)
|
187 |
-
);
|
188 |
-
};
|
189 |
-
}
|
190 |
-
}
|
191 |
-
|
192 |
-
class blcPostContainerManager extends blcContainerManager {
|
193 |
-
var $container_class_name = 'blcPostContainer';
|
194 |
-
|
195 |
-
var $_conf; //Keep a local reference to the BLC configuration manager. Yields a minor performance benefit.
|
196 |
-
|
197 |
-
/**
|
198 |
-
* Set up hooks that monitor added/modified/deleted posts.
|
199 |
-
*
|
200 |
-
* @return void
|
201 |
-
*/
|
202 |
-
function init(){
|
203 |
-
//These hooks update the synch & instance records when posts are added, deleted or modified.
|
204 |
-
add_action('delete_post', array(&$this,'post_deleted'));
|
205 |
-
add_action('save_post', array(&$this,'post_saved'));
|
206 |
-
//We also treat post trashing/untrashing as delete/save.
|
207 |
-
add_action('trash_post', array(&$this,'post_deleted'));
|
208 |
-
add_action('untrash_post', array(&$this,'post_saved'));
|
209 |
-
|
210 |
-
//Highlight and nofollow broken links in posts & pages
|
211 |
-
$this->_conf = & blc_get_configuration();
|
212 |
-
if ( $this->_conf->options['mark_broken_links'] || $this->_conf->options['nofollow_broken_links'] ){
|
213 |
-
add_filter( 'the_content', array(&$this,'hook_the_content') );
|
214 |
-
if ( $this->_conf->options['mark_broken_links'] && !empty( $this->_conf->options['broken_link_css'] ) ){
|
215 |
-
add_action( 'wp_head', array(&$this,'hook_wp_head') );
|
216 |
-
}
|
217 |
-
}
|
218 |
-
}
|
219 |
-
|
220 |
-
/**
|
221 |
-
* Remove the synch. record and link instances associated with a post when it's deleted
|
222 |
-
*
|
223 |
-
* @param int $post_id
|
224 |
-
* @return void
|
225 |
-
*/
|
226 |
-
function post_deleted($post_id){
|
227 |
-
//Get the associated container object
|
228 |
-
$post_container = blc_get_container( array($this->container_type, intval($post_id)) );
|
229 |
-
//Delete it
|
230 |
-
$post_container->delete();
|
231 |
-
//Clean up any dangling links
|
232 |
-
blc_cleanup_links();
|
233 |
-
}
|
234 |
-
|
235 |
-
/**
|
236 |
-
* When a post is saved or modified, mark it as unparsed.
|
237 |
-
*
|
238 |
-
* @param int $post_id
|
239 |
-
* @return void
|
240 |
-
*/
|
241 |
-
function post_saved($post_id){
|
242 |
-
//Get the container
|
243 |
-
$args = array($this->container_type, intval($post_id));
|
244 |
-
$post_container = blc_get_container( $args );
|
245 |
-
|
246 |
-
//Get the post
|
247 |
-
$post = $post_container->get_wrapped_object();
|
248 |
-
|
249 |
-
//Only check links in posts, not revisions and attachments
|
250 |
-
if ( ($post->post_type != 'post') && ($post->post_type != 'page') ) return;
|
251 |
-
//Only check published posts
|
252 |
-
if ( $post->post_status != 'publish' ) return;
|
253 |
-
|
254 |
-
$post_container->mark_as_unsynched();
|
255 |
-
}
|
256 |
-
|
257 |
-
|
258 |
-
/**
|
259 |
-
* Instantiate multiple containers of the container type managed by this class.
|
260 |
-
*
|
261 |
-
* @param array $containers Array of assoc. arrays containing container data.
|
262 |
-
* @param string $purpose An optional code indicating how the retrieved containers will be used.
|
263 |
-
* @param bool $load_wrapped_objects Preload wrapped objects regardless of purpose.
|
264 |
-
*
|
265 |
-
* @return array of blcPostContainer indexed by "container_type|container_id"
|
266 |
-
*/
|
267 |
-
function get_containers($containers, $purpose = '', $load_wrapped_objects = false){
|
268 |
-
$containers = $this->make_containers($containers);
|
269 |
-
|
270 |
-
//Preload post data if it is likely to be useful later
|
271 |
-
$preload = $load_wrapped_objects || in_array($purpose, array(BLC_FOR_DISPLAY, BLC_FOR_PARSING));
|
272 |
-
if ( $preload ){
|
273 |
-
$post_ids = array();
|
274 |
-
foreach($containers as $container){
|
275 |
-
$post_ids[] = $container->container_id;
|
276 |
-
}
|
277 |
-
|
278 |
-
$args = array('include' => implode(',', $post_ids));
|
279 |
-
$posts = get_posts($args);
|
280 |
-
|
281 |
-
foreach($posts as $post){
|
282 |
-
$key = $this->container_type . '|' . $post->ID;
|
283 |
-
if ( isset($containers[$key]) ){
|
284 |
-
$containers[$key]->wrapped_object = $post;
|
285 |
-
}
|
286 |
-
}
|
287 |
-
}
|
288 |
-
|
289 |
-
return $containers;
|
290 |
-
}
|
291 |
-
|
292 |
-
/**
|
293 |
-
* Create or update synchronization records for all posts.
|
294 |
-
*
|
295 |
-
* @param bool $forced If true, assume that all synch. records are gone and will need to be recreated from scratch.
|
296 |
-
* @return void
|
297 |
-
*/
|
298 |
-
function resynch($forced = false){
|
299 |
-
global $wpdb;
|
300 |
-
|
301 |
-
if ( $forced ){
|
302 |
-
//Create new synchronization records for all posts.
|
303 |
-
$q = "INSERT INTO {$wpdb->prefix}blc_synch(container_id, container_type, synched)
|
304 |
-
SELECT id, 'post', 0
|
305 |
-
FROM {$wpdb->posts}
|
306 |
-
WHERE
|
307 |
-
{$wpdb->posts}.post_status = 'publish'
|
308 |
-
AND {$wpdb->posts}.post_type IN ('post', 'page')";
|
309 |
-
$wpdb->query( $q );
|
310 |
-
} else {
|
311 |
-
//Delete synch records corresponding to posts that no longer exist.
|
312 |
-
$q = "DELETE synch.*
|
313 |
-
FROM
|
314 |
-
{$wpdb->prefix}blc_synch AS synch LEFT JOIN {$wpdb->posts} AS posts
|
315 |
-
ON posts.ID = synch.container_id
|
316 |
-
WHERE
|
317 |
-
synch.container_type = 'post' AND posts.ID IS NULL";
|
318 |
-
$wpdb->query( $q );
|
319 |
-
|
320 |
-
//Remove the 'synched' flag from all posts that have been updated
|
321 |
-
//since the last time they were parsed/synchronized.
|
322 |
-
$q = "UPDATE
|
323 |
-
{$wpdb->prefix}blc_synch AS synch
|
324 |
-
JOIN {$wpdb->posts} AS posts ON (synch.container_id = posts.ID and synch.container_type='post')
|
325 |
-
SET
|
326 |
-
synched = 0
|
327 |
-
WHERE
|
328 |
-
synch.last_synch < posts.post_modified";
|
329 |
-
$wpdb->query( $q );
|
330 |
-
|
331 |
-
//Create synch. records for posts that don't have them.
|
332 |
-
$q = "INSERT INTO {$wpdb->prefix}blc_synch(container_id, container_type, synched)
|
333 |
-
SELECT id, 'post', 0
|
334 |
-
FROM
|
335 |
-
{$wpdb->posts} AS posts LEFT JOIN {$wpdb->prefix}blc_synch AS synch
|
336 |
-
ON (synch.container_id = posts.ID and synch.container_type='post')
|
337 |
-
WHERE
|
338 |
-
posts.post_status = 'publish'
|
339 |
-
AND posts.post_type IN ('post', 'page')
|
340 |
-
AND synch.container_id IS NULL";
|
341 |
-
$wpdb->query($q);
|
342 |
-
}
|
343 |
-
}
|
344 |
-
|
345 |
-
/**
|
346 |
-
* Get the message to display after $n posts have been deleted.
|
347 |
-
*
|
348 |
-
* @param int $n Number of deleted posts.
|
349 |
-
* @return string A delete confirmation message, e.g. "5 posts were moved to trash"
|
350 |
-
*/
|
351 |
-
function ui_bulk_delete_message($n){
|
352 |
-
//Since the "Trash" feature has been introduced, calling wp_delete_post
|
353 |
-
//doesn't actually delete the post (unless you set force_delete to True),
|
354 |
-
//just moves it to the trash. So we pick the message accordingly.
|
355 |
-
if ( function_exists('wp_trash_post') && EMPTY_TRASH_DAYS ){
|
356 |
-
$delete_msg = _n("%d post moved to the trash", "%d posts moved to the trash", $n, 'broken-link-checker');
|
357 |
-
} else {
|
358 |
-
$delete_msg = _n("%d post deleted", "%d posts deleted", $n, 'broken-link-checker');
|
359 |
-
}
|
360 |
-
return sprintf($delete_msg, $n);
|
361 |
-
}
|
362 |
-
|
363 |
-
/**
|
364 |
-
* Hook for the 'the_content' filter. Scans the current post and adds the 'broken_link'
|
365 |
-
* CSS class to all links that are known to be broken. Currently works only on standard
|
366 |
-
* HTML links (i.e. the '<a href=...' kind).
|
367 |
-
*
|
368 |
-
* @param string $content Post content
|
369 |
-
* @return string Modified post content.
|
370 |
-
*/
|
371 |
-
function hook_the_content($content){
|
372 |
-
global $post, $wpdb;
|
373 |
-
if ( empty($post) ) return $content;
|
374 |
-
|
375 |
-
//Retrieve info about all occurences of broken links in the current post
|
376 |
-
$q = "
|
377 |
-
SELECT instances.raw_url
|
378 |
-
FROM {$wpdb->prefix}blc_instances AS instances JOIN {$wpdb->prefix}blc_links AS links
|
379 |
-
ON instances.link_id = links.link_id
|
380 |
-
WHERE
|
381 |
-
instances.container_type = %s
|
382 |
-
AND instances.container_id = %d
|
383 |
-
AND links.broken = 1
|
384 |
-
AND parser_type = 'link'
|
385 |
-
";
|
386 |
-
$q = $wpdb->prepare($q, $this->container_type, $post->ID);
|
387 |
-
$links = $wpdb->get_results($q, ARRAY_A);
|
388 |
-
|
389 |
-
//Return the content unmodified if there are no broken links in this post.
|
390 |
-
if ( empty($links) || !is_array($links) ){
|
391 |
-
return $content;
|
392 |
-
}
|
393 |
-
|
394 |
-
//Put the broken link URLs in an array
|
395 |
-
$broken_link_urls = array();
|
396 |
-
foreach($links as $link){
|
397 |
-
$broken_link_urls[] = $link['raw_url'];
|
398 |
-
}
|
399 |
-
|
400 |
-
//Iterate over all HTML links and modify the broken ones
|
401 |
-
$parser = &blc_get_parser('link');
|
402 |
-
$content = $parser->multi_edit($content, array(&$this, 'highlight_broken_link'), $broken_link_urls);
|
403 |
-
|
404 |
-
return $content;
|
405 |
-
}
|
406 |
-
|
407 |
-
/**
|
408 |
-
* Analyse a link and add 'broken_link' CSS class if the link is broken.
|
409 |
-
*
|
410 |
-
* @see blcHtmlLink::multi_edit()
|
411 |
-
*
|
412 |
-
* @param array $link Associative array of link data.
|
413 |
-
* @param array $broken_link_urls List of broken link URLs present in the current post.
|
414 |
-
* @return array|string The modified link
|
415 |
-
*/
|
416 |
-
function highlight_broken_link($link, $broken_link_urls){
|
417 |
-
if ( !in_array($link['href'], $broken_link_urls) ){
|
418 |
-
//Link not broken = return the original link tag
|
419 |
-
return $link['#raw'];
|
420 |
-
}
|
421 |
-
|
422 |
-
//Add 'broken_link' to the 'class' attribute (unless already present).
|
423 |
-
if ( $this->_conf->options['mark_broken_links'] ){
|
424 |
-
if ( isset($link['class']) ){
|
425 |
-
$classes = explode(' ', $link['class']);
|
426 |
-
if ( !in_array('broken_link', $classes) ){
|
427 |
-
$classes[] = 'broken_link';
|
428 |
-
$link['class'] = implode(' ', $classes);
|
429 |
-
}
|
430 |
-
} else {
|
431 |
-
$link['class'] = 'broken_link';
|
432 |
-
}
|
433 |
-
}
|
434 |
-
|
435 |
-
//Nofollow the link (unless it's already nofollow'ed)
|
436 |
-
if ( $this->_conf->options['nofollow_broken_links'] ){
|
437 |
-
if ( isset($link['rel']) ){
|
438 |
-
$relations = explode(' ', $link['rel']);
|
439 |
-
if ( !in_array('nofollow', $relations) ){
|
440 |
-
$relations[] = 'nofollow';
|
441 |
-
$link['rel'] = implode(' ', $relations);
|
442 |
-
}
|
443 |
-
} else {
|
444 |
-
$link['rel'] = 'nofollow';
|
445 |
-
}
|
446 |
-
}
|
447 |
-
|
448 |
-
return $link;
|
449 |
-
}
|
450 |
-
|
451 |
-
/**
|
452 |
-
* A hook for the 'wp_head' action. Outputs the user-defined broken link CSS.
|
453 |
-
*
|
454 |
-
* @return void
|
455 |
-
*/
|
456 |
-
function hook_wp_head(){
|
457 |
-
$conf = & blc_get_configuration();
|
458 |
-
echo '<style type="text/css">',$conf->options['broken_link_css'],'</style>';
|
459 |
-
}
|
460 |
-
}
|
461 |
-
|
462 |
-
blc_register_container('post', 'blcPostContainerManager');
|
463 |
-
|
464 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/extra-strings.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
_x("Basic HTTP", "module name", "broken-link-checker");
|
3 |
+
_x("Blogroll items", "module name", "broken-link-checker");
|
4 |
+
_x("Comments", "module name", "broken-link-checker");
|
5 |
+
_x("Custom fields", "module name", "broken-link-checker");
|
6 |
+
_x("Embedded DailyMotion videos", "module name", "broken-link-checker");
|
7 |
+
_x("Embedded Vimeo videos", "module name", "broken-link-checker");
|
8 |
+
_x("Embedded YouTube videos", "module name", "broken-link-checker");
|
9 |
+
_x("HTML images", "module name", "broken-link-checker");
|
10 |
+
_x("HTML links", "module name", "broken-link-checker");
|
11 |
+
_x("MediaFire API", "module name", "broken-link-checker");
|
12 |
+
_x("MegaUpload API", "module name", "broken-link-checker");
|
13 |
+
_x("Plaintext URLs", "module name", "broken-link-checker");
|
14 |
+
_x("RapidShare API", "module name", "broken-link-checker");
|
15 |
+
_x("YouTube API", "module name", "broken-link-checker");
|
16 |
+
_x("Posts", "module name", "broken-link-checker");
|
17 |
+
_x("Pages", "module name", "broken-link-checker");
|
18 |
+
?>
|
includes/instances.php
CHANGED
@@ -95,7 +95,7 @@ class blcLinkInstance {
|
|
95 |
function edit($new_url, $old_url = ''){
|
96 |
|
97 |
//Get the container that contains this link
|
98 |
-
$container = $this->get_container();
|
99 |
if ( is_null($container) ){
|
100 |
return new WP_Error(
|
101 |
'container_not_found',
|
@@ -104,7 +104,7 @@ class blcLinkInstance {
|
|
104 |
}
|
105 |
|
106 |
//Get the parser.
|
107 |
-
$parser = $this->get_parser();
|
108 |
if ( is_null($parser) ){
|
109 |
return new WP_Error(
|
110 |
'parser_not_found',
|
@@ -125,6 +125,16 @@ class blcLinkInstance {
|
|
125 |
//indicating success.
|
126 |
$this->raw_url = $result;
|
127 |
return true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
} else {
|
129 |
//Otherwise, it will return an error object. In this case we'll
|
130 |
//just pass it back to the caller and let them sort it out.
|
@@ -141,7 +151,7 @@ class blcLinkInstance {
|
|
141 |
function unlink( $url = null ) {
|
142 |
|
143 |
//Get the container that contains this link
|
144 |
-
$container = $this->get_container();
|
145 |
if ( is_null($container) ){
|
146 |
return new WP_Error(
|
147 |
'container_not_found',
|
@@ -150,7 +160,7 @@ class blcLinkInstance {
|
|
150 |
}
|
151 |
|
152 |
//Get the parser.
|
153 |
-
$parser = $this->get_parser();
|
154 |
if ( is_null($parser) ){
|
155 |
return new WP_Error(
|
156 |
'parser_not_found',
|
@@ -296,7 +306,7 @@ class blcLinkInstance {
|
|
296 |
* @return string The associated URL, or an empty string if the instance is currently not assigned to any link.
|
297 |
*/
|
298 |
function get_url(){
|
299 |
-
$link = $this->get_link();
|
300 |
|
301 |
if ( !is_null($link) ){
|
302 |
return $link->url;
|
@@ -312,7 +322,7 @@ class blcLinkInstance {
|
|
312 |
*/
|
313 |
function &get_container(){
|
314 |
if( is_null($this->_container) ){
|
315 |
-
$this->_container = &
|
316 |
}
|
317 |
|
318 |
return $this->_container;
|
@@ -325,8 +335,8 @@ class blcLinkInstance {
|
|
325 |
* @param string $field
|
326 |
* @return void
|
327 |
*/
|
328 |
-
function set_container(
|
329 |
-
$this->_container =
|
330 |
|
331 |
$this->container_field = $field;
|
332 |
|
@@ -346,7 +356,7 @@ class blcLinkInstance {
|
|
346 |
*/
|
347 |
function &get_parser(){
|
348 |
if ( is_null($this->_parser) ){
|
349 |
-
$this->_parser = &
|
350 |
}
|
351 |
|
352 |
return $this->_parser;
|
@@ -358,8 +368,8 @@ class blcLinkInstance {
|
|
358 |
* @param blcParser|null $new_parser
|
359 |
* @return void
|
360 |
*/
|
361 |
-
function set_parser(
|
362 |
-
$this->_parser =
|
363 |
|
364 |
if ( is_null($new_parser) ){
|
365 |
$this->parser_type = '';
|
@@ -409,7 +419,7 @@ class blcLinkInstance {
|
|
409 |
* @return string HTML
|
410 |
*/
|
411 |
function ui_get_link_text($context = 'display'){
|
412 |
-
$parser = $this->get_parser();
|
413 |
|
414 |
if ( !is_null($parser) ){
|
415 |
$text = $parser->ui_get_link_text($this, $context);
|
@@ -431,7 +441,7 @@ class blcLinkInstance {
|
|
431 |
*/
|
432 |
function ui_get_action_links(){
|
433 |
//The container is responsible for generating the links.
|
434 |
-
$container = $this->get_container();
|
435 |
if ( !is_null($container) ){
|
436 |
return $container->ui_get_action_links($this->container_field);
|
437 |
} else {
|
@@ -449,7 +459,7 @@ class blcLinkInstance {
|
|
449 |
*/
|
450 |
function ui_get_source($context = 'display'){
|
451 |
//The container is also responsible for generating the "Source" column HTML.
|
452 |
-
$container = $this->get_container();
|
453 |
if ( !is_null($container) ){
|
454 |
return $container->ui_get_source($this->container_field, $context);
|
455 |
} else {
|
@@ -482,16 +492,12 @@ function blc_get_instances( $link_ids, $purpose = '', $load_containers = false,
|
|
482 |
|
483 |
//Skip instances that reference containers or parsers that aren't currently loaded
|
484 |
if ( !$include_invalid ){
|
485 |
-
$
|
486 |
-
$
|
487 |
-
$
|
488 |
-
$loaded_parsers = array_keys($parserRegistry->get_registered_parsers());
|
489 |
-
|
490 |
-
$loaded_containers = array_map(array(&$wpdb, 'escape'), $loaded_containers);
|
491 |
-
$loaded_parsers = array_map(array(&$wpdb, 'escape'), $loaded_parsers);
|
492 |
|
493 |
-
$q .= " AND container_type IN (
|
494 |
-
$q .= " AND parser_type IN (
|
495 |
}
|
496 |
|
497 |
$results = $wpdb->get_results($q, ARRAY_A);
|
@@ -513,7 +519,7 @@ function blc_get_instances( $link_ids, $purpose = '', $load_containers = false,
|
|
513 |
);
|
514 |
}
|
515 |
|
516 |
-
$containers =
|
517 |
}
|
518 |
|
519 |
//Create an object for each instance and group them by link ID
|
@@ -550,16 +556,12 @@ function blc_get_usable_instance_count(){
|
|
550 |
$q = "SELECT COUNT(instance_id) FROM {$wpdb->prefix}blc_instances WHERE 1";
|
551 |
|
552 |
//Skip instances that reference containers or parsers that aren't currently loaded
|
553 |
-
$
|
554 |
-
$
|
555 |
-
$
|
556 |
-
$loaded_parsers = array_keys($parserRegistry->get_registered_parsers());
|
557 |
|
558 |
-
$
|
559 |
-
$
|
560 |
-
|
561 |
-
$q .= " AND container_type IN ('" . implode("', '", $loaded_containers) . "') ";
|
562 |
-
$q .= " AND parser_type IN ('" . implode("', '", $loaded_parsers) . "') ";
|
563 |
|
564 |
return $wpdb->get_var($q);
|
565 |
}
|
@@ -581,22 +583,16 @@ function blc_cleanup_instances(){
|
|
581 |
synch.container_id IS NULL";
|
582 |
$rez = $wpdb->query($q);
|
583 |
|
584 |
-
|
585 |
-
$
|
586 |
-
$
|
587 |
-
$
|
588 |
-
|
589 |
-
$loaded_containers = array_map(array(&$wpdb, 'escape'), $loaded_containers);
|
590 |
-
$loaded_containers = "'" . implode("', '", $loaded_containers) . "'";
|
591 |
-
|
592 |
-
$loaded_parsers = array_map(array(&$wpdb, 'escape'), $loaded_parsers);
|
593 |
-
$loaded_parsers = "'" . implode("', '", $loaded_parsers) . "'";
|
594 |
|
595 |
$q = "DELETE instances.*
|
596 |
FROM {$wpdb->prefix}blc_instances AS instances
|
597 |
WHERE
|
598 |
-
instances.container_type NOT IN ({$
|
599 |
-
instances.parser_type NOT IN ({$
|
600 |
$rez2 = $wpdb->query($q);
|
601 |
|
602 |
return ($rez !== false) && ($rez2 !== false);
|
95 |
function edit($new_url, $old_url = ''){
|
96 |
|
97 |
//Get the container that contains this link
|
98 |
+
$container = & $this->get_container();
|
99 |
if ( is_null($container) ){
|
100 |
return new WP_Error(
|
101 |
'container_not_found',
|
104 |
}
|
105 |
|
106 |
//Get the parser.
|
107 |
+
$parser = & $this->get_parser();
|
108 |
if ( is_null($parser) ){
|
109 |
return new WP_Error(
|
110 |
'parser_not_found',
|
125 |
//indicating success.
|
126 |
$this->raw_url = $result;
|
127 |
return true;
|
128 |
+
} elseif ( is_array($result) ){
|
129 |
+
//More advanced containers/parsers may return an array of values to
|
130 |
+
//modify several fields at once.
|
131 |
+
$allowed_fields = array('raw_url', 'link_text', 'link_context');
|
132 |
+
foreach($result as $key => $value){
|
133 |
+
if ( in_array($key, $allowed_fields) ){
|
134 |
+
$this->$key = $value;
|
135 |
+
}
|
136 |
+
}
|
137 |
+
return true;
|
138 |
} else {
|
139 |
//Otherwise, it will return an error object. In this case we'll
|
140 |
//just pass it back to the caller and let them sort it out.
|
151 |
function unlink( $url = null ) {
|
152 |
|
153 |
//Get the container that contains this link
|
154 |
+
$container = & $this->get_container();
|
155 |
if ( is_null($container) ){
|
156 |
return new WP_Error(
|
157 |
'container_not_found',
|
160 |
}
|
161 |
|
162 |
//Get the parser.
|
163 |
+
$parser = & $this->get_parser();
|
164 |
if ( is_null($parser) ){
|
165 |
return new WP_Error(
|
166 |
'parser_not_found',
|
306 |
* @return string The associated URL, or an empty string if the instance is currently not assigned to any link.
|
307 |
*/
|
308 |
function get_url(){
|
309 |
+
$link = & $this->get_link();
|
310 |
|
311 |
if ( !is_null($link) ){
|
312 |
return $link->url;
|
322 |
*/
|
323 |
function &get_container(){
|
324 |
if( is_null($this->_container) ){
|
325 |
+
$this->_container = & blcContainerHelper::get_container( array($this->container_type, $this->container_id) );
|
326 |
}
|
327 |
|
328 |
return $this->_container;
|
335 |
* @param string $field
|
336 |
* @return void
|
337 |
*/
|
338 |
+
function set_container(&$new_container, $field = ''){
|
339 |
+
$this->_container = &$new_container;
|
340 |
|
341 |
$this->container_field = $field;
|
342 |
|
356 |
*/
|
357 |
function &get_parser(){
|
358 |
if ( is_null($this->_parser) ){
|
359 |
+
$this->_parser = & blcParserHelper::get_parser($this->parser_type);
|
360 |
}
|
361 |
|
362 |
return $this->_parser;
|
368 |
* @param blcParser|null $new_parser
|
369 |
* @return void
|
370 |
*/
|
371 |
+
function set_parser(&$new_parser){
|
372 |
+
$this->_parser = &$new_parser;
|
373 |
|
374 |
if ( is_null($new_parser) ){
|
375 |
$this->parser_type = '';
|
419 |
* @return string HTML
|
420 |
*/
|
421 |
function ui_get_link_text($context = 'display'){
|
422 |
+
$parser = & $this->get_parser();
|
423 |
|
424 |
if ( !is_null($parser) ){
|
425 |
$text = $parser->ui_get_link_text($this, $context);
|
441 |
*/
|
442 |
function ui_get_action_links(){
|
443 |
//The container is responsible for generating the links.
|
444 |
+
$container = & $this->get_container();
|
445 |
if ( !is_null($container) ){
|
446 |
return $container->ui_get_action_links($this->container_field);
|
447 |
} else {
|
459 |
*/
|
460 |
function ui_get_source($context = 'display'){
|
461 |
//The container is also responsible for generating the "Source" column HTML.
|
462 |
+
$container = & $this->get_container();
|
463 |
if ( !is_null($container) ){
|
464 |
return $container->ui_get_source($this->container_field, $context);
|
465 |
} else {
|
492 |
|
493 |
//Skip instances that reference containers or parsers that aren't currently loaded
|
494 |
if ( !$include_invalid ){
|
495 |
+
$manager = & blcModuleManager::getInstance();
|
496 |
+
$active_containers = $manager->get_escaped_ids('container');
|
497 |
+
$active_parsers = $manager->get_escaped_ids('parser');
|
|
|
|
|
|
|
|
|
498 |
|
499 |
+
$q .= " AND container_type IN ({$active_containers}) ";
|
500 |
+
$q .= " AND parser_type IN ({$active_parsers}) ";
|
501 |
}
|
502 |
|
503 |
$results = $wpdb->get_results($q, ARRAY_A);
|
519 |
);
|
520 |
}
|
521 |
|
522 |
+
$containers = blcContainerHelper::get_containers($container_ids, $purpose, $load_wrapped_objects);
|
523 |
}
|
524 |
|
525 |
//Create an object for each instance and group them by link ID
|
556 |
$q = "SELECT COUNT(instance_id) FROM {$wpdb->prefix}blc_instances WHERE 1";
|
557 |
|
558 |
//Skip instances that reference containers or parsers that aren't currently loaded
|
559 |
+
$manager = & blcModuleManager::getInstance();
|
560 |
+
$active_containers = $manager->get_escaped_ids('container');
|
561 |
+
$active_parsers = $manager->get_escaped_ids('parser');
|
|
|
562 |
|
563 |
+
$q .= " AND container_type IN ({$active_containers}) ";
|
564 |
+
$q .= " AND parser_type IN ({$active_parsers}) ";
|
|
|
|
|
|
|
565 |
|
566 |
return $wpdb->get_var($q);
|
567 |
}
|
583 |
synch.container_id IS NULL";
|
584 |
$rez = $wpdb->query($q);
|
585 |
|
586 |
+
//Delete instances that reference containers and parsers that are no longer active
|
587 |
+
$manager = & blcModuleManager::getInstance();
|
588 |
+
$active_containers = $manager->get_escaped_ids('container');
|
589 |
+
$active_parsers = $manager->get_escaped_ids('parser');
|
|
|
|
|
|
|
|
|
|
|
|
|
590 |
|
591 |
$q = "DELETE instances.*
|
592 |
FROM {$wpdb->prefix}blc_instances AS instances
|
593 |
WHERE
|
594 |
+
instances.container_type NOT IN ({$active_containers}) OR
|
595 |
+
instances.parser_type NOT IN ({$active_parsers})";
|
596 |
$rez2 = $wpdb->query($q);
|
597 |
|
598 |
return ($rez !== false) && ($rez2 !== false);
|
includes/link-query.php
ADDED
@@ -0,0 +1,764 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class for querying, sorting and filtering links.
|
5 |
+
* Used as a singleton.
|
6 |
+
*
|
7 |
+
* @package Broken Link Checker
|
8 |
+
* @access public
|
9 |
+
*/
|
10 |
+
class blcLinkQuery {
|
11 |
+
|
12 |
+
var $native_filters;
|
13 |
+
var $search_filter;
|
14 |
+
var $custom_filters = array();
|
15 |
+
|
16 |
+
var $valid_url_params = array();
|
17 |
+
|
18 |
+
function __construct(){
|
19 |
+
//Init. the available native filters.
|
20 |
+
$this->native_filters = array(
|
21 |
+
'broken' => array(
|
22 |
+
'params' => array(
|
23 |
+
'where_expr' => '( broken = 1 )',
|
24 |
+
),
|
25 |
+
'name' => __('Broken', 'broken-link-checker'),
|
26 |
+
'heading' => __('Broken Links', 'broken-link-checker'),
|
27 |
+
'heading_zero' => __('No broken links found', 'broken-link-checker'),
|
28 |
+
'native' => true,
|
29 |
+
),
|
30 |
+
'redirects' => array(
|
31 |
+
'params' => array(
|
32 |
+
'where_expr' => '( redirect_count > 0 )',
|
33 |
+
),
|
34 |
+
'name' => __('Redirects', 'broken-link-checker'),
|
35 |
+
'heading' => __('Redirected Links', 'broken-link-checker'),
|
36 |
+
'heading_zero' => __('No redirects found', 'broken-link-checker'),
|
37 |
+
'native' => true,
|
38 |
+
),
|
39 |
+
|
40 |
+
'all' => array(
|
41 |
+
'params' => array(
|
42 |
+
'where_expr' => '1',
|
43 |
+
),
|
44 |
+
'name' => __('All', 'broken-link-checker'),
|
45 |
+
'heading' => __('Detected Links', 'broken-link-checker'),
|
46 |
+
'heading_zero' => __('No links found (yet)', 'broken-link-checker'),
|
47 |
+
'native' => true,
|
48 |
+
),
|
49 |
+
);
|
50 |
+
|
51 |
+
//Create the special "search" filter
|
52 |
+
$this->search_filter = array(
|
53 |
+
'name' => __('Search', 'broken-link-checker'),
|
54 |
+
'heading' => __('Search Results', 'broken-link-checker'),
|
55 |
+
'heading_zero' => __('No links found for your query', 'broken-link-checker'),
|
56 |
+
'params' => array(),
|
57 |
+
'use_url_params' => true,
|
58 |
+
'hidden' => true,
|
59 |
+
);
|
60 |
+
|
61 |
+
//These search arguments may be passed via the URL if the filter's 'use_url_params' field is set to True.
|
62 |
+
//They map to the fields of the search form on the Tools -> Broken Links page. Only these arguments
|
63 |
+
//can be used in user-defined filters.
|
64 |
+
$this->valid_url_params = array(
|
65 |
+
's_link_text',
|
66 |
+
's_link_url',
|
67 |
+
's_parser_type',
|
68 |
+
's_container_type',
|
69 |
+
's_link_type',
|
70 |
+
's_http_code',
|
71 |
+
's_filter',
|
72 |
+
);
|
73 |
+
}
|
74 |
+
|
75 |
+
function blcLinkQuery(){
|
76 |
+
$this->__construct();
|
77 |
+
}
|
78 |
+
|
79 |
+
function &getInstance(){
|
80 |
+
static $instance = null;
|
81 |
+
if ( is_null($instance) ){
|
82 |
+
$instance = new blcLinkQuery;
|
83 |
+
}
|
84 |
+
return $instance;
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Load and return the list of user-defined link filters.
|
89 |
+
*
|
90 |
+
* @return array An array of custom filter definitions. If there are no custom filters defined returns an empty array.
|
91 |
+
*/
|
92 |
+
function load_custom_filters(){
|
93 |
+
global $wpdb;
|
94 |
+
|
95 |
+
$filter_data = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}blc_filters ORDER BY name ASC", ARRAY_A);
|
96 |
+
$filters = array();
|
97 |
+
|
98 |
+
if ( !empty($filter_data) ) {
|
99 |
+
foreach($filter_data as $data){
|
100 |
+
wp_parse_str($data['params'], $params);
|
101 |
+
|
102 |
+
$filters[ 'f'.$data['id'] ] = array(
|
103 |
+
'name' => $data['name'],
|
104 |
+
'params' => $params,
|
105 |
+
'heading' => ucwords($data['name']),
|
106 |
+
'heading_zero' => __('No links found for your query', 'broken-link-checker'),
|
107 |
+
'custom' => true,
|
108 |
+
);
|
109 |
+
}
|
110 |
+
}
|
111 |
+
|
112 |
+
$this->custom_filters = $filters;
|
113 |
+
|
114 |
+
return $filters;
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Add a custom link filter.
|
119 |
+
*
|
120 |
+
* @param string $name Filter name.
|
121 |
+
* @param string|array $params Filter params. Either as a query string, or an array.
|
122 |
+
* @return string|bool The ID of the newly added filter, or False.
|
123 |
+
*/
|
124 |
+
function create_custom_filter($name, $params){
|
125 |
+
global $wpdb;
|
126 |
+
|
127 |
+
if ( is_array($params) ){
|
128 |
+
$params = http_build_query($params, null, '&');
|
129 |
+
}
|
130 |
+
|
131 |
+
//Save the new filter
|
132 |
+
$q = $wpdb->prepare(
|
133 |
+
"INSERT INTO {$wpdb->prefix}blc_filters(name, params) VALUES (%s, %s)",
|
134 |
+
$name, $params
|
135 |
+
);
|
136 |
+
|
137 |
+
if ( $wpdb->query($q) !== false ){
|
138 |
+
$filter_id = 'f'.$wpdb->insert_id;
|
139 |
+
return $filter_id;
|
140 |
+
} else {
|
141 |
+
return false;
|
142 |
+
}
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Delete a custom filter
|
147 |
+
*
|
148 |
+
* @param string $filter_id
|
149 |
+
* @return bool True on success, False if a database error occured.
|
150 |
+
*/
|
151 |
+
function delete_custom_filter($filter_id){
|
152 |
+
global $wpdb;
|
153 |
+
|
154 |
+
//Remove the "f" character from the filter ID to get its database key
|
155 |
+
$filter_id = intval(ltrim($_POST['filter_id'], 'f'));
|
156 |
+
|
157 |
+
//Try to delete the filter
|
158 |
+
$q = $wpdb->prepare("DELETE FROM {$wpdb->prefix}blc_filters WHERE id = %d", $filter_id);
|
159 |
+
if ( $wpdb->query($q) !== false ){
|
160 |
+
return true;
|
161 |
+
} else {
|
162 |
+
return false;
|
163 |
+
}
|
164 |
+
}
|
165 |
+
|
166 |
+
function get_filters(){
|
167 |
+
$filters = array_merge($this->native_filters, $this->custom_filters);
|
168 |
+
$filters['search'] = $this->search_filter;
|
169 |
+
return $filters;
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Get a link search filter by filter ID.
|
174 |
+
*
|
175 |
+
* @param string $filter_id
|
176 |
+
* @return array|null
|
177 |
+
*/
|
178 |
+
function get_filter($filter_id){
|
179 |
+
$filters = $this->get_filters();
|
180 |
+
if ( isset($filters[$filter_id]) ){
|
181 |
+
return $filters[$filter_id];
|
182 |
+
} else {
|
183 |
+
return null;
|
184 |
+
}
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Get link search parameters from the specified filter.
|
189 |
+
*
|
190 |
+
* @param array $filter
|
191 |
+
* @return array An array of parameters suitable for use with blcLinkQuery::get_links()
|
192 |
+
*/
|
193 |
+
function get_search_params( $filter = null ){
|
194 |
+
//If present, the filter's parameters may be saved either as an array or a string.
|
195 |
+
$params = array();
|
196 |
+
if ( !empty($filter) && !empty($filter['params']) ){
|
197 |
+
$params = $filter['params'];
|
198 |
+
if ( is_string( $params ) ){
|
199 |
+
wp_parse_str($params, $params);
|
200 |
+
}
|
201 |
+
}
|
202 |
+
|
203 |
+
//Merge in the parameters from the current request, if required
|
204 |
+
if ( isset($filter['use_url_params']) && $filter['use_url_params'] ){
|
205 |
+
$params = array_merge($params, $this->get_url_search_params());
|
206 |
+
}
|
207 |
+
|
208 |
+
return $params;
|
209 |
+
}
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Extract search query parameters from the current URL
|
213 |
+
*
|
214 |
+
* @return array
|
215 |
+
*/
|
216 |
+
function get_url_search_params(){
|
217 |
+
$url_params = array();
|
218 |
+
foreach ($_GET as $param => $value){
|
219 |
+
if ( in_array($param, $this->valid_url_params) ){
|
220 |
+
$url_params[$param] = $value;
|
221 |
+
}
|
222 |
+
}
|
223 |
+
return $url_params;
|
224 |
+
}
|
225 |
+
|
226 |
+
|
227 |
+
|
228 |
+
/**
|
229 |
+
* A helper method for parsing a list of search criteria and generating the parts of the SQL query.
|
230 |
+
*
|
231 |
+
* @see blcLinkQuery::get_links()
|
232 |
+
*
|
233 |
+
* @param array $params An array of search criteria.
|
234 |
+
* @return array 'where_exprs' - an array of search expressions, 'join_instances' - whether joining the instance table is required.
|
235 |
+
*/
|
236 |
+
function compile_search_params($params){
|
237 |
+
global $wpdb;
|
238 |
+
|
239 |
+
//Track whether we'll need to left-join the instance table to run the query.
|
240 |
+
$join_instances = false;
|
241 |
+
|
242 |
+
//Generate the individual clauses of the WHERE expression and store them in an array.
|
243 |
+
$pieces = array();
|
244 |
+
|
245 |
+
//Convert parser and container type lists to arrays of valid values
|
246 |
+
$s_parser_type = array();
|
247 |
+
if ( !empty($params['s_parser_type']) ){
|
248 |
+
$s_parser_type = $params['s_parser_type'];
|
249 |
+
if ( is_string($s_parser_type) ){
|
250 |
+
$s_parser_type = preg_split('/[,\s]+/', $s_parser_type);
|
251 |
+
}
|
252 |
+
}
|
253 |
+
|
254 |
+
$s_container_type = array();
|
255 |
+
if ( !empty($params['s_container_type']) ){
|
256 |
+
$s_container_type = $params['s_container_type'];
|
257 |
+
if ( is_string($s_container_type) ){
|
258 |
+
$s_container_type = preg_split('/[,\s]+/', $s_container_type);
|
259 |
+
}
|
260 |
+
}
|
261 |
+
|
262 |
+
//Don't include links with instances that reference invalid (not currently loaded)
|
263 |
+
//containers and parsers (unless specifically told to also include invalid links).
|
264 |
+
if ( empty($params['include_invalid']) ){
|
265 |
+
$join_instances = true;
|
266 |
+
|
267 |
+
$module_manager = & blcModuleManager::getInstance();
|
268 |
+
$loaded_containers = array_keys($module_manager->get_active_by_category('container'));
|
269 |
+
$loaded_parsers = array_keys($module_manager->get_active_by_category('parser'));
|
270 |
+
|
271 |
+
if ( empty($s_parser_type) ){
|
272 |
+
$s_parser_type = $loaded_parsers;
|
273 |
+
} else {
|
274 |
+
$s_parser_type = array_intersect($s_parser_type, $loaded_parsers);
|
275 |
+
}
|
276 |
+
|
277 |
+
if ( empty($s_container_type) ){
|
278 |
+
$s_container_type = $loaded_containers;
|
279 |
+
} else {
|
280 |
+
$s_container_type = array_intersect($s_container_type, $loaded_containers);
|
281 |
+
}
|
282 |
+
}
|
283 |
+
|
284 |
+
//Parser type should match the parser_type column in the instance table.
|
285 |
+
if ( !empty($s_parser_type) ){
|
286 |
+
$s_parser_type = array_map('trim', array_unique($s_parser_type));
|
287 |
+
$s_parser_type = array_map(array(&$wpdb, 'escape'), $s_parser_type);
|
288 |
+
|
289 |
+
if ( count($s_parser_type) == 1 ){
|
290 |
+
$pieces[] = sprintf("instances.parser_type = '%s'", reset($s_parser_type));
|
291 |
+
} else {
|
292 |
+
$pieces[] = "instances.parser_type IN ('" . implode("', '", $s_parser_type) . "')";
|
293 |
+
}
|
294 |
+
|
295 |
+
$join_instances = true;
|
296 |
+
}
|
297 |
+
|
298 |
+
//Container type should match the container_type column in the instance table.
|
299 |
+
if ( !empty($s_container_type) ){
|
300 |
+
//Sanitize for use in SQL
|
301 |
+
$s_container_type = array_map('trim', array_unique($s_container_type));
|
302 |
+
$s_container_type = array_map(array(&$wpdb, 'escape'), $s_container_type);
|
303 |
+
|
304 |
+
if ( count($s_container_type) == 1 ){
|
305 |
+
$pieces[] = sprintf("instances.container_type = '%s'", reset($s_container_type));
|
306 |
+
} else {
|
307 |
+
$pieces[] = "instances.container_type IN ('" . implode("', '", $s_container_type) . "')";
|
308 |
+
}
|
309 |
+
|
310 |
+
$join_instances = true;
|
311 |
+
}
|
312 |
+
|
313 |
+
//A part of the WHERE expression can be specified explicitly
|
314 |
+
if ( !empty($params['where_expr']) ){
|
315 |
+
$pieces[] = $params['where_expr'];
|
316 |
+
$join_instances = $join_instances || ( stripos($params['where_expr'], 'instances') !== false );
|
317 |
+
}
|
318 |
+
|
319 |
+
//List of allowed link ids (either an array or comma-separated)
|
320 |
+
if ( !empty($params['link_ids']) ){
|
321 |
+
$link_ids = $params['link_ids'];
|
322 |
+
|
323 |
+
if ( is_string($link_ids) ){
|
324 |
+
$link_ids = preg_split('/[,\s]+/', $link_ids);
|
325 |
+
}
|
326 |
+
|
327 |
+
//Only accept non-zero integers
|
328 |
+
$sanitized_link_ids = array();
|
329 |
+
foreach($link_ids as $id){
|
330 |
+
$id = intval($id);
|
331 |
+
if ( $id != 0 ){
|
332 |
+
$sanitized_link_ids[] = $id;
|
333 |
+
}
|
334 |
+
}
|
335 |
+
|
336 |
+
$pieces[] = 'links.link_id IN (' . implode(', ', $sanitized_link_ids) . ')';
|
337 |
+
}
|
338 |
+
|
339 |
+
//Anchor text - use LIKE search
|
340 |
+
if ( !empty($params['s_link_text']) ){
|
341 |
+
$s_link_text = like_escape($wpdb->escape($params['s_link_text']));
|
342 |
+
$s_link_text = str_replace('*', '%', $s_link_text);
|
343 |
+
|
344 |
+
$pieces[] = '(instances.link_text LIKE "%' . $s_link_text . '%")';
|
345 |
+
$join_instances = true;
|
346 |
+
}
|
347 |
+
|
348 |
+
//URL - try to match both the initial URL and the final URL.
|
349 |
+
//There is limited wildcard support, e.g. "google.*/search" will match both
|
350 |
+
//"google.com/search" and "google.lv/search"
|
351 |
+
if ( !empty($params['s_link_url']) ){
|
352 |
+
$s_link_url = like_escape($wpdb->escape($params['s_link_url']));
|
353 |
+
$s_link_url = str_replace('*', '%', $s_link_url);
|
354 |
+
|
355 |
+
$pieces[] = '(links.url LIKE "%'. $s_link_url .'%") OR '.
|
356 |
+
'(links.final_url LIKE "%'. $s_link_url .'%")';
|
357 |
+
}
|
358 |
+
|
359 |
+
//Container ID should match... you guessed it - container_id
|
360 |
+
if ( !empty($params['s_container_id']) ){
|
361 |
+
$s_container_id = intval($params['s_container_id']);
|
362 |
+
if ( $s_container_id != 0 ){
|
363 |
+
$pieces[] = "instances.container_id = $s_container_id";
|
364 |
+
$join_instances = true;
|
365 |
+
}
|
366 |
+
}
|
367 |
+
|
368 |
+
//Link type can match either the the parser_type or the container_type.
|
369 |
+
if ( !empty($params['s_link_type']) ){
|
370 |
+
$s_link_type = $wpdb->escape($params['s_link_type']);
|
371 |
+
$pieces[] = "instances.parser_type = '$s_link_type' OR instances.container_type='$s_link_type'";
|
372 |
+
$join_instances = true;
|
373 |
+
}
|
374 |
+
|
375 |
+
//HTTP code - the user can provide a list of HTTP response codes and code ranges.
|
376 |
+
//Example : 201,400-410,500
|
377 |
+
if ( !empty($params['s_http_code']) ){
|
378 |
+
//Strip spaces.
|
379 |
+
$params['s_http_code'] = str_replace(' ', '', $params['s_http_code']);
|
380 |
+
//Split by comma
|
381 |
+
$codes = explode(',', $params['s_http_code']);
|
382 |
+
|
383 |
+
$individual_codes = array();
|
384 |
+
$ranges = array();
|
385 |
+
|
386 |
+
//Try to parse each response code or range. Invalid ones are simply ignored.
|
387 |
+
foreach($codes as $code){
|
388 |
+
if ( is_numeric($code) ){
|
389 |
+
//It's a single number
|
390 |
+
$individual_codes[] = abs(intval($code));
|
391 |
+
} elseif ( strpos($code, '-') !== false ) {
|
392 |
+
//Try to parse it as a range
|
393 |
+
$range = explode( '-', $code, 2 );
|
394 |
+
if ( (count($range) == 2) && is_numeric($range[0]) && is_numeric($range[0]) ){
|
395 |
+
//Make sure the smaller code comes first
|
396 |
+
$range = array( intval($range[0]), intval($range[1]) );
|
397 |
+
$ranges[] = array( min($range), max($range) );
|
398 |
+
}
|
399 |
+
}
|
400 |
+
}
|
401 |
+
|
402 |
+
$piece = array();
|
403 |
+
|
404 |
+
//All individual response codes get one "http_code IN (...)" clause
|
405 |
+
if ( !empty($individual_codes) ){
|
406 |
+
$piece[] = '(links.http_code IN ('. implode(', ', $individual_codes) .'))';
|
407 |
+
}
|
408 |
+
|
409 |
+
//Ranges get a "http_code BETWEEN min AND max" clause each
|
410 |
+
if ( !empty($ranges) ){
|
411 |
+
$range_strings = array();
|
412 |
+
foreach($ranges as $range){
|
413 |
+
$range_strings[] = "(links.http_code BETWEEN $range[0] AND $range[1])";
|
414 |
+
}
|
415 |
+
$piece[] = '( ' . implode(' OR ', $range_strings) . ' )';
|
416 |
+
}
|
417 |
+
|
418 |
+
//Finally, generate a composite WHERE clause for both types of response code queries
|
419 |
+
if ( !empty($piece) ){
|
420 |
+
$pieces[] = implode(' OR ', $piece);
|
421 |
+
}
|
422 |
+
|
423 |
+
}
|
424 |
+
|
425 |
+
//Custom filters can optionally call one of the native filters
|
426 |
+
//to narrow down the result set.
|
427 |
+
if ( !empty($params['s_filter']) && isset($this->native_filters[$params['s_filter']]) ){
|
428 |
+
$the_filter = $this->native_filters[$params['s_filter']];
|
429 |
+
$extra_criteria = $this->compile_search_params($the_filter['params']);
|
430 |
+
|
431 |
+
$pieces = array_merge($pieces, $extra_criteria['where_exprs']);
|
432 |
+
$join_instances = $join_instances || $extra_criteria['join_instances'];
|
433 |
+
}
|
434 |
+
|
435 |
+
return array(
|
436 |
+
'where_exprs' => $pieces,
|
437 |
+
'join_instances' => $join_instances,
|
438 |
+
);
|
439 |
+
}
|
440 |
+
|
441 |
+
/**
|
442 |
+
* blcLinkQuery::get_links()
|
443 |
+
*
|
444 |
+
* @see blc_get_links()
|
445 |
+
*
|
446 |
+
* @param array $params
|
447 |
+
* @param string $purpose
|
448 |
+
* @return array|int
|
449 |
+
*/
|
450 |
+
function get_links($params = null){
|
451 |
+
global $wpdb;
|
452 |
+
|
453 |
+
if( !is_array($params) ){
|
454 |
+
$params = array();
|
455 |
+
}
|
456 |
+
|
457 |
+
$defaults = array(
|
458 |
+
'offset' => 0,
|
459 |
+
'max_results' => 0,
|
460 |
+
'load_instances' => false,
|
461 |
+
'load_containers' => false,
|
462 |
+
'load_wrapped_objects' => false,
|
463 |
+
'count_only' => false,
|
464 |
+
'purpose' => '',
|
465 |
+
'include_invalid' => false,
|
466 |
+
);
|
467 |
+
|
468 |
+
$params = array_merge($defaults, $params);
|
469 |
+
|
470 |
+
//Compile the search-related params into search expressions usable in a WHERE clause
|
471 |
+
$criteria = $this->compile_search_params($params);
|
472 |
+
|
473 |
+
//Build the WHERE clause
|
474 |
+
if ( !empty($criteria['where_exprs']) ){
|
475 |
+
$where_expr = "\t( " . implode(" ) AND\n\t( ", $criteria['where_exprs']) . ' ) ';
|
476 |
+
} else {
|
477 |
+
$where_expr = '1';
|
478 |
+
}
|
479 |
+
|
480 |
+
//Join the blc_instances table if it's required to perform the search.
|
481 |
+
$joins = "";
|
482 |
+
if ( $criteria['join_instances'] ){
|
483 |
+
$joins = "JOIN {$wpdb->prefix}blc_instances AS instances ON links.link_id = instances.link_id";
|
484 |
+
}
|
485 |
+
|
486 |
+
if ( $params['count_only'] ){
|
487 |
+
//Only get the number of matching links.
|
488 |
+
$q = "
|
489 |
+
SELECT COUNT(*)
|
490 |
+
FROM (
|
491 |
+
SELECT 0
|
492 |
+
|
493 |
+
FROM
|
494 |
+
{$wpdb->prefix}blc_links AS links
|
495 |
+
$joins
|
496 |
+
|
497 |
+
WHERE
|
498 |
+
$where_expr
|
499 |
+
|
500 |
+
GROUP BY links.link_id) AS foo";
|
501 |
+
|
502 |
+
return $wpdb->get_var($q);
|
503 |
+
}
|
504 |
+
|
505 |
+
//Select the required links.
|
506 |
+
$q = "SELECT
|
507 |
+
links.*
|
508 |
+
|
509 |
+
FROM
|
510 |
+
{$wpdb->prefix}blc_links AS links
|
511 |
+
$joins
|
512 |
+
|
513 |
+
WHERE
|
514 |
+
$where_expr
|
515 |
+
|
516 |
+
GROUP BY links.link_id"; //Note: would be a lot faster without GROUP BY
|
517 |
+
|
518 |
+
//Add the LIMIT clause
|
519 |
+
if ( $params['max_results'] || $params['offset'] ){
|
520 |
+
$q .= sprintf("\nLIMIT %d, %d", $params['offset'], $params['max_results']);
|
521 |
+
}
|
522 |
+
|
523 |
+
$results = $wpdb->get_results($q, ARRAY_A);
|
524 |
+
if ( empty($results) ){
|
525 |
+
return array();
|
526 |
+
}
|
527 |
+
|
528 |
+
//Create the link objects
|
529 |
+
$links = array();
|
530 |
+
|
531 |
+
foreach($results as $result){
|
532 |
+
$link = new blcLink($result);
|
533 |
+
$links[$link->link_id] = $link;
|
534 |
+
}
|
535 |
+
|
536 |
+
$purpose = $params['purpose'];
|
537 |
+
/*
|
538 |
+
Preload instances if :
|
539 |
+
* It has been requested via the 'load_instances' argument.
|
540 |
+
* The links are going to be displayed or edited, which involves instances.
|
541 |
+
*/
|
542 |
+
$load_instances = $params['load_instances'] || in_array($purpose, array(BLC_FOR_DISPLAY, BLC_FOR_EDITING));
|
543 |
+
|
544 |
+
if ( $load_instances ){
|
545 |
+
$link_ids = array_keys($links);
|
546 |
+
$all_instances = blc_get_instances($link_ids, $purpose, $params['load_containers'], $params['load_wrapped_objects']);
|
547 |
+
//Assign each batch of instances to the right link
|
548 |
+
foreach($all_instances as $link_id => $instances){
|
549 |
+
$links[$link_id]->_instances = $instances;
|
550 |
+
}
|
551 |
+
}
|
552 |
+
|
553 |
+
return $links;
|
554 |
+
}
|
555 |
+
|
556 |
+
/**
|
557 |
+
* Calculate the number of results for all known filters
|
558 |
+
*
|
559 |
+
* @return void
|
560 |
+
*/
|
561 |
+
function count_filter_results(){
|
562 |
+
foreach($this->native_filters as $filter_id => $filter){
|
563 |
+
$this->native_filters[$filter_id]['count'] = $this->get_filter_links(
|
564 |
+
$filter, array('count_only' => true)
|
565 |
+
);
|
566 |
+
}
|
567 |
+
|
568 |
+
foreach($this->custom_filters as $filter_id => $filter){
|
569 |
+
$this->custom_filters[$filter_id]['count'] = $this->get_filter_links(
|
570 |
+
$filter, array('count_only' => true)
|
571 |
+
);
|
572 |
+
}
|
573 |
+
|
574 |
+
$this->search_filter['count'] = $this->get_filter_links($this->search_filter, array('count_only' => true));
|
575 |
+
}
|
576 |
+
|
577 |
+
/**
|
578 |
+
* Retrieve a list of links matching a filter.
|
579 |
+
*
|
580 |
+
* @uses blcLinkQuery::get_links()
|
581 |
+
*
|
582 |
+
* @param string|array $filter Either a filter ID or an array containing filter data.
|
583 |
+
* @param array $extra_params Optional extra criteria that will override those set by the filter. See blc_get_links() for details.
|
584 |
+
* @return array|int Either an array of blcLink objects, or an integer indicating the number of links that match the filter.
|
585 |
+
*/
|
586 |
+
function get_filter_links($filter, $extra_params = null){
|
587 |
+
if ( is_string($filter) ){
|
588 |
+
$filter = $this->get_filter($filter);
|
589 |
+
}
|
590 |
+
|
591 |
+
$params = $this->get_search_params($filter);
|
592 |
+
|
593 |
+
|
594 |
+
if ( !empty($extra_params) ){
|
595 |
+
$params = array_merge($params, $extra_params);
|
596 |
+
}
|
597 |
+
|
598 |
+
return $this->get_links($params);
|
599 |
+
}
|
600 |
+
|
601 |
+
/**
|
602 |
+
* Print a menu of available filters, both native and user-created.
|
603 |
+
*
|
604 |
+
* @param string $current Current filter ID.
|
605 |
+
* @return void
|
606 |
+
*/
|
607 |
+
function print_filter_menu($current = ''){
|
608 |
+
$filters = $this->get_filters();
|
609 |
+
|
610 |
+
echo '<ul class="subsubsub">';
|
611 |
+
|
612 |
+
//Construct a submenu of filter types
|
613 |
+
$items = array();
|
614 |
+
foreach ($filters as $filter => $data){
|
615 |
+
if ( !empty($data['hidden']) ) continue; //skip hidden filters
|
616 |
+
|
617 |
+
$class = $number_class = '';
|
618 |
+
|
619 |
+
if ( $current == $filter ) {
|
620 |
+
$class = 'class="current"';
|
621 |
+
$number_class = 'current-link-count';
|
622 |
+
}
|
623 |
+
|
624 |
+
$items[] = "<li><a href='tools.php?page=view-broken-links&filter_id=$filter' $class>
|
625 |
+
{$data['name']}</a> <span class='count'>(<span class='$number_class'>{$data['count']}</span>)</span>";
|
626 |
+
}
|
627 |
+
echo implode(' |</li>', $items);
|
628 |
+
|
629 |
+
echo '</ul>';
|
630 |
+
}
|
631 |
+
|
632 |
+
/**
|
633 |
+
* Print the appropriate heading for the given filter.
|
634 |
+
*
|
635 |
+
* @param array $current_filter
|
636 |
+
* @return void
|
637 |
+
*/
|
638 |
+
function print_filter_heading($current_filter){
|
639 |
+
echo '<h2>';
|
640 |
+
//Output a header matching the current filter
|
641 |
+
if ( $current_filter['count'] > 0 ){
|
642 |
+
echo $current_filter['heading'] . " (<span class='current-link-count'>{$current_filter['count']}</span>)";
|
643 |
+
} else {
|
644 |
+
echo $current_filter['heading_zero'] . "<span class='current-link-count'></span>";
|
645 |
+
}
|
646 |
+
echo '</h2>';
|
647 |
+
}
|
648 |
+
|
649 |
+
/**
|
650 |
+
* Execute a filter.
|
651 |
+
*
|
652 |
+
* Gathers paging and search parameters from $_GET and executes the specified filter.
|
653 |
+
* The returned array contains standard filter data plus several additional fields :
|
654 |
+
* 'filter_id' - Which filter was used. May differ from the specified $filter_id due to fallback settings.
|
655 |
+
* 'per_page' - How many results per page the method tried to retrieve.
|
656 |
+
* 'page' - Which page of results was retrieved.
|
657 |
+
* 'max_pages' - The total number of results pages, calculated using the above 'per_page' value.
|
658 |
+
* 'links' - An array of retrieved links (blcLink objects).
|
659 |
+
* 'search_params' - An associative array of the current search parameters as extracted either from the current URL or the filter itself.
|
660 |
+
* 'is_broken_filter' - TRUE if the filter was set to retrieve only broken links, FALSE otherwise.
|
661 |
+
*
|
662 |
+
* @param string $filter_id Filter ID.
|
663 |
+
* @param int $page Optional. Which page of results to retrieve. Defaults to returning the first page of results.
|
664 |
+
* @param int $per_page Optional. The number of results per page. Defaults to 30.
|
665 |
+
* @param string $fallback Optional. Which filter to use if none match the specified $filter_id. Defaults to the native broken link filter.
|
666 |
+
* @return array Associative array of filter data and the results of its execution.
|
667 |
+
*/
|
668 |
+
function exec_filter($filter_id, $page = 1, $per_page = 30, $fallback = 'broken'){
|
669 |
+
|
670 |
+
//Get the selected filter (defaults to displaying broken links)
|
671 |
+
$current_filter = $this->get_filter($filter_id);
|
672 |
+
if ( empty($current_filter) ){
|
673 |
+
$current_filter = $this->get_filter($fallback);
|
674 |
+
$filter_id = $fallback;
|
675 |
+
}
|
676 |
+
|
677 |
+
//Page number must be > 0
|
678 |
+
if ($page < 1) $page = 1;
|
679 |
+
|
680 |
+
//Links per page [1 - 500]
|
681 |
+
if ($per_page < 1){
|
682 |
+
$per_page = 30;
|
683 |
+
} else if ($per_page > 500){
|
684 |
+
$per_page = 500;
|
685 |
+
}
|
686 |
+
|
687 |
+
//Calculate the maximum number of pages.
|
688 |
+
$max_pages = ceil($current_filter['count'] / $per_page);
|
689 |
+
|
690 |
+
//Select the required links
|
691 |
+
$extra_params = array(
|
692 |
+
'offset' => ( ($page-1) * $per_page ),
|
693 |
+
'max_results' => $per_page,
|
694 |
+
'purpose' => BLC_FOR_DISPLAY,
|
695 |
+
);
|
696 |
+
$links = $this->get_filter_links($current_filter, $extra_params);
|
697 |
+
|
698 |
+
//If the current request is a user-initiated search query (either directly or
|
699 |
+
//via a custom filter), save the search params. They can later be used to pre-fill
|
700 |
+
//the search form or build a new/modified custom filter.
|
701 |
+
$search_params = array();
|
702 |
+
if ( !empty($current_filter['custom']) || ($filter_id == 'search') ){
|
703 |
+
$search_params = $this->get_search_params($current_filter);
|
704 |
+
}
|
705 |
+
|
706 |
+
//TODO: Simplify this. Maybe overhaul the filter system to let us query the effective filter.
|
707 |
+
$is_broken_filter =
|
708 |
+
($filter_id == 'broken')
|
709 |
+
|| ( isset($current_filter['params']['s_filter']) && ($current_filter['params']['s_filter'] == 'broken') )
|
710 |
+
|| ( isset($_GET['s_filter']) && ($_GET['s_filter'] == 'broken') );
|
711 |
+
|
712 |
+
//Save the effective filter data in the filter array.
|
713 |
+
//It can be used later to print the link table.
|
714 |
+
$current_filter = array_merge(array(
|
715 |
+
'filter_id' => $filter_id,
|
716 |
+
'page' => $page,
|
717 |
+
'per_page' => $per_page,
|
718 |
+
'max_pages' => $max_pages,
|
719 |
+
'links' => $links,
|
720 |
+
'search_params' => $search_params,
|
721 |
+
'is_broken_filter' => $is_broken_filter,
|
722 |
+
), $current_filter);
|
723 |
+
|
724 |
+
return $current_filter;
|
725 |
+
}
|
726 |
+
}
|
727 |
+
|
728 |
+
/**
|
729 |
+
* Retrieve a list of links matching some criteria.
|
730 |
+
*
|
731 |
+
* The function argument should be an associative array describing the criteria.
|
732 |
+
* The supported keys are :
|
733 |
+
* 'offset' - Skip the first X results. Default is 0.
|
734 |
+
* 'max_results' - The maximum number of links to return. Defaults to returning all results.
|
735 |
+
* 'link_ids' - Retrieve only links with these IDs. This should either be a comma-separated list or an array.
|
736 |
+
* 's_link_text' - Link text must match this keyphrase (performs a fulltext search).
|
737 |
+
* 's_link_url' - Link URL must contain this string. You can use "*" as a wildcard.
|
738 |
+
* 's_parser_type' - Filter links by the type of link parser that was used to find them.
|
739 |
+
* 's_container_type' - Filter links by where they were found, e.g. 'post'.
|
740 |
+
* 's_container_id' - Find links that belong to a container with this ID (should be used together with s_container_type).
|
741 |
+
* 's_link_type' - Either parser type or container type must match this.
|
742 |
+
* 's_http_code' - Filter by HTTP code. Example : 201,400-410,500
|
743 |
+
* 's_filter' - Use a built-in filter. Available filters : 'broken', 'redirects', 'all'
|
744 |
+
* 'where_expr' - Advanced. Lets you directly specify a part of the WHERE clause.
|
745 |
+
* 'load_instances' - Pre-load all link instance data for each link. Default is false.
|
746 |
+
* 'load_containers' - Pre-load container data for each instance. Default is false.
|
747 |
+
* 'load_wrapped_objects' - Pre-load wrapped object data (e.g. posts, comments, etc) for each container. Default is false.
|
748 |
+
* 'count_only' - Only return the number of results (int), not the whole result set. 'offset' and 'max_results' will be ignored if this is set. Default is false.
|
749 |
+
* 'purpose' - An optional code indicating how the links will be used.
|
750 |
+
* 'include_invalid' - Include links that have no instances and links that only have instances that reference not-loaded containers or parsers. Defaults to false.
|
751 |
+
*
|
752 |
+
* All keys are optional.
|
753 |
+
*
|
754 |
+
* @uses blcLinkQuery::get_links();
|
755 |
+
*
|
756 |
+
* @param array $params
|
757 |
+
* @return int|array Either an array of blcLink objects, or the number of results for the query.
|
758 |
+
*/
|
759 |
+
function blc_get_links($params = null){
|
760 |
+
$instance = & blcLinkQuery::getInstance();
|
761 |
+
return $instance->get_links($params, $purpose);
|
762 |
+
}
|
763 |
+
|
764 |
+
?>
|
includes/links.php
CHANGED
@@ -6,6 +6,13 @@
|
|
6 |
*/
|
7 |
|
8 |
if (!class_exists('blcLink')){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
class blcLink {
|
10 |
|
11 |
//Object state
|
@@ -34,6 +41,9 @@ class blcLink {
|
|
34 |
var $false_positive = false;
|
35 |
var $result_hash = '';
|
36 |
|
|
|
|
|
|
|
37 |
var $log = '';
|
38 |
|
39 |
//A list of DB fields and their storage formats
|
@@ -42,6 +52,55 @@ class blcLink {
|
|
42 |
//A cached list of the link's instances
|
43 |
var $_instances = null;
|
44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
function __construct($arg = null){
|
46 |
global $wpdb;
|
47 |
|
@@ -63,6 +122,8 @@ class blcLink {
|
|
63 |
'false_positive' => 'bool',
|
64 |
'may_recheck' => 'bool',
|
65 |
'being_checked' => 'bool',
|
|
|
|
|
66 |
);
|
67 |
|
68 |
if (is_int($arg)){
|
@@ -183,10 +244,12 @@ class blcLink {
|
|
183 |
'may_recheck' => true,
|
184 |
'log' => '',
|
185 |
'result_hash' => '',
|
|
|
|
|
186 |
);
|
187 |
|
188 |
|
189 |
-
$checker = &
|
190 |
|
191 |
if ( is_null($checker) ){
|
192 |
//Oops, there are no checker implementations that can handle this link.
|
@@ -307,6 +370,26 @@ class blcLink {
|
|
307 |
|
308 |
if ( $this->is_new ){
|
309 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
310 |
//Insert a new row
|
311 |
$q = sprintf(
|
312 |
"INSERT INTO {$wpdb->prefix}blc_links( %s ) VALUES( %s )",
|
@@ -743,645 +826,71 @@ class blcLink {
|
|
743 |
|
744 |
return $this->_instances;
|
745 |
}
|
746 |
-
}
|
747 |
-
|
748 |
-
} //class_exists
|
749 |
-
|
750 |
-
/**
|
751 |
-
* Class for querying, sorting and filtering links.
|
752 |
-
* Used as a singleton.
|
753 |
-
*
|
754 |
-
* @package Broken Link Checker
|
755 |
-
* @access public
|
756 |
-
*/
|
757 |
-
class blcLinkQuery {
|
758 |
-
|
759 |
-
var $native_filters;
|
760 |
-
var $search_filter;
|
761 |
-
var $custom_filters = array();
|
762 |
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
'params' => array(
|
779 |
-
'where_expr' => '( redirect_count > 0 )',
|
780 |
-
),
|
781 |
-
'name' => __('Redirects', 'broken-link-checker'),
|
782 |
-
'heading' => __('Redirected Links', 'broken-link-checker'),
|
783 |
-
'heading_zero' => __('No redirects found', 'broken-link-checker'),
|
784 |
-
'native' => true,
|
785 |
-
),
|
786 |
|
787 |
-
'all' => array(
|
788 |
-
'params' => array(
|
789 |
-
'where_expr' => '1',
|
790 |
-
),
|
791 |
-
'name' => __('All', 'broken-link-checker'),
|
792 |
-
'heading' => __('Detected Links', 'broken-link-checker'),
|
793 |
-
'heading_zero' => __('No links found (yet)', 'broken-link-checker'),
|
794 |
-
'native' => true,
|
795 |
-
),
|
796 |
-
);
|
797 |
-
|
798 |
-
//Create the special "search" filter
|
799 |
-
$this->search_filter = array(
|
800 |
-
'name' => __('Search', 'broken-link-checker'),
|
801 |
-
'heading' => __('Search Results', 'broken-link-checker'),
|
802 |
-
'heading_zero' => __('No links found for your query', 'broken-link-checker'),
|
803 |
-
'params' => array(),
|
804 |
-
'use_url_params' => true,
|
805 |
-
'hidden' => true,
|
806 |
-
);
|
807 |
-
|
808 |
-
//These search arguments may be passed via the URL if the filter's 'use_url_params' field is set to True.
|
809 |
-
//They map to the fields of the search form on the Tools -> Broken Links page. Only these arguments
|
810 |
-
//can be used in user-defined filters.
|
811 |
-
$this->valid_url_params = array(
|
812 |
-
's_link_text',
|
813 |
-
's_link_url',
|
814 |
-
's_parser_type',
|
815 |
-
's_container_type',
|
816 |
-
's_link_type',
|
817 |
-
's_http_code',
|
818 |
-
's_filter',
|
819 |
-
);
|
820 |
-
}
|
821 |
-
|
822 |
-
function blcLinkQuery(){
|
823 |
-
$this->__construct();
|
824 |
-
}
|
825 |
-
|
826 |
-
function &getInstance(){
|
827 |
-
static $instance = null;
|
828 |
-
if ( is_null($instance) ){
|
829 |
-
$instance = new blcLinkQuery;
|
830 |
-
}
|
831 |
-
return $instance;
|
832 |
-
}
|
833 |
-
|
834 |
-
/**
|
835 |
-
* Load and return the list of user-defined link filters.
|
836 |
-
*
|
837 |
-
* @return array An array of custom filter definitions. If there are no custom filters defined returns an empty array.
|
838 |
-
*/
|
839 |
-
function load_custom_filters(){
|
840 |
-
global $wpdb;
|
841 |
-
|
842 |
-
$filter_data = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}blc_filters ORDER BY name ASC", ARRAY_A);
|
843 |
-
$filters = array();
|
844 |
-
|
845 |
-
if ( !empty($filter_data) ) {
|
846 |
-
foreach($filter_data as $data){
|
847 |
-
wp_parse_str($data['params'], $params);
|
848 |
-
|
849 |
-
$filters[ 'f'.$data['id'] ] = array(
|
850 |
-
'name' => $data['name'],
|
851 |
-
'params' => $params,
|
852 |
-
'heading' => ucwords($data['name']),
|
853 |
-
'heading_zero' => __('No links found for your query', 'broken-link-checker'),
|
854 |
-
'custom' => true,
|
855 |
-
);
|
856 |
-
}
|
857 |
-
}
|
858 |
-
|
859 |
-
$this->custom_filters = $filters;
|
860 |
-
|
861 |
-
return $filters;
|
862 |
-
}
|
863 |
-
|
864 |
-
/**
|
865 |
-
* Add a custom link filter.
|
866 |
-
*
|
867 |
-
* @param string $name Filter name.
|
868 |
-
* @param string|array $params Filter params. Either as a query string, or an array.
|
869 |
-
* @return string|bool The ID of the newly added filter, or False.
|
870 |
-
*/
|
871 |
-
function create_custom_filter($name, $params){
|
872 |
-
global $wpdb;
|
873 |
-
|
874 |
-
if ( is_array($params) ){
|
875 |
-
$params = http_build_query($params, null, '&');
|
876 |
-
}
|
877 |
-
|
878 |
-
//Save the new filter
|
879 |
-
$q = $wpdb->prepare(
|
880 |
-
"INSERT INTO {$wpdb->prefix}blc_filters(name, params) VALUES (%s, %s)",
|
881 |
-
$name, $params
|
882 |
-
);
|
883 |
-
|
884 |
-
if ( $wpdb->query($q) !== false ){
|
885 |
-
$filter_id = 'f'.$wpdb->insert_id;
|
886 |
-
return $filter_id;
|
887 |
-
} else {
|
888 |
-
return false;
|
889 |
-
}
|
890 |
-
}
|
891 |
-
|
892 |
-
/**
|
893 |
-
* Delete a custom filter
|
894 |
-
*
|
895 |
-
* @param string $filter_id
|
896 |
-
* @return bool True on success, False if a database error occured.
|
897 |
-
*/
|
898 |
-
function delete_custom_filter($filter_id){
|
899 |
-
global $wpdb;
|
900 |
-
|
901 |
-
//Remove the "f" character from the filter ID to get its database key
|
902 |
-
$filter_id = intval(ltrim($_POST['filter_id'], 'f'));
|
903 |
-
|
904 |
-
//Try to delete the filter
|
905 |
-
$q = $wpdb->prepare("DELETE FROM {$wpdb->prefix}blc_filters WHERE id = %d", $filter_id);
|
906 |
-
if ( $wpdb->query($q) !== false ){
|
907 |
-
return true;
|
908 |
-
} else {
|
909 |
-
return false;
|
910 |
-
}
|
911 |
-
}
|
912 |
-
|
913 |
-
function get_filters(){
|
914 |
-
$filters = array_merge($this->native_filters, $this->custom_filters);
|
915 |
-
$filters['search'] = $this->search_filter;
|
916 |
-
return $filters;
|
917 |
-
}
|
918 |
-
|
919 |
-
/**
|
920 |
-
* Get a link search filter by filter ID.
|
921 |
-
*
|
922 |
-
* @param string $filter_id
|
923 |
-
* @return array|null
|
924 |
-
*/
|
925 |
-
function get_filter($filter_id){
|
926 |
-
$filters = $this->get_filters();
|
927 |
-
if ( isset($filters[$filter_id]) ){
|
928 |
-
return $filters[$filter_id];
|
929 |
} else {
|
930 |
-
return null;
|
931 |
-
}
|
932 |
-
}
|
933 |
-
|
934 |
-
/**
|
935 |
-
* Get link search parameters from the specified filter.
|
936 |
-
*
|
937 |
-
* @param array $filter
|
938 |
-
* @return array An array of parameters suitable for use with blcLinkQuery::get_links()
|
939 |
-
*/
|
940 |
-
function get_search_params( $filter = null ){
|
941 |
-
//If present, the filter's parameters may be saved either as an array or a string.
|
942 |
-
$params = array();
|
943 |
-
if ( !empty($filter) && !empty($filter['params']) ){
|
944 |
-
$params = $filter['params'];
|
945 |
-
if ( is_string( $params ) ){
|
946 |
-
wp_parse_str($params, $params);
|
947 |
-
}
|
948 |
-
}
|
949 |
-
|
950 |
-
//Merge in the parameters from the current request, if required
|
951 |
-
if ( isset($filter['use_url_params']) && $filter['use_url_params'] ){
|
952 |
-
$params = array_merge($params, $this->get_url_search_params());
|
953 |
-
}
|
954 |
-
|
955 |
-
return $params;
|
956 |
-
}
|
957 |
-
|
958 |
-
/**
|
959 |
-
* Extract search query parameters from the current URL
|
960 |
-
*
|
961 |
-
* @return array
|
962 |
-
*/
|
963 |
-
function get_url_search_params(){
|
964 |
-
$url_params = array();
|
965 |
-
foreach ($_GET as $param => $value){
|
966 |
-
if ( in_array($param, $this->valid_url_params) ){
|
967 |
-
$url_params[$param] = $value;
|
968 |
-
}
|
969 |
-
}
|
970 |
-
return $url_params;
|
971 |
-
}
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
/**
|
976 |
-
* A helper method for parsing a list of search criteria and generating the parts of the SQL query.
|
977 |
-
*
|
978 |
-
* @see blcLinkQuery::get_links()
|
979 |
-
*
|
980 |
-
* @param array $params An array of search criteria.
|
981 |
-
* @return array 'where_exprs' - an array of search expressions, 'join_instances' - whether joining the instance table is required.
|
982 |
-
*/
|
983 |
-
function compile_search_params($params){
|
984 |
-
global $wpdb;
|
985 |
-
|
986 |
-
//Track whether we'll need to left-join the instance table to run the query.
|
987 |
-
$join_instances = false;
|
988 |
-
|
989 |
-
//Generate the individual clauses of the WHERE expression and store them in an array.
|
990 |
-
$pieces = array();
|
991 |
-
|
992 |
-
//Convert parser and container type lists to arrays of valid values
|
993 |
-
$s_parser_type = array();
|
994 |
-
if ( !empty($params['s_parser_type']) ){
|
995 |
-
$s_parser_type = $params['s_parser_type'];
|
996 |
-
if ( is_string($s_parser_type) ){
|
997 |
-
$s_parser_type = preg_split('/[,\s]+/', $s_parser_type);
|
998 |
-
}
|
999 |
-
}
|
1000 |
-
|
1001 |
-
$s_container_type = array();
|
1002 |
-
if ( !empty($params['s_container_type']) ){
|
1003 |
-
$s_container_type = $params['s_container_type'];
|
1004 |
-
if ( is_string($s_container_type) ){
|
1005 |
-
$s_container_type = preg_split('/[,\s]+/', $s_container_type);
|
1006 |
-
}
|
1007 |
-
}
|
1008 |
-
|
1009 |
-
//Don't include links with instances that reference invalid (not currently loaded)
|
1010 |
-
//containers and parsers (unless specifically told to also include invalid links).
|
1011 |
-
if ( empty($params['include_invalid']) ){
|
1012 |
-
$join_instances = true;
|
1013 |
-
|
1014 |
-
$containerRegistry = & blcContainerRegistry::getInstance();
|
1015 |
-
$loaded_containers = array_keys($containerRegistry->get_registered_containers());
|
1016 |
-
$parserRegistry = & blcParserRegistry::getInstance();
|
1017 |
-
$loaded_parsers = array_keys($parserRegistry->get_registered_parsers());
|
1018 |
-
|
1019 |
-
if ( empty($s_parser_type) ){
|
1020 |
-
$s_parser_type = $loaded_parsers;
|
1021 |
-
} else {
|
1022 |
-
$s_parser_type = array_intersect($s_parser_type, $loaded_parsers);
|
1023 |
-
}
|
1024 |
-
|
1025 |
-
if ( empty($s_container_type) ){
|
1026 |
-
$s_container_type = $loaded_containers;
|
1027 |
-
} else {
|
1028 |
-
$s_container_type = array_intersect($s_container_type, $loaded_containers);
|
1029 |
-
}
|
1030 |
-
}
|
1031 |
-
|
1032 |
-
//Parser type should match the parser_type column in the instance table.
|
1033 |
-
if ( !empty($s_parser_type) ){
|
1034 |
-
$s_parser_type = array_map('trim', array_unique($s_parser_type));
|
1035 |
-
$s_parser_type = array_map(array(&$wpdb, 'escape'), $s_parser_type);
|
1036 |
|
1037 |
-
if (
|
1038 |
-
|
1039 |
-
|
1040 |
-
$
|
1041 |
-
|
1042 |
-
|
1043 |
-
$join_instances = true;
|
1044 |
-
}
|
1045 |
-
|
1046 |
-
//Container type should match the container_type column in the instance table.
|
1047 |
-
if ( !empty($s_container_type) ){
|
1048 |
-
//Sanitize for use in SQL
|
1049 |
-
$s_container_type = array_map('trim', array_unique($s_container_type));
|
1050 |
-
$s_container_type = array_map(array(&$wpdb, 'escape'), $s_container_type);
|
1051 |
-
|
1052 |
-
if ( count($s_container_type) == 1 ){
|
1053 |
-
$pieces[] = sprintf("instances.container_type = '%s'", reset($s_container_type));
|
1054 |
-
} else {
|
1055 |
-
$pieces[] = "instances.container_type IN ('" . implode("', '", $s_container_type) . "')";
|
1056 |
-
}
|
1057 |
-
|
1058 |
-
$join_instances = true;
|
1059 |
-
}
|
1060 |
-
|
1061 |
-
//A part of the WHERE expression can be specified explicitly
|
1062 |
-
if ( !empty($params['where_expr']) ){
|
1063 |
-
$pieces[] = $params['where_expr'];
|
1064 |
-
$join_instances = $join_instances || ( stripos($params['where_expr'], 'instances') !== false );
|
1065 |
-
}
|
1066 |
-
|
1067 |
-
//List of allowed link ids (either an array or comma-separated)
|
1068 |
-
if ( !empty($params['link_ids']) ){
|
1069 |
-
$link_ids = $params['link_ids'];
|
1070 |
-
|
1071 |
-
if ( is_string($link_ids) ){
|
1072 |
-
$link_ids = preg_split('/[,\s]+/', $link_ids);
|
1073 |
-
}
|
1074 |
-
|
1075 |
-
//Only accept non-zero integers
|
1076 |
-
$sanitized_link_ids = array();
|
1077 |
-
foreach($link_ids as $id){
|
1078 |
-
$id = intval($id);
|
1079 |
-
if ( $id != 0 ){
|
1080 |
-
$sanitized_link_ids[] = $id;
|
1081 |
-
}
|
1082 |
-
}
|
1083 |
-
|
1084 |
-
$pieces[] = 'links.link_id IN (' . implode(', ', $sanitized_link_ids) . ')';
|
1085 |
-
}
|
1086 |
-
|
1087 |
-
//Anchor text - use LIKE search
|
1088 |
-
if ( !empty($params['s_link_text']) ){
|
1089 |
-
$s_link_text = like_escape($wpdb->escape($params['s_link_text']));
|
1090 |
-
$s_link_text = str_replace('*', '%', $s_link_text);
|
1091 |
-
|
1092 |
-
$pieces[] = '(instances.link_text LIKE "%' . $s_link_text . '%")';
|
1093 |
-
$join_instances = true;
|
1094 |
-
}
|
1095 |
-
|
1096 |
-
//URL - try to match both the initial URL and the final URL.
|
1097 |
-
//There is limited wildcard support, e.g. "google.*/search" will match both
|
1098 |
-
//"google.com/search" and "google.lv/search"
|
1099 |
-
if ( !empty($params['s_link_url']) ){
|
1100 |
-
$s_link_url = like_escape($wpdb->escape($params['s_link_url']));
|
1101 |
-
$s_link_url = str_replace('*', '%', $s_link_url);
|
1102 |
-
|
1103 |
-
$pieces[] = '(links.url LIKE "%'. $s_link_url .'%") OR '.
|
1104 |
-
'(links.final_url LIKE "%'. $s_link_url .'%")';
|
1105 |
-
}
|
1106 |
-
|
1107 |
-
//Container ID should match... you guessed it - container_id
|
1108 |
-
if ( !empty($params['s_container_id']) ){
|
1109 |
-
$s_container_id = intval($params['s_container_id']);
|
1110 |
-
if ( $s_container_id != 0 ){
|
1111 |
-
$pieces[] = "instances.container_id = $s_container_id";
|
1112 |
-
$join_instances = true;
|
1113 |
-
}
|
1114 |
-
}
|
1115 |
-
|
1116 |
-
//Link type can match either the the parser_type or the container_type.
|
1117 |
-
if ( !empty($params['s_link_type']) ){
|
1118 |
-
$s_link_type = $wpdb->escape($params['s_link_type']);
|
1119 |
-
$pieces[] = "instances.parser_type = '$s_link_type' OR instances.container_type='$s_link_type'";
|
1120 |
-
$join_instances = true;
|
1121 |
-
}
|
1122 |
-
|
1123 |
-
//HTTP code - the user can provide a list of HTTP response codes and code ranges.
|
1124 |
-
//Example : 201,400-410,500
|
1125 |
-
if ( !empty($params['s_http_code']) ){
|
1126 |
-
//Strip spaces.
|
1127 |
-
$params['s_http_code'] = str_replace(' ', '', $params['s_http_code']);
|
1128 |
-
//Split by comma
|
1129 |
-
$codes = explode(',', $params['s_http_code']);
|
1130 |
-
|
1131 |
-
$individual_codes = array();
|
1132 |
-
$ranges = array();
|
1133 |
-
|
1134 |
-
//Try to parse each response code or range. Invalid ones are simply ignored.
|
1135 |
-
foreach($codes as $code){
|
1136 |
-
if ( is_numeric($code) ){
|
1137 |
-
//It's a single number
|
1138 |
-
$individual_codes[] = abs(intval($code));
|
1139 |
-
} elseif ( strpos($code, '-') !== false ) {
|
1140 |
-
//Try to parse it as a range
|
1141 |
-
$range = explode( '-', $code, 2 );
|
1142 |
-
if ( (count($range) == 2) && is_numeric($range[0]) && is_numeric($range[0]) ){
|
1143 |
-
//Make sure the smaller code comes first
|
1144 |
-
$range = array( intval($range[0]), intval($range[1]) );
|
1145 |
-
$ranges[] = array( min($range), max($range) );
|
1146 |
-
}
|
1147 |
-
}
|
1148 |
-
}
|
1149 |
-
|
1150 |
-
$piece = array();
|
1151 |
-
|
1152 |
-
//All individual response codes get one "http_code IN (...)" clause
|
1153 |
-
if ( !empty($individual_codes) ){
|
1154 |
-
$piece[] = '(links.http_code IN ('. implode(', ', $individual_codes) .'))';
|
1155 |
-
}
|
1156 |
-
|
1157 |
-
//Ranges get a "http_code BETWEEN min AND max" clause each
|
1158 |
-
if ( !empty($ranges) ){
|
1159 |
-
$range_strings = array();
|
1160 |
-
foreach($ranges as $range){
|
1161 |
-
$range_strings[] = "(links.http_code BETWEEN $range[0] AND $range[1])";
|
1162 |
-
}
|
1163 |
-
$piece[] = '( ' . implode(' OR ', $range_strings) . ' )';
|
1164 |
-
}
|
1165 |
-
|
1166 |
-
//Finally, generate a composite WHERE clause for both types of response code queries
|
1167 |
-
if ( !empty($piece) ){
|
1168 |
-
$pieces[] = implode(' OR ', $piece);
|
1169 |
-
}
|
1170 |
-
|
1171 |
-
}
|
1172 |
-
|
1173 |
-
//Custom filters can optionally call one of the native filters
|
1174 |
-
//to narrow down the result set.
|
1175 |
-
if ( !empty($params['s_filter']) && isset($this->native_filters[$params['s_filter']]) ){
|
1176 |
-
$the_filter = $this->native_filters[$params['s_filter']];
|
1177 |
-
$extra_criteria = $this->compile_search_params($the_filter['params']);
|
1178 |
-
|
1179 |
-
$pieces = array_merge($pieces, $extra_criteria['where_exprs']);
|
1180 |
-
$join_instances = $join_instances || $extra_criteria['join_instances'];
|
1181 |
-
}
|
1182 |
-
|
1183 |
-
return array(
|
1184 |
-
'where_exprs' => $pieces,
|
1185 |
-
'join_instances' => $join_instances,
|
1186 |
-
);
|
1187 |
-
}
|
1188 |
-
|
1189 |
-
/**
|
1190 |
-
* blcLinkQuery::get_links()
|
1191 |
-
*
|
1192 |
-
* @see blc_get_links()
|
1193 |
-
*
|
1194 |
-
* @param array $params
|
1195 |
-
* @param string $purpose
|
1196 |
-
* @return array|int
|
1197 |
-
*/
|
1198 |
-
function get_links($params = null){
|
1199 |
-
global $wpdb;
|
1200 |
-
|
1201 |
-
if( !is_array($params) ){
|
1202 |
-
$params = array();
|
1203 |
-
}
|
1204 |
-
|
1205 |
-
$defaults = array(
|
1206 |
-
'offset' => 0,
|
1207 |
-
'max_results' => 0,
|
1208 |
-
'load_instances' => false,
|
1209 |
-
'load_containers' => false,
|
1210 |
-
'load_wrapped_objects' => false,
|
1211 |
-
'count_only' => false,
|
1212 |
-
'purpose' => '',
|
1213 |
-
'include_invalid' => false,
|
1214 |
-
);
|
1215 |
-
|
1216 |
-
$params = array_merge($defaults, $params);
|
1217 |
-
|
1218 |
-
//Compile the search-related params into search expressions usable in a WHERE clause
|
1219 |
-
$criteria = $this->compile_search_params($params);
|
1220 |
-
|
1221 |
-
//Build the WHERE clause
|
1222 |
-
if ( !empty($criteria['where_exprs']) ){
|
1223 |
-
$where_expr = "\t( " . implode(" ) AND\n\t( ", $criteria['where_exprs']) . ' ) ';
|
1224 |
-
} else {
|
1225 |
-
$where_expr = '1';
|
1226 |
-
}
|
1227 |
-
|
1228 |
-
//Join the blc_instances table if it's required to perform the search.
|
1229 |
-
$joins = "";
|
1230 |
-
if ( $criteria['join_instances'] ){
|
1231 |
-
$joins = "JOIN {$wpdb->prefix}blc_instances AS instances ON links.link_id = instances.link_id";
|
1232 |
-
}
|
1233 |
-
|
1234 |
-
if ( $params['count_only'] ){
|
1235 |
-
//Only get the number of matching links.
|
1236 |
-
$q = "
|
1237 |
-
SELECT COUNT(*)
|
1238 |
-
FROM (
|
1239 |
-
SELECT 0
|
1240 |
|
1241 |
-
|
1242 |
-
|
1243 |
-
$joins
|
1244 |
|
1245 |
-
|
1246 |
-
$where_expr
|
1247 |
|
1248 |
-
|
1249 |
-
|
1250 |
-
|
1251 |
-
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
1255 |
-
|
|
|
|
|
|
|
1256 |
|
1257 |
-
|
1258 |
-
{$wpdb->prefix}blc_links AS links
|
1259 |
-
$joins
|
1260 |
|
1261 |
-
|
1262 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1263 |
|
1264 |
-
GROUP BY links.link_id"; //Note: would be a lot faster without GROUP BY
|
1265 |
-
|
1266 |
-
//Add the LIMIT clause
|
1267 |
-
if ( $params['max_results'] || $params['offset'] ){
|
1268 |
-
$q .= sprintf("\nLIMIT %d, %d", $params['offset'], $params['max_results']);
|
1269 |
-
}
|
1270 |
-
|
1271 |
-
$results = $wpdb->get_results($q, ARRAY_A);
|
1272 |
-
if ( empty($results) ){
|
1273 |
-
return array();
|
1274 |
-
}
|
1275 |
-
|
1276 |
-
//Create the link objects
|
1277 |
-
$links = array();
|
1278 |
-
|
1279 |
-
foreach($results as $result){
|
1280 |
-
$link = new blcLink($result);
|
1281 |
-
$links[$link->link_id] = $link;
|
1282 |
-
}
|
1283 |
-
|
1284 |
-
$purpose = $params['purpose'];
|
1285 |
-
/*
|
1286 |
-
Preload instances if :
|
1287 |
-
* It has been requested via the 'load_instances' argument.
|
1288 |
-
* The links are going to be displayed or edited, which involves instances.
|
1289 |
-
*/
|
1290 |
-
$load_instances = $params['load_instances'] || in_array($purpose, array(BLC_FOR_DISPLAY, BLC_FOR_EDITING));
|
1291 |
-
|
1292 |
-
if ( $load_instances ){
|
1293 |
-
$link_ids = array_keys($links);
|
1294 |
-
$all_instances = blc_get_instances($link_ids, $purpose, $params['load_containers'], $params['load_wrapped_objects']);
|
1295 |
-
//Assign each batch of instances to the right link
|
1296 |
-
foreach($all_instances as $link_id => $instances){
|
1297 |
-
$links[$link_id]->_instances = $instances;
|
1298 |
}
|
1299 |
}
|
1300 |
-
|
1301 |
-
return $links;
|
1302 |
-
}
|
1303 |
-
|
1304 |
-
/**
|
1305 |
-
* Calculate the number of results for all known filters
|
1306 |
-
*
|
1307 |
-
* @return void
|
1308 |
-
*/
|
1309 |
-
function count_filter_results(){
|
1310 |
-
foreach($this->native_filters as $filter_id => $filter){
|
1311 |
-
$this->native_filters[$filter_id]['count'] = $this->get_filter_links(
|
1312 |
-
$filter, array('count_only' => true)
|
1313 |
-
);
|
1314 |
-
}
|
1315 |
|
1316 |
-
|
1317 |
-
$this->custom_filters[$filter_id]['count'] = $this->get_filter_links(
|
1318 |
-
$filter, array('count_only' => true)
|
1319 |
-
);
|
1320 |
-
}
|
1321 |
-
|
1322 |
-
$this->search_filter['count'] = $this->get_filter_links($this->search_filter, array('count_only' => true));
|
1323 |
}
|
1324 |
|
1325 |
-
/**
|
1326 |
-
* Retrieve a list of links matching a filter.
|
1327 |
-
*
|
1328 |
-
* @uses blcLinkQuery::get_links()
|
1329 |
-
*
|
1330 |
-
* @param string|array $filter Either a filter ID or an array containing filter data.
|
1331 |
-
* @param array $extra_params Optional extra criteria that will override those set by the filter. See blc_get_links() for details.
|
1332 |
-
* @return array|int Either an array of blcLink objects, or an integer indicating the number of links that match the filter.
|
1333 |
-
*/
|
1334 |
-
function get_filter_links($filter, $extra_params = null){
|
1335 |
-
if ( is_string($filter) ){
|
1336 |
-
$filter = $this->get_filter($filter);
|
1337 |
-
}
|
1338 |
-
|
1339 |
-
$params = $this->get_search_params($filter);
|
1340 |
-
|
1341 |
-
|
1342 |
-
if ( !empty($extra_params) ){
|
1343 |
-
$params = array_merge($params, $extra_params);
|
1344 |
-
}
|
1345 |
-
|
1346 |
-
return $this->get_links($params);
|
1347 |
-
}
|
1348 |
}
|
1349 |
|
1350 |
-
|
1351 |
-
* Retrieve a list of links matching some criteria.
|
1352 |
-
*
|
1353 |
-
* The function argument should be an associative array describing the criteria.
|
1354 |
-
* The supported keys are :
|
1355 |
-
* 'offset' - Skip the first X results. Default is 0.
|
1356 |
-
* 'max_results' - The maximum number of links to return. Defaults to returning all results.
|
1357 |
-
* 'link_ids' - Retrieve only links with these IDs. This should either be a comma-separated list or an array.
|
1358 |
-
* 's_link_text' - Link text must match this keyphrase (performs a fulltext search).
|
1359 |
-
* 's_link_url' - Link URL must contain this string. You can use "*" as a wildcard.
|
1360 |
-
* 's_parser_type' - Filter links by the type of link parser that was used to find them.
|
1361 |
-
* 's_container_type' - Filter links by where they were found, e.g. 'post'.
|
1362 |
-
* 's_container_id' - Find links that belong to a container with this ID (should be used together with s_container_type).
|
1363 |
-
* 's_link_type' - Either parser type or container type must match this.
|
1364 |
-
* 's_http_code' - Filter by HTTP code. Example : 201,400-410,500
|
1365 |
-
* 's_filter' - Use a built-in filter. Available filters : 'broken', 'redirects', 'all'
|
1366 |
-
* 'where_expr' - Advanced. Lets you directly specify a part of the WHERE clause.
|
1367 |
-
* 'load_instances' - Pre-load all link instance data for each link. Default is false.
|
1368 |
-
* 'load_containers' - Pre-load container data for each instance. Default is false.
|
1369 |
-
* 'load_wrapped_objects' - Pre-load wrapped object data (e.g. posts, comments, etc) for each container. Default is false.
|
1370 |
-
* 'count_only' - Only return the number of results (int), not the whole result set. 'offset' and 'max_results' will be ignored if this is set. Default is false.
|
1371 |
-
* 'purpose' - An optional code indicating how the links will be used.
|
1372 |
-
* 'include_invalid' - Include links that have no instances and links that only have instances that reference not-loaded containers or parsers. Defaults to false.
|
1373 |
-
*
|
1374 |
-
* All keys are optional.
|
1375 |
-
*
|
1376 |
-
* @uses blcLinkQuery::get_links();
|
1377 |
-
*
|
1378 |
-
* @param array $params
|
1379 |
-
* @return int|array Either an array of blcLink objects, or the number of results for the query.
|
1380 |
-
*/
|
1381 |
-
function blc_get_links($params = null){
|
1382 |
-
$instance = & blcLinkQuery::getInstance();
|
1383 |
-
return $instance->get_links($params, $purpose);
|
1384 |
-
}
|
1385 |
|
1386 |
/**
|
1387 |
* Remove orphaned links that have no corresponding instances.
|
6 |
*/
|
7 |
|
8 |
if (!class_exists('blcLink')){
|
9 |
+
|
10 |
+
define('BLC_LINK_STATUS_UNKNOWN', 'unknown');
|
11 |
+
define('BLC_LINK_STATUS_OK', 'ok');
|
12 |
+
define('BLC_LINK_STATUS_INFO', 'info');
|
13 |
+
define('BLC_LINK_STATUS_WARNING', 'warning');
|
14 |
+
define('BLC_LINK_STATUS_ERROR', 'error');
|
15 |
+
|
16 |
class blcLink {
|
17 |
|
18 |
//Object state
|
41 |
var $false_positive = false;
|
42 |
var $result_hash = '';
|
43 |
|
44 |
+
var $status_text = '';
|
45 |
+
var $status_code = '';
|
46 |
+
|
47 |
var $log = '';
|
48 |
|
49 |
//A list of DB fields and their storage formats
|
52 |
//A cached list of the link's instances
|
53 |
var $_instances = null;
|
54 |
|
55 |
+
var $http_status_codes = array(
|
56 |
+
// [Informational 1xx]
|
57 |
+
100=>'Continue',
|
58 |
+
101=>'Switching Protocols',
|
59 |
+
// [Successful 2xx]
|
60 |
+
200=>'OK',
|
61 |
+
201=>'Created',
|
62 |
+
202=>'Accepted',
|
63 |
+
203=>'Non-Authoritative Information',
|
64 |
+
204=>'No Content',
|
65 |
+
205=>'Reset Content',
|
66 |
+
206=>'Partial Content',
|
67 |
+
// [Redirection 3xx]
|
68 |
+
300=>'Multiple Choices',
|
69 |
+
301=>'Moved Permanently',
|
70 |
+
302=>'Found',
|
71 |
+
303=>'See Other',
|
72 |
+
304=>'Not Modified',
|
73 |
+
305=>'Use Proxy',
|
74 |
+
//306=>'(Unused)',
|
75 |
+
307=>'Temporary Redirect',
|
76 |
+
// [Client Error 4xx]
|
77 |
+
400=>'Bad Request',
|
78 |
+
401=>'Unauthorized',
|
79 |
+
402=>'Payment Required',
|
80 |
+
403=>'Forbidden',
|
81 |
+
404=>'Not Found',
|
82 |
+
405=>'Method Not Allowed',
|
83 |
+
406=>'Not Acceptable',
|
84 |
+
407=>'Proxy Authentication Required',
|
85 |
+
408=>'Request Timeout',
|
86 |
+
409=>'Conflict',
|
87 |
+
410=>'Gone',
|
88 |
+
411=>'Length Required',
|
89 |
+
412=>'Precondition Failed',
|
90 |
+
413=>'Request Entity Too Large',
|
91 |
+
414=>'Request-URI Too Long',
|
92 |
+
415=>'Unsupported Media Type',
|
93 |
+
416=>'Requested Range Not Satisfiable',
|
94 |
+
417=>'Expectation Failed',
|
95 |
+
// [Server Error 5xx]
|
96 |
+
500=>'Internal Server Error',
|
97 |
+
501=>'Not Implemented',
|
98 |
+
502=>'Bad Gateway',
|
99 |
+
503=>'Service Unavailable',
|
100 |
+
504=>'Gateway Timeout',
|
101 |
+
505=>'HTTP Version Not Supported',
|
102 |
+
);
|
103 |
+
|
104 |
function __construct($arg = null){
|
105 |
global $wpdb;
|
106 |
|
122 |
'false_positive' => 'bool',
|
123 |
'may_recheck' => 'bool',
|
124 |
'being_checked' => 'bool',
|
125 |
+
'status_text' => '%s',
|
126 |
+
'status_code' => '%s',
|
127 |
);
|
128 |
|
129 |
if (is_int($arg)){
|
244 |
'may_recheck' => true,
|
245 |
'log' => '',
|
246 |
'result_hash' => '',
|
247 |
+
'status_text' => '',
|
248 |
+
'status_code' => '',
|
249 |
);
|
250 |
|
251 |
|
252 |
+
$checker = & blcCheckerHelper::get_checker_for($this->url);
|
253 |
|
254 |
if ( is_null($checker) ){
|
255 |
//Oops, there are no checker implementations that can handle this link.
|
370 |
|
371 |
if ( $this->is_new ){
|
372 |
|
373 |
+
//BUG: Technically, there should be a 'LOCK TABLES wp_blc_links WRITE' here. In fact,
|
374 |
+
//the plugin should probably lock all involved tables whenever it parses something, lest
|
375 |
+
//the user (ot another plugin) modify the thing being parsed while we're working.
|
376 |
+
//The problem with table locking, though, is that parsing takes a long time and having
|
377 |
+
//all of WP freeze while the plugin is working would be a Bad Thing. Food for thought.
|
378 |
+
|
379 |
+
//Check if there's already a link with this URL present
|
380 |
+
$q = $wpdb->prepare(
|
381 |
+
"SELECT link_id FROM {$wpdb->prefix}blc_links WHERE url = %s",
|
382 |
+
$this->url
|
383 |
+
);
|
384 |
+
$existing_id = $wpdb->get_var($q);
|
385 |
+
|
386 |
+
if ( !empty($existing_id) ){
|
387 |
+
//Dammit.
|
388 |
+
$this->link_id = $existing_id;
|
389 |
+
$this->is_new = false;
|
390 |
+
return true;
|
391 |
+
}
|
392 |
+
|
393 |
//Insert a new row
|
394 |
$q = sprintf(
|
395 |
"INSERT INTO {$wpdb->prefix}blc_links( %s ) VALUES( %s )",
|
826 |
|
827 |
return $this->_instances;
|
828 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
829 |
|
830 |
+
/**
|
831 |
+
* Determine the status text and status code corresponding to the current state of this link.
|
832 |
+
*
|
833 |
+
* @return array Associative array with two keys, 'text' and 'code'.
|
834 |
+
*/
|
835 |
+
function analyse_status(){
|
836 |
+
$code = BLC_LINK_STATUS_UNKNOWN;
|
837 |
+
$text = _x('Unknown', 'link status', 'broken-link-checker');
|
838 |
+
|
839 |
+
//Status text
|
840 |
+
if ( isset($this->status_text) && !empty($this->status_text) && !empty($this->status_code) ){
|
841 |
+
|
842 |
+
//Lucky, the checker module has already set it for us.
|
843 |
+
$text = $this->status_text;
|
844 |
+
$code = $this->status_code;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
845 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
846 |
} else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
847 |
|
848 |
+
if ( $this->broken ){
|
849 |
+
|
850 |
+
$code = BLC_LINK_STATUS_WARNING;
|
851 |
+
$text = __('Unknown Error', 'link status', 'broken-link-checker');
|
852 |
+
|
853 |
+
if ( $this->timeout ){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
854 |
|
855 |
+
$text = __('Timeout', 'broken-link-checker');
|
856 |
+
$code = BLC_LINK_STATUS_WARNING;
|
|
|
857 |
|
858 |
+
} elseif ( $this->http_code ) {
|
|
|
859 |
|
860 |
+
//Only 404 (Not Found) and 410 (Gone) are treated as broken-for-sure.
|
861 |
+
if ( in_array($this->http_code, array(404, 410)) ){
|
862 |
+
$code = BLC_LINK_STATUS_ERROR;
|
863 |
+
} else {
|
864 |
+
$code = BLC_LINK_STATUS_WARNING;
|
865 |
+
}
|
866 |
+
|
867 |
+
if ( array_key_exists(intval($this->http_code), $this->http_status_codes) ){
|
868 |
+
$text = $this->http_status_codes[intval($this->http_code)];
|
869 |
+
}
|
870 |
+
}
|
871 |
|
872 |
+
} else {
|
|
|
|
|
873 |
|
874 |
+
if ( !$this->last_check ) {
|
875 |
+
$text = __('Not checked', 'broken-link-checker');
|
876 |
+
$code = BLC_LINK_STATUS_UNKNOWN;
|
877 |
+
} elseif ( $this->false_positive ) {
|
878 |
+
$text = __('False positive', 'broken-link-checker');
|
879 |
+
$code = BLC_LINK_STATUS_UNKNOWN;
|
880 |
+
} else {
|
881 |
+
$text = _x('OK', 'link status', 'broken-link-checker');
|
882 |
+
$code = BLC_LINK_STATUS_OK;
|
883 |
+
}
|
884 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
885 |
}
|
886 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
887 |
|
888 |
+
return compact('text', 'code');
|
|
|
|
|
|
|
|
|
|
|
|
|
889 |
}
|
890 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
891 |
}
|
892 |
|
893 |
+
} //class_exists
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
894 |
|
895 |
/**
|
896 |
* Remove orphaned links that have no corresponding instances.
|
logger.php → includes/logger.php
RENAMED
File without changes
|
includes/module-base.php
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @author Janis Elsts
|
5 |
+
* @copyright 2010
|
6 |
+
*/
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Base class for BLC modules.
|
10 |
+
*
|
11 |
+
* @package Broken Link Checker
|
12 |
+
* @author Janis Elsts
|
13 |
+
* @access public
|
14 |
+
*/
|
15 |
+
class blcModule {
|
16 |
+
|
17 |
+
var $module_id; //The ID of this module. Usually a lowercase string.
|
18 |
+
var $cached_header; //An associative array containing the header data of the module file.
|
19 |
+
var $plugin_conf; //A reference to the plugin's global configuration object.
|
20 |
+
var $module_manager; //A reference to the module manager.
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Class constructor
|
24 |
+
*
|
25 |
+
* @param string $module_id
|
26 |
+
* @param array $cached_header
|
27 |
+
* @param blcPluginConfiguration $plugin_conf
|
28 |
+
* @param blcModuleManager $module_manager
|
29 |
+
* @return void
|
30 |
+
*/
|
31 |
+
function blcModule($module_id, $cached_header, &$plugin_conf, &$module_manager){
|
32 |
+
$this->module_id = $module_id;
|
33 |
+
$this->cached_header = $cached_header;
|
34 |
+
$this->plugin_conf = &$plugin_conf;
|
35 |
+
$this->module_manager = &$module_manager;
|
36 |
+
|
37 |
+
$this->init();
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Module initializer. Called when the module is first instantiated.
|
42 |
+
* The default implementation does nothing. Override it in a subclass to
|
43 |
+
* specify some sort of start-up behaviour.
|
44 |
+
*
|
45 |
+
* @return void
|
46 |
+
*/
|
47 |
+
function init(){
|
48 |
+
//Should be overridden in a sub-class.
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Called when the module is activated.
|
53 |
+
* Should be overridden in a sub-class.
|
54 |
+
*
|
55 |
+
* @return void
|
56 |
+
*/
|
57 |
+
function activated(){
|
58 |
+
//Should be overridden in a sub-class.
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Called when the module is deactivated.
|
63 |
+
* Should be overridden in a sub-class.
|
64 |
+
*
|
65 |
+
* @return void
|
66 |
+
*/
|
67 |
+
function deactivated(){
|
68 |
+
//Should be overridden in a sub-class.
|
69 |
+
}
|
70 |
+
}
|
71 |
+
|
72 |
+
?>
|
includes/module-manager.php
ADDED
@@ -0,0 +1,860 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class blcModuleManager {
|
4 |
+
|
5 |
+
var $plugin_conf;
|
6 |
+
var $module_dir = '';
|
7 |
+
|
8 |
+
var $_module_cache;
|
9 |
+
var $_category_cache;
|
10 |
+
var $_category_cache_active;
|
11 |
+
var $_virtual_modules = array();
|
12 |
+
|
13 |
+
var $loaded;
|
14 |
+
var $instances;
|
15 |
+
var $default_active_modules;
|
16 |
+
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Class "constructor".
|
20 |
+
*
|
21 |
+
* @param array $default_active_modules An array of module ids specifying which modules are active by default.
|
22 |
+
* @return void
|
23 |
+
*/
|
24 |
+
function init($default_active_modules = null){
|
25 |
+
$this->module_dir = realpath(dirname(__FILE__) . '/../modules');
|
26 |
+
|
27 |
+
$this->plugin_conf = & blc_get_configuration();
|
28 |
+
$this->default_active_modules = $default_active_modules;
|
29 |
+
|
30 |
+
$this->loaded = array();
|
31 |
+
$this->instances = array();
|
32 |
+
|
33 |
+
add_filter('extra_plugin_headers', array(&$this, 'inject_module_headers'));
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Get an instance of the module manager.
|
38 |
+
*
|
39 |
+
* @param array|null $default_active_modules
|
40 |
+
* @return object
|
41 |
+
*/
|
42 |
+
function &getInstance($default_active_modules = null){
|
43 |
+
static $instance = null;
|
44 |
+
if ( is_null($instance) ){
|
45 |
+
$instance = new blcModuleManager();
|
46 |
+
$instance->init($default_active_modules);
|
47 |
+
}
|
48 |
+
return $instance;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Retrieve a list of all installed BLC modules.
|
53 |
+
*
|
54 |
+
* This is essentially a slightly modified copy of get_plugins().
|
55 |
+
*
|
56 |
+
* @return array An associative array of module headers indexed by module ID.
|
57 |
+
*/
|
58 |
+
function get_modules(){
|
59 |
+
if ( !isset($this->_module_cache) ){
|
60 |
+
//Refresh the module cache.
|
61 |
+
|
62 |
+
$relative_path = '/' . plugin_basename($this->module_dir);
|
63 |
+
if ( !function_exists('get_plugins') ){
|
64 |
+
//BUG: Potentional security flaw/bug. plugin.php is not meant to be loaded outside admin panel.
|
65 |
+
require_once(ABSPATH . 'wp-admin/includes/plugin.php');
|
66 |
+
}
|
67 |
+
$modules = get_plugins( $relative_path );
|
68 |
+
|
69 |
+
$this->_module_cache = array();
|
70 |
+
|
71 |
+
foreach($modules as $module_filename => $module_header){
|
72 |
+
//Figure out the module ID. If not specified, it is equal to module's filename (sans the .php)
|
73 |
+
if ( !empty($module_header['ModuleID']) ){
|
74 |
+
$module_id = strtolower(trim($module_header['ModuleID']));
|
75 |
+
} else {
|
76 |
+
$module_id = strtolower(basename($module_filename, '.php'));
|
77 |
+
}
|
78 |
+
|
79 |
+
$module_header = $this->normalize_module_header($module_header, $module_id, $module_filename);
|
80 |
+
$this->_module_cache[$module_id] = $module_header;
|
81 |
+
}
|
82 |
+
|
83 |
+
$this->_category_cache = null;
|
84 |
+
}
|
85 |
+
|
86 |
+
return array_merge($this->_module_cache, $this->_virtual_modules);
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Retrieve modules that match a specific category, or all modules sorted by categories.
|
91 |
+
*
|
92 |
+
* If a category ID is specified, this method returns the modules that have the "ModuleCategory:"
|
93 |
+
* file header set to that value, or an empty array if no modules match that category. The
|
94 |
+
* return array is indexed by module id :
|
95 |
+
* [module_id1 => module1_data, module_id1 => module2_data, ...]
|
96 |
+
*
|
97 |
+
* If category is omitted, this method returns a list of all categories plus the modules
|
98 |
+
* they contain. Only categories that have at least one module will be included. The return
|
99 |
+
* value is an array of arrays, indexed by category ID :
|
100 |
+
* [category1 => [module1_id => module1_data, module2_id => module2_data, ...], ...]
|
101 |
+
*
|
102 |
+
*
|
103 |
+
* @param string $category Category id, e.g. "parser" or "container". Optional.
|
104 |
+
* @param bool $markup Apply markup to module headers. Defaults to false.
|
105 |
+
* @param bool $translate Translate module headers. Defaults to false.
|
106 |
+
* @return array An array of categories or module data.
|
107 |
+
*/
|
108 |
+
function get_modules_by_category($category = '', $markup = false, $translate = false){
|
109 |
+
if ( !isset($this->_category_cache) ){
|
110 |
+
$this->_category_cache = $this->sort_into_categories($this->get_modules());
|
111 |
+
}
|
112 |
+
|
113 |
+
if ( empty($category) ){
|
114 |
+
if ( $markup || $translate ){
|
115 |
+
|
116 |
+
//Translate/apply markup to module headers
|
117 |
+
$processed = array();
|
118 |
+
$blc_plugin_file = blc_get_plugin_file();
|
119 |
+
|
120 |
+
foreach($this->_category_cache as $category_id => $modules){
|
121 |
+
$processed[$category_id] = array();
|
122 |
+
foreach($modules as $module_id => $module_data){
|
123 |
+
$module_data = _get_plugin_data_markup_translate(
|
124 |
+
$blc_plugin_file, //Modules use the same .mo file as BLC itself
|
125 |
+
$module_data,
|
126 |
+
$markup,
|
127 |
+
$translate
|
128 |
+
);
|
129 |
+
$processed[$category_id][$module_id] = $module_data;
|
130 |
+
}
|
131 |
+
}
|
132 |
+
|
133 |
+
return $processed;
|
134 |
+
} else {
|
135 |
+
return $this->_category_cache;
|
136 |
+
}
|
137 |
+
} else {
|
138 |
+
if ( isset($this->_category_cache[$category]) ){
|
139 |
+
if ( $markup || $translate ){
|
140 |
+
//Translate/apply markup to module headers
|
141 |
+
$processed = array();
|
142 |
+
$blc_plugin_file = blc_get_plugin_file();
|
143 |
+
foreach($this->_category_cache[$category] as $module_id => $module_data){
|
144 |
+
$module_data = _get_plugin_data_markup_translate(
|
145 |
+
$blc_plugin_file, //Modules use the same .mo file as BLC itself
|
146 |
+
$module_data,
|
147 |
+
$markup,
|
148 |
+
$translate
|
149 |
+
);
|
150 |
+
$processed[$module_id] = $module_data;
|
151 |
+
}
|
152 |
+
return $processed;
|
153 |
+
} else {
|
154 |
+
return $this->_category_cache[$category];
|
155 |
+
}
|
156 |
+
} else {
|
157 |
+
return array();
|
158 |
+
}
|
159 |
+
}
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Retrieve active modules that match a specific category, or all active modules sorted by categories.
|
164 |
+
*
|
165 |
+
* @see blcModuleManager::get_modules_by_category()
|
166 |
+
*
|
167 |
+
* @param string $category Category id. Optional.
|
168 |
+
* @return array An associative array of categories or module data.
|
169 |
+
*/
|
170 |
+
function get_active_by_category($category = ''){
|
171 |
+
if ( !isset($this->_category_cache_active) ){
|
172 |
+
$this->_category_cache_active = $this->sort_into_categories($this->get_active_modules());
|
173 |
+
}
|
174 |
+
|
175 |
+
if ( empty($category) ){
|
176 |
+
return $this->_category_cache_active;
|
177 |
+
} else {
|
178 |
+
if ( isset($this->_category_cache_active[$category]) ){
|
179 |
+
return $this->_category_cache_active[$category];
|
180 |
+
} else {
|
181 |
+
return array();
|
182 |
+
}
|
183 |
+
}
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* Get the module ids of all active modules that belong to a specific category,
|
188 |
+
* quoted and ready for use in SQL.
|
189 |
+
*
|
190 |
+
* @param string $category Category ID. If not specified, a list of all active modules will be returned.
|
191 |
+
* @return string A comma separated list of single-quoted module ids, e.g. 'module-foo','module-bar','modbaz'
|
192 |
+
*/
|
193 |
+
function get_escaped_ids($category = ''){
|
194 |
+
global $wpdb;
|
195 |
+
|
196 |
+
if ( empty($category) ){
|
197 |
+
$modules = $this->get_active_modules();
|
198 |
+
} else {
|
199 |
+
$modules = $this->get_active_by_category($category);
|
200 |
+
}
|
201 |
+
|
202 |
+
$modules = array_map(array(&$wpdb, 'escape'), array_keys($modules));
|
203 |
+
$modules = "'" . implode("', '", $modules) . "'";
|
204 |
+
|
205 |
+
return $modules;
|
206 |
+
}
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Sort a list of modules into categories. Inside each category, modules are sorted by priority (descending).
|
210 |
+
*
|
211 |
+
* @access private
|
212 |
+
*
|
213 |
+
* @param array $modules
|
214 |
+
* @return array
|
215 |
+
*/
|
216 |
+
function sort_into_categories($modules){
|
217 |
+
$categories = array();
|
218 |
+
|
219 |
+
foreach($modules as $module_id => $module_data){
|
220 |
+
$cat = $module_data['ModuleCategory'];
|
221 |
+
if ( isset($categories[$cat]) ){
|
222 |
+
$categories[$cat][$module_id] = $module_data;
|
223 |
+
} else {
|
224 |
+
$categories[$cat] = array($module_id => $module_data);
|
225 |
+
}
|
226 |
+
}
|
227 |
+
|
228 |
+
foreach($categories as $cat => $cat_modules){
|
229 |
+
uasort($categories[$cat], array(&$this, 'compare_priorities'));
|
230 |
+
}
|
231 |
+
|
232 |
+
return $categories;
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Callback for sorting modules by priority.
|
237 |
+
*
|
238 |
+
* @access private
|
239 |
+
*
|
240 |
+
* @param array $a First module header.
|
241 |
+
* @param array $b Second module header.
|
242 |
+
* @return int
|
243 |
+
*/
|
244 |
+
function compare_priorities($a, $b){
|
245 |
+
return $b['ModulePriority'] - $a['ModulePriority'];
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Retrieve a reference to an active module.
|
250 |
+
*
|
251 |
+
* Each module is instantiated only once, so if the module was already loaded you'll get back
|
252 |
+
* a reference to the existing module object. If the module isn't loaded or instantiated yet,
|
253 |
+
* the function will do it automatically (but only for active modules).
|
254 |
+
*
|
255 |
+
* @param string $module_id Module ID.
|
256 |
+
* @param bool $autoload Optional. Whether to load the module file if it's not loaded yet. Defaults to TRUE.
|
257 |
+
* @param string $category Optional. Return the module only if it's in a specific category. Categories are ignored by default.
|
258 |
+
* @return blcModule A reference to a module object, or NULL on error.
|
259 |
+
*/
|
260 |
+
function &get_module($module_id, $autoload = true, $category=''){
|
261 |
+
if ( !is_string($module_id) ){
|
262 |
+
//$backtrace = debug_backtrace();
|
263 |
+
//FB::error($backtrace, "get_module called with a non-string argument");
|
264 |
+
return null;
|
265 |
+
}
|
266 |
+
|
267 |
+
if ( empty($this->loaded[$module_id]) ){
|
268 |
+
if ( $autoload && $this->is_active($module_id) ){
|
269 |
+
if ( !$this->load_module($module_id) ){
|
270 |
+
return null;
|
271 |
+
}
|
272 |
+
} else {
|
273 |
+
return null;
|
274 |
+
}
|
275 |
+
}
|
276 |
+
|
277 |
+
if ( !empty($category) ){
|
278 |
+
$data = $this->get_module_data($module_id);
|
279 |
+
if ( $data['ModuleCategory'] != $category ){
|
280 |
+
return null;
|
281 |
+
}
|
282 |
+
}
|
283 |
+
|
284 |
+
$module = &$this->init_module($module_id);
|
285 |
+
return $module;
|
286 |
+
}
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Retrieve the header data of a specific module.
|
290 |
+
* Uses cached module info if available.
|
291 |
+
*
|
292 |
+
* @param string $module_id
|
293 |
+
* @param bool $use_active_cache Check the active module cache before the general one. Defaults to true.
|
294 |
+
* @return array Associative array of module data, or FALSE if the specified module was not found.
|
295 |
+
*/
|
296 |
+
function get_module_data($module_id, $use_active_cache = true){
|
297 |
+
//Check virtual modules
|
298 |
+
if ( isset($this->_virtual_modules[$module_id]) ){
|
299 |
+
return $this->_virtual_modules[$module_id];
|
300 |
+
}
|
301 |
+
|
302 |
+
//Check active modules
|
303 |
+
if ( $use_active_cache && isset($this->plugin_conf->options['active_modules'][$module_id]) ){
|
304 |
+
return $this->plugin_conf->options['active_modules'][$module_id];
|
305 |
+
}
|
306 |
+
|
307 |
+
//Otherwise, use the general module cache
|
308 |
+
if ( !isset($this->_module_cache) ){
|
309 |
+
$this->get_modules(); //Populates the cache
|
310 |
+
}
|
311 |
+
|
312 |
+
if ( isset($this->_module_cache[$module_id]) ){
|
313 |
+
return $this->_module_cache[$module_id];
|
314 |
+
} else {
|
315 |
+
return false;
|
316 |
+
}
|
317 |
+
}
|
318 |
+
|
319 |
+
/**
|
320 |
+
* Retrieve a list of active modules.
|
321 |
+
*
|
322 |
+
* The list of active modules is stored in the 'active_modules' key of the
|
323 |
+
* plugin configuration object. If this key is not set, this function will
|
324 |
+
* create it and populate it using the list of default active modules passed
|
325 |
+
* to the module manager's constructor.
|
326 |
+
*
|
327 |
+
* @return array Associative array of module data indexed by module ID.
|
328 |
+
*/
|
329 |
+
function get_active_modules(){
|
330 |
+
if ( isset($this->plugin_conf->options['active_modules']) ){
|
331 |
+
return $this->plugin_conf->options['active_modules'];
|
332 |
+
}
|
333 |
+
|
334 |
+
$active = array();
|
335 |
+
$modules = $this->get_modules();
|
336 |
+
|
337 |
+
if ( is_array($this->default_active_modules) ){
|
338 |
+
foreach($this->default_active_modules as $module_id){
|
339 |
+
if ( array_key_exists($module_id, $modules) ){
|
340 |
+
$active[$module_id] = $modules[$module_id];
|
341 |
+
}
|
342 |
+
}
|
343 |
+
}
|
344 |
+
|
345 |
+
$this->plugin_conf->options['active_modules'] = $active;
|
346 |
+
$this->plugin_conf->save_options();
|
347 |
+
|
348 |
+
return $this->plugin_conf->options['active_modules'];
|
349 |
+
}
|
350 |
+
|
351 |
+
/**
|
352 |
+
* Determine if module is active.
|
353 |
+
*
|
354 |
+
* @param string $module_id
|
355 |
+
* @return bool
|
356 |
+
*/
|
357 |
+
function is_active($module_id){
|
358 |
+
return array_key_exists($module_id, $this->get_active_modules());
|
359 |
+
}
|
360 |
+
|
361 |
+
/**
|
362 |
+
* Activate a module.
|
363 |
+
* Does nothing if the module is already active.
|
364 |
+
*
|
365 |
+
* @param string $module_id
|
366 |
+
* @return bool True if module was activated sucessfully, false otherwise.
|
367 |
+
*/
|
368 |
+
function activate($module_id){
|
369 |
+
if ( $this->is_active($module_id) ){
|
370 |
+
return true;
|
371 |
+
}
|
372 |
+
|
373 |
+
//Retrieve the module header
|
374 |
+
$module_data = $this->get_module_data($module_id, false);
|
375 |
+
if ( !$module_data ){
|
376 |
+
return false;
|
377 |
+
}
|
378 |
+
|
379 |
+
//Attempt to load the module
|
380 |
+
if ( $this->load_module($module_id, $module_data) ){
|
381 |
+
//Okay, if it loads, we can assume it works.
|
382 |
+
$this->plugin_conf->options['active_modules'][$module_id] = $module_data;
|
383 |
+
$this->plugin_conf->save_options();
|
384 |
+
//Invalidate the per-category active module cache
|
385 |
+
$this->_category_cache_active = null;
|
386 |
+
|
387 |
+
//Notify the module that it's been activated
|
388 |
+
$module = & $this->get_module($module_id);
|
389 |
+
if ( $module ){
|
390 |
+
$module->activated();
|
391 |
+
}
|
392 |
+
} else {
|
393 |
+
return false;
|
394 |
+
}
|
395 |
+
}
|
396 |
+
|
397 |
+
/**
|
398 |
+
* Deactivate a module.
|
399 |
+
* Does nothing if the module is already inactive.
|
400 |
+
*
|
401 |
+
* @param string $module_id
|
402 |
+
* @return bool
|
403 |
+
*/
|
404 |
+
function deactivate($module_id){
|
405 |
+
if ( !$this->is_active($module_id) ){
|
406 |
+
return true;
|
407 |
+
}
|
408 |
+
|
409 |
+
//Some modules are supposed to be always active and thus can't be deactivated
|
410 |
+
$module_data = $this->get_module_data($module_id, false);
|
411 |
+
if ( isset($module_data['ModuleAlwaysActive']) && $module_data['ModuleAlwaysActive'] ){
|
412 |
+
return false;
|
413 |
+
}
|
414 |
+
|
415 |
+
//Notify the module that it's being deactivated
|
416 |
+
$module = & $this->get_module($module_id);
|
417 |
+
if ( $module ){
|
418 |
+
$module->deactivated();
|
419 |
+
}
|
420 |
+
|
421 |
+
unset($this->plugin_conf->options['active_modules'][$module_id]);
|
422 |
+
|
423 |
+
//Keep track of when each module was last deactivated. Used for parser resynchronization.
|
424 |
+
if ( isset($this->plugin_conf->options['module_deactivated_when']) ){
|
425 |
+
$this->plugin_conf->options['module_deactivated_when'][$module_id] = current_time('timestamp');
|
426 |
+
} else {
|
427 |
+
$this->plugin_conf->options['module_deactivated_when'] = array(
|
428 |
+
$module_id => current_time('timestamp'),
|
429 |
+
);
|
430 |
+
}
|
431 |
+
$this->plugin_conf->save_options();
|
432 |
+
|
433 |
+
$this->_category_cache_active = null; //Invalidate the by-category cache since we just changed something
|
434 |
+
return true;
|
435 |
+
}
|
436 |
+
|
437 |
+
/**
|
438 |
+
* Determine when a module was last deactivated.
|
439 |
+
*
|
440 |
+
* @param string $module_id Module ID.
|
441 |
+
* @return int Timestamp of last deactivation, or 0 if the module has never been deactivated.
|
442 |
+
*/
|
443 |
+
function get_last_deactivation_time($module_id){
|
444 |
+
if ( isset($this->plugin_conf->options['module_deactivated_when'][$module_id]) ){
|
445 |
+
return $this->plugin_conf->options['module_deactivated_when'][$module_id];
|
446 |
+
} else {
|
447 |
+
return 0;
|
448 |
+
}
|
449 |
+
}
|
450 |
+
|
451 |
+
/**
|
452 |
+
* Set the current list of active modules. If any of the modules are not currently active,
|
453 |
+
* they will be activated. Any currently active modules that are not on the new list will
|
454 |
+
* be deactivated.
|
455 |
+
*
|
456 |
+
* @param array $ids An array of module IDs.
|
457 |
+
* @return void
|
458 |
+
*/
|
459 |
+
function set_active_modules($ids){
|
460 |
+
$current_active = array_keys($this->get_active_modules());
|
461 |
+
|
462 |
+
$activate = array_diff($ids, $current_active);
|
463 |
+
$deactivate = array_diff($current_active, $ids);
|
464 |
+
|
465 |
+
//Deactivate any modules not present in the new list
|
466 |
+
foreach($deactivate as $module_id){
|
467 |
+
$this->deactivate($module_id);
|
468 |
+
}
|
469 |
+
|
470 |
+
//Activate modules present in the new list but not in the old list
|
471 |
+
foreach($activate as $module_id){
|
472 |
+
$this->activate($module_id);
|
473 |
+
}
|
474 |
+
|
475 |
+
//Ensure all active modules have the latest headers
|
476 |
+
$this->refresh_active_module_cache();
|
477 |
+
|
478 |
+
//Invalidate the per-category active module cache
|
479 |
+
$this->_category_cache_active = null;
|
480 |
+
}
|
481 |
+
|
482 |
+
/**
|
483 |
+
* Send the activation message to all currently active plugins when the plugin is activated.
|
484 |
+
*
|
485 |
+
* @return void
|
486 |
+
*/
|
487 |
+
function plugin_activated(){
|
488 |
+
//Ensure all active modules have the latest headers
|
489 |
+
$this->refresh_active_module_cache();
|
490 |
+
|
491 |
+
//Notify them that we've been activated
|
492 |
+
$active = $this->get_active_modules();
|
493 |
+
foreach($active as $module_id => $module_data){
|
494 |
+
$module = & $this->get_module($module_id);
|
495 |
+
if ( $module ){
|
496 |
+
$module->activated();
|
497 |
+
}
|
498 |
+
}
|
499 |
+
}
|
500 |
+
|
501 |
+
/**
|
502 |
+
* Refresh the cached data of all active modules.
|
503 |
+
*
|
504 |
+
* @return array An updated list of active modules.
|
505 |
+
*/
|
506 |
+
function refresh_active_module_cache(){
|
507 |
+
$modules = $this->get_modules();
|
508 |
+
foreach($this->plugin_conf->options['active_modules'] as $module_id => $module_header){
|
509 |
+
if ( array_key_exists($module_id, $modules) ){
|
510 |
+
$this->plugin_conf->options['active_modules'][$module_id] = $modules[$module_id];
|
511 |
+
}
|
512 |
+
}
|
513 |
+
$this->plugin_conf->save_options();
|
514 |
+
$this->_category_cache_active = null; //Invalidate the by-category active module cache
|
515 |
+
return $this->plugin_conf->options['active_modules'];
|
516 |
+
}
|
517 |
+
|
518 |
+
/**
|
519 |
+
* Load active modules.
|
520 |
+
*
|
521 |
+
* @param string $context Optional. If specified, only the modules that match this context (or the "all" context) will be loaded.
|
522 |
+
* @return void
|
523 |
+
*/
|
524 |
+
function load_modules($context = ''){
|
525 |
+
$active = $this->get_active_modules();
|
526 |
+
//Avoid trying to load a virtual module before the module that registered it has been loaded.
|
527 |
+
$active = $this->put_virtual_last($active);
|
528 |
+
|
529 |
+
foreach($active as $module_id => $module_data){
|
530 |
+
//Load the module
|
531 |
+
$should_load = ($module_data['ModuleContext'] == 'all') || (!empty($context) && $module_data['ModuleContext'] == $context);
|
532 |
+
if ( $should_load ){
|
533 |
+
$this->load_module($module_id, $module_data);
|
534 |
+
}
|
535 |
+
}
|
536 |
+
}
|
537 |
+
|
538 |
+
/**
|
539 |
+
* Load and possibly instantiate a specific module.
|
540 |
+
*
|
541 |
+
* @access private
|
542 |
+
*
|
543 |
+
* @param string $module_id
|
544 |
+
* @param array $module_data
|
545 |
+
* @return bool True if the module was successfully loaded, false otherwise.
|
546 |
+
*/
|
547 |
+
function load_module($module_id, $module_data = null){
|
548 |
+
|
549 |
+
//Only load each module once.
|
550 |
+
if ( !empty($this->loaded[$module_id]) ){
|
551 |
+
return true;
|
552 |
+
}
|
553 |
+
|
554 |
+
if ( !isset($module_data) ){
|
555 |
+
$module_data = $this->get_module_data($module_id);
|
556 |
+
if ( empty($module_data) ){
|
557 |
+
return false;
|
558 |
+
}
|
559 |
+
}
|
560 |
+
|
561 |
+
//Only load Pro-version modules with BLC Pro
|
562 |
+
if ( $module_data['ModuleRequiresPro'] && !defined('BLC_PRO_VERSION') ){
|
563 |
+
return false;
|
564 |
+
}
|
565 |
+
|
566 |
+
//Load a normal module
|
567 |
+
if ( empty($module_data['virtual']) ){
|
568 |
+
|
569 |
+
//Skip invalid and missing modules
|
570 |
+
if ( empty($module_data['file']) ){
|
571 |
+
return false;
|
572 |
+
}
|
573 |
+
|
574 |
+
//Get the full path to the module file
|
575 |
+
$filename = $this->module_dir . '/' . $module_data['file'];
|
576 |
+
if ( !file_exists($filename) ){
|
577 |
+
return false;
|
578 |
+
}
|
579 |
+
|
580 |
+
//Load it
|
581 |
+
include $filename;
|
582 |
+
$this->loaded[$module_id] = true;
|
583 |
+
|
584 |
+
} else {
|
585 |
+
|
586 |
+
//Virtual modules don't need to be explicitly loaded, but they must
|
587 |
+
//be registered.
|
588 |
+
if ( !array_key_exists($module_id, $this->_virtual_modules) ) {
|
589 |
+
return false;
|
590 |
+
}
|
591 |
+
$this->loaded[$module_id] = true;
|
592 |
+
|
593 |
+
}
|
594 |
+
|
595 |
+
//Instantiate the main module class unless lazy init is on (default is off)
|
596 |
+
if ( !array_key_exists($module_id, $this->instances) ){ //Only try to instantiate once
|
597 |
+
if ( !$module_data['ModuleLazyInit'] ){
|
598 |
+
$this->init_module($module_id, $module_data);
|
599 |
+
}
|
600 |
+
}
|
601 |
+
|
602 |
+
return true;
|
603 |
+
}
|
604 |
+
|
605 |
+
/**
|
606 |
+
* Instantiate a certain module.
|
607 |
+
*
|
608 |
+
* @param string $module_id
|
609 |
+
* @param array $module_data Optional. The header data of the module that needs to be instantiated. If not specified, it will be retrieved automatically.
|
610 |
+
* @return object The newly instantiated module object (extends blcModule), or NULL on error.
|
611 |
+
*/
|
612 |
+
function &init_module($module_id, $module_data = null){
|
613 |
+
//Each module is only instantiated once.
|
614 |
+
if ( isset($this->instances[$module_id]) ){
|
615 |
+
return $this->instances[$module_id];
|
616 |
+
}
|
617 |
+
|
618 |
+
if ( !isset($module_data) ){
|
619 |
+
$module_data = $this->get_module_data($module_id);
|
620 |
+
if ( empty($module_data) ){
|
621 |
+
return null;
|
622 |
+
}
|
623 |
+
}
|
624 |
+
|
625 |
+
if ( !empty($module_data['ModuleClassName']) && class_exists($module_data['ModuleClassName']) ){
|
626 |
+
$className = $module_data['ModuleClassName'];
|
627 |
+
$this->instances[$module_id] = new $className(
|
628 |
+
$module_id,
|
629 |
+
$module_data,
|
630 |
+
$this->plugin_conf,
|
631 |
+
$this
|
632 |
+
);
|
633 |
+
return $this->instances[$module_id];
|
634 |
+
};
|
635 |
+
|
636 |
+
return null;
|
637 |
+
}
|
638 |
+
|
639 |
+
function is_instantiated($module_id){
|
640 |
+
return !empty($this->instances[$module_id]);
|
641 |
+
}
|
642 |
+
|
643 |
+
/**
|
644 |
+
* Register a virtual module.
|
645 |
+
*
|
646 |
+
* Virtual modules are the same as normal modules, except that they can be added
|
647 |
+
* on the fly, e.g. by other modules.
|
648 |
+
*
|
649 |
+
* @param string $module_id Module Id.
|
650 |
+
* @param string $module_data Associative array of module data. All module header fields are allowed, except ModuleID.
|
651 |
+
* @return void
|
652 |
+
*/
|
653 |
+
function register_virtual_module($module_id, $module_data){
|
654 |
+
$module_data = $this->normalize_module_header($module_data, $module_id);
|
655 |
+
$module_data['virtual'] = true;
|
656 |
+
$this->_virtual_modules[$module_id] = $module_data;
|
657 |
+
}
|
658 |
+
|
659 |
+
/**
|
660 |
+
* Sort an array of modules so that all virtual modules are placed at its end.
|
661 |
+
*
|
662 |
+
* @param array $modules Input array, [module_id => module_data, ...].
|
663 |
+
* @return array Sorted array.
|
664 |
+
*/
|
665 |
+
function put_virtual_last($modules){
|
666 |
+
uasort($modules, array(&$this, 'compare_virtual_flags'));
|
667 |
+
return $modules;
|
668 |
+
}
|
669 |
+
|
670 |
+
/**
|
671 |
+
* Callback function for sorting modules by the state of their 'virtual' flag.
|
672 |
+
*
|
673 |
+
* @param array $a Associative array of module A data
|
674 |
+
* @param array $b Associative array of module B data
|
675 |
+
* @return int
|
676 |
+
*/
|
677 |
+
function compare_virtual_flags($a, $b){
|
678 |
+
if ( empty($a['virtual']) ){
|
679 |
+
return empty($b['virtual'])?0:-1;
|
680 |
+
} else {
|
681 |
+
return empty($b['virtual'])?1:0;
|
682 |
+
}
|
683 |
+
}
|
684 |
+
|
685 |
+
/**
|
686 |
+
* Validate active modules.
|
687 |
+
*
|
688 |
+
* Validates all active modules, deactivates invalid ones and returns
|
689 |
+
* an array of deactivated modules.
|
690 |
+
*
|
691 |
+
* @return array
|
692 |
+
*/
|
693 |
+
function validate_active_modules(){
|
694 |
+
$active = $this->get_active_modules();
|
695 |
+
if ( empty($active) ){
|
696 |
+
return array();
|
697 |
+
}
|
698 |
+
|
699 |
+
$invalid = array();
|
700 |
+
foreach($active as $module_id => $module_data){
|
701 |
+
$rez = $this->validate_module($module_data);
|
702 |
+
if ( is_wp_error($rez) ){
|
703 |
+
$invalid[$module_id] = $rez;
|
704 |
+
$this->deactivate($module_id);
|
705 |
+
}
|
706 |
+
}
|
707 |
+
|
708 |
+
return $invalid;
|
709 |
+
}
|
710 |
+
|
711 |
+
/**
|
712 |
+
* Validate module data.
|
713 |
+
*
|
714 |
+
* Checks that the module file exists or that the module
|
715 |
+
* is a currently registered virtual module.
|
716 |
+
*
|
717 |
+
* @param array $module_data Associative array of module data.
|
718 |
+
* @return bool|WP_Error True on success, an error object if the module fails validation
|
719 |
+
*/
|
720 |
+
function validate_module($module_data){
|
721 |
+
if ( empty($module_data['ModuleID']) ){
|
722 |
+
return new WP_Error('invalid_cached_header', 'The cached module header is invalid');
|
723 |
+
}
|
724 |
+
|
725 |
+
if ( empty($module_data['virtual']) ){
|
726 |
+
//Normal modules must have a valid filename
|
727 |
+
if ( empty($module_data['file']) ){
|
728 |
+
return new WP_Error('module_not_found', 'Invalid module file');
|
729 |
+
}
|
730 |
+
|
731 |
+
$filename = $this->module_dir . '/' . $module_data['file'];
|
732 |
+
if ( !file_exists($filename) ){
|
733 |
+
return new WP_Error('module_not_found', 'Module file not found');
|
734 |
+
}
|
735 |
+
|
736 |
+
//The module file header must be in the proper format. While $module_data comes
|
737 |
+
//from cache and can be assumed to be correct, get_modules() will attempt to load
|
738 |
+
//the current headers and only return modules with semi-valid headers.
|
739 |
+
$installed = $this->get_modules();
|
740 |
+
if ( !array_key_exists($module_data['ModuleID'], $installed) ){
|
741 |
+
return new WP_Error('invalid_module_header', 'Invalid module header');
|
742 |
+
}
|
743 |
+
} else {
|
744 |
+
//Virtual modules need to be currently registered
|
745 |
+
if ( !array_key_exists($module_data['ModuleID'], $this->_virtual_modules) ){
|
746 |
+
return new WP_Error('module_not_registered', 'The virtual module is not registered');
|
747 |
+
}
|
748 |
+
}
|
749 |
+
|
750 |
+
return true;
|
751 |
+
}
|
752 |
+
|
753 |
+
/**
|
754 |
+
* Add BLC-module specific headers to the list of allowed plugin headers. This
|
755 |
+
* lets us use get_plugins() to retrieve the list of BLC modules.
|
756 |
+
*
|
757 |
+
* @param array $headers Currently known plugin headers.
|
758 |
+
* @return array New plugin headers.
|
759 |
+
*/
|
760 |
+
function inject_module_headers($headers){
|
761 |
+
$module_headers = array(
|
762 |
+
'ModuleID',
|
763 |
+
'ModuleCategory',
|
764 |
+
'ModuleContext',
|
765 |
+
'ModuleLazyInit',
|
766 |
+
'ModuleClassName',
|
767 |
+
'ModulePriority',
|
768 |
+
'ModuleCheckerUrlPattern',
|
769 |
+
'ModuleHidden', //Don't show the module in the Settings page
|
770 |
+
'ModuleAlwaysActive', //Module can't be deactivated.
|
771 |
+
'ModuleRequiresPro', //Can only be activated in the Pro version
|
772 |
+
);
|
773 |
+
|
774 |
+
return array_merge($headers, $module_headers);
|
775 |
+
}
|
776 |
+
|
777 |
+
/**
|
778 |
+
* Normalize a module header, using defaults where necessary.
|
779 |
+
*
|
780 |
+
* @param array $module_header Module header, as read from the module's .php file.
|
781 |
+
* @param string $module_id Module ID.
|
782 |
+
* @param string $module_filename Module filename. Optional.
|
783 |
+
* @return array Normalized module header.
|
784 |
+
*/
|
785 |
+
function normalize_module_header($module_header, $module_id, $module_filename = ''){
|
786 |
+
//Default values for optional module header fields
|
787 |
+
$defaults = array(
|
788 |
+
'ModuleContext' => 'all',
|
789 |
+
'ModuleCategory' => 'other',
|
790 |
+
'ModuleLazyInit' => 'false',
|
791 |
+
'ModulePriority' => '0',
|
792 |
+
'ModuleHidden' => 'false',
|
793 |
+
'ModuleAlwaysActive' => 'false',
|
794 |
+
'ModuleRequiresPro' => 'false',
|
795 |
+
'TextDomain' => 'broken-link-checker', //For translating module headers
|
796 |
+
);
|
797 |
+
|
798 |
+
$module_header['ModuleID'] = $module_id; //Just for consistency
|
799 |
+
$module_header['file'] = $module_filename; //Used later to load the module
|
800 |
+
|
801 |
+
//Apply defaults
|
802 |
+
foreach($defaults as $field => $default_value){
|
803 |
+
if ( empty($module_header[$field]) ){
|
804 |
+
$module_header[$field] = $default_value;
|
805 |
+
}
|
806 |
+
}
|
807 |
+
|
808 |
+
//Convert bool/int fields from strings to native datatypes
|
809 |
+
$module_header['ModuleLazyInit'] = $this->str_to_bool($module_header['ModuleLazyInit']);
|
810 |
+
$module_header['ModuleHidden'] = $this->str_to_bool($module_header['ModuleHidden']);
|
811 |
+
$module_header['ModuleAlwaysActive'] = $this->str_to_bool($module_header['ModuleAlwaysActive']);
|
812 |
+
$module_header['ModuleRequiresPro'] = $this->str_to_bool($module_header['ModuleRequiresPro']);
|
813 |
+
$module_header['ModulePriority'] = intval($module_header['ModulePriority']);
|
814 |
+
|
815 |
+
return $module_header;
|
816 |
+
}
|
817 |
+
|
818 |
+
/**
|
819 |
+
* Converts the strings "true" and "false" to boolean TRUE and FALSE, respectively.
|
820 |
+
* Any other string will yield FALSE.
|
821 |
+
*
|
822 |
+
* @param string $value "true" or "false", case-insensitive.
|
823 |
+
* @return bool
|
824 |
+
*/
|
825 |
+
function str_to_bool($value){
|
826 |
+
$value = trim(strtolower($value));
|
827 |
+
return $value == 'true';
|
828 |
+
}
|
829 |
+
|
830 |
+
/**
|
831 |
+
* Generates a PHP script that calls the __() i18n function with
|
832 |
+
* the name and description of each available module. The generated
|
833 |
+
* script is used to make module headers show up in the .POT file.
|
834 |
+
*
|
835 |
+
* @access private
|
836 |
+
*
|
837 |
+
* @return string
|
838 |
+
*/
|
839 |
+
function _build_header_translation_code(){
|
840 |
+
$this->_module_cache = null; //Clear the cache
|
841 |
+
$modules = $this->get_modules();
|
842 |
+
|
843 |
+
$strings = array();
|
844 |
+
foreach($modules as $module_id => $module_header){
|
845 |
+
if ( $module_header['ModuleHidden'] || ($module_id == 'write-module-placeholders')) {
|
846 |
+
continue;
|
847 |
+
}
|
848 |
+
if ( !empty($module_header['Name']) ){
|
849 |
+
$strings[] = sprintf(
|
850 |
+
'_x("%s", "module name", "broken-link-checker");',
|
851 |
+
str_replace('"', '\"', $module_header['Name'])
|
852 |
+
);
|
853 |
+
}
|
854 |
+
}
|
855 |
+
|
856 |
+
return "<?php\n" . implode("\n", $strings) . "\n?>";
|
857 |
+
}
|
858 |
+
}
|
859 |
+
|
860 |
+
?>
|
includes/modules.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Load all files pertaining to BLC's module subsystem
|
5 |
+
*/
|
6 |
+
|
7 |
+
require 'module-manager.php';
|
8 |
+
require 'module-base.php';
|
9 |
+
|
10 |
+
require 'containers.php';
|
11 |
+
require 'checkers.php';
|
12 |
+
require 'parsers.php';
|
13 |
+
|
14 |
+
$blc_module_manager = & blcModuleManager::getInstance(array(
|
15 |
+
//List of modules active by default
|
16 |
+
'http', //Link checker for the HTTP(s) protocol
|
17 |
+
'link', //HTML link parser
|
18 |
+
'image', //HTML image parser
|
19 |
+
'metadata', //Metadata (custom field) parser
|
20 |
+
'url_field', //URL field parser
|
21 |
+
'blogroll', //Blogroll container
|
22 |
+
'comment', //Comment container
|
23 |
+
'custom_field', //Post metadata container (aka custom fields)
|
24 |
+
'post', //Post content container
|
25 |
+
'page', //Page content container
|
26 |
+
'dummy', //Dummy container used as a fallback
|
27 |
+
));
|
28 |
+
|
29 |
+
require 'any-post.php';
|
30 |
+
|
31 |
+
?>
|
includes/parsers.php
CHANGED
@@ -1,100 +1,5 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
/**
|
4 |
-
* Parser Registry class for managing parsers. Used as a singleton.
|
5 |
-
*
|
6 |
-
* @see blcParser
|
7 |
-
*
|
8 |
-
* @package Broken Link Checker
|
9 |
-
* @access public
|
10 |
-
*/
|
11 |
-
class blcParserRegistry {
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @access protected
|
15 |
-
*/
|
16 |
-
var $registered_parsers = array();
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Get an instance of the parser registry class.
|
20 |
-
*
|
21 |
-
* @return blcParserRegistry
|
22 |
-
*/
|
23 |
-
function &getInstance(){
|
24 |
-
static $instance = null;
|
25 |
-
if ( is_null($instance) ){
|
26 |
-
$instance = new blcParserRegistry;
|
27 |
-
}
|
28 |
-
return $instance;
|
29 |
-
}
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Register a new link parser.
|
33 |
-
*
|
34 |
-
* @param string $parser_type A unique string identifying the parser.
|
35 |
-
* @param string $class_name Name of the class implementing the parser.
|
36 |
-
* @return bool True on success, false if this parser type is already registered.
|
37 |
-
*/
|
38 |
-
function register_parser( $parser_type, $class_name ){
|
39 |
-
if ( isset($this->registered_parsers[$parser_type]) ){
|
40 |
-
return false;
|
41 |
-
}
|
42 |
-
|
43 |
-
$parser = new $class_name($parser_type);
|
44 |
-
$this->registered_parsers[$parser_type] = $parser;
|
45 |
-
|
46 |
-
return true;
|
47 |
-
}
|
48 |
-
|
49 |
-
/**
|
50 |
-
* Retrieve a list of all registered parsers.
|
51 |
-
*
|
52 |
-
* @return array An associative array of parser objects indexed by parser ID.
|
53 |
-
*/
|
54 |
-
function get_registered_parsers(){
|
55 |
-
return $this->registered_parsers;
|
56 |
-
}
|
57 |
-
|
58 |
-
/**
|
59 |
-
* Get the parser matching a parser type ID.
|
60 |
-
*
|
61 |
-
* @param string $parser_type
|
62 |
-
* @return blcParser|null
|
63 |
-
*/
|
64 |
-
function &get_parser( $parser_type ){
|
65 |
-
if ( isset($this->registered_parsers[$parser_type]) ){
|
66 |
-
return $this->registered_parsers[$parser_type];
|
67 |
-
} else {
|
68 |
-
return null;
|
69 |
-
}
|
70 |
-
}
|
71 |
-
|
72 |
-
/**
|
73 |
-
* Get all parsers that support either the specified format or the container type.
|
74 |
-
* If a parser supports both, it will still be included only once.
|
75 |
-
*
|
76 |
-
* @param string $format
|
77 |
-
* @param string $container_type
|
78 |
-
* @return array of blcParser
|
79 |
-
*/
|
80 |
-
function get_parsers( $format, $container_type ){
|
81 |
-
$found = array();
|
82 |
-
|
83 |
-
foreach($this->registered_parsers as $parser){
|
84 |
-
if ( in_array($format, $parser->supported_formats) || in_array($container_type, $parser->supported_containers) ){
|
85 |
-
array_push($found, $parser);
|
86 |
-
}
|
87 |
-
}
|
88 |
-
|
89 |
-
return $found;
|
90 |
-
}
|
91 |
-
|
92 |
-
}
|
93 |
-
|
94 |
-
//Create the parser registry singleton.
|
95 |
-
$GLOBALS['blc_parser_registry'] = & blcParserRegistry::getInstance();
|
96 |
-
|
97 |
-
|
98 |
/**
|
99 |
* A base class for parsers.
|
100 |
*
|
@@ -117,30 +22,58 @@ $GLOBALS['blc_parser_registry'] = & blcParserRegistry::getInstance();
|
|
117 |
* @package Broken Link Checker
|
118 |
* @access public
|
119 |
*/
|
120 |
-
class blcParser {
|
121 |
|
122 |
var $parser_type;
|
123 |
var $supported_formats = array();
|
124 |
var $supported_containers = array();
|
125 |
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
$this->parser_type = $
|
134 |
}
|
135 |
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
$this->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
}
|
145 |
|
146 |
/**
|
@@ -196,13 +129,13 @@ class blcParser {
|
|
196 |
* @param blcLinkInstance $instance
|
197 |
* @return string HTML
|
198 |
*/
|
199 |
-
function ui_get_link_text(
|
200 |
return $instance->link_text;
|
201 |
}
|
202 |
|
203 |
/**
|
204 |
* Turn a relative URL into an absolute one.
|
205 |
-
*
|
206 |
* @param string $url Relative URL.
|
207 |
* @param string $base_url Base URL. If omitted, the blog's root URL will be used.
|
208 |
* @return string
|
@@ -332,47 +265,57 @@ class blcParser {
|
|
332 |
}
|
333 |
|
334 |
/**
|
335 |
-
*
|
336 |
-
*
|
337 |
* @see blcParser
|
338 |
-
*
|
339 |
-
* @
|
340 |
-
*
|
341 |
-
* @param string $parser_type A unique string identifying the parser, e.g. "html_link"
|
342 |
-
* @param string $class_name Name of the class that implements the parser.
|
343 |
-
* @return bool
|
344 |
-
*/
|
345 |
-
function blc_register_parser( $parser_type, $class_name ) {
|
346 |
-
$instance = & blcParserRegistry::getInstance();
|
347 |
-
return $instance->register_parser($parser_type, $class_name);
|
348 |
-
}
|
349 |
-
|
350 |
-
/**
|
351 |
-
* Get the parser matching a parser type id.
|
352 |
-
*
|
353 |
-
* @uses blcParserRegistry::get_parser()
|
354 |
-
*
|
355 |
-
* @param string $parser_type
|
356 |
-
* @return blcParser|null
|
357 |
-
*/
|
358 |
-
function &blc_get_parser( $parser_type ){
|
359 |
-
$instance = & blcParserRegistry::getInstance();
|
360 |
-
return $instance->get_parser($parser_type);
|
361 |
-
}
|
362 |
-
|
363 |
-
/**
|
364 |
-
* Get all parsers that support either the specified format or container type.
|
365 |
-
*
|
366 |
-
* @uses blcParserRegistry::get_parsers()
|
367 |
-
*
|
368 |
-
* @param string $format
|
369 |
-
* @param string $container_type
|
370 |
-
* @return array of blcParser
|
371 |
*/
|
372 |
-
|
373 |
-
|
374 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
375 |
}
|
376 |
|
377 |
-
|
378 |
?>
|
1 |
<?php
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
/**
|
4 |
* A base class for parsers.
|
5 |
*
|
22 |
* @package Broken Link Checker
|
23 |
* @access public
|
24 |
*/
|
25 |
+
class blcParser extends blcModule {
|
26 |
|
27 |
var $parser_type;
|
28 |
var $supported_formats = array();
|
29 |
var $supported_containers = array();
|
30 |
|
31 |
+
/**
|
32 |
+
* Initialize the parser. Nothing much here.
|
33 |
+
*
|
34 |
+
* @return void
|
35 |
+
*/
|
36 |
+
function init(){
|
37 |
+
parent::init();
|
38 |
+
$this->parser_type = $this->module_id;
|
39 |
}
|
40 |
|
41 |
+
/**
|
42 |
+
* Called when the parser is activated.
|
43 |
+
*
|
44 |
+
* @return void
|
45 |
+
*/
|
46 |
+
function activated(){
|
47 |
+
parent::activated();
|
48 |
+
$this->resynch_relevant_containers();
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Mark containers that this parser might be interested in as unparsed.
|
53 |
+
*
|
54 |
+
* @uses blcContainerHelper::mark_as_unsynched_where()
|
55 |
+
*
|
56 |
+
* @param bool $only_return If true, just return the list of formats and container types without actually modifying any synch. records.
|
57 |
+
* @return void|array Either nothing or an array in the form [ [format1=>timestamp1, ...], [container_type1=>timestamp1, ...] ]
|
58 |
+
*/
|
59 |
+
function resynch_relevant_containers($only_return = false){
|
60 |
+
$last_deactivated = $this->module_manager->get_last_deactivation_time($this->module_id);
|
61 |
+
|
62 |
+
$formats = array();
|
63 |
+
foreach($this->supported_formats as $format){
|
64 |
+
$formats[$format] = $last_deactivated;
|
65 |
+
}
|
66 |
+
|
67 |
+
$container_types = array();
|
68 |
+
foreach($this->supported_containers as $container_type){
|
69 |
+
$container_types[$container_type] = $last_deactivated;
|
70 |
+
}
|
71 |
+
|
72 |
+
if ( $only_return ){
|
73 |
+
return array($formats, $container_types);
|
74 |
+
} else {
|
75 |
+
blcContainerHelper::mark_as_unsynched_where($formats, $container_types);
|
76 |
+
}
|
77 |
}
|
78 |
|
79 |
/**
|
129 |
* @param blcLinkInstance $instance
|
130 |
* @return string HTML
|
131 |
*/
|
132 |
+
function ui_get_link_text(&$instance, $context = 'display'){
|
133 |
return $instance->link_text;
|
134 |
}
|
135 |
|
136 |
/**
|
137 |
* Turn a relative URL into an absolute one.
|
138 |
+
*
|
139 |
* @param string $url Relative URL.
|
140 |
* @param string $base_url Base URL. If omitted, the blog's root URL will be used.
|
141 |
* @return string
|
265 |
}
|
266 |
|
267 |
/**
|
268 |
+
* A helper class for working with parsers. All its methods should be called statically.
|
269 |
+
*
|
270 |
* @see blcParser
|
271 |
+
*
|
272 |
+
* @package Broken Link Checker
|
273 |
+
* @access public
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
274 |
*/
|
275 |
+
class blcParserHelper {
|
276 |
+
|
277 |
+
/**
|
278 |
+
* Get the parser matching a parser type ID.
|
279 |
+
*
|
280 |
+
* @uses blcModuleManager::get_module()
|
281 |
+
*
|
282 |
+
* @param string $parser_type
|
283 |
+
* @return blcParser|null
|
284 |
+
*/
|
285 |
+
function &get_parser( $parser_type ){
|
286 |
+
$manager = & blcModuleManager::getInstance();
|
287 |
+
return $manager->get_module($parser_type, true, 'parser');
|
288 |
+
}
|
289 |
+
|
290 |
+
/**
|
291 |
+
* Get all parsers that support either the specified format or the container type.
|
292 |
+
* If a parser supports both, it will still be included only once.
|
293 |
+
*
|
294 |
+
* @param string $format
|
295 |
+
* @param string $container_type
|
296 |
+
* @return array of blcParser
|
297 |
+
*/
|
298 |
+
function get_parsers( $format, $container_type ){
|
299 |
+
$found = array();
|
300 |
+
|
301 |
+
//Retrieve a list of active parsers
|
302 |
+
$manager = & blcModuleManager::getInstance();
|
303 |
+
$active_parsers = $manager->get_modules_by_category('parser');
|
304 |
+
|
305 |
+
//Try each one
|
306 |
+
foreach($active_parsers as $module_id => $module_data){
|
307 |
+
$parser = & $manager->get_module($module_id); //Will autoload if necessary
|
308 |
+
if ( !$parser ){
|
309 |
+
continue;
|
310 |
+
}
|
311 |
+
|
312 |
+
if ( in_array($format, $parser->supported_formats) || in_array($container_type, $parser->supported_containers) ){
|
313 |
+
array_push($found, $parser);
|
314 |
+
}
|
315 |
+
}
|
316 |
+
|
317 |
+
return $found;
|
318 |
+
}
|
319 |
}
|
320 |
|
|
|
321 |
?>
|
includes/screen-options/screen-options.js
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery(function($){
|
2 |
+
function performAutosave(){
|
3 |
+
var panel = $(this).parents('div.custom-options-panel');
|
4 |
+
var params = panel.find('input, select, textarea').serialize();
|
5 |
+
params = params + '&action=save_settings-' + panel.attr('id');
|
6 |
+
$.post(
|
7 |
+
'admin-ajax.php',
|
8 |
+
params
|
9 |
+
);
|
10 |
+
}
|
11 |
+
|
12 |
+
$('#screen-options-wrap div.requires-autosave').find('input, select, textarea').change(performAutosave);
|
13 |
+
});
|
includes/screen-options/screen-options.php
ADDED
@@ -0,0 +1,282 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( !class_exists('wsScreenOptions12') ):
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class for adding new panels to the "Screen Options" box.
|
7 |
+
*
|
8 |
+
* Do not access this class directly. Instead, use the add_screen_options_panel() function.
|
9 |
+
*
|
10 |
+
* @author Janis Elsts
|
11 |
+
* @copyright 2010
|
12 |
+
* @version 1.2
|
13 |
+
* @access public
|
14 |
+
*/
|
15 |
+
class wsScreenOptions12 {
|
16 |
+
var $registered_panels; //List of custom "Screen Options" panels
|
17 |
+
var $page_panels; //Index of panels registered for each page ($page => array of panel ids).
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Class constructor
|
21 |
+
*
|
22 |
+
* @return void
|
23 |
+
*/
|
24 |
+
function init(){
|
25 |
+
$this->registered_panels = array();
|
26 |
+
$this->page_panels = array();
|
27 |
+
|
28 |
+
add_filter('screen_settings', array(&$this, 'append_screen_settings'), 10, 2);
|
29 |
+
add_action('admin_print_scripts', array(&$this, 'add_autosave_script'));
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Add a new settings panel to the "Screen Options" box.
|
34 |
+
*
|
35 |
+
* @param string $id String to use in the 'id' attribute of the settings panel. Should be unique.
|
36 |
+
* @param string $title Title of the settings panel. Set to an empty string to omit title.
|
37 |
+
* @param callback $callback Function that fills the panel with the desired content. Should return its output.
|
38 |
+
* @param string|array $page The page(s) on which to show the panel (similar to add_meta_box()).
|
39 |
+
* @param callback $save_callback Optional. Function that saves the settings.
|
40 |
+
* @param bool $autosave Optional. If se, settings will be automatically saved (via AJAX) when the value of any input element in the panel changes. Defaults to false.
|
41 |
+
* @return void
|
42 |
+
*/
|
43 |
+
function add_screen_options_panel($id, $title, $callback, $page, $save_callback = null, $autosave = false){
|
44 |
+
if ( !is_array($page) ){
|
45 |
+
$page = array($page);
|
46 |
+
}
|
47 |
+
//Convert page hooks/slugs to screen IDs
|
48 |
+
$page = array_map(array(&$this, 'page_to_screen_id'), $page);
|
49 |
+
$page = array_unique($page);
|
50 |
+
|
51 |
+
$new_panel = array(
|
52 |
+
'title' => $title,
|
53 |
+
'callback' => $callback,
|
54 |
+
'page' => $page,
|
55 |
+
'save_callback' => $save_callback,
|
56 |
+
'autosave' => $autosave,
|
57 |
+
);
|
58 |
+
|
59 |
+
if ( $save_callback ){
|
60 |
+
add_action('wp_ajax_save_settings-' . $id, array(&$this, 'ajax_save_callback'));
|
61 |
+
}
|
62 |
+
|
63 |
+
//Store the panel ID in each relevant page's list
|
64 |
+
foreach($page as $page_id){
|
65 |
+
if ( !isset($this->page_panels[$page_id]) ){
|
66 |
+
$this->page_panels[$page_id] = array();
|
67 |
+
}
|
68 |
+
$this->page_panels[$page_id][] = $id;
|
69 |
+
}
|
70 |
+
|
71 |
+
$this->registered_panels[$id] = $new_panel;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Convert a page hook name to a screen ID.
|
76 |
+
*
|
77 |
+
* @uses convert_to_screen()
|
78 |
+
* @access private
|
79 |
+
*
|
80 |
+
* @param string $page
|
81 |
+
* @return string
|
82 |
+
*/
|
83 |
+
function page_to_screen_id($page){
|
84 |
+
if ( function_exists('convert_to_screen') ){
|
85 |
+
$screen = convert_to_screen($page);
|
86 |
+
if ( isset($screen->id) ){
|
87 |
+
return $screen->id;
|
88 |
+
} else {
|
89 |
+
return '';
|
90 |
+
}
|
91 |
+
} else {
|
92 |
+
return str_replace( array('.php', '-new', '-add' ), '', $page);
|
93 |
+
}
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Append custom panel HTML to the "Screen Options" box of the current page.
|
98 |
+
* Callback for the 'screen_settings' filter (available in WP 3.0 and up).
|
99 |
+
*
|
100 |
+
* @access private
|
101 |
+
*
|
102 |
+
* @param string $current
|
103 |
+
* @param string $screen Screen object (undocumented).
|
104 |
+
* @return string The HTML code to append to "Screen Options"
|
105 |
+
*/
|
106 |
+
function append_screen_settings($current, $screen){
|
107 |
+
global $hook_suffix;
|
108 |
+
|
109 |
+
//Sanity check
|
110 |
+
if ( !isset($screen->id) ) {
|
111 |
+
return $current;
|
112 |
+
}
|
113 |
+
|
114 |
+
//Are there any panels that want to appear on this page?
|
115 |
+
$panels = $this->get_panels_for_screen($screen->id, $hook_suffix);
|
116 |
+
if ( empty($panels) ){
|
117 |
+
return $current;
|
118 |
+
}
|
119 |
+
|
120 |
+
//Append all panels registered for this screen
|
121 |
+
foreach($panels as $panel_id){
|
122 |
+
$panel = $this->registered_panels[$panel_id];
|
123 |
+
|
124 |
+
//Add panel title
|
125 |
+
if ( !empty($panel['title']) ){
|
126 |
+
$current .= "\n<h5>".$panel['title']."</h5>\n";
|
127 |
+
}
|
128 |
+
//Generate panel contents
|
129 |
+
if ( is_callable($panel['callback']) ){
|
130 |
+
$contents = call_user_func($panel['callback']);
|
131 |
+
$classes = array(
|
132 |
+
'custom-options-panel',
|
133 |
+
);
|
134 |
+
if ( $panel['autosave'] ){
|
135 |
+
$classes[] = 'requires-autosave';
|
136 |
+
}
|
137 |
+
|
138 |
+
$contents = sprintf(
|
139 |
+
'<div id="%s" class="%s"><input type="hidden" name="_wpnonce-%s" value="%s" />%s</div>',
|
140 |
+
esc_attr($panel_id),
|
141 |
+
implode(' ',$classes),
|
142 |
+
esc_attr($panel_id),
|
143 |
+
wp_create_nonce('save_settings-'.$panel_id),
|
144 |
+
$contents
|
145 |
+
);
|
146 |
+
|
147 |
+
$current .= $contents;
|
148 |
+
}
|
149 |
+
}
|
150 |
+
|
151 |
+
return $current;
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* AJAX callback for the "Screen Options" autosave.
|
156 |
+
*
|
157 |
+
* @access private
|
158 |
+
* @return void
|
159 |
+
*/
|
160 |
+
function ajax_save_callback(){
|
161 |
+
if ( empty($_POST['action']) ){
|
162 |
+
die('0');
|
163 |
+
}
|
164 |
+
|
165 |
+
//The 'action' argument is in the form "save_settings-panel_id"
|
166 |
+
$id = end(explode('-', $_POST['action'], 2));
|
167 |
+
|
168 |
+
//Basic security check.
|
169 |
+
check_ajax_referer('save_settings-' . $id, '_wpnonce-' . $id);
|
170 |
+
|
171 |
+
//Hand the request to the registered callback, if any
|
172 |
+
if ( !isset($this->registered_panels[$id]) ){
|
173 |
+
exit('0');
|
174 |
+
}
|
175 |
+
$panel = $this->registered_panels[$id];
|
176 |
+
if ( is_callable($panel['save_callback']) ){
|
177 |
+
call_user_func($panel['save_callback'], $_POST);
|
178 |
+
die('1');
|
179 |
+
} else {
|
180 |
+
die('0');
|
181 |
+
}
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Add/enqueue supporting JavaScript for the autosave function of custom "Screen Options" panels.
|
186 |
+
*
|
187 |
+
* Checks if the current page is supposed to contain any autosave-enabled
|
188 |
+
* panels and adds the script only if that's the case.
|
189 |
+
*
|
190 |
+
* @return void
|
191 |
+
*/
|
192 |
+
function add_autosave_script(){
|
193 |
+
//Get the page id/hook/slug/whatever.
|
194 |
+
global $hook_suffix;
|
195 |
+
|
196 |
+
//Check if we have some panels with autosave registered for this page.
|
197 |
+
$panels = $this->get_panels_for_screen('', $hook_suffix);
|
198 |
+
if ( empty($panels) ){
|
199 |
+
return;
|
200 |
+
}
|
201 |
+
|
202 |
+
$got_autosave = false;
|
203 |
+
foreach($panels as $panel_id){
|
204 |
+
if ( $this->registered_panels[$panel_id]['autosave'] ){
|
205 |
+
$got_autosave = true;
|
206 |
+
break;
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
+
if ( $got_autosave ){
|
211 |
+
//Enqueue the script itself
|
212 |
+
$url = plugins_url('screen-options.js', __FILE__);
|
213 |
+
wp_enqueue_script('screen-options-custom-autosave', $url, array('jquery'));
|
214 |
+
}
|
215 |
+
}
|
216 |
+
|
217 |
+
/**
|
218 |
+
* Get custom panels registered for a particular screen and/or page.
|
219 |
+
*
|
220 |
+
* @param string $screen_id Screen ID.
|
221 |
+
* @param string $page Optional. Page filename or hook name.
|
222 |
+
* @return array Array of custom panels.
|
223 |
+
*/
|
224 |
+
function get_panels_for_screen($screen_id, $page = ''){
|
225 |
+
if ( isset($this->page_panels[$screen_id]) && !empty($this->page_panels[$screen_id]) ){
|
226 |
+
$panels = $this->page_panels[$screen_id];
|
227 |
+
} else {
|
228 |
+
$panels = array();
|
229 |
+
}
|
230 |
+
if ( !empty($page) ){
|
231 |
+
$page_as_screen = $this->page_to_screen_id($page);
|
232 |
+
if ( isset($this->page_panels[$page_as_screen]) && !empty($this->page_panels[$page_as_screen]) ){
|
233 |
+
$panels = array_merge($panels, $this->page_panels[$page_as_screen]);
|
234 |
+
}
|
235 |
+
}
|
236 |
+
return array_unique($panels);
|
237 |
+
}
|
238 |
+
}
|
239 |
+
|
240 |
+
//All versions of the class are stored in a global array
|
241 |
+
//and only the latest version is actually used.
|
242 |
+
global $ws_screen_options_versions;
|
243 |
+
if ( !isset($ws_screen_options_versions) ){
|
244 |
+
$ws_screen_options_versions = array();
|
245 |
+
}
|
246 |
+
$ws_screen_options_versions['1.2'] = 'wsScreenOptions12';
|
247 |
+
|
248 |
+
endif;
|
249 |
+
|
250 |
+
if ( !function_exists('add_screen_options_panel') ){
|
251 |
+
|
252 |
+
/**
|
253 |
+
* Add a new settings panel to the "Screen Options" box.
|
254 |
+
*
|
255 |
+
* @see wsScreenOptions10::add_screen_options_panel()
|
256 |
+
*
|
257 |
+
* @param string $id String to use in the 'id' attribute of the settings panel. Should be unique.
|
258 |
+
* @param string $title Title of the settings panel. Set to an empty string to omit title.
|
259 |
+
* @param callback $callback Function that fills the panel with the desired content. Should return its output.
|
260 |
+
* @param string|array $page The page(s) on which to show the panel (similar to add_meta_box()).
|
261 |
+
* @param callback $save_callback Optional. Function that saves the settings contained in the panel.
|
262 |
+
* @param bool $autosave Optional. If set, settings will be automatically saved (via AJAX) when the value of any input element in the panel changes. Defaults to false.
|
263 |
+
* @return void
|
264 |
+
*/
|
265 |
+
function add_screen_options_panel($id, $title, $callback, $page, $save_callback = null, $autosave = false){
|
266 |
+
global $ws_screen_options_versions;
|
267 |
+
|
268 |
+
static $instance = null;
|
269 |
+
if ( is_null($instance) ){
|
270 |
+
//Instantiate the latest version of the wsScreenOptions class
|
271 |
+
uksort($ws_screen_options_versions, 'version_compare');
|
272 |
+
$className = end($ws_screen_options_versions);
|
273 |
+
$instance = new $className;
|
274 |
+
$instance->init();
|
275 |
+
}
|
276 |
+
|
277 |
+
return $instance->add_screen_options_panel($id, $title, $callback, $page, $save_callback, $autosave);
|
278 |
+
}
|
279 |
+
|
280 |
+
}
|
281 |
+
|
282 |
+
?>
|
utility-class.php → includes/utility-class.php
RENAMED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
/**
|
4 |
* @author W-Shadow
|
5 |
-
* @copyright
|
6 |
*/
|
7 |
|
8 |
|
@@ -36,146 +36,6 @@ if ( !class_exists('blcUtility') ){
|
|
36 |
|
37 |
class blcUtility {
|
38 |
|
39 |
-
//A regxp for images
|
40 |
-
function img_pattern(){
|
41 |
-
// \1 \2 \3 URL \4
|
42 |
-
return '/(<img[\s]+[^>]*src\s*=\s*)([\"\'])([^>]+?)\2([^<>]*>)/i';
|
43 |
-
}
|
44 |
-
|
45 |
-
//A regexp for links
|
46 |
-
function link_pattern(){
|
47 |
-
// \1 \2 \3 URL \4 \5 Text \6
|
48 |
-
return '/(<a[\s]+[^>]*href\s*=\s*)([\"\'])([^>]+?)\2([^<>]*>)((?sU).*)(<\/a>)/i';
|
49 |
-
}
|
50 |
-
|
51 |
-
/**
|
52 |
-
* blcUtility::normalize_url()
|
53 |
-
*
|
54 |
-
* @param string $url
|
55 |
-
* @params string $base_url (Optional) The base URL is used to convert a relative URL to a fully-qualified one
|
56 |
-
* @return string A normalized URL or FALSE if the URL is invalid
|
57 |
-
*/
|
58 |
-
function normalize_url($url, $base_url = ''){
|
59 |
-
//Sometimes links may contain shortcodes. Parse them.
|
60 |
-
$url = do_shortcode($url);
|
61 |
-
|
62 |
-
$parts = @parse_url($url);
|
63 |
-
if(!$parts) return false; //Invalid URL
|
64 |
-
|
65 |
-
if(isset($parts['scheme'])) {
|
66 |
-
//Only HTTP(S) links are checked. Other protocols are not supported.
|
67 |
-
if ( ($parts['scheme'] != 'http') && ($parts['scheme'] != 'https') )
|
68 |
-
return false;
|
69 |
-
}
|
70 |
-
|
71 |
-
$url = html_entity_decode($url);
|
72 |
-
$url = preg_replace(
|
73 |
-
array('/([\?&]PHPSESSID=\w+)$/i', //remove session ID
|
74 |
-
'/(#[^\/]*)$/', //and anchors/fragments
|
75 |
-
'/&/', //convert improper HTML entities
|
76 |
-
'/^(javascript:.*)/i', //treat links that contain JS as links with an empty URL
|
77 |
-
'/([\?&]sid=\w+)$/i' //remove another flavour of session ID
|
78 |
-
),
|
79 |
-
array('','','&','',''),
|
80 |
-
$url);
|
81 |
-
$url = trim($url);
|
82 |
-
|
83 |
-
if ( $url=='' ) return false;
|
84 |
-
|
85 |
-
// turn relative URLs into absolute URLs
|
86 |
-
if ( empty($base_url) ) $base_url = get_option('siteurl');
|
87 |
-
$url = blcUtility::relative2absolute( $base_url, $url);
|
88 |
-
return $url;
|
89 |
-
}
|
90 |
-
|
91 |
-
/**
|
92 |
-
* blcUtility::relative2absolute()
|
93 |
-
* Turns a relative URL into an absolute one given a base URL.
|
94 |
-
*
|
95 |
-
* @param string $absolute Base URL
|
96 |
-
* @param string $relative A relative URL
|
97 |
-
* @return string
|
98 |
-
*/
|
99 |
-
function relative2absolute($absolute, $relative) {
|
100 |
-
$p = @parse_url($relative);
|
101 |
-
if(!$p) {
|
102 |
-
//WTF? $relative is a seriously malformed URL
|
103 |
-
return false;
|
104 |
-
}
|
105 |
-
if( isset($p["scheme"]) ) return $relative;
|
106 |
-
|
107 |
-
//If the relative URL is just a query string, simply attach it to the absolute URL and return
|
108 |
-
if ( substr($relative, 0, 1) == '?' ){
|
109 |
-
return $absolute . $relative;
|
110 |
-
}
|
111 |
-
|
112 |
-
$parts=(parse_url($absolute));
|
113 |
-
|
114 |
-
if(substr($relative,0,1)=='/') {
|
115 |
-
//Relative URL starts with a slash => ignore the base path and jump straight to the root.
|
116 |
-
$path_segments = explode("/", $relative);
|
117 |
-
array_shift($path_segments);
|
118 |
-
} else {
|
119 |
-
if(isset($parts['path'])){
|
120 |
-
$aparts=explode('/',$parts['path']);
|
121 |
-
array_pop($aparts);
|
122 |
-
$aparts=array_filter($aparts);
|
123 |
-
} else {
|
124 |
-
$aparts=array();
|
125 |
-
}
|
126 |
-
|
127 |
-
//Merge together the base path & the relative path
|
128 |
-
$aparts = array_merge($aparts, explode("/", $relative));
|
129 |
-
|
130 |
-
//Filter the merged path
|
131 |
-
$path_segments = array();
|
132 |
-
foreach($aparts as $part){
|
133 |
-
if ( $part == '.' ){
|
134 |
-
continue; //. = "this directory". It's basically a no-op, so we skip it.
|
135 |
-
} elseif ( $part == '..' ) {
|
136 |
-
array_pop($path_segments); //.. = one directory up. Remove the last seen path segment.
|
137 |
-
} else {
|
138 |
-
array_push($path_segments, $part); //Normal directory -> add it to the path.
|
139 |
-
}
|
140 |
-
}
|
141 |
-
}
|
142 |
-
$path = implode("/", $path_segments);
|
143 |
-
|
144 |
-
$url = '';
|
145 |
-
if($parts['scheme']) {
|
146 |
-
$url = "$parts[scheme]://";
|
147 |
-
}
|
148 |
-
if(isset($parts['user'])) {
|
149 |
-
$url .= $parts['user'];
|
150 |
-
if(isset($parts['pass'])) {
|
151 |
-
$url .= ":".$parts['pass'];
|
152 |
-
}
|
153 |
-
$url .= "@";
|
154 |
-
}
|
155 |
-
if(isset($parts['host'])) {
|
156 |
-
$url .= $parts['host']."/";
|
157 |
-
}
|
158 |
-
$url .= $path;
|
159 |
-
|
160 |
-
return $url;
|
161 |
-
}
|
162 |
-
|
163 |
-
|
164 |
-
/**
|
165 |
-
* blcUtility::urlencodefix()
|
166 |
-
* Takes an URL and replaces spaces and some other non-alphanumeric characters with their urlencoded equivalents.
|
167 |
-
*
|
168 |
-
* @param string $str
|
169 |
-
* @return string
|
170 |
-
*/
|
171 |
-
function urlencodefix($url){
|
172 |
-
return preg_replace_callback(
|
173 |
-
'|[^a-z0-9\+\-\/\\#:.=?&%@]|i',
|
174 |
-
create_function('$str','return rawurlencode($str[0]);'),
|
175 |
-
$url
|
176 |
-
);
|
177 |
-
}
|
178 |
-
|
179 |
/**
|
180 |
* blcUtility::is_safe_mode()
|
181 |
* Checks if PHP is running in safe mode
|
@@ -355,6 +215,131 @@ class blcUtility {
|
|
355 |
return $tags;
|
356 |
}
|
357 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
358 |
}//class
|
359 |
|
360 |
}//class_exists
|
2 |
|
3 |
/**
|
4 |
* @author W-Shadow
|
5 |
+
* @copyright 2010
|
6 |
*/
|
7 |
|
8 |
|
36 |
|
37 |
class blcUtility {
|
38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
/**
|
40 |
* blcUtility::is_safe_mode()
|
41 |
* Checks if PHP is running in safe mode
|
215 |
return $tags;
|
216 |
}
|
217 |
|
218 |
+
/**
|
219 |
+
* Extract <embed> elements from a HTML string.
|
220 |
+
*
|
221 |
+
* This function returns an array of <embed> elements found in the input
|
222 |
+
* string. Only <embed>'s that are inside <object>'s are considered. Embeds
|
223 |
+
* without a 'src' attribute are skipped.
|
224 |
+
*
|
225 |
+
* Each array item has the same basic structure as the array items
|
226 |
+
* returned by blcUtility::extract_tags(), plus an additional 'wrapper' key
|
227 |
+
* that contains similarly structured info about the wrapping <object> tag.
|
228 |
+
*
|
229 |
+
* @uses blcUtility::extract_tags() This function is a simple wrapper around extract_tags()
|
230 |
+
*
|
231 |
+
* @param string $html
|
232 |
+
* @return array
|
233 |
+
*/
|
234 |
+
function extract_embeds($html){
|
235 |
+
$results = array();
|
236 |
+
|
237 |
+
//remove all <code></code> blocks first
|
238 |
+
$content = preg_replace('/<code[^>]*>.+?<\/code>/si', ' ', $content);
|
239 |
+
|
240 |
+
//Find likely-looking <object> elements
|
241 |
+
$objects = blcUtility::extract_tags($html, 'object', false, true);
|
242 |
+
foreach($objects as $candidate){
|
243 |
+
//Find the <embed> tag
|
244 |
+
$embed = blcUtility::extract_tags($candidate['full_tag'], 'embed', false);
|
245 |
+
if ( empty($embed)) continue;
|
246 |
+
$embed = reset($embed); //Take the first (and only) found <embed> element
|
247 |
+
|
248 |
+
if ( empty($embed['attributes']['src']) ){
|
249 |
+
continue;
|
250 |
+
}
|
251 |
+
|
252 |
+
$embed['wrapper'] = $candidate;
|
253 |
+
|
254 |
+
$results[] = $embed;
|
255 |
+
}
|
256 |
+
|
257 |
+
return $results;
|
258 |
+
}
|
259 |
+
|
260 |
+
/**
|
261 |
+
* Get the value of a cookie.
|
262 |
+
*
|
263 |
+
* @param string $cookie_name The name of the cookie to return.
|
264 |
+
* @param string $default_value Optional. If the cookie is not set, this value will be returned instead. Defaults to an empty string.
|
265 |
+
* @return mixed Either the value of the requested cookie, or $default_value.
|
266 |
+
*/
|
267 |
+
function get_cookie($cookie_name, $default_value = ''){
|
268 |
+
if ( isset($_COOKIE[$cookie_name]) ){
|
269 |
+
return $_COOKIE[$cookie_name];
|
270 |
+
} else {
|
271 |
+
return $default_value;
|
272 |
+
}
|
273 |
+
}
|
274 |
+
|
275 |
+
/**
|
276 |
+
* Format a time delta using a fuzzy format, e.g. '2 minutes ago', '2 days', etc.
|
277 |
+
*
|
278 |
+
* @param int $delta Time period in seconds.
|
279 |
+
* @param string $type Optional. The output template to use.
|
280 |
+
* @return string
|
281 |
+
*/
|
282 |
+
function fuzzy_delta($delta, $template = 'default'){
|
283 |
+
$ONE_MINUTE = 60;
|
284 |
+
$ONE_HOUR = 60 * $ONE_MINUTE;
|
285 |
+
$ONE_DAY = 24 * $ONE_HOUR;
|
286 |
+
$ONE_MONTH = $ONE_DAY * 3652425 / 120000;
|
287 |
+
$ONE_YEAR = $ONE_DAY * 3652425 / 10000;
|
288 |
+
|
289 |
+
$templates = array(
|
290 |
+
'seconds' => array(
|
291 |
+
'default' => _n_noop('%d second', '%d seconds'),
|
292 |
+
'ago' => _n_noop('%d second ago', '%d seconds ago'),
|
293 |
+
),
|
294 |
+
'minutes' => array(
|
295 |
+
'default' => _n_noop('%d minute', '%d minutes'),
|
296 |
+
'ago' => _n_noop('%d minute ago', '%d minutes ago'),
|
297 |
+
),
|
298 |
+
'hours' => array(
|
299 |
+
'default' => _n_noop('%d hour', '%d hours'),
|
300 |
+
'ago' => _n_noop('%d hour ago', '%d hours ago'),
|
301 |
+
),
|
302 |
+
'days' => array(
|
303 |
+
'default' => _n_noop('%d day', '%d days'),
|
304 |
+
'ago' => _n_noop('%d day ago', '%d days ago'),
|
305 |
+
),
|
306 |
+
'months' => array(
|
307 |
+
'default' => _n_noop('%d month', '%d months'),
|
308 |
+
'ago' => _n_noop('%d month ago', '%d months ago'),
|
309 |
+
),
|
310 |
+
);
|
311 |
+
|
312 |
+
if ( $delta < 1 ) {
|
313 |
+
$delta = 1;
|
314 |
+
}
|
315 |
+
|
316 |
+
if ( $delta < $ONE_MINUTE ){
|
317 |
+
$units = 'seconds';
|
318 |
+
} elseif ( $delta < $ONE_HOUR ){
|
319 |
+
$delta = intval($delta / $ONE_MINUTE);
|
320 |
+
$units = 'minutes';
|
321 |
+
} elseif ( $delta < $ONE_DAY ){
|
322 |
+
$delta = intval($delta / $ONE_HOUR);
|
323 |
+
$units = 'hours';
|
324 |
+
} elseif ( $delta < $ONE_MONTH ){
|
325 |
+
$delta = intval($delta / $ONE_DAY);
|
326 |
+
$units = 'days';
|
327 |
+
} else {
|
328 |
+
$delta = intval( $delta / $ONE_MONTH );
|
329 |
+
$units = 'months';
|
330 |
+
}
|
331 |
+
|
332 |
+
return sprintf(
|
333 |
+
_n(
|
334 |
+
$templates[$units][$template][0],
|
335 |
+
$templates[$units][$template][1],
|
336 |
+
$delta,
|
337 |
+
'broken-link-checker'
|
338 |
+
),
|
339 |
+
$delta
|
340 |
+
);
|
341 |
+
}
|
342 |
+
|
343 |
}//class
|
344 |
|
345 |
}//class_exists
|
js/jquery.cookie.js
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Cookie plugin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2006 Klaus Hartl (stilbuero.de)
|
5 |
+
* Dual licensed under the MIT and GPL licenses:
|
6 |
+
* http://www.opensource.org/licenses/mit-license.php
|
7 |
+
* http://www.gnu.org/licenses/gpl.html
|
8 |
+
*
|
9 |
+
*/
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Create a cookie with the given name and value and other optional parameters.
|
13 |
+
*
|
14 |
+
* @example $.cookie('the_cookie', 'the_value');
|
15 |
+
* @desc Set the value of a cookie.
|
16 |
+
* @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
|
17 |
+
* @desc Create a cookie with all available options.
|
18 |
+
* @example $.cookie('the_cookie', 'the_value');
|
19 |
+
* @desc Create a session cookie.
|
20 |
+
* @example $.cookie('the_cookie', null);
|
21 |
+
* @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
|
22 |
+
* used when the cookie was set.
|
23 |
+
*
|
24 |
+
* @param String name The name of the cookie.
|
25 |
+
* @param String value The value of the cookie.
|
26 |
+
* @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
|
27 |
+
* @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
|
28 |
+
* If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
|
29 |
+
* If set to null or omitted, the cookie will be a session cookie and will not be retained
|
30 |
+
* when the the browser exits.
|
31 |
+
* @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
|
32 |
+
* @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
|
33 |
+
* @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
|
34 |
+
* require a secure protocol (like HTTPS).
|
35 |
+
* @type undefined
|
36 |
+
*
|
37 |
+
* @name $.cookie
|
38 |
+
* @cat Plugins/Cookie
|
39 |
+
* @author Klaus Hartl/klaus.hartl@stilbuero.de
|
40 |
+
*/
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Get the value of a cookie with the given name.
|
44 |
+
*
|
45 |
+
* @example $.cookie('the_cookie');
|
46 |
+
* @desc Get the value of a cookie.
|
47 |
+
*
|
48 |
+
* @param String name The name of the cookie.
|
49 |
+
* @return The value of the cookie.
|
50 |
+
* @type String
|
51 |
+
*
|
52 |
+
* @name $.cookie
|
53 |
+
* @cat Plugins/Cookie
|
54 |
+
* @author Klaus Hartl/klaus.hartl@stilbuero.de
|
55 |
+
*/
|
56 |
+
jQuery.cookie = function(name, value, options) {
|
57 |
+
if (typeof value != 'undefined') { // name and value given, set cookie
|
58 |
+
options = options || {};
|
59 |
+
if (value === null) {
|
60 |
+
value = '';
|
61 |
+
options.expires = -1;
|
62 |
+
}
|
63 |
+
var expires = '';
|
64 |
+
if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
|
65 |
+
var date;
|
66 |
+
if (typeof options.expires == 'number') {
|
67 |
+
date = new Date();
|
68 |
+
date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
|
69 |
+
} else {
|
70 |
+
date = options.expires;
|
71 |
+
}
|
72 |
+
expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
|
73 |
+
}
|
74 |
+
// CAUTION: Needed to parenthesize options.path and options.domain
|
75 |
+
// in the following expressions, otherwise they evaluate to undefined
|
76 |
+
// in the packed version for some reason...
|
77 |
+
var path = options.path ? '; path=' + (options.path) : '';
|
78 |
+
var domain = options.domain ? '; domain=' + (options.domain) : '';
|
79 |
+
var secure = options.secure ? '; secure' : '';
|
80 |
+
document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
|
81 |
+
} else { // only name given, get cookie
|
82 |
+
var cookieValue = null;
|
83 |
+
if (document.cookie && document.cookie != '') {
|
84 |
+
var cookies = document.cookie.split(';');
|
85 |
+
for (var i = 0; i < cookies.length; i++) {
|
86 |
+
var cookie = jQuery.trim(cookies[i]);
|
87 |
+
// Does this cookie string begin with the name we want?
|
88 |
+
if (cookie.substring(0, name.length + 1) == (name + '=')) {
|
89 |
+
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
90 |
+
break;
|
91 |
+
}
|
92 |
+
}
|
93 |
+
}
|
94 |
+
return cookieValue;
|
95 |
+
}
|
96 |
+
};
|
languages/broken-link-checker-pt_PT.po
CHANGED
@@ -1,18 +1,18 @@
|
|
1 |
-
# Translation of the WordPress plugin Broken Link Checker 0.9.
|
2 |
# Copyright (C) 2010 Janis Elsts
|
3 |
# This file is distributed under the same license as the Broken Link Checker package.
|
4 |
-
# Tradução em português pt_PT do plugin Broken Link Checker - v.1.
|
5 |
-
# Autor:
|
6 |
# Website: http://jobs.mowster.net/ - <jobs@mowster.net>
|
7 |
#
|
8 |
msgid ""
|
9 |
msgstr ""
|
10 |
"Project-Id-Version: Broken Link Checker PT\n"
|
11 |
-
"Report-Msgid-Bugs-To:
|
12 |
-
"POT-Creation-Date: 2010-
|
13 |
"PO-Revision-Date: \n"
|
14 |
"Last-Translator: \n"
|
15 |
-
"Language-Team:
|
16 |
"MIME-Version: 1.0\n"
|
17 |
"Content-Type: text/plain; charset=UTF-8\n"
|
18 |
"Content-Transfer-Encoding: 8bit\n"
|
@@ -24,765 +24,922 @@ msgstr ""
|
|
24 |
"X-Poedit-Basepath: ..\n"
|
25 |
"X-Poedit-SearchPath-0: .\n"
|
26 |
|
27 |
-
#: broken-link-checker.php:
|
28 |
msgid "Once Weekly"
|
29 |
msgstr "Uma vez por semana"
|
30 |
|
31 |
-
#:
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
msgid "Loading..."
|
34 |
msgstr "Carregando..."
|
35 |
|
36 |
-
#: core.php:
|
37 |
-
#: core.php:
|
38 |
msgid "[ Network error ]"
|
39 |
msgstr "[ Problema na rede ]"
|
40 |
|
41 |
-
#: core.php:
|
42 |
msgid "Automatically expand the widget if broken links have been detected"
|
43 |
msgstr "Expandir automaticamente a caixa se existirem links offline"
|
44 |
|
45 |
-
#: core.php:
|
46 |
#, php-format
|
47 |
msgid "Failed to delete old DB tables. Database error : %s"
|
48 |
msgstr "Não foi possível apagar as tabelas antigas da Base de dados. Erro de Base de dados : %s"
|
49 |
|
50 |
-
#: core.php:
|
51 |
#, php-format
|
52 |
msgid "Unexpected error: The plugin doesn't know how to upgrade its database to version '%d'."
|
53 |
msgstr "Erro inesperado: O plugin não consegue actualizar a Base de dados para a versão '%d'."
|
54 |
|
55 |
-
#: core.php:
|
56 |
-
#: core.php:
|
57 |
-
#: core.php:
|
58 |
-
#: core.php:
|
59 |
#, php-format
|
60 |
msgid "Failed to create table '%s'. Database error: %s"
|
61 |
msgstr "Não foi possível criar a tabela '%s'. Erro na Base de dados: %s"
|
62 |
|
63 |
-
#: core.php:
|
64 |
msgid "Link Checker Settings"
|
65 |
msgstr "Definições do Links offline"
|
66 |
|
67 |
-
#: core.php:
|
68 |
msgid "Link Checker"
|
69 |
msgstr "Links offline"
|
70 |
|
71 |
-
#: core.php:
|
72 |
-
|
73 |
-
msgstr "Ver Links offline"
|
74 |
-
|
75 |
-
#: core.php:481
|
76 |
-
#: includes/links.php:771
|
77 |
msgid "Broken Links"
|
78 |
msgstr "Links offline"
|
79 |
|
80 |
-
#: core.php:
|
|
|
|
|
|
|
|
|
81 |
#, php-format
|
82 |
msgid "Highlight links broken for at least %s days"
|
83 |
msgstr "Sublinhar links offline pelo menos por %s dias"
|
84 |
|
85 |
-
#: core.php:
|
86 |
msgid "Settings"
|
87 |
msgstr "Definições"
|
88 |
|
89 |
-
#: core.php:
|
90 |
-
#: core.php:
|
91 |
#, php-format
|
92 |
msgid "Error: The plugin's database tables are not up to date! (Current version : %d, expected : %d)"
|
93 |
msgstr "Erro: As tabelas do plugin na Base de dados não estão actualizadas! (Versão actual : %d, obrigatória : %d)"
|
94 |
|
95 |
-
#: core.php:
|
96 |
msgid "Settings saved."
|
97 |
msgstr "Definições guardadas."
|
98 |
|
99 |
-
#: core.php:
|
100 |
msgid "Broken Link Checker Options"
|
101 |
msgstr "Opções : Links offline"
|
102 |
|
103 |
-
#: core.php:
|
104 |
msgid "Status"
|
105 |
msgstr "Estado"
|
106 |
|
107 |
-
#: core.php:
|
108 |
-
#: core.php:
|
109 |
msgid "Show debug info"
|
110 |
msgstr "Mostrar sistema"
|
111 |
|
112 |
-
#: core.php:
|
113 |
msgid "Re-check all pages"
|
114 |
msgstr "Verificar de novo todas as páginas"
|
115 |
|
116 |
-
#: core.php:
|
117 |
msgid "Check each link"
|
118 |
msgstr "Verificar cada link"
|
119 |
|
120 |
-
#: core.php:
|
121 |
#, php-format
|
122 |
msgid "Every %s hours"
|
123 |
msgstr "Cada %s horas"
|
124 |
|
125 |
-
#: core.php:
|
126 |
msgid "Existing links will be checked this often. New links will usually be checked ASAP."
|
127 |
msgstr "Os links existentes serão verificados com esta frequência. Os novos links comprovados logo que possível."
|
128 |
|
129 |
-
#: core.php:
|
130 |
msgid "Broken link CSS"
|
131 |
msgstr "Link CSS offline"
|
132 |
|
133 |
-
#: core.php:
|
134 |
msgid "Apply <em>class=\"broken_link\"</em> to broken links"
|
135 |
msgstr "Aplicar <em>class=\"broken_link\"</em> aos links offline"
|
136 |
|
137 |
-
#: core.php:
|
138 |
msgid "Removed link CSS"
|
139 |
msgstr "Link CSS removido"
|
140 |
|
141 |
-
#: core.php:
|
142 |
msgid "Apply <em>class=\"removed_link\"</em> to unlinked links"
|
143 |
msgstr "Aplicar <em>class=\"removed_link\"</em> aos links sem ligação"
|
144 |
|
145 |
-
#: core.php:
|
146 |
msgid "Broken link SEO"
|
147 |
msgstr "Link SEO offline"
|
148 |
|
149 |
-
#: core.php:
|
150 |
msgid "Apply <em>rel=\"nofollow\"</em> to broken links"
|
151 |
msgstr "Aplicar <em>rel=\"nofollow\"</em> aos links offline"
|
152 |
|
153 |
-
#: core.php:
|
154 |
msgid "Exclusion list"
|
155 |
msgstr "Lista de exclusão"
|
156 |
|
157 |
-
#: core.php:
|
158 |
msgid "Don't check links where the URL contains any of these words (one per line) :"
|
159 |
msgstr "Não verificar links que a URL tenha alguma destas palavras (uma por linha):"
|
160 |
|
161 |
-
#: core.php:
|
162 |
msgid "Custom fields"
|
163 |
msgstr "Campos personalizados"
|
164 |
|
165 |
-
#: core.php:
|
166 |
msgid "Check URLs entered in these custom fields (one per line) :"
|
167 |
msgstr "Verificar as seguintes URL personalizadas (uma por linha):"
|
168 |
|
169 |
-
#: core.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
msgid "E-mail notifications"
|
171 |
msgstr "Notificações por e-mail"
|
172 |
|
173 |
-
#: core.php:
|
174 |
msgid "Send me e-mail notifications about newly detected broken links"
|
175 |
msgstr "Enviar um e-mail notificando sobre os novos links offline detectados"
|
176 |
|
177 |
-
#: core.php:
|
178 |
msgid "Advanced"
|
179 |
msgstr "Avançado"
|
180 |
|
181 |
-
#: core.php:
|
182 |
msgid "Timeout"
|
183 |
msgstr "Intervalo"
|
184 |
|
185 |
-
#: core.php:
|
186 |
-
#: core.php:
|
|
|
187 |
#, php-format
|
188 |
msgid "%s seconds"
|
189 |
msgstr "%s segundos"
|
190 |
|
191 |
-
#: core.php:
|
192 |
msgid "Links that take longer than this to load will be marked as broken."
|
193 |
msgstr "Os links que demoram mais que este tempo a abrir serão marcados como offline."
|
194 |
|
195 |
-
#: core.php:
|
196 |
msgid "Link monitor"
|
197 |
msgstr "Monitor de links"
|
198 |
|
199 |
-
#: core.php:
|
200 |
msgid "Run continuously while the Dashboard is open"
|
201 |
msgstr "Executar continuamente enquanto o Painel do WordPress está aberto"
|
202 |
|
203 |
-
#: core.php:
|
204 |
msgid "Run hourly in the background"
|
205 |
msgstr "Executar a cada hora em segundo plano"
|
206 |
|
207 |
-
#: core.php:
|
208 |
msgid "Max. execution time"
|
209 |
msgstr "Tempo máximo de execução"
|
210 |
|
211 |
-
#: core.php:
|
212 |
msgid "The plugin works by periodically launching a background job that parses your posts for links, checks the discovered URLs, and performs other time-consuming tasks. Here you can set for how long, at most, the link monitor may run each time before stopping."
|
213 |
msgstr "O plugin funciona executando periodicamente uma tarefa em segundo plano que analiza os links, verifica os URL encontrados e realiza outras tarefas que consomem tempo. Aqui pode-se estabelecer a duração máxima cada vez que o monitor de links é executado antes de parar."
|
214 |
|
215 |
-
#: core.php:
|
216 |
msgid "Custom temporary directory"
|
217 |
msgstr "Pasta temporária personalizada"
|
218 |
|
219 |
-
#: core.php:
|
220 |
msgid "OK"
|
221 |
msgstr "Aceitar"
|
222 |
|
223 |
-
#: core.php:
|
224 |
msgid "Error : This directory isn't writable by PHP."
|
225 |
msgstr "Erro: PHP não pode escrever nesse directório."
|
226 |
|
227 |
-
#: core.php:
|
228 |
msgid "Error : This directory doesn't exist."
|
229 |
msgstr "Erro: Não existe esse directório."
|
230 |
|
231 |
-
#: core.php:
|
232 |
msgid "Set this field if you want the plugin to use a custom directory for its lockfiles. Otherwise, leave it blank."
|
233 |
msgstr "Preencha este campo se deseja que o plugin utilize um directório personalizado para seus ficheiros temporários. Caso contrário, deixa-lo em branco."
|
234 |
|
235 |
-
#: core.php:
|
236 |
msgid "Server load limit"
|
237 |
msgstr "Limite de carregamento do servidor"
|
238 |
|
239 |
-
#: core.php:
|
240 |
#, php-format
|
241 |
msgid "Link checking will be suspended if the average <a href=\"%s\">server load</a> rises above this number. Leave this field blank to disable load limiting."
|
242 |
msgstr "A verificação dos links será suspensa se a média do <a href=\"%s\">carregamento do servidor</a> passa este valor. Deixar o campo em branco para não existir limite."
|
243 |
|
244 |
-
#: core.php:
|
245 |
msgid "Load limiting only works on Linux-like systems where <code>/proc/loadavg</code> is present and accessible."
|
246 |
msgstr "O limite de carregamento somente funciona em sistemas Linux onde <code>/proc/loadavg</code> está presente e acessível."
|
247 |
|
248 |
-
#: core.php:
|
249 |
msgid "Save Changes"
|
250 |
msgstr "Guardar alterações"
|
251 |
|
252 |
-
#: core.php:
|
253 |
msgid "Hide debug info"
|
254 |
msgstr "Ocultar informação"
|
255 |
|
256 |
-
#: core.php:
|
257 |
-
#: core.php:
|
258 |
-
#: core.php:
|
259 |
#, php-format
|
260 |
msgid "Database error : %s"
|
261 |
msgstr "Erro na Base de dados: %s"
|
262 |
|
263 |
-
#: core.php:
|
264 |
msgid "Bulk Actions"
|
265 |
msgstr "Edição em Massa"
|
266 |
|
267 |
-
#: core.php:
|
268 |
msgid "Recheck"
|
269 |
msgstr "Voltar a verificar"
|
270 |
|
271 |
-
#: core.php:
|
272 |
msgid "Fix redirects"
|
273 |
msgstr "Reparar redirects"
|
274 |
|
275 |
-
#: core.php:
|
276 |
-
|
277 |
-
|
|
|
|
|
|
|
|
|
278 |
msgid "Unlink"
|
279 |
msgstr "Remover link"
|
280 |
|
281 |
-
#: core.php:
|
282 |
msgid "Delete sources"
|
283 |
msgstr "Apagar fontes"
|
284 |
|
285 |
-
#: core.php:
|
286 |
-
#: core.php:
|
287 |
msgid "Apply"
|
288 |
msgstr "Aplicar"
|
289 |
|
290 |
-
#: core.php:
|
291 |
msgid "«"
|
292 |
msgstr "«"
|
293 |
|
294 |
-
#: core.php:
|
295 |
msgid "»"
|
296 |
msgstr "»"
|
297 |
|
298 |
-
#: core.php:
|
299 |
-
#: core.php:
|
300 |
#, php-format
|
301 |
msgid "Displaying %s–%s of <span class=\"current-link-count\">%s</span>"
|
302 |
msgstr "Mostrando %s–%s de <span class=\"current-link-count\">%s</span>"
|
303 |
|
304 |
-
#: core.php:
|
305 |
msgid "Source"
|
306 |
msgstr "Fonte"
|
307 |
|
308 |
-
#: core.php:
|
309 |
msgid "Link Text"
|
310 |
msgstr "Texto do Link"
|
311 |
|
312 |
-
#: core.php:
|
313 |
#: includes/admin/search-form.php:42
|
314 |
msgid "URL"
|
315 |
msgstr "URL"
|
316 |
|
317 |
-
#: core.php:
|
318 |
msgid "[An orphaned link! This is a bug.]"
|
319 |
msgstr "[Um link orfão! Bug.]"
|
320 |
|
321 |
-
#: core.php:
|
322 |
msgid "Show more info about this link"
|
323 |
msgstr "Mostrar mais informação sobre este link"
|
324 |
|
325 |
-
#: core.php:
|
326 |
-
#: core.php:
|
327 |
msgid "Details"
|
328 |
msgstr "Detalhes"
|
329 |
|
330 |
-
#: core.php:
|
331 |
msgid "Remove this link from all posts"
|
332 |
msgstr "Eliminar este link"
|
333 |
|
334 |
-
#: core.php:
|
335 |
msgid "Remove this link from the list of broken links and mark it as valid"
|
336 |
msgstr "Eliminar este link da lista dos links offline e marca-lo como válido"
|
337 |
|
338 |
-
#: core.php:
|
339 |
-
#: includes/admin/links-page-js.php:
|
340 |
msgid "Not broken"
|
341 |
msgstr "Funcional"
|
342 |
|
343 |
-
#: core.php:
|
344 |
msgid "Edit link URL"
|
345 |
msgstr "Editar URL do link"
|
346 |
|
347 |
-
#: core.php:
|
348 |
-
#: includes/admin/links-page-js.php:
|
349 |
-
#: includes/admin/links-page-js.php:
|
350 |
msgid "Edit URL"
|
351 |
msgstr "Editar URL"
|
352 |
|
353 |
-
#: core.php:
|
354 |
msgid "Cancel URL editing"
|
355 |
msgstr "Cancelar a edição do URL"
|
356 |
|
357 |
-
#: core.php:
|
358 |
-
#: includes/admin/search-form.php:87
|
359 |
msgid "Cancel"
|
360 |
msgstr "Cancelar"
|
361 |
|
362 |
-
#: core.php:
|
363 |
msgid "You must enter a filter name!"
|
364 |
msgstr "Deve introduzir um nome para o filtro!"
|
365 |
|
366 |
-
#: core.php:
|
367 |
msgid "Invalid search query."
|
368 |
msgstr "Procura inválida."
|
369 |
|
370 |
-
#: core.php:
|
371 |
#, php-format
|
372 |
msgid "Filter \"%s\" created"
|
373 |
msgstr "Filtro \"%s\" criado"
|
374 |
|
375 |
-
#: core.php:
|
376 |
msgid "Filter ID not specified."
|
377 |
msgstr "ID do Filtro não especificado."
|
378 |
|
379 |
-
#: core.php:
|
380 |
msgid "Filter deleted"
|
381 |
msgstr "Filtro eliminado"
|
382 |
|
383 |
-
#: core.php:
|
384 |
#, php-format
|
385 |
msgid "Replaced %d redirect with a direct link"
|
386 |
-
|
387 |
-
msgstr[0] "Substituídos %d redirect com um link directo"
|
388 |
-
msgstr[1] "Substituídos %d redirects com links directos"
|
389 |
|
390 |
-
#: core.php:
|
391 |
#, php-format
|
392 |
msgid "Failed to fix %d redirect"
|
393 |
msgid_plural "Failed to fix %d redirects"
|
394 |
msgstr[0] "Não foi possível reparar %d redirect"
|
395 |
msgstr[1] "Não foi possível reparar %d redirects"
|
396 |
|
397 |
-
#: core.php:
|
398 |
msgid "None of the selected links are redirects!"
|
399 |
msgstr "Nenhum dos links seleccionados são redirects!"
|
400 |
|
401 |
-
#: core.php:
|
402 |
#, php-format
|
403 |
msgid "%d link removed"
|
404 |
msgid_plural "%d links removed"
|
405 |
msgstr[0] "%d link eliminado"
|
406 |
msgstr[1] "%d links eliminados"
|
407 |
|
408 |
-
#: core.php:
|
409 |
#, php-format
|
410 |
msgid "Failed to remove %d link"
|
411 |
msgid_plural "Failed to remove %d links"
|
412 |
msgstr[0] "Erro a remover %d link"
|
413 |
msgstr[1] "Erro a remover %d links"
|
414 |
|
415 |
-
#: core.php:
|
416 |
msgid "Didn't find anything to delete!"
|
417 |
msgstr "Não foi encontrado nada para apagar!"
|
418 |
|
419 |
-
#: core.php:
|
420 |
#, php-format
|
421 |
msgid "%d link scheduled for rechecking"
|
422 |
msgid_plural "%d links scheduled for rechecking"
|
423 |
msgstr[0] "%d link agendado para verificação"
|
424 |
msgstr[1] "%d links agendados para verificação"
|
425 |
|
426 |
-
#: core.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
427 |
msgid "Post published on"
|
428 |
msgstr "Post publicado em"
|
429 |
|
430 |
-
#: core.php:
|
431 |
msgid "Link last checked"
|
432 |
msgstr "Última verificação"
|
433 |
|
434 |
-
#: core.php:
|
435 |
msgid "Never"
|
436 |
msgstr "Nunca"
|
437 |
|
438 |
-
#: core.php:
|
439 |
#: includes/admin/search-form.php:45
|
440 |
msgid "HTTP code"
|
441 |
msgstr "Código HTTP"
|
442 |
|
443 |
-
#: core.php:
|
444 |
msgid "Response time"
|
445 |
msgstr "Tempo de resposta"
|
446 |
|
447 |
-
#: core.php:
|
448 |
#, php-format
|
449 |
msgid "%2.3f seconds"
|
450 |
msgstr "%2.3f segundos"
|
451 |
|
452 |
-
#: core.php:
|
453 |
msgid "Final URL"
|
454 |
msgstr "URL final"
|
455 |
|
456 |
-
#: core.php:
|
457 |
msgid "Redirect count"
|
458 |
msgstr "Contagem de redirects"
|
459 |
|
460 |
-
#: core.php:
|
461 |
msgid "Instance count"
|
462 |
msgstr "Contagem de casos"
|
463 |
|
464 |
-
#: core.php:
|
465 |
#, php-format
|
466 |
msgid "This link has failed %d time."
|
467 |
msgid_plural "This link has failed %d times."
|
468 |
msgstr[0] "Este link falhou %d vez."
|
469 |
msgstr[1] "Este link falhou %d vezes."
|
470 |
|
471 |
-
#: core.php:
|
472 |
#, php-format
|
473 |
msgid "This link has been broken for %s."
|
474 |
msgstr "Link offline durante %s."
|
475 |
|
476 |
-
#: core.php:
|
477 |
msgid "Log"
|
478 |
msgstr "Registro"
|
479 |
|
480 |
-
#: core.php:
|
481 |
msgid "less than a minute"
|
482 |
msgstr "menos de um minuto"
|
483 |
|
484 |
-
#: core.php:
|
485 |
#, php-format
|
486 |
msgid "%d minute"
|
487 |
msgid_plural "%d minutes"
|
488 |
msgstr[0] "%d minuto"
|
489 |
msgstr[1] "%d minutos"
|
490 |
|
491 |
-
#: core.php:
|
492 |
-
#: core.php:
|
493 |
#, php-format
|
494 |
msgid "%d hour"
|
495 |
msgid_plural "%d hours"
|
496 |
msgstr[0] "%d hora"
|
497 |
msgstr[1] "%d horas"
|
498 |
|
499 |
-
#: core.php:
|
500 |
-
#: core.php:
|
501 |
#, php-format
|
502 |
msgid "%d day"
|
503 |
msgid_plural "%d days"
|
504 |
msgstr[0] "%d dia"
|
505 |
msgstr[1] "%d dias"
|
506 |
|
507 |
-
#: core.php:
|
508 |
#, php-format
|
509 |
msgid "%d month"
|
510 |
msgid_plural "%d months"
|
511 |
msgstr[0] "%d mês"
|
512 |
msgstr[1] "%d meses"
|
513 |
|
514 |
-
#: core.php:
|
515 |
msgid "View broken links"
|
516 |
msgstr "Ver links offline"
|
517 |
|
518 |
-
#: core.php:
|
519 |
#, php-format
|
520 |
msgid "Found %d broken link"
|
521 |
msgid_plural "Found %d broken links"
|
522 |
msgstr[0] "Encontrado %d Link offline"
|
523 |
msgstr[1] "Encontrados %d Links offline"
|
524 |
|
525 |
-
#: core.php:
|
526 |
msgid "No broken links found."
|
527 |
msgstr "Não existem links offline."
|
528 |
|
529 |
-
#: core.php:
|
530 |
#, php-format
|
531 |
msgid "%d URL in the work queue"
|
532 |
msgid_plural "%d URLs in the work queue"
|
533 |
msgstr[0] "%d URL em espera"
|
534 |
msgstr[1] "%d URLs em espera"
|
535 |
|
536 |
-
#: core.php:
|
537 |
msgid "No URLs in the work queue."
|
538 |
msgstr "Não existem URL em espera para verificação."
|
539 |
|
540 |
-
#: core.php:
|
541 |
#, php-format
|
542 |
msgid "Detected %d unique URL"
|
543 |
msgid_plural "Detected %d unique URLs"
|
544 |
msgstr[0] "Detectada %d URL única"
|
545 |
msgstr[1] "Detectadas %d URL únicas"
|
546 |
|
547 |
-
#: core.php:
|
548 |
#, php-format
|
549 |
msgid "in %d link"
|
550 |
msgid_plural "in %d links"
|
551 |
msgstr[0] "em %d link"
|
552 |
msgstr[1] "em %d links"
|
553 |
|
554 |
-
#: core.php:
|
555 |
msgid "and still searching..."
|
556 |
msgstr "procurando..."
|
557 |
|
558 |
-
#: core.php:
|
559 |
msgid "Searching your blog for links..."
|
560 |
msgstr "Procurando links..."
|
561 |
|
562 |
-
#: core.php:
|
563 |
msgid "No links detected."
|
564 |
msgstr "Não se encontraram links."
|
565 |
|
566 |
-
#: core.php:
|
567 |
-
#: core.php:
|
568 |
-
#: core.php:
|
569 |
-
#: core.php:
|
570 |
msgid "You're not allowed to do that!"
|
571 |
msgstr "Não permitido!"
|
572 |
|
573 |
-
#: core.php:
|
574 |
-
#: core.php:
|
575 |
-
#: core.php:
|
576 |
#, php-format
|
577 |
msgid "Oops, I can't find the link %d"
|
578 |
msgstr "Oops, não é possível encontrar o link %d"
|
579 |
|
580 |
-
#: core.php:
|
581 |
-
msgid "This link was manually marked as working by the user."
|
582 |
-
msgstr "Este link foi marcado manualmente como válido por outro utilizador."
|
583 |
-
|
584 |
-
#: core.php:2374
|
585 |
msgid "Oops, couldn't modify the link!"
|
586 |
msgstr "Oops, não é possível modificar o link!"
|
587 |
|
588 |
-
#: core.php:
|
589 |
-
#: core.php:
|
590 |
msgid "Error : link_id not specified"
|
591 |
msgstr "Erro: link_id não especificado"
|
592 |
|
593 |
-
#: core.php:
|
594 |
msgid "Oops, the new URL is invalid!"
|
595 |
msgstr "Oops, a nova URL não é válida"
|
596 |
|
597 |
-
#: core.php:
|
598 |
-
#: core.php:
|
599 |
msgid "An unexpected error occured!"
|
600 |
msgstr "Ocorreu um erro inesperado!"
|
601 |
|
602 |
-
#: core.php:
|
603 |
msgid "Error : link_id or new_url not specified"
|
604 |
msgstr "Erro: link_id ou new_url não especificado"
|
605 |
|
606 |
-
#: core.php:
|
607 |
msgid "You don't have sufficient privileges to access this information!"
|
608 |
msgstr "Não tem previlégios suficientes para aceder a esta informação!"
|
609 |
|
610 |
-
#: core.php:
|
611 |
msgid "Error : link ID not specified"
|
612 |
msgstr "Erro: link ID não especificado"
|
613 |
|
614 |
-
#: core.php:
|
615 |
#, php-format
|
616 |
msgid "Failed to load link details (%s)"
|
617 |
msgstr "Erro a carregar os detalhes do link (%s)"
|
618 |
|
619 |
-
#: core.php:
|
|
|
|
|
|
|
|
|
620 |
#, php-format
|
621 |
msgid "The current temporary directory is not accessible; please <a href=\"%s\">set a different one</a>."
|
622 |
msgstr "O directório temporário não está acessível; por favor, <a href=\"%s\">especifique um diferente</a>."
|
623 |
|
624 |
-
#: core.php:
|
625 |
#, php-format
|
626 |
msgid "Please make the directory <code>%1$s</code> writable by plugins or <a href=\"%2$s\">set a custom temporary directory</a>."
|
627 |
msgstr "Por favor, deve permitir que os plugins possam gravar dados no directório <code>%1$s</code> ou <a href=\"%2$s\">especificar um directório temporário personalizado</a>."
|
628 |
|
629 |
-
#: core.php:
|
630 |
msgid "Broken Link Checker can't create a lockfile."
|
631 |
msgstr "Links offline não pode criar um ficheiro temporário."
|
632 |
|
633 |
-
#: core.php:
|
634 |
msgid "The plugin uses a file-based locking mechanism to ensure that only one instance of the resource-heavy link checking algorithm is running at any given time. Unfortunately, BLC can't find a writable directory where it could store the lockfile - it failed to detect the location of your server's temporary directory, and the plugin's own directory isn't writable by PHP. To fix this problem, please make the plugin's directory writable or enter a specify a custom temporary directory in the plugin's settings."
|
635 |
msgstr "Este plugin utiliza um sistema de bloqueio de ficheiros para garantir que somente se executa uma instância do algoritmo de verificação de links num momento determinado, uma vez que consome bastantes recursos. Infelizmente, o plugin não pode encontrar um directório que possa armazenar um ficheiro temporário - erro ao detectar a localização do directório temporário no servidor, assim como o própio directório do plugin não permite a escrita pelo PHP. Para resolver, terá que dar permissões de escrita ao directório ou especificar um directório temporário na configuração do plugin."
|
636 |
|
637 |
-
#: core.php:
|
638 |
msgid "PHP version"
|
639 |
msgstr "Versão PHP"
|
640 |
|
641 |
-
#: core.php:
|
642 |
msgid "MySQL version"
|
643 |
msgstr "Versão MySQL"
|
644 |
|
645 |
-
#: core.php:
|
646 |
msgid "You have an old version of CURL. Redirect detection may not work properly."
|
647 |
msgstr "Versão de CURL obsoleta. A detecção de redirects pode não funcionar correctamente."
|
648 |
|
649 |
-
#: core.php:
|
650 |
-
#: core.php:
|
651 |
-
#: core.php:
|
652 |
msgid "Not installed"
|
653 |
msgstr "Não instalado"
|
654 |
|
655 |
-
#: core.php:
|
656 |
msgid "CURL version"
|
657 |
msgstr "Versão CURL"
|
658 |
|
659 |
-
#: core.php:
|
660 |
msgid "Installed"
|
661 |
msgstr "Instalado"
|
662 |
|
663 |
-
#: core.php:
|
664 |
msgid "You must have either CURL or Snoopy installed for the plugin to work!"
|
665 |
msgstr "Instalação de CURL ou Snoopy necessário para que funcione o plugin!"
|
666 |
|
667 |
-
#: core.php:
|
668 |
msgid "On"
|
669 |
msgstr "Activado"
|
670 |
|
671 |
-
#: core.php:
|
672 |
msgid "Redirects may be detected as broken links when safe_mode is on."
|
673 |
msgstr "Os redirects podem ser detectados como links offline quando o safe_mode está habilitado."
|
674 |
|
675 |
-
#: core.php:
|
676 |
-
#: core.php:
|
677 |
msgid "Off"
|
678 |
msgstr "Desactivado"
|
679 |
|
680 |
-
#: core.php:
|
681 |
#, php-format
|
682 |
msgid "On ( %s )"
|
683 |
msgstr "Activado ( %s )"
|
684 |
|
685 |
-
#: core.php:
|
686 |
msgid "Redirects may be detected as broken links when open_basedir is on."
|
687 |
msgstr "Os redirects podem ser considerados links offline quando o open_basedir está activo."
|
688 |
|
689 |
-
#: core.php:
|
690 |
msgid "Can't create a lockfile. Please specify a custom temporary directory."
|
691 |
msgstr "Não foi possível criar um ficheiro. Por favor, especifique um directório temporário personalizado."
|
692 |
|
693 |
-
#: core.php:
|
|
|
|
|
|
|
|
|
694 |
#, php-format
|
695 |
msgid "[%s] Broken links detected"
|
696 |
msgstr "[%s] Links offline detectados"
|
697 |
|
698 |
-
#: core.php:
|
699 |
#, php-format
|
700 |
msgid "Broken Link Checker has detected %d new broken link on your site."
|
701 |
msgid_plural "Broken Link Checker has detected %d new broken links on your site."
|
702 |
msgstr[0] "Links offline detectou %d novo link sem ligação."
|
703 |
msgstr[1] "Links offline detectou %d novos links sem ligação."
|
704 |
|
705 |
-
#: core.php:
|
706 |
#, php-format
|
707 |
msgid "Here's a list of the first %d broken links:"
|
708 |
msgid_plural "Here's a list of the first %d broken links:"
|
709 |
msgstr[0] "Lista do primeiro %d link sem ligação:"
|
710 |
msgstr[1] "Lista dos primeiros %d links sem ligação:"
|
711 |
|
712 |
-
#: core.php:
|
713 |
msgid "Here's a list of the new broken links: "
|
714 |
msgstr "Novos links offline:"
|
715 |
|
716 |
-
#: core.php:
|
717 |
#, php-format
|
718 |
msgid "Link text : %s"
|
719 |
msgstr "Texto do Link : %s"
|
720 |
|
721 |
-
#: core.php:
|
722 |
#, php-format
|
723 |
msgid "Link URL : <a href=\"%s\">%s</a>"
|
724 |
msgstr "Link URL : <a href=\"%s\">%s</a>"
|
725 |
|
726 |
-
#: core.php:
|
727 |
#, php-format
|
728 |
msgid "Source : %s"
|
729 |
msgstr "Fonte : %s"
|
730 |
|
731 |
-
#: core.php:
|
732 |
msgid "You can see all broken links here:"
|
733 |
msgstr "Links offline:"
|
734 |
|
735 |
-
#: includes/
|
736 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
737 |
msgid "Wait..."
|
738 |
msgstr "Espere ..."
|
739 |
|
740 |
-
#: includes/admin/links-page-js.php:
|
741 |
msgid "Save URL"
|
742 |
msgstr "Guardar URL"
|
743 |
|
744 |
-
#: includes/admin/links-page-js.php:
|
745 |
msgid "Saving changes..."
|
746 |
msgstr "Guardando alterações ..."
|
747 |
|
748 |
-
#: includes/admin/links-page-js.php:
|
749 |
#, php-format
|
750 |
msgid "%d instances of the link were successfully modified."
|
751 |
msgstr "%d casos de links que se modificaram com sucesso."
|
752 |
|
753 |
-
#: includes/admin/links-page-js.php:
|
754 |
#, php-format
|
755 |
msgid "However, %d instances couldn't be edited and still point to the old URL."
|
756 |
msgstr "No entanto, %d casos não puderam ser editados e ainda apontam para a antiga URL."
|
757 |
|
758 |
-
#: includes/admin/links-page-js.php:
|
759 |
msgid "The link could not be modified."
|
760 |
msgstr "O link não pode ser modificado."
|
761 |
|
762 |
-
#: includes/admin/links-page-js.php:
|
763 |
-
#: includes/admin/links-page-js.php:
|
764 |
msgid "The following error(s) occured :"
|
765 |
msgstr "Erro(s) :"
|
766 |
|
767 |
-
#: includes/admin/links-page-js.php:
|
768 |
#, php-format
|
769 |
msgid "%d instances of the link were successfully unlinked."
|
770 |
msgstr "%d casos de links foram removidos com sucesso."
|
771 |
|
772 |
-
#: includes/admin/links-page-js.php:
|
773 |
#, php-format
|
774 |
msgid "However, %d instances couldn't be removed."
|
775 |
msgstr "No entanto, %d casos não foram removidos."
|
776 |
|
777 |
-
#: includes/admin/links-page-js.php:
|
778 |
msgid "The plugin failed to remove the link."
|
779 |
msgstr "O plugin não removeu o link."
|
780 |
|
781 |
-
#: includes/admin/links-page-js.php:
|
782 |
msgid "Enter a name for the new custom filter"
|
783 |
msgstr "Introduza o nome para o novo filtro personalizado"
|
784 |
|
785 |
-
#: includes/admin/links-page-js.php:
|
786 |
msgid ""
|
787 |
"You are about to delete the current filter.\n"
|
788 |
"'Cancel' to stop, 'OK' to delete"
|
@@ -790,7 +947,7 @@ msgstr ""
|
|
790 |
"Está a ponto de apagar o filtro actual.\n"
|
791 |
" 'Cancelar' para sair, 'Aceitar' para apagar."
|
792 |
|
793 |
-
#: includes/admin/links-page-js.php:
|
794 |
msgid ""
|
795 |
"Are you sure you want to delete all posts, bookmarks or other items that contain any of the selected links? This action can't be undone.\n"
|
796 |
"'Cancel' to stop, 'OK' to delete"
|
@@ -799,19 +956,6 @@ msgstr ""
|
|
799 |
"Esta acção não pode ser anulada.\n"
|
800 |
"'Cancelar' para anular a operação, 'Aceitar' para apagar"
|
801 |
|
802 |
-
#: includes/admin/search-form.php:13
|
803 |
-
msgid "Save This Search As a Filter"
|
804 |
-
msgstr "Criar Filtro desta Procura"
|
805 |
-
|
806 |
-
#: includes/admin/search-form.php:23
|
807 |
-
msgid "Delete This Filter"
|
808 |
-
msgstr "Apagar este Filtro"
|
809 |
-
|
810 |
-
#: includes/admin/search-form.php:29
|
811 |
-
#: includes/links.php:798
|
812 |
-
msgid "Search"
|
813 |
-
msgstr "Procurar"
|
814 |
-
|
815 |
#: includes/admin/search-form.php:39
|
816 |
msgid "Link text"
|
817 |
msgstr "Texto do link"
|
@@ -820,86 +964,64 @@ msgstr "Texto do link"
|
|
820 |
msgid "Link status"
|
821 |
msgstr "Estado do link"
|
822 |
|
823 |
-
#: includes/admin/search-form.php:
|
824 |
msgid "Link type"
|
825 |
msgstr "Tipo de link"
|
826 |
|
827 |
-
#: includes/admin/search-form.php:
|
828 |
msgid "Any"
|
829 |
msgstr "Qualquer"
|
830 |
|
831 |
-
#: includes/admin/search-form.php:
|
832 |
msgid "Normal link"
|
833 |
msgstr "Link normal"
|
834 |
|
835 |
-
#: includes/admin/search-form.php:
|
836 |
-
#: includes/parsers/image.php:142
|
837 |
msgid "Image"
|
838 |
msgstr "Imagem"
|
839 |
|
840 |
-
#: includes/admin/search-form.php:
|
841 |
-
#: includes/containers/custom_field.php:176
|
842 |
msgid "Custom field"
|
843 |
msgstr "Campo personalizado"
|
844 |
|
845 |
-
#: includes/admin/search-form.php:
|
846 |
#: includes/containers/blogroll.php:13
|
847 |
msgid "Bookmark"
|
848 |
msgstr "Favorito"
|
849 |
|
850 |
-
#: includes/admin/search-form.php:
|
851 |
-
#: includes/containers/comment.php:137
|
852 |
msgid "Comment"
|
853 |
msgstr "Comentário"
|
854 |
|
855 |
-
#: includes/
|
856 |
-
|
857 |
-
msgstr "Procurar"
|
858 |
-
|
859 |
-
#: includes/checkers/http.php:186
|
860 |
-
#: includes/checkers/http.php:253
|
861 |
#, php-format
|
862 |
msgid "HTTP code : %d"
|
863 |
msgstr "Código HTTP : %d"
|
864 |
|
865 |
-
#: includes/checkers/http.php:
|
866 |
-
#: includes/checkers/http.php:
|
867 |
msgid "(No response)"
|
868 |
msgstr "(Sem resposta)"
|
869 |
|
870 |
-
#: includes/checkers/http.php:
|
871 |
msgid "Most likely the connection timed out or the domain doesn't exist."
|
872 |
msgstr "Provável que o tempo da ligação se tenha esgotado ou que o domínio não exista."
|
873 |
|
874 |
-
#: includes/checkers/http.php:
|
875 |
msgid "Request timed out."
|
876 |
msgstr "Tempo de espera esgotado."
|
877 |
|
878 |
-
#: includes/checkers/http.php:
|
879 |
msgid "Using Snoopy"
|
880 |
msgstr "Utilizando Snoopy"
|
881 |
|
882 |
-
#: includes/containers.php:262
|
883 |
-
#, php-format
|
884 |
-
msgid "Container type '%s' not recognized"
|
885 |
-
msgstr "Recipiente tipo '%s' não foi reconhecido"
|
886 |
-
|
887 |
-
#: includes/containers.php:792
|
888 |
-
#, php-format
|
889 |
-
msgid "%d '%s' has been deleted"
|
890 |
-
msgid_plural "%d '%s' have been deleted"
|
891 |
-
msgstr[0] "%d '%s' foi apagado"
|
892 |
-
msgstr[1] "%d '%s' foram apagados"
|
893 |
-
|
894 |
#: includes/containers/blogroll.php:19
|
895 |
#: includes/containers/blogroll.php:38
|
896 |
msgid "Edit this bookmark"
|
897 |
msgstr "Editar este favorito"
|
898 |
|
899 |
#: includes/containers/blogroll.php:38
|
900 |
-
#: includes/containers/comment.php:107
|
901 |
-
#: includes/containers/custom_field.php:201
|
902 |
-
#: includes/containers/post.php:16
|
903 |
msgid "Edit"
|
904 |
msgstr "Editar"
|
905 |
|
@@ -913,14 +1035,10 @@ msgstr ""
|
|
913 |
" 'Cancelar' para sair, 'Aceitar' para apagar."
|
914 |
|
915 |
#: includes/containers/blogroll.php:39
|
916 |
-
#: includes/containers/custom_field.php:206
|
917 |
-
#: includes/containers/post.php:21
|
918 |
msgid "Delete"
|
919 |
msgstr "Apagar"
|
920 |
|
921 |
#: includes/containers/blogroll.php:75
|
922 |
-
#: includes/containers/comment.php:36
|
923 |
-
#: includes/containers/post.php:86
|
924 |
msgid "Nothing to update"
|
925 |
msgstr "Sem actualização"
|
926 |
|
@@ -938,8 +1056,8 @@ msgstr "Não foi possível eliminar o link blogroll \"%s\" (%d)"
|
|
938 |
#, php-format
|
939 |
msgid "%d blogroll link deleted"
|
940 |
msgid_plural "%d blogroll links deleted"
|
941 |
-
msgstr[0] "%d link blogroll
|
942 |
-
msgstr[1] "%d links blogroll
|
943 |
|
944 |
#: includes/containers/comment.php:46
|
945 |
#, php-format
|
@@ -951,24 +1069,10 @@ msgstr "Não foi possível actualizar o comentário %d"
|
|
951 |
msgid "Failed to delete comment %d"
|
952 |
msgstr "Erro ao apagar o comentário %d"
|
953 |
|
954 |
-
#: includes/containers/comment.php:107
|
955 |
-
#: includes/containers/comment.php:149
|
956 |
-
msgid "Edit comment"
|
957 |
-
msgstr "Editar comentário"
|
958 |
-
|
959 |
#: includes/containers/comment.php:114
|
960 |
msgid "Delete Permanently"
|
961 |
msgstr "Apagado definitivamente"
|
962 |
|
963 |
-
#: includes/containers/comment.php:116
|
964 |
-
msgid "Move this comment to the trash"
|
965 |
-
msgstr "Mover este comentário para o lixo"
|
966 |
-
|
967 |
-
#: includes/containers/comment.php:116
|
968 |
-
msgctxt "verb"
|
969 |
-
msgid "Trash"
|
970 |
-
msgstr "Lixo"
|
971 |
-
|
972 |
#: includes/containers/comment.php:120
|
973 |
msgid "View comment"
|
974 |
msgstr "Ver comentário"
|
@@ -979,14 +1083,14 @@ msgstr "Ver comentário"
|
|
979 |
msgid "View"
|
980 |
msgstr "Ver"
|
981 |
|
982 |
-
#: includes/containers/comment.php:
|
983 |
#, php-format
|
984 |
msgid "%d comment moved to the trash"
|
985 |
msgid_plural "%d comments moved to the trash"
|
986 |
msgstr[0] "%d comentário movido para o lixo"
|
987 |
msgstr[1] "%d comentários movidos para o lixo"
|
988 |
|
989 |
-
#: includes/containers/comment.php:
|
990 |
#, php-format
|
991 |
msgid "%d comment has been deleted"
|
992 |
msgid_plural "%d comments have been deleted"
|
@@ -1004,15 +1108,17 @@ msgid "Failed to delete the meta field '%s' on %s [%d]"
|
|
1004 |
msgstr "Erro ao apagar o campo meta '%s' em %s [%d]"
|
1005 |
|
1006 |
#: includes/containers/custom_field.php:191
|
1007 |
-
#: includes/containers/custom_field.php:201
|
1008 |
#: includes/containers/post.php:16
|
1009 |
#: includes/containers/post.php:41
|
1010 |
msgid "Edit this post"
|
1011 |
msgstr "Editar post"
|
1012 |
|
|
|
|
|
|
|
|
|
1013 |
#: includes/containers/custom_field.php:204
|
1014 |
-
|
1015 |
-
msgid "Move this post to the Trash"
|
1016 |
msgstr "Mover este post para o lixo"
|
1017 |
|
1018 |
#: includes/containers/custom_field.php:204
|
@@ -1041,22 +1147,22 @@ msgstr ""
|
|
1041 |
msgid "View \"%s\""
|
1042 |
msgstr "Ver \"%s\""
|
1043 |
|
1044 |
-
#: includes/containers/custom_field.php:
|
1045 |
-
#: includes/containers/post.php:
|
1046 |
#, php-format
|
1047 |
msgid "Failed to delete post \"%s\" (%d)"
|
1048 |
msgstr "Erro ao apagar o post \"%s\" (%d)"
|
1049 |
|
1050 |
-
#: includes/containers/custom_field.php:
|
1051 |
-
#: includes/containers/post.php:
|
1052 |
#, php-format
|
1053 |
msgid "%d post moved to the trash"
|
1054 |
msgid_plural "%d posts moved to the trash"
|
1055 |
msgstr[0] "%d post transferido para o lixo"
|
1056 |
msgstr[1] "%d posts transferidos para o lixo"
|
1057 |
|
1058 |
-
#: includes/containers/custom_field.php:
|
1059 |
-
#: includes/containers/post.php:
|
1060 |
#, php-format
|
1061 |
msgid "%d post deleted"
|
1062 |
msgid_plural "%d posts deleted"
|
@@ -1069,130 +1175,12 @@ msgstr[1] "%d posts apagados"
|
|
1069 |
msgid "I don't know how to edit a '%s' [%d]."
|
1070 |
msgstr "Não é possível editar '%s' [%d]."
|
1071 |
|
1072 |
-
#: includes/containers/post.php:
|
|
|
|
|
|
|
|
|
1073 |
#, php-format
|
1074 |
msgid "Updating post %d failed"
|
1075 |
msgstr "Actualização do post %d falhou"
|
1076 |
|
1077 |
-
#: includes/instances.php:102
|
1078 |
-
#: includes/instances.php:148
|
1079 |
-
#, php-format
|
1080 |
-
msgid "Container %s[%d] not found"
|
1081 |
-
msgstr "Recipiente %s[%d] não encontrado"
|
1082 |
-
|
1083 |
-
#: includes/instances.php:111
|
1084 |
-
#: includes/instances.php:157
|
1085 |
-
#, php-format
|
1086 |
-
msgid "Parser '%s' not found."
|
1087 |
-
msgstr "Analizador sintáctico '%s' não encontrado."
|
1088 |
-
|
1089 |
-
#: includes/links.php:157
|
1090 |
-
msgid "The plugin script was terminated while trying to check the link."
|
1091 |
-
msgstr "O script do plugin terminou enquanto tentava verificar o link."
|
1092 |
-
|
1093 |
-
#: includes/links.php:201
|
1094 |
-
msgid "The plugin doesn't know how to check this type of link."
|
1095 |
-
msgstr "O plugin não consegue verificar este tipo de link."
|
1096 |
-
|
1097 |
-
#: includes/links.php:289
|
1098 |
-
msgid "Link is valid."
|
1099 |
-
msgstr "Link operacional."
|
1100 |
-
|
1101 |
-
#: includes/links.php:291
|
1102 |
-
msgid "Link is broken."
|
1103 |
-
msgstr "Link sem ligação."
|
1104 |
-
|
1105 |
-
#: includes/links.php:484
|
1106 |
-
#: includes/links.php:586
|
1107 |
-
#: includes/links.php:621
|
1108 |
-
msgid "Link is not valid"
|
1109 |
-
msgstr "Link não válido"
|
1110 |
-
|
1111 |
-
#: includes/links.php:501
|
1112 |
-
msgid "This link can not be edited because it is not used anywhere on this site."
|
1113 |
-
msgstr "Este link não pode ser editado porque não é utilizado em nenhuma parte da página."
|
1114 |
-
|
1115 |
-
#: includes/links.php:527
|
1116 |
-
msgid "Failed to create a DB entry for the new URL."
|
1117 |
-
msgstr "Falhou a criação de um registro na Base de dados para um novo URL."
|
1118 |
-
|
1119 |
-
#: includes/links.php:599
|
1120 |
-
msgid "This link is not a redirect"
|
1121 |
-
msgstr "O link não é um redirect"
|
1122 |
-
|
1123 |
-
#: includes/links.php:648
|
1124 |
-
#: includes/links.php:685
|
1125 |
-
msgid "Couldn't delete the link's database record"
|
1126 |
-
msgstr "Não é possível apagar o registro do link na Base de dados"
|
1127 |
-
|
1128 |
-
#: includes/links.php:770
|
1129 |
-
msgid "Broken"
|
1130 |
-
msgstr "Offline"
|
1131 |
-
|
1132 |
-
#: includes/links.php:772
|
1133 |
-
msgid "No broken links found"
|
1134 |
-
msgstr "Links offline (0)"
|
1135 |
-
|
1136 |
-
#: includes/links.php:779
|
1137 |
-
msgid "Redirects"
|
1138 |
-
msgstr "Redirects"
|
1139 |
-
|
1140 |
-
#: includes/links.php:780
|
1141 |
-
msgid "Redirected Links"
|
1142 |
-
msgstr "Links Redirects"
|
1143 |
-
|
1144 |
-
#: includes/links.php:781
|
1145 |
-
msgid "No redirects found"
|
1146 |
-
msgstr "Redirects (0)"
|
1147 |
-
|
1148 |
-
#: includes/links.php:789
|
1149 |
-
msgid "All"
|
1150 |
-
msgstr "Todos"
|
1151 |
-
|
1152 |
-
#: includes/links.php:790
|
1153 |
-
msgid "Detected Links"
|
1154 |
-
msgstr "Links encontrados"
|
1155 |
-
|
1156 |
-
#: includes/links.php:791
|
1157 |
-
msgid "No links found (yet)"
|
1158 |
-
msgstr "Links (0)"
|
1159 |
-
|
1160 |
-
#: includes/links.php:799
|
1161 |
-
msgid "Search Results"
|
1162 |
-
msgstr "Resultados da procura"
|
1163 |
-
|
1164 |
-
#: includes/links.php:800
|
1165 |
-
#: includes/links.php:843
|
1166 |
-
msgid "No links found for your query"
|
1167 |
-
msgstr "Sem resultados"
|
1168 |
-
|
1169 |
-
#: includes/parsers.php:151
|
1170 |
-
#, php-format
|
1171 |
-
msgid "Editing is not implemented in the '%s' parser"
|
1172 |
-
msgstr "Edição não implementada no '%s' analizador sintáctico"
|
1173 |
-
|
1174 |
-
#: includes/parsers.php:166
|
1175 |
-
#, php-format
|
1176 |
-
msgid "Unlinking is not implemented in the '%s' parser"
|
1177 |
-
msgstr "Remover links não foi implementado no '%s' analizador sintáctico"
|
1178 |
-
|
1179 |
-
#. Plugin Name of the plugin/theme
|
1180 |
-
msgid "Broken Link Checker"
|
1181 |
-
msgstr "Links offline"
|
1182 |
-
|
1183 |
-
#. Plugin URI of the plugin/theme
|
1184 |
-
msgid "http://w-shadow.com/blog/2007/08/05/broken-link-checker-for-wordpress/"
|
1185 |
-
msgstr "http://w-shadow.com/blog/2007/08/05/broken-link-checker-for-wordpress/"
|
1186 |
-
|
1187 |
-
#. Description of the plugin/theme
|
1188 |
-
msgid "Checks your blog for broken links and missing images and notifies you on the dashboard if any are found."
|
1189 |
-
msgstr "Verifica o blog procurando os links e imagens em falta, informa no Painel do WordPress os resultados da verificação."
|
1190 |
-
|
1191 |
-
#. Author of the plugin/theme
|
1192 |
-
msgid "Janis Elsts"
|
1193 |
-
msgstr "Janis Elsts"
|
1194 |
-
|
1195 |
-
#. Author URI of the plugin/theme
|
1196 |
-
msgid "http://w-shadow.com/blog/"
|
1197 |
-
msgstr "http://w-shadow.com/blog/"
|
1198 |
-
|
1 |
+
# Translation of the WordPress plugin Broken Link Checker 0.9.4.2 by Janis Elsts.
|
2 |
# Copyright (C) 2010 Janis Elsts
|
3 |
# This file is distributed under the same license as the Broken Link Checker package.
|
4 |
+
# Tradução em português pt_PT do plugin Broken Link Checker - v.1.1 - 30/06/2010
|
5 |
+
# Autor: PedroDM - <pm[at]mowster[dot]net>
|
6 |
# Website: http://jobs.mowster.net/ - <jobs@mowster.net>
|
7 |
#
|
8 |
msgid ""
|
9 |
msgstr ""
|
10 |
"Project-Id-Version: Broken Link Checker PT\n"
|
11 |
+
"Report-Msgid-Bugs-To: \n"
|
12 |
+
"POT-Creation-Date: 2010-07-11 13:18-0000\n"
|
13 |
"PO-Revision-Date: \n"
|
14 |
"Last-Translator: \n"
|
15 |
+
"Language-Team: MwJobs | http://jobs.mowster.net <jobs@mowster.net>\n"
|
16 |
"MIME-Version: 1.0\n"
|
17 |
"Content-Type: text/plain; charset=UTF-8\n"
|
18 |
"Content-Transfer-Encoding: 8bit\n"
|
24 |
"X-Poedit-Basepath: ..\n"
|
25 |
"X-Poedit-SearchPath-0: .\n"
|
26 |
|
27 |
+
#: broken-link-checker.php:316
|
28 |
msgid "Once Weekly"
|
29 |
msgstr "Uma vez por semana"
|
30 |
|
31 |
+
#: broken-link-checker.php:322
|
32 |
+
msgid "Twice a Month"
|
33 |
+
msgstr "Bi-Mensal"
|
34 |
+
|
35 |
+
#: broken-link-checker.php:345
|
36 |
+
msgid "Broken Link Checker installation failed"
|
37 |
+
msgstr "Opções : Links offline"
|
38 |
+
|
39 |
+
#: core.php:139
|
40 |
+
#: includes/admin/links-page-js.php:35
|
41 |
msgid "Loading..."
|
42 |
msgstr "Carregando..."
|
43 |
|
44 |
+
#: core.php:162
|
45 |
+
#: core.php:943
|
46 |
msgid "[ Network error ]"
|
47 |
msgstr "[ Problema na rede ]"
|
48 |
|
49 |
+
#: core.php:187
|
50 |
msgid "Automatically expand the widget if broken links have been detected"
|
51 |
msgstr "Expandir automaticamente a caixa se existirem links offline"
|
52 |
|
53 |
+
#: core.php:424
|
54 |
#, php-format
|
55 |
msgid "Failed to delete old DB tables. Database error : %s"
|
56 |
msgstr "Não foi possível apagar as tabelas antigas da Base de dados. Erro de Base de dados : %s"
|
57 |
|
58 |
+
#: core.php:447
|
59 |
#, php-format
|
60 |
msgid "Unexpected error: The plugin doesn't know how to upgrade its database to version '%d'."
|
61 |
msgstr "Erro inesperado: O plugin não consegue actualizar a Base de dados para a versão '%d'."
|
62 |
|
63 |
+
#: core.php:499
|
64 |
+
#: core.php:536
|
65 |
+
#: core.php:586
|
66 |
+
#: core.php:618
|
67 |
#, php-format
|
68 |
msgid "Failed to create table '%s'. Database error: %s"
|
69 |
msgstr "Não foi possível criar a tabela '%s'. Erro na Base de dados: %s"
|
70 |
|
71 |
+
#: core.php:678
|
72 |
msgid "Link Checker Settings"
|
73 |
msgstr "Definições do Links offline"
|
74 |
|
75 |
+
#: core.php:679
|
76 |
msgid "Link Checker"
|
77 |
msgstr "Links offline"
|
78 |
|
79 |
+
#: core.php:684
|
80 |
+
#: includes/links.php:773
|
|
|
|
|
|
|
|
|
81 |
msgid "Broken Links"
|
82 |
msgstr "Links offline"
|
83 |
|
84 |
+
#: core.php:700
|
85 |
+
msgid "View Broken Links"
|
86 |
+
msgstr "Ver Links offline"
|
87 |
+
|
88 |
+
#: core.php:726
|
89 |
#, php-format
|
90 |
msgid "Highlight links broken for at least %s days"
|
91 |
msgstr "Sublinhar links offline pelo menos por %s dias"
|
92 |
|
93 |
+
#: core.php:752
|
94 |
msgid "Settings"
|
95 |
msgstr "Definições"
|
96 |
|
97 |
+
#: core.php:762
|
98 |
+
#: core.php:1300
|
99 |
#, php-format
|
100 |
msgid "Error: The plugin's database tables are not up to date! (Current version : %d, expected : %d)"
|
101 |
msgstr "Erro: As tabelas do plugin na Base de dados não estão actualizadas! (Versão actual : %d, obrigatória : %d)"
|
102 |
|
103 |
+
#: core.php:899
|
104 |
msgid "Settings saved."
|
105 |
msgstr "Definições guardadas."
|
106 |
|
107 |
+
#: core.php:908
|
108 |
msgid "Broken Link Checker Options"
|
109 |
msgstr "Opções : Links offline"
|
110 |
|
111 |
+
#: core.php:921
|
112 |
msgid "Status"
|
113 |
msgstr "Estado"
|
114 |
|
115 |
+
#: core.php:923
|
116 |
+
#: core.php:1278
|
117 |
msgid "Show debug info"
|
118 |
msgstr "Mostrar sistema"
|
119 |
|
120 |
+
#: core.php:956
|
121 |
msgid "Re-check all pages"
|
122 |
msgstr "Verificar de novo todas as páginas"
|
123 |
|
124 |
+
#: core.php:980
|
125 |
msgid "Check each link"
|
126 |
msgstr "Verificar cada link"
|
127 |
|
128 |
+
#: core.php:985
|
129 |
#, php-format
|
130 |
msgid "Every %s hours"
|
131 |
msgstr "Cada %s horas"
|
132 |
|
133 |
+
#: core.php:994
|
134 |
msgid "Existing links will be checked this often. New links will usually be checked ASAP."
|
135 |
msgstr "Os links existentes serão verificados com esta frequência. Os novos links comprovados logo que possível."
|
136 |
|
137 |
+
#: core.php:1001
|
138 |
msgid "Broken link CSS"
|
139 |
msgstr "Link CSS offline"
|
140 |
|
141 |
+
#: core.php:1006
|
142 |
msgid "Apply <em>class=\"broken_link\"</em> to broken links"
|
143 |
msgstr "Aplicar <em>class=\"broken_link\"</em> aos links offline"
|
144 |
|
145 |
+
#: core.php:1018
|
146 |
msgid "Removed link CSS"
|
147 |
msgstr "Link CSS removido"
|
148 |
|
149 |
+
#: core.php:1023
|
150 |
msgid "Apply <em>class=\"removed_link\"</em> to unlinked links"
|
151 |
msgstr "Aplicar <em>class=\"removed_link\"</em> aos links sem ligação"
|
152 |
|
153 |
+
#: core.php:1035
|
154 |
msgid "Broken link SEO"
|
155 |
msgstr "Link SEO offline"
|
156 |
|
157 |
+
#: core.php:1040
|
158 |
msgid "Apply <em>rel=\"nofollow\"</em> to broken links"
|
159 |
msgstr "Aplicar <em>rel=\"nofollow\"</em> aos links offline"
|
160 |
|
161 |
+
#: core.php:1046
|
162 |
msgid "Exclusion list"
|
163 |
msgstr "Lista de exclusão"
|
164 |
|
165 |
+
#: core.php:1047
|
166 |
msgid "Don't check links where the URL contains any of these words (one per line) :"
|
167 |
msgstr "Não verificar links que a URL tenha alguma destas palavras (uma por linha):"
|
168 |
|
169 |
+
#: core.php:1057
|
170 |
msgid "Custom fields"
|
171 |
msgstr "Campos personalizados"
|
172 |
|
173 |
+
#: core.php:1058
|
174 |
msgid "Check URLs entered in these custom fields (one per line) :"
|
175 |
msgstr "Verificar as seguintes URL personalizadas (uma por linha):"
|
176 |
|
177 |
+
#: core.php:1068
|
178 |
+
msgid "Comment links"
|
179 |
+
msgstr "Comentário"
|
180 |
+
|
181 |
+
#: core.php:1074
|
182 |
+
msgid "Check comment links"
|
183 |
+
msgstr "Verificar link comentário"
|
184 |
+
|
185 |
+
#: core.php:1081
|
186 |
msgid "E-mail notifications"
|
187 |
msgstr "Notificações por e-mail"
|
188 |
|
189 |
+
#: core.php:1087
|
190 |
msgid "Send me e-mail notifications about newly detected broken links"
|
191 |
msgstr "Enviar um e-mail notificando sobre os novos links offline detectados"
|
192 |
|
193 |
+
#: core.php:1095
|
194 |
msgid "Advanced"
|
195 |
msgstr "Avançado"
|
196 |
|
197 |
+
#: core.php:1100
|
198 |
msgid "Timeout"
|
199 |
msgstr "Intervalo"
|
200 |
|
201 |
+
#: core.php:1106
|
202 |
+
#: core.php:1150
|
203 |
+
#: core.php:3216
|
204 |
#, php-format
|
205 |
msgid "%s seconds"
|
206 |
msgstr "%s segundos"
|
207 |
|
208 |
+
#: core.php:1115
|
209 |
msgid "Links that take longer than this to load will be marked as broken."
|
210 |
msgstr "Os links que demoram mais que este tempo a abrir serão marcados como offline."
|
211 |
|
212 |
+
#: core.php:1122
|
213 |
msgid "Link monitor"
|
214 |
msgstr "Monitor de links"
|
215 |
|
216 |
+
#: core.php:1128
|
217 |
msgid "Run continuously while the Dashboard is open"
|
218 |
msgstr "Executar continuamente enquanto o Painel do WordPress está aberto"
|
219 |
|
220 |
+
#: core.php:1136
|
221 |
msgid "Run hourly in the background"
|
222 |
msgstr "Executar a cada hora em segundo plano"
|
223 |
|
224 |
+
#: core.php:1144
|
225 |
msgid "Max. execution time"
|
226 |
msgstr "Tempo máximo de execução"
|
227 |
|
228 |
+
#: core.php:1161
|
229 |
msgid "The plugin works by periodically launching a background job that parses your posts for links, checks the discovered URLs, and performs other time-consuming tasks. Here you can set for how long, at most, the link monitor may run each time before stopping."
|
230 |
msgstr "O plugin funciona executando periodicamente uma tarefa em segundo plano que analiza os links, verifica os URL encontrados e realiza outras tarefas que consomem tempo. Aqui pode-se estabelecer a duração máxima cada vez que o monitor de links é executado antes de parar."
|
231 |
|
232 |
+
#: core.php:1171
|
233 |
msgid "Custom temporary directory"
|
234 |
msgstr "Pasta temporária personalizada"
|
235 |
|
236 |
+
#: core.php:1180
|
237 |
msgid "OK"
|
238 |
msgstr "Aceitar"
|
239 |
|
240 |
+
#: core.php:1183
|
241 |
msgid "Error : This directory isn't writable by PHP."
|
242 |
msgstr "Erro: PHP não pode escrever nesse directório."
|
243 |
|
244 |
+
#: core.php:1188
|
245 |
msgid "Error : This directory doesn't exist."
|
246 |
msgstr "Erro: Não existe esse directório."
|
247 |
|
248 |
+
#: core.php:1196
|
249 |
msgid "Set this field if you want the plugin to use a custom directory for its lockfiles. Otherwise, leave it blank."
|
250 |
msgstr "Preencha este campo se deseja que o plugin utilize um directório personalizado para seus ficheiros temporários. Caso contrário, deixa-lo em branco."
|
251 |
|
252 |
+
#: core.php:1203
|
253 |
msgid "Server load limit"
|
254 |
msgstr "Limite de carregamento do servidor"
|
255 |
|
256 |
+
#: core.php:1244
|
257 |
#, php-format
|
258 |
msgid "Link checking will be suspended if the average <a href=\"%s\">server load</a> rises above this number. Leave this field blank to disable load limiting."
|
259 |
msgstr "A verificação dos links será suspensa se a média do <a href=\"%s\">carregamento do servidor</a> passa este valor. Deixar o campo em branco para não existir limite."
|
260 |
|
261 |
+
#: core.php:1254
|
262 |
msgid "Load limiting only works on Linux-like systems where <code>/proc/loadavg</code> is present and accessible."
|
263 |
msgstr "O limite de carregamento somente funciona em sistemas Linux onde <code>/proc/loadavg</code> está presente e acessível."
|
264 |
|
265 |
+
#: core.php:1263
|
266 |
msgid "Save Changes"
|
267 |
msgstr "Guardar alterações"
|
268 |
|
269 |
+
#: core.php:1276
|
270 |
msgid "Hide debug info"
|
271 |
msgstr "Ocultar informação"
|
272 |
|
273 |
+
#: core.php:1393
|
274 |
+
#: core.php:1730
|
275 |
+
#: core.php:1762
|
276 |
#, php-format
|
277 |
msgid "Database error : %s"
|
278 |
msgstr "Erro na Base de dados: %s"
|
279 |
|
280 |
+
#: core.php:1471
|
281 |
msgid "Bulk Actions"
|
282 |
msgstr "Edição em Massa"
|
283 |
|
284 |
+
#: core.php:1472
|
285 |
msgid "Recheck"
|
286 |
msgstr "Voltar a verificar"
|
287 |
|
288 |
+
#: core.php:1473
|
289 |
msgid "Fix redirects"
|
290 |
msgstr "Reparar redirects"
|
291 |
|
292 |
+
#: core.php:1474
|
293 |
+
msgid "Mark as not broken"
|
294 |
+
msgstr "Funcional"
|
295 |
+
|
296 |
+
#: core.php:1475
|
297 |
+
#: core.php:1629
|
298 |
+
#: includes/admin/links-page-js.php:307
|
299 |
msgid "Unlink"
|
300 |
msgstr "Remover link"
|
301 |
|
302 |
+
#: core.php:1476
|
303 |
msgid "Delete sources"
|
304 |
msgstr "Apagar fontes"
|
305 |
|
306 |
+
#: core.php:1490
|
307 |
+
#: core.php:1664
|
308 |
msgid "Apply"
|
309 |
msgstr "Aplicar"
|
310 |
|
311 |
+
#: core.php:1497
|
312 |
msgid "«"
|
313 |
msgstr "«"
|
314 |
|
315 |
+
#: core.php:1498
|
316 |
msgid "»"
|
317 |
msgstr "»"
|
318 |
|
319 |
+
#: core.php:1505
|
320 |
+
#: core.php:1670
|
321 |
#, php-format
|
322 |
msgid "Displaying %s–%s of <span class=\"current-link-count\">%s</span>"
|
323 |
msgstr "Mostrando %s–%s de <span class=\"current-link-count\">%s</span>"
|
324 |
|
325 |
+
#: core.php:1524
|
326 |
msgid "Source"
|
327 |
msgstr "Fonte"
|
328 |
|
329 |
+
#: core.php:1525
|
330 |
msgid "Link Text"
|
331 |
msgstr "Texto do Link"
|
332 |
|
333 |
+
#: core.php:1526
|
334 |
#: includes/admin/search-form.php:42
|
335 |
msgid "URL"
|
336 |
msgstr "URL"
|
337 |
|
338 |
+
#: core.php:1602
|
339 |
msgid "[An orphaned link! This is a bug.]"
|
340 |
msgstr "[Um link orfão! Bug.]"
|
341 |
|
342 |
+
#: core.php:1626
|
343 |
msgid "Show more info about this link"
|
344 |
msgstr "Mostrar mais informação sobre este link"
|
345 |
|
346 |
+
#: core.php:1626
|
347 |
+
#: core.php:3089
|
348 |
msgid "Details"
|
349 |
msgstr "Detalhes"
|
350 |
|
351 |
+
#: core.php:1628
|
352 |
msgid "Remove this link from all posts"
|
353 |
msgstr "Eliminar este link"
|
354 |
|
355 |
+
#: core.php:1634
|
356 |
msgid "Remove this link from the list of broken links and mark it as valid"
|
357 |
msgstr "Eliminar este link da lista dos links offline e marca-lo como válido"
|
358 |
|
359 |
+
#: core.php:1635
|
360 |
+
#: includes/admin/links-page-js.php:92
|
361 |
msgid "Not broken"
|
362 |
msgstr "Funcional"
|
363 |
|
364 |
+
#: core.php:1639
|
365 |
msgid "Edit link URL"
|
366 |
msgstr "Editar URL do link"
|
367 |
|
368 |
+
#: core.php:1639
|
369 |
+
#: includes/admin/links-page-js.php:213
|
370 |
+
#: includes/admin/links-page-js.php:241
|
371 |
msgid "Edit URL"
|
372 |
msgstr "Editar URL"
|
373 |
|
374 |
+
#: core.php:1645
|
375 |
msgid "Cancel URL editing"
|
376 |
msgstr "Cancelar a edição do URL"
|
377 |
|
378 |
+
#: core.php:1645
|
|
|
379 |
msgid "Cancel"
|
380 |
msgstr "Cancelar"
|
381 |
|
382 |
+
#: core.php:1712
|
383 |
msgid "You must enter a filter name!"
|
384 |
msgstr "Deve introduzir um nome para o filtro!"
|
385 |
|
386 |
+
#: core.php:1716
|
387 |
msgid "Invalid search query."
|
388 |
msgstr "Procura inválida."
|
389 |
|
390 |
+
#: core.php:1725
|
391 |
#, php-format
|
392 |
msgid "Filter \"%s\" created"
|
393 |
msgstr "Filtro \"%s\" criado"
|
394 |
|
395 |
+
#: core.php:1752
|
396 |
msgid "Filter ID not specified."
|
397 |
msgstr "ID do Filtro não especificado."
|
398 |
|
399 |
+
#: core.php:1759
|
400 |
msgid "Filter deleted"
|
401 |
msgstr "Filtro eliminado"
|
402 |
|
403 |
+
#: core.php:1807
|
404 |
#, php-format
|
405 |
msgid "Replaced %d redirect with a direct link"
|
406 |
+
msgstr "Substituídos %d redirect com um link directo"
|
|
|
|
|
407 |
|
408 |
+
#: core.php:1818
|
409 |
#, php-format
|
410 |
msgid "Failed to fix %d redirect"
|
411 |
msgid_plural "Failed to fix %d redirects"
|
412 |
msgstr[0] "Não foi possível reparar %d redirect"
|
413 |
msgstr[1] "Não foi possível reparar %d redirects"
|
414 |
|
415 |
+
#: core.php:1828
|
416 |
msgid "None of the selected links are redirects!"
|
417 |
msgstr "Nenhum dos links seleccionados são redirects!"
|
418 |
|
419 |
+
#: core.php:1874
|
420 |
#, php-format
|
421 |
msgid "%d link removed"
|
422 |
msgid_plural "%d links removed"
|
423 |
msgstr[0] "%d link eliminado"
|
424 |
msgstr[1] "%d links eliminados"
|
425 |
|
426 |
+
#: core.php:1885
|
427 |
#, php-format
|
428 |
msgid "Failed to remove %d link"
|
429 |
msgid_plural "Failed to remove %d links"
|
430 |
msgstr[0] "Erro a remover %d link"
|
431 |
msgstr[1] "Erro a remover %d links"
|
432 |
|
433 |
+
#: core.php:1973
|
434 |
msgid "Didn't find anything to delete!"
|
435 |
msgstr "Não foi encontrado nada para apagar!"
|
436 |
|
437 |
+
#: core.php:2001
|
438 |
#, php-format
|
439 |
msgid "%d link scheduled for rechecking"
|
440 |
msgid_plural "%d links scheduled for rechecking"
|
441 |
msgstr[0] "%d link agendado para verificação"
|
442 |
msgstr[1] "%d links agendados para verificação"
|
443 |
|
444 |
+
#: core.php:2046
|
445 |
+
#: core.php:2723
|
446 |
+
msgid "This link was manually marked as working by the user."
|
447 |
+
msgstr "Este link foi marcado manualmente como válido por outro utilizador."
|
448 |
+
|
449 |
+
#: core.php:2053
|
450 |
+
#, php-format
|
451 |
+
msgid "Couldn't modify link %d"
|
452 |
+
msgstr "Oops, impossível modificar o link %d"
|
453 |
+
|
454 |
+
#: core.php:2064
|
455 |
+
#, php-format
|
456 |
+
msgid "%d link marked as not broken"
|
457 |
+
msgid_plural "%d links marked as not broken"
|
458 |
+
msgstr[0] "%d link marcado como funcional"
|
459 |
+
msgstr[1] "%d links marcados como funcionais"
|
460 |
+
|
461 |
+
#: core.php:2088
|
462 |
msgid "Post published on"
|
463 |
msgstr "Post publicado em"
|
464 |
|
465 |
+
#: core.php:2093
|
466 |
msgid "Link last checked"
|
467 |
msgstr "Última verificação"
|
468 |
|
469 |
+
#: core.php:2097
|
470 |
msgid "Never"
|
471 |
msgstr "Nunca"
|
472 |
|
473 |
+
#: core.php:2103
|
474 |
#: includes/admin/search-form.php:45
|
475 |
msgid "HTTP code"
|
476 |
msgstr "Código HTTP"
|
477 |
|
478 |
+
#: core.php:2108
|
479 |
msgid "Response time"
|
480 |
msgstr "Tempo de resposta"
|
481 |
|
482 |
+
#: core.php:2110
|
483 |
#, php-format
|
484 |
msgid "%2.3f seconds"
|
485 |
msgstr "%2.3f segundos"
|
486 |
|
487 |
+
#: core.php:2113
|
488 |
msgid "Final URL"
|
489 |
msgstr "URL final"
|
490 |
|
491 |
+
#: core.php:2118
|
492 |
msgid "Redirect count"
|
493 |
msgstr "Contagem de redirects"
|
494 |
|
495 |
+
#: core.php:2123
|
496 |
msgid "Instance count"
|
497 |
msgstr "Contagem de casos"
|
498 |
|
499 |
+
#: core.php:2132
|
500 |
#, php-format
|
501 |
msgid "This link has failed %d time."
|
502 |
msgid_plural "This link has failed %d times."
|
503 |
msgstr[0] "Este link falhou %d vez."
|
504 |
msgstr[1] "Este link falhou %d vezes."
|
505 |
|
506 |
+
#: core.php:2140
|
507 |
#, php-format
|
508 |
msgid "This link has been broken for %s."
|
509 |
msgstr "Link offline durante %s."
|
510 |
|
511 |
+
#: core.php:2151
|
512 |
msgid "Log"
|
513 |
msgstr "Registro"
|
514 |
|
515 |
+
#: core.php:2177
|
516 |
msgid "less than a minute"
|
517 |
msgstr "menos de um minuto"
|
518 |
|
519 |
+
#: core.php:2185
|
520 |
#, php-format
|
521 |
msgid "%d minute"
|
522 |
msgid_plural "%d minutes"
|
523 |
msgstr[0] "%d minuto"
|
524 |
msgstr[1] "%d minutos"
|
525 |
|
526 |
+
#: core.php:2199
|
527 |
+
#: core.php:2226
|
528 |
#, php-format
|
529 |
msgid "%d hour"
|
530 |
msgid_plural "%d hours"
|
531 |
msgstr[0] "%d hora"
|
532 |
msgstr[1] "%d horas"
|
533 |
|
534 |
+
#: core.php:2214
|
535 |
+
#: core.php:2255
|
536 |
#, php-format
|
537 |
msgid "%d day"
|
538 |
msgid_plural "%d days"
|
539 |
msgstr[0] "%d dia"
|
540 |
msgstr[1] "%d dias"
|
541 |
|
542 |
+
#: core.php:2244
|
543 |
#, php-format
|
544 |
msgid "%d month"
|
545 |
msgid_plural "%d months"
|
546 |
msgstr[0] "%d mês"
|
547 |
msgstr[1] "%d meses"
|
548 |
|
549 |
+
#: core.php:2589
|
550 |
msgid "View broken links"
|
551 |
msgstr "Ver links offline"
|
552 |
|
553 |
+
#: core.php:2590
|
554 |
#, php-format
|
555 |
msgid "Found %d broken link"
|
556 |
msgid_plural "Found %d broken links"
|
557 |
msgstr[0] "Encontrado %d Link offline"
|
558 |
msgstr[1] "Encontrados %d Links offline"
|
559 |
|
560 |
+
#: core.php:2596
|
561 |
msgid "No broken links found."
|
562 |
msgstr "Não existem links offline."
|
563 |
|
564 |
+
#: core.php:2603
|
565 |
#, php-format
|
566 |
msgid "%d URL in the work queue"
|
567 |
msgid_plural "%d URLs in the work queue"
|
568 |
msgstr[0] "%d URL em espera"
|
569 |
msgstr[1] "%d URLs em espera"
|
570 |
|
571 |
+
#: core.php:2606
|
572 |
msgid "No URLs in the work queue."
|
573 |
msgstr "Não existem URL em espera para verificação."
|
574 |
|
575 |
+
#: core.php:2612
|
576 |
#, php-format
|
577 |
msgid "Detected %d unique URL"
|
578 |
msgid_plural "Detected %d unique URLs"
|
579 |
msgstr[0] "Detectada %d URL única"
|
580 |
msgstr[1] "Detectadas %d URL únicas"
|
581 |
|
582 |
+
#: core.php:2613
|
583 |
#, php-format
|
584 |
msgid "in %d link"
|
585 |
msgid_plural "in %d links"
|
586 |
msgstr[0] "em %d link"
|
587 |
msgstr[1] "em %d links"
|
588 |
|
589 |
+
#: core.php:2618
|
590 |
msgid "and still searching..."
|
591 |
msgstr "procurando..."
|
592 |
|
593 |
+
#: core.php:2624
|
594 |
msgid "Searching your blog for links..."
|
595 |
msgstr "Procurando links..."
|
596 |
|
597 |
+
#: core.php:2626
|
598 |
msgid "No links detected."
|
599 |
msgstr "Não se encontraram links."
|
600 |
|
601 |
+
#: core.php:2708
|
602 |
+
#: core.php:2744
|
603 |
+
#: core.php:2807
|
604 |
+
#: core.php:2889
|
605 |
msgid "You're not allowed to do that!"
|
606 |
msgstr "Não permitido!"
|
607 |
|
608 |
+
#: core.php:2716
|
609 |
+
#: core.php:2754
|
610 |
+
#: core.php:2817
|
611 |
#, php-format
|
612 |
msgid "Oops, I can't find the link %d"
|
613 |
msgstr "Oops, não é possível encontrar o link %d"
|
614 |
|
615 |
+
#: core.php:2729
|
|
|
|
|
|
|
|
|
616 |
msgid "Oops, couldn't modify the link!"
|
617 |
msgstr "Oops, não é possível modificar o link!"
|
618 |
|
619 |
+
#: core.php:2732
|
620 |
+
#: core.php:2843
|
621 |
msgid "Error : link_id not specified"
|
622 |
msgstr "Erro: link_id não especificado"
|
623 |
|
624 |
+
#: core.php:2764
|
625 |
msgid "Oops, the new URL is invalid!"
|
626 |
msgstr "Oops, a nova URL não é válida"
|
627 |
|
628 |
+
#: core.php:2775
|
629 |
+
#: core.php:2826
|
630 |
msgid "An unexpected error occured!"
|
631 |
msgstr "Ocorreu um erro inesperado!"
|
632 |
|
633 |
+
#: core.php:2793
|
634 |
msgid "Error : link_id or new_url not specified"
|
635 |
msgstr "Erro: link_id ou new_url não especificado"
|
636 |
|
637 |
+
#: core.php:2852
|
638 |
msgid "You don't have sufficient privileges to access this information!"
|
639 |
msgstr "Não tem previlégios suficientes para aceder a esta informação!"
|
640 |
|
641 |
+
#: core.php:2865
|
642 |
msgid "Error : link ID not specified"
|
643 |
msgstr "Erro: link ID não especificado"
|
644 |
|
645 |
+
#: core.php:2876
|
646 |
#, php-format
|
647 |
msgid "Failed to load link details (%s)"
|
648 |
msgstr "Erro a carregar os detalhes do link (%s)"
|
649 |
|
650 |
+
#: core.php:3061
|
651 |
+
msgid "Broken Link Checker"
|
652 |
+
msgstr "Links offline"
|
653 |
+
|
654 |
+
#: core.php:3075
|
655 |
#, php-format
|
656 |
msgid "The current temporary directory is not accessible; please <a href=\"%s\">set a different one</a>."
|
657 |
msgstr "O directório temporário não está acessível; por favor, <a href=\"%s\">especifique um diferente</a>."
|
658 |
|
659 |
+
#: core.php:3080
|
660 |
#, php-format
|
661 |
msgid "Please make the directory <code>%1$s</code> writable by plugins or <a href=\"%2$s\">set a custom temporary directory</a>."
|
662 |
msgstr "Por favor, deve permitir que os plugins possam gravar dados no directório <code>%1$s</code> ou <a href=\"%2$s\">especificar um directório temporário personalizado</a>."
|
663 |
|
664 |
+
#: core.php:3087
|
665 |
msgid "Broken Link Checker can't create a lockfile."
|
666 |
msgstr "Links offline não pode criar um ficheiro temporário."
|
667 |
|
668 |
+
#: core.php:3092
|
669 |
msgid "The plugin uses a file-based locking mechanism to ensure that only one instance of the resource-heavy link checking algorithm is running at any given time. Unfortunately, BLC can't find a writable directory where it could store the lockfile - it failed to detect the location of your server's temporary directory, and the plugin's own directory isn't writable by PHP. To fix this problem, please make the plugin's directory writable or enter a specify a custom temporary directory in the plugin's settings."
|
670 |
msgstr "Este plugin utiliza um sistema de bloqueio de ficheiros para garantir que somente se executa uma instância do algoritmo de verificação de links num momento determinado, uma vez que consome bastantes recursos. Infelizmente, o plugin não pode encontrar um directório que possa armazenar um ficheiro temporário - erro ao detectar a localização do directório temporário no servidor, assim como o própio directório do plugin não permite a escrita pelo PHP. Para resolver, terá que dar permissões de escrita ao directório ou especificar um directório temporário na configuração do plugin."
|
671 |
|
672 |
+
#: core.php:3111
|
673 |
msgid "PHP version"
|
674 |
msgstr "Versão PHP"
|
675 |
|
676 |
+
#: core.php:3117
|
677 |
msgid "MySQL version"
|
678 |
msgstr "Versão MySQL"
|
679 |
|
680 |
+
#: core.php:3130
|
681 |
msgid "You have an old version of CURL. Redirect detection may not work properly."
|
682 |
msgstr "Versão de CURL obsoleta. A detecção de redirects pode não funcionar correctamente."
|
683 |
|
684 |
+
#: core.php:3142
|
685 |
+
#: core.php:3158
|
686 |
+
#: core.php:3163
|
687 |
msgid "Not installed"
|
688 |
msgstr "Não instalado"
|
689 |
|
690 |
+
#: core.php:3145
|
691 |
msgid "CURL version"
|
692 |
msgstr "Versão CURL"
|
693 |
|
694 |
+
#: core.php:3151
|
695 |
msgid "Installed"
|
696 |
msgstr "Instalado"
|
697 |
|
698 |
+
#: core.php:3164
|
699 |
msgid "You must have either CURL or Snoopy installed for the plugin to work!"
|
700 |
msgstr "Instalação de CURL ou Snoopy necessário para que funcione o plugin!"
|
701 |
|
702 |
+
#: core.php:3175
|
703 |
msgid "On"
|
704 |
msgstr "Activado"
|
705 |
|
706 |
+
#: core.php:3176
|
707 |
msgid "Redirects may be detected as broken links when safe_mode is on."
|
708 |
msgstr "Os redirects podem ser detectados como links offline quando o safe_mode está habilitado."
|
709 |
|
710 |
+
#: core.php:3181
|
711 |
+
#: core.php:3195
|
712 |
msgid "Off"
|
713 |
msgstr "Desactivado"
|
714 |
|
715 |
+
#: core.php:3189
|
716 |
#, php-format
|
717 |
msgid "On ( %s )"
|
718 |
msgstr "Activado ( %s )"
|
719 |
|
720 |
+
#: core.php:3190
|
721 |
msgid "Redirects may be detected as broken links when open_basedir is on."
|
722 |
msgstr "Os redirects podem ser considerados links offline quando o open_basedir está activo."
|
723 |
|
724 |
+
#: core.php:3209
|
725 |
msgid "Can't create a lockfile. Please specify a custom temporary directory."
|
726 |
msgstr "Não foi possível criar um ficheiro. Por favor, especifique um directório temporário personalizado."
|
727 |
|
728 |
+
#: core.php:3233
|
729 |
+
msgid "If this value is zero even after several page reloads you have probably encountered a bug."
|
730 |
+
msgstr "Se este valor é zero depois de recarregar várias provavelmente encontrou um bug."
|
731 |
+
|
732 |
+
#: core.php:3289
|
733 |
#, php-format
|
734 |
msgid "[%s] Broken links detected"
|
735 |
msgstr "[%s] Links offline detectados"
|
736 |
|
737 |
+
#: core.php:3295
|
738 |
#, php-format
|
739 |
msgid "Broken Link Checker has detected %d new broken link on your site."
|
740 |
msgid_plural "Broken Link Checker has detected %d new broken links on your site."
|
741 |
msgstr[0] "Links offline detectou %d novo link sem ligação."
|
742 |
msgstr[1] "Links offline detectou %d novos links sem ligação."
|
743 |
|
744 |
+
#: core.php:3310
|
745 |
#, php-format
|
746 |
msgid "Here's a list of the first %d broken links:"
|
747 |
msgid_plural "Here's a list of the first %d broken links:"
|
748 |
msgstr[0] "Lista do primeiro %d link sem ligação:"
|
749 |
msgstr[1] "Lista dos primeiros %d links sem ligação:"
|
750 |
|
751 |
+
#: core.php:3318
|
752 |
msgid "Here's a list of the new broken links: "
|
753 |
msgstr "Novos links offline:"
|
754 |
|
755 |
+
#: core.php:3330
|
756 |
#, php-format
|
757 |
msgid "Link text : %s"
|
758 |
msgstr "Texto do Link : %s"
|
759 |
|
760 |
+
#: core.php:3331
|
761 |
#, php-format
|
762 |
msgid "Link URL : <a href=\"%s\">%s</a>"
|
763 |
msgstr "Link URL : <a href=\"%s\">%s</a>"
|
764 |
|
765 |
+
#: core.php:3332
|
766 |
#, php-format
|
767 |
msgid "Source : %s"
|
768 |
msgstr "Fonte : %s"
|
769 |
|
770 |
+
#: core.php:3346
|
771 |
msgid "You can see all broken links here:"
|
772 |
msgstr "Links offline:"
|
773 |
|
774 |
+
#: includes/containers.php:284
|
775 |
+
#, php-format
|
776 |
+
msgid "Container type '%s' not recognized"
|
777 |
+
msgstr "Recipiente tipo '%s' não foi reconhecido"
|
778 |
+
|
779 |
+
#: includes/containers.php:814
|
780 |
+
#, php-format
|
781 |
+
msgid "%d '%s' has been deleted"
|
782 |
+
msgid_plural "%d '%s' have been deleted"
|
783 |
+
msgstr[0] "%d '%s' foi apagado"
|
784 |
+
msgstr[1] "%d '%s' foram apagados"
|
785 |
+
|
786 |
+
#: includes/instances.php:102
|
787 |
+
#: includes/instances.php:148
|
788 |
+
#, php-format
|
789 |
+
msgid "Container %s[%d] not found"
|
790 |
+
msgstr "Recipiente %s[%d] não encontrado"
|
791 |
+
|
792 |
+
#: includes/instances.php:111
|
793 |
+
#: includes/instances.php:157
|
794 |
+
#, php-format
|
795 |
+
msgid "Parser '%s' not found."
|
796 |
+
msgstr "Analizador sintáctico '%s' não encontrado."
|
797 |
+
|
798 |
+
#: includes/links.php:152
|
799 |
+
msgid "The plugin script was terminated while trying to check the link."
|
800 |
+
msgstr "O script do plugin terminou enquanto tentava verificar o link."
|
801 |
+
|
802 |
+
#: includes/links.php:196
|
803 |
+
msgid "The plugin doesn't know how to check this type of link."
|
804 |
+
msgstr "O plugin não consegue verificar este tipo de link."
|
805 |
+
|
806 |
+
#: includes/links.php:284
|
807 |
+
msgid "Link is valid."
|
808 |
+
msgstr "Link operacional."
|
809 |
+
|
810 |
+
#: includes/links.php:286
|
811 |
+
msgid "Link is broken."
|
812 |
+
msgstr "Link sem ligação."
|
813 |
+
|
814 |
+
#: includes/links.php:479
|
815 |
+
#: includes/links.php:581
|
816 |
+
#: includes/links.php:616
|
817 |
+
msgid "Link is not valid"
|
818 |
+
msgstr "Link não válido"
|
819 |
+
|
820 |
+
#: includes/links.php:496
|
821 |
+
msgid "This link can not be edited because it is not used anywhere on this site."
|
822 |
+
msgstr "Este link não pode ser editado porque não é utilizado em nenhuma parte da página."
|
823 |
+
|
824 |
+
#: includes/links.php:522
|
825 |
+
msgid "Failed to create a DB entry for the new URL."
|
826 |
+
msgstr "Falhou a criação de um registro na Base de dados para um novo URL."
|
827 |
+
|
828 |
+
#: includes/links.php:594
|
829 |
+
msgid "This link is not a redirect"
|
830 |
+
msgstr "O link não é um redirect"
|
831 |
+
|
832 |
+
#: includes/links.php:643
|
833 |
+
#: includes/links.php:680
|
834 |
+
msgid "Couldn't delete the link's database record"
|
835 |
+
msgstr "Não é possível apagar o registro do link na Base de dados"
|
836 |
+
|
837 |
+
#: includes/links.php:772
|
838 |
+
msgid "Broken"
|
839 |
+
msgstr "Offline"
|
840 |
+
|
841 |
+
#: includes/links.php:774
|
842 |
+
msgid "No broken links found"
|
843 |
+
msgstr "Links offline (0)"
|
844 |
+
|
845 |
+
#: includes/links.php:781
|
846 |
+
msgid "Redirects"
|
847 |
+
msgstr "Redirects"
|
848 |
+
|
849 |
+
#: includes/links.php:782
|
850 |
+
msgid "Redirected Links"
|
851 |
+
msgstr "Links Redirects"
|
852 |
+
|
853 |
+
#: includes/links.php:783
|
854 |
+
msgid "No redirects found"
|
855 |
+
msgstr "Redirects (0)"
|
856 |
+
|
857 |
+
#: includes/links.php:791
|
858 |
+
msgid "All"
|
859 |
+
msgstr "Todos"
|
860 |
+
|
861 |
+
#: includes/links.php:792
|
862 |
+
msgid "Detected Links"
|
863 |
+
msgstr "Links encontrados"
|
864 |
+
|
865 |
+
#: includes/links.php:793
|
866 |
+
msgid "No links found (yet)"
|
867 |
+
msgstr "Links (0)"
|
868 |
+
|
869 |
+
#: includes/links.php:800
|
870 |
+
msgid "Search"
|
871 |
+
msgstr "Procurar"
|
872 |
+
|
873 |
+
#: includes/links.php:801
|
874 |
+
msgid "Search Results"
|
875 |
+
msgstr "Resultados da procura"
|
876 |
+
|
877 |
+
#: includes/links.php:802
|
878 |
+
#: includes/links.php:853
|
879 |
+
msgid "No links found for your query"
|
880 |
+
msgstr "Sem resultados"
|
881 |
+
|
882 |
+
#: includes/parsers.php:173
|
883 |
+
#, php-format
|
884 |
+
msgid "Editing is not implemented in the '%s' parser"
|
885 |
+
msgstr "Edição não implementada no '%s' analizador sintáctico"
|
886 |
+
|
887 |
+
#: includes/parsers.php:188
|
888 |
+
#, php-format
|
889 |
+
msgid "Unlinking is not implemented in the '%s' parser"
|
890 |
+
msgstr "Remover links não foi implementado no '%s' analizador sintáctico"
|
891 |
+
|
892 |
+
#: includes/admin/links-page-js.php:54
|
893 |
+
#: includes/admin/links-page-js.php:248
|
894 |
msgid "Wait..."
|
895 |
msgstr "Espere ..."
|
896 |
|
897 |
+
#: includes/admin/links-page-js.php:123
|
898 |
msgid "Save URL"
|
899 |
msgstr "Guardar URL"
|
900 |
|
901 |
+
#: includes/admin/links-page-js.php:134
|
902 |
msgid "Saving changes..."
|
903 |
msgstr "Guardando alterações ..."
|
904 |
|
905 |
+
#: includes/admin/links-page-js.php:180
|
906 |
#, php-format
|
907 |
msgid "%d instances of the link were successfully modified."
|
908 |
msgstr "%d casos de links que se modificaram com sucesso."
|
909 |
|
910 |
+
#: includes/admin/links-page-js.php:186
|
911 |
#, php-format
|
912 |
msgid "However, %d instances couldn't be edited and still point to the old URL."
|
913 |
msgstr "No entanto, %d casos não puderam ser editados e ainda apontam para a antiga URL."
|
914 |
|
915 |
+
#: includes/admin/links-page-js.php:192
|
916 |
msgid "The link could not be modified."
|
917 |
msgstr "O link não pode ser modificado."
|
918 |
|
919 |
+
#: includes/admin/links-page-js.php:195
|
920 |
+
#: includes/admin/links-page-js.php:299
|
921 |
msgid "The following error(s) occured :"
|
922 |
msgstr "Erro(s) :"
|
923 |
|
924 |
+
#: includes/admin/links-page-js.php:285
|
925 |
#, php-format
|
926 |
msgid "%d instances of the link were successfully unlinked."
|
927 |
msgstr "%d casos de links foram removidos com sucesso."
|
928 |
|
929 |
+
#: includes/admin/links-page-js.php:291
|
930 |
#, php-format
|
931 |
msgid "However, %d instances couldn't be removed."
|
932 |
msgstr "No entanto, %d casos não foram removidos."
|
933 |
|
934 |
+
#: includes/admin/links-page-js.php:296
|
935 |
msgid "The plugin failed to remove the link."
|
936 |
msgstr "O plugin não removeu o link."
|
937 |
|
938 |
+
#: includes/admin/links-page-js.php:351
|
939 |
msgid "Enter a name for the new custom filter"
|
940 |
msgstr "Introduza o nome para o novo filtro personalizado"
|
941 |
|
942 |
+
#: includes/admin/links-page-js.php:362
|
943 |
msgid ""
|
944 |
"You are about to delete the current filter.\n"
|
945 |
"'Cancel' to stop, 'OK' to delete"
|
947 |
"Está a ponto de apagar o filtro actual.\n"
|
948 |
" 'Cancelar' para sair, 'Aceitar' para apagar."
|
949 |
|
950 |
+
#: includes/admin/links-page-js.php:385
|
951 |
msgid ""
|
952 |
"Are you sure you want to delete all posts, bookmarks or other items that contain any of the selected links? This action can't be undone.\n"
|
953 |
"'Cancel' to stop, 'OK' to delete"
|
956 |
"Esta acção não pode ser anulada.\n"
|
957 |
"'Cancelar' para anular a operação, 'Aceitar' para apagar"
|
958 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
959 |
#: includes/admin/search-form.php:39
|
960 |
msgid "Link text"
|
961 |
msgstr "Texto do link"
|
964 |
msgid "Link status"
|
965 |
msgstr "Estado do link"
|
966 |
|
967 |
+
#: includes/admin/search-form.php:65
|
968 |
msgid "Link type"
|
969 |
msgstr "Tipo de link"
|
970 |
|
971 |
+
#: includes/admin/search-form.php:69
|
972 |
msgid "Any"
|
973 |
msgstr "Qualquer"
|
974 |
|
975 |
+
#: includes/admin/search-form.php:70
|
976 |
msgid "Normal link"
|
977 |
msgstr "Link normal"
|
978 |
|
979 |
+
#: includes/admin/search-form.php:71
|
|
|
980 |
msgid "Image"
|
981 |
msgstr "Imagem"
|
982 |
|
983 |
+
#: includes/admin/search-form.php:72
|
|
|
984 |
msgid "Custom field"
|
985 |
msgstr "Campo personalizado"
|
986 |
|
987 |
+
#: includes/admin/search-form.php:73
|
988 |
#: includes/containers/blogroll.php:13
|
989 |
msgid "Bookmark"
|
990 |
msgstr "Favorito"
|
991 |
|
992 |
+
#: includes/admin/search-form.php:74
|
|
|
993 |
msgid "Comment"
|
994 |
msgstr "Comentário"
|
995 |
|
996 |
+
#: includes/checkers/http.php:195
|
997 |
+
#: includes/checkers/http.php:262
|
|
|
|
|
|
|
|
|
998 |
#, php-format
|
999 |
msgid "HTTP code : %d"
|
1000 |
msgstr "Código HTTP : %d"
|
1001 |
|
1002 |
+
#: includes/checkers/http.php:197
|
1003 |
+
#: includes/checkers/http.php:264
|
1004 |
msgid "(No response)"
|
1005 |
msgstr "(Sem resposta)"
|
1006 |
|
1007 |
+
#: includes/checkers/http.php:203
|
1008 |
msgid "Most likely the connection timed out or the domain doesn't exist."
|
1009 |
msgstr "Provável que o tempo da ligação se tenha esgotado ou que o domínio não exista."
|
1010 |
|
1011 |
+
#: includes/checkers/http.php:271
|
1012 |
msgid "Request timed out."
|
1013 |
msgstr "Tempo de espera esgotado."
|
1014 |
|
1015 |
+
#: includes/checkers/http.php:289
|
1016 |
msgid "Using Snoopy"
|
1017 |
msgstr "Utilizando Snoopy"
|
1018 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1019 |
#: includes/containers/blogroll.php:19
|
1020 |
#: includes/containers/blogroll.php:38
|
1021 |
msgid "Edit this bookmark"
|
1022 |
msgstr "Editar este favorito"
|
1023 |
|
1024 |
#: includes/containers/blogroll.php:38
|
|
|
|
|
|
|
1025 |
msgid "Edit"
|
1026 |
msgstr "Editar"
|
1027 |
|
1035 |
" 'Cancelar' para sair, 'Aceitar' para apagar."
|
1036 |
|
1037 |
#: includes/containers/blogroll.php:39
|
|
|
|
|
1038 |
msgid "Delete"
|
1039 |
msgstr "Apagar"
|
1040 |
|
1041 |
#: includes/containers/blogroll.php:75
|
|
|
|
|
1042 |
msgid "Nothing to update"
|
1043 |
msgstr "Sem actualização"
|
1044 |
|
1056 |
#, php-format
|
1057 |
msgid "%d blogroll link deleted"
|
1058 |
msgid_plural "%d blogroll links deleted"
|
1059 |
+
msgstr[0] "%d link blogroll apagado"
|
1060 |
+
msgstr[1] "%d links blogroll apagados"
|
1061 |
|
1062 |
#: includes/containers/comment.php:46
|
1063 |
#, php-format
|
1069 |
msgid "Failed to delete comment %d"
|
1070 |
msgstr "Erro ao apagar o comentário %d"
|
1071 |
|
|
|
|
|
|
|
|
|
|
|
1072 |
#: includes/containers/comment.php:114
|
1073 |
msgid "Delete Permanently"
|
1074 |
msgstr "Apagado definitivamente"
|
1075 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1076 |
#: includes/containers/comment.php:120
|
1077 |
msgid "View comment"
|
1078 |
msgstr "Ver comentário"
|
1083 |
msgid "View"
|
1084 |
msgstr "Ver"
|
1085 |
|
1086 |
+
#: includes/containers/comment.php:279
|
1087 |
#, php-format
|
1088 |
msgid "%d comment moved to the trash"
|
1089 |
msgid_plural "%d comments moved to the trash"
|
1090 |
msgstr[0] "%d comentário movido para o lixo"
|
1091 |
msgstr[1] "%d comentários movidos para o lixo"
|
1092 |
|
1093 |
+
#: includes/containers/comment.php:289
|
1094 |
#, php-format
|
1095 |
msgid "%d comment has been deleted"
|
1096 |
msgid_plural "%d comments have been deleted"
|
1108 |
msgstr "Erro ao apagar o campo meta '%s' em %s [%d]"
|
1109 |
|
1110 |
#: includes/containers/custom_field.php:191
|
|
|
1111 |
#: includes/containers/post.php:16
|
1112 |
#: includes/containers/post.php:41
|
1113 |
msgid "Edit this post"
|
1114 |
msgstr "Editar post"
|
1115 |
|
1116 |
+
#: includes/containers/custom_field.php:201
|
1117 |
+
msgid "Edit this item"
|
1118 |
+
msgstr "Editar post"
|
1119 |
+
|
1120 |
#: includes/containers/custom_field.php:204
|
1121 |
+
msgid "Move this item to the Trash"
|
|
|
1122 |
msgstr "Mover este post para o lixo"
|
1123 |
|
1124 |
#: includes/containers/custom_field.php:204
|
1147 |
msgid "View \"%s\""
|
1148 |
msgstr "Ver \"%s\""
|
1149 |
|
1150 |
+
#: includes/containers/custom_field.php:304
|
1151 |
+
#: includes/containers/post.php:183
|
1152 |
#, php-format
|
1153 |
msgid "Failed to delete post \"%s\" (%d)"
|
1154 |
msgstr "Erro ao apagar o post \"%s\" (%d)"
|
1155 |
|
1156 |
+
#: includes/containers/custom_field.php:535
|
1157 |
+
#: includes/containers/post.php:356
|
1158 |
#, php-format
|
1159 |
msgid "%d post moved to the trash"
|
1160 |
msgid_plural "%d posts moved to the trash"
|
1161 |
msgstr[0] "%d post transferido para o lixo"
|
1162 |
msgstr[1] "%d posts transferidos para o lixo"
|
1163 |
|
1164 |
+
#: includes/containers/custom_field.php:537
|
1165 |
+
#: includes/containers/post.php:358
|
1166 |
#, php-format
|
1167 |
msgid "%d post deleted"
|
1168 |
msgid_plural "%d posts deleted"
|
1175 |
msgid "I don't know how to edit a '%s' [%d]."
|
1176 |
msgstr "Não é possível editar '%s' [%d]."
|
1177 |
|
1178 |
+
#: includes/containers/post.php:19
|
1179 |
+
msgid "Move this post to the Trash"
|
1180 |
+
msgstr "Mover este post para o lixo"
|
1181 |
+
|
1182 |
+
#: includes/containers/post.php:152
|
1183 |
#, php-format
|
1184 |
msgid "Updating post %d failed"
|
1185 |
msgstr "Actualização do post %d falhou"
|
1186 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
languages/broken-link-checker.pot
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
# Translation of the WordPress plugin Broken Link Checker 0.9.
|
2 |
# Copyright (C) 2010 Janis Elsts
|
3 |
# This file is distributed under the same license as the Broken Link Checker package.
|
4 |
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
|
@@ -6,216 +6,202 @@
|
|
6 |
#, fuzzy
|
7 |
msgid ""
|
8 |
msgstr ""
|
9 |
-
"Project-Id-Version: Broken Link Checker 0.9.
|
10 |
"Report-Msgid-Bugs-To: http://wordpress.org/tag/broken-link-checker\n"
|
11 |
-
"POT-Creation-Date: 2010-
|
12 |
"PO-Revision-Date: 2010-MO-DA HO:MI+ZONE\n"
|
13 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14 |
"Language-Team: LANGUAGE <LL@li.org>\n"
|
15 |
"MIME-Version: 1.0\n"
|
16 |
"Content-Type: text/plain; charset=utf-8\n"
|
17 |
"Content-Transfer-Encoding: 8bit\n"
|
18 |
-
"Plural-Forms: nplurals=
|
19 |
|
20 |
-
#:
|
21 |
-
msgid "
|
22 |
msgstr ""
|
23 |
|
24 |
-
#:
|
25 |
-
msgid "
|
26 |
msgstr ""
|
27 |
|
28 |
-
#:
|
29 |
-
msgid "
|
30 |
msgstr ""
|
31 |
|
32 |
-
#: core
|
33 |
-
msgid "
|
34 |
msgstr ""
|
35 |
|
36 |
-
#: core
|
37 |
-
msgid "
|
38 |
msgstr ""
|
39 |
|
40 |
-
#: core.php:
|
41 |
-
msgid "
|
42 |
msgstr ""
|
43 |
|
44 |
-
#: core.php:
|
45 |
-
|
46 |
-
msgid "Failed to delete old DB tables. Database error : %s"
|
47 |
msgstr ""
|
48 |
|
49 |
-
#: core.php:
|
50 |
-
|
51 |
-
msgid ""
|
52 |
-
"Unexpected error: The plugin doesn't know how to upgrade its database to "
|
53 |
-
"version '%d'."
|
54 |
msgstr ""
|
55 |
|
56 |
-
#: core
|
57 |
#, php-format
|
58 |
-
msgid "
|
|
|
|
|
59 |
msgstr ""
|
60 |
|
61 |
-
#: core.php:
|
62 |
-
msgid "
|
63 |
msgstr ""
|
64 |
|
65 |
-
#: core.php:
|
66 |
-
msgid "
|
67 |
msgstr ""
|
68 |
|
69 |
-
#: core.php:
|
70 |
-
msgid "
|
71 |
msgstr ""
|
72 |
|
73 |
-
#: core
|
74 |
-
msgid "
|
75 |
msgstr ""
|
76 |
|
77 |
-
#: core.php:
|
78 |
-
|
79 |
-
msgid "Highlight links broken for at least %s days"
|
80 |
msgstr ""
|
81 |
|
82 |
-
#: core.php:
|
83 |
-
msgid "
|
84 |
msgstr ""
|
85 |
|
86 |
-
#: core
|
87 |
-
|
88 |
-
msgid ""
|
89 |
-
"Error: The plugin's database tables are not up to date! (Current version : %"
|
90 |
-
"d, expected : %d)"
|
91 |
msgstr ""
|
92 |
|
93 |
-
#: core.php:
|
94 |
-
msgid "
|
95 |
msgstr ""
|
96 |
|
97 |
-
#: core.php:
|
98 |
msgid "Broken Link Checker Options"
|
99 |
msgstr ""
|
100 |
|
101 |
-
#: core.php:
|
102 |
msgid "Status"
|
103 |
msgstr ""
|
104 |
|
105 |
-
#: core.php:
|
106 |
msgid "Show debug info"
|
107 |
msgstr ""
|
108 |
|
109 |
-
#: core.php:
|
110 |
-
msgid "Re-check all pages"
|
111 |
-
msgstr ""
|
112 |
-
|
113 |
-
#: core.php:956
|
114 |
msgid "Check each link"
|
115 |
msgstr ""
|
116 |
|
117 |
-
#: core.php:
|
118 |
#, php-format
|
119 |
msgid "Every %s hours"
|
120 |
msgstr ""
|
121 |
|
122 |
-
#: core.php:
|
123 |
msgid ""
|
124 |
"Existing links will be checked this often. New links will usually be checked "
|
125 |
"ASAP."
|
126 |
msgstr ""
|
127 |
|
128 |
-
#: core.php:
|
129 |
-
msgid "
|
130 |
-
msgstr ""
|
131 |
-
|
132 |
-
#: core.php:982
|
133 |
-
msgid "Apply <em>class=\"broken_link\"</em> to broken links"
|
134 |
msgstr ""
|
135 |
|
136 |
-
#: core.php:
|
137 |
-
msgid "
|
138 |
msgstr ""
|
139 |
|
140 |
-
#: core.php:
|
141 |
-
msgid "
|
142 |
msgstr ""
|
143 |
|
144 |
-
#: core.php:
|
145 |
-
msgid "
|
146 |
msgstr ""
|
147 |
|
148 |
-
#: core.php:
|
149 |
-
msgid "
|
150 |
msgstr ""
|
151 |
|
152 |
-
#: core.php:
|
153 |
-
msgid "
|
154 |
msgstr ""
|
155 |
|
156 |
-
#: core.php:
|
157 |
-
msgid ""
|
158 |
-
"Don't check links where the URL contains any of these words (one per line) :"
|
159 |
msgstr ""
|
160 |
|
161 |
-
#: core.php:
|
162 |
-
msgid "
|
163 |
msgstr ""
|
164 |
|
165 |
-
#: core.php:
|
166 |
-
msgid "
|
167 |
msgstr ""
|
168 |
|
169 |
-
#: core.php:
|
170 |
-
msgid "
|
171 |
msgstr ""
|
172 |
|
173 |
-
#: core.php:
|
174 |
-
msgid "
|
175 |
msgstr ""
|
176 |
|
177 |
-
#: core.php:
|
178 |
-
msgid "
|
179 |
msgstr ""
|
180 |
|
181 |
-
#: core.php:
|
182 |
-
msgid "
|
|
|
183 |
msgstr ""
|
184 |
|
185 |
-
#: core.php:
|
186 |
-
msgid "
|
187 |
msgstr ""
|
188 |
|
189 |
-
#: core.php:
|
190 |
msgid "Timeout"
|
191 |
msgstr ""
|
192 |
|
193 |
-
#: core.php:
|
194 |
#, php-format
|
195 |
msgid "%s seconds"
|
196 |
msgstr ""
|
197 |
|
198 |
-
#: core.php:
|
199 |
msgid "Links that take longer than this to load will be marked as broken."
|
200 |
msgstr ""
|
201 |
|
202 |
-
#: core.php:
|
203 |
msgid "Link monitor"
|
204 |
msgstr ""
|
205 |
|
206 |
-
#: core.php:
|
207 |
msgid "Run continuously while the Dashboard is open"
|
208 |
msgstr ""
|
209 |
|
210 |
-
#: core.php:
|
211 |
msgid "Run hourly in the background"
|
212 |
msgstr ""
|
213 |
|
214 |
-
#: core.php:
|
215 |
msgid "Max. execution time"
|
216 |
msgstr ""
|
217 |
|
218 |
-
#: core.php:
|
219 |
msgid ""
|
220 |
"The plugin works by periodically launching a background job that parses your "
|
221 |
"posts for links, checks the discovered URLs, and performs other time-"
|
@@ -223,436 +209,324 @@ msgid ""
|
|
223 |
"may run each time before stopping."
|
224 |
msgstr ""
|
225 |
|
226 |
-
#: core.php:
|
227 |
msgid "Custom temporary directory"
|
228 |
msgstr ""
|
229 |
|
230 |
-
#: core.php:
|
231 |
msgid "OK"
|
232 |
msgstr ""
|
233 |
|
234 |
-
#: core.php:
|
235 |
msgid "Error : This directory isn't writable by PHP."
|
236 |
msgstr ""
|
237 |
|
238 |
-
#: core.php:
|
239 |
msgid "Error : This directory doesn't exist."
|
240 |
msgstr ""
|
241 |
|
242 |
-
#: core.php:
|
243 |
msgid ""
|
244 |
"Set this field if you want the plugin to use a custom directory for its "
|
245 |
"lockfiles. Otherwise, leave it blank."
|
246 |
msgstr ""
|
247 |
|
248 |
-
#: core.php:
|
249 |
msgid "Server load limit"
|
250 |
msgstr ""
|
251 |
|
252 |
-
#: core.php:
|
253 |
#, php-format
|
254 |
msgid ""
|
255 |
"Link checking will be suspended if the average <a href=\"%s\">server load</"
|
256 |
"a> rises above this number. Leave this field blank to disable load limiting."
|
257 |
msgstr ""
|
258 |
|
259 |
-
#: core.php:
|
260 |
msgid ""
|
261 |
"Load limiting only works on Linux-like systems where <code>/proc/loadavg</"
|
262 |
"code> is present and accessible."
|
263 |
msgstr ""
|
264 |
|
265 |
-
#: core.php:
|
266 |
-
msgid "
|
267 |
-
msgstr ""
|
268 |
-
|
269 |
-
#: core.php:1252
|
270 |
-
msgid "Hide debug info"
|
271 |
-
msgstr ""
|
272 |
-
|
273 |
-
#: core.php:1369 core.php:1705 core.php:1737
|
274 |
-
#, php-format
|
275 |
-
msgid "Database error : %s"
|
276 |
-
msgstr ""
|
277 |
-
|
278 |
-
#: core.php:1446
|
279 |
-
msgid "Bulk Actions"
|
280 |
-
msgstr ""
|
281 |
-
|
282 |
-
#: core.php:1447
|
283 |
-
msgid "Recheck"
|
284 |
msgstr ""
|
285 |
|
286 |
-
#: core.php:
|
287 |
-
msgid "
|
288 |
-
msgstr ""
|
289 |
-
|
290 |
-
#: core.php:1449
|
291 |
-
msgid "Mark as not broken"
|
292 |
msgstr ""
|
293 |
|
294 |
-
#: core
|
295 |
-
msgid "
|
|
|
|
|
296 |
msgstr ""
|
297 |
|
298 |
-
#: core.php:
|
299 |
-
msgid "
|
300 |
msgstr ""
|
301 |
|
302 |
-
#: core
|
303 |
-
msgid "
|
304 |
msgstr ""
|
305 |
|
306 |
-
#: core.php:
|
307 |
-
msgid "
|
308 |
msgstr ""
|
309 |
|
310 |
-
#: core.php:
|
311 |
-
msgid "
|
312 |
msgstr ""
|
313 |
|
314 |
-
#: core.php:
|
315 |
#, php-format
|
316 |
-
msgid "
|
317 |
-
msgstr ""
|
318 |
-
|
319 |
-
#: core.php:1499
|
320 |
-
msgid "Source"
|
321 |
-
msgstr ""
|
322 |
-
|
323 |
-
#: core.php:1500
|
324 |
-
msgid "Link Text"
|
325 |
-
msgstr ""
|
326 |
-
|
327 |
-
#: core.php:1501 includes/admin/search-form.php:42
|
328 |
-
msgid "URL"
|
329 |
-
msgstr ""
|
330 |
-
|
331 |
-
#: core.php:1577
|
332 |
-
msgid "[An orphaned link! This is a bug.]"
|
333 |
-
msgstr ""
|
334 |
-
|
335 |
-
#: core.php:1601
|
336 |
-
msgid "Show more info about this link"
|
337 |
-
msgstr ""
|
338 |
-
|
339 |
-
#: core.php:1601 core.php:3062
|
340 |
-
msgid "Details"
|
341 |
-
msgstr ""
|
342 |
-
|
343 |
-
#: core.php:1603
|
344 |
-
msgid "Remove this link from all posts"
|
345 |
-
msgstr ""
|
346 |
-
|
347 |
-
#: core.php:1609
|
348 |
-
msgid "Remove this link from the list of broken links and mark it as valid"
|
349 |
-
msgstr ""
|
350 |
-
|
351 |
-
#: core.php:1610 includes/admin/links-page-js.php:78
|
352 |
-
msgid "Not broken"
|
353 |
-
msgstr ""
|
354 |
-
|
355 |
-
#: core.php:1614
|
356 |
-
msgid "Edit link URL"
|
357 |
-
msgstr ""
|
358 |
-
|
359 |
-
#: core.php:1614 includes/admin/links-page-js.php:199
|
360 |
-
#: includes/admin/links-page-js.php:227
|
361 |
-
msgid "Edit URL"
|
362 |
-
msgstr ""
|
363 |
-
|
364 |
-
#: core.php:1620
|
365 |
-
msgid "Cancel URL editing"
|
366 |
-
msgstr ""
|
367 |
-
|
368 |
-
#: core.php:1620 includes/admin/search-form.php:87
|
369 |
-
msgid "Cancel"
|
370 |
msgstr ""
|
371 |
|
372 |
-
#: core.php:
|
373 |
msgid "You must enter a filter name!"
|
374 |
msgstr ""
|
375 |
|
376 |
-
#: core.php:
|
377 |
msgid "Invalid search query."
|
378 |
msgstr ""
|
379 |
|
380 |
-
#: core.php:
|
381 |
#, php-format
|
382 |
msgid "Filter \"%s\" created"
|
383 |
msgstr ""
|
384 |
|
385 |
-
#: core.php:
|
386 |
msgid "Filter ID not specified."
|
387 |
msgstr ""
|
388 |
|
389 |
-
#: core.php:
|
390 |
msgid "Filter deleted"
|
391 |
msgstr ""
|
392 |
|
393 |
-
#: core.php:
|
394 |
#, php-format
|
395 |
msgid "Replaced %d redirect with a direct link"
|
396 |
msgid_plural "Replaced %d redirects with direct links"
|
397 |
msgstr[0] ""
|
398 |
msgstr[1] ""
|
399 |
|
400 |
-
#: core.php:
|
401 |
#, php-format
|
402 |
msgid "Failed to fix %d redirect"
|
403 |
msgid_plural "Failed to fix %d redirects"
|
404 |
msgstr[0] ""
|
405 |
msgstr[1] ""
|
406 |
|
407 |
-
#: core.php:
|
408 |
msgid "None of the selected links are redirects!"
|
409 |
msgstr ""
|
410 |
|
411 |
-
#: core.php:
|
412 |
#, php-format
|
413 |
msgid "%d link removed"
|
414 |
msgid_plural "%d links removed"
|
415 |
msgstr[0] ""
|
416 |
msgstr[1] ""
|
417 |
|
418 |
-
#: core.php:
|
419 |
#, php-format
|
420 |
msgid "Failed to remove %d link"
|
421 |
msgid_plural "Failed to remove %d links"
|
422 |
msgstr[0] ""
|
423 |
msgstr[1] ""
|
424 |
|
425 |
-
#: core.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
426 |
msgid "Didn't find anything to delete!"
|
427 |
msgstr ""
|
428 |
|
429 |
-
#: core.php:
|
430 |
#, php-format
|
431 |
msgid "%d link scheduled for rechecking"
|
432 |
msgid_plural "%d links scheduled for rechecking"
|
433 |
msgstr[0] ""
|
434 |
msgstr[1] ""
|
435 |
|
436 |
-
#: core.php:
|
437 |
msgid "This link was manually marked as working by the user."
|
438 |
msgstr ""
|
439 |
|
440 |
-
#: core.php:
|
441 |
#, php-format
|
442 |
msgid "Couldn't modify link %d"
|
443 |
msgstr ""
|
444 |
|
445 |
-
#: core.php:
|
446 |
#, php-format
|
447 |
msgid "%d link marked as not broken"
|
448 |
msgid_plural "%d links marked as not broken"
|
449 |
msgstr[0] ""
|
450 |
msgstr[1] ""
|
451 |
|
452 |
-
#: core.php:
|
453 |
-
msgid "
|
454 |
-
msgstr ""
|
455 |
-
|
456 |
-
#: core.php:2068
|
457 |
-
msgid "Link last checked"
|
458 |
-
msgstr ""
|
459 |
-
|
460 |
-
#: core.php:2072
|
461 |
-
msgid "Never"
|
462 |
-
msgstr ""
|
463 |
-
|
464 |
-
#: core.php:2078 includes/admin/search-form.php:45
|
465 |
-
msgid "HTTP code"
|
466 |
-
msgstr ""
|
467 |
-
|
468 |
-
#: core.php:2083
|
469 |
-
msgid "Response time"
|
470 |
msgstr ""
|
471 |
|
472 |
-
#: core.php:
|
473 |
-
|
474 |
-
msgid "%2.3f seconds"
|
475 |
msgstr ""
|
476 |
|
477 |
-
#: core.php:
|
478 |
-
msgid "
|
479 |
msgstr ""
|
480 |
|
481 |
-
#: core.php:
|
482 |
-
msgid "
|
483 |
msgstr ""
|
484 |
|
485 |
-
#: core.php:
|
486 |
-
msgid "
|
487 |
msgstr ""
|
488 |
|
489 |
-
#: core.php:
|
490 |
-
#, php-format
|
491 |
-
msgid "This link has failed %d time."
|
492 |
-
msgid_plural "This link has failed %d times."
|
493 |
-
msgstr[0] ""
|
494 |
-
msgstr[1] ""
|
495 |
-
|
496 |
-
#: core.php:2115
|
497 |
#, php-format
|
498 |
-
msgid "
|
499 |
msgstr ""
|
500 |
|
501 |
-
#: core.php:
|
502 |
-
msgid "
|
503 |
msgstr ""
|
504 |
|
505 |
-
#: core.php:
|
506 |
-
msgid "
|
507 |
msgstr ""
|
508 |
|
509 |
-
#: core.php:
|
510 |
-
#, php-format
|
511 |
-
msgid "%d minute"
|
512 |
-
msgid_plural "%d minutes"
|
513 |
-
msgstr[0] ""
|
514 |
-
msgstr[1] ""
|
515 |
-
|
516 |
-
#: core.php:2174 core.php:2201
|
517 |
-
#, php-format
|
518 |
-
msgid "%d hour"
|
519 |
-
msgid_plural "%d hours"
|
520 |
-
msgstr[0] ""
|
521 |
-
msgstr[1] ""
|
522 |
-
|
523 |
-
#: core.php:2189 core.php:2230
|
524 |
-
#, php-format
|
525 |
-
msgid "%d day"
|
526 |
-
msgid_plural "%d days"
|
527 |
-
msgstr[0] ""
|
528 |
-
msgstr[1] ""
|
529 |
-
|
530 |
-
#: core.php:2219
|
531 |
-
#, php-format
|
532 |
-
msgid "%d month"
|
533 |
-
msgid_plural "%d months"
|
534 |
-
msgstr[0] ""
|
535 |
-
msgstr[1] ""
|
536 |
-
|
537 |
-
#: core.php:2562
|
538 |
msgid "View broken links"
|
539 |
msgstr ""
|
540 |
|
541 |
-
#: core.php:
|
542 |
#, php-format
|
543 |
msgid "Found %d broken link"
|
544 |
msgid_plural "Found %d broken links"
|
545 |
msgstr[0] ""
|
546 |
msgstr[1] ""
|
547 |
|
548 |
-
#: core.php:
|
549 |
msgid "No broken links found."
|
550 |
msgstr ""
|
551 |
|
552 |
-
#: core.php:
|
553 |
#, php-format
|
554 |
msgid "%d URL in the work queue"
|
555 |
msgid_plural "%d URLs in the work queue"
|
556 |
msgstr[0] ""
|
557 |
msgstr[1] ""
|
558 |
|
559 |
-
#: core.php:
|
560 |
msgid "No URLs in the work queue."
|
561 |
msgstr ""
|
562 |
|
563 |
-
#: core.php:
|
564 |
#, php-format
|
565 |
msgid "Detected %d unique URL"
|
566 |
msgid_plural "Detected %d unique URLs"
|
567 |
msgstr[0] ""
|
568 |
msgstr[1] ""
|
569 |
|
570 |
-
#: core.php:
|
571 |
#, php-format
|
572 |
msgid "in %d link"
|
573 |
msgid_plural "in %d links"
|
574 |
msgstr[0] ""
|
575 |
msgstr[1] ""
|
576 |
|
577 |
-
#: core.php:
|
578 |
msgid "and still searching..."
|
579 |
msgstr ""
|
580 |
|
581 |
-
#: core.php:
|
582 |
msgid "Searching your blog for links..."
|
583 |
msgstr ""
|
584 |
|
585 |
-
#: core.php:
|
586 |
msgid "No links detected."
|
587 |
msgstr ""
|
588 |
|
589 |
-
#: core
|
590 |
-
|
|
|
591 |
msgstr ""
|
592 |
|
593 |
-
#: core.php:
|
594 |
#, php-format
|
595 |
msgid "Oops, I can't find the link %d"
|
596 |
msgstr ""
|
597 |
|
598 |
-
#: core.php:
|
599 |
msgid "Oops, couldn't modify the link!"
|
600 |
msgstr ""
|
601 |
|
602 |
-
#: core.php:
|
603 |
msgid "Error : link_id not specified"
|
604 |
msgstr ""
|
605 |
|
606 |
-
#: core.php:
|
607 |
msgid "Oops, the new URL is invalid!"
|
608 |
msgstr ""
|
609 |
|
610 |
-
#: core.php:
|
611 |
msgid "An unexpected error occured!"
|
612 |
msgstr ""
|
613 |
|
614 |
-
#: core.php:
|
615 |
msgid "Error : link_id or new_url not specified"
|
616 |
msgstr ""
|
617 |
|
618 |
-
#: core.php:
|
619 |
msgid "You don't have sufficient privileges to access this information!"
|
620 |
msgstr ""
|
621 |
|
622 |
-
#: core.php:
|
623 |
msgid "Error : link ID not specified"
|
624 |
msgstr ""
|
625 |
|
626 |
-
#: core.php:
|
627 |
#, php-format
|
628 |
msgid "Failed to load link details (%s)"
|
629 |
msgstr ""
|
630 |
|
631 |
-
#. #-#-#-#-# plugin.pot (Broken Link Checker 0.9.
|
632 |
#. Plugin Name of the plugin/theme
|
633 |
-
#: core.php:
|
634 |
msgid "Broken Link Checker"
|
635 |
msgstr ""
|
636 |
|
637 |
-
#: core.php:
|
638 |
#, php-format
|
639 |
msgid ""
|
640 |
"The current temporary directory is not accessible; please <a href=\"%s\">set "
|
641 |
"a different one</a>."
|
642 |
msgstr ""
|
643 |
|
644 |
-
#: core.php:
|
645 |
#, php-format
|
646 |
msgid ""
|
647 |
"Please make the directory <code>%1$s</code> writable by plugins or <a href="
|
648 |
"\"%2$s\">set a custom temporary directory</a>."
|
649 |
msgstr ""
|
650 |
|
651 |
-
#: core.php:
|
652 |
msgid "Broken Link Checker can't create a lockfile."
|
653 |
msgstr ""
|
654 |
|
655 |
-
#: core.php:
|
656 |
msgid ""
|
657 |
"The plugin uses a file-based locking mechanism to ensure that only one "
|
658 |
"instance of the resource-heavy link checking algorithm is running at any "
|
@@ -663,66 +537,72 @@ msgid ""
|
|
663 |
"specify a custom temporary directory in the plugin's settings."
|
664 |
msgstr ""
|
665 |
|
666 |
-
#: core.php:
|
667 |
msgid "PHP version"
|
668 |
msgstr ""
|
669 |
|
670 |
-
#: core.php:
|
671 |
msgid "MySQL version"
|
672 |
msgstr ""
|
673 |
|
674 |
-
#: core.php:
|
675 |
msgid ""
|
676 |
"You have an old version of CURL. Redirect detection may not work properly."
|
677 |
msgstr ""
|
678 |
|
679 |
-
#: core.php:
|
680 |
msgid "Not installed"
|
681 |
msgstr ""
|
682 |
|
683 |
-
#: core.php:
|
684 |
msgid "CURL version"
|
685 |
msgstr ""
|
686 |
|
687 |
-
#: core.php:
|
688 |
msgid "Installed"
|
689 |
msgstr ""
|
690 |
|
691 |
-
#: core.php:
|
692 |
msgid "You must have either CURL or Snoopy installed for the plugin to work!"
|
693 |
msgstr ""
|
694 |
|
695 |
-
#: core.php:
|
696 |
msgid "On"
|
697 |
msgstr ""
|
698 |
|
699 |
-
#: core.php:
|
700 |
msgid "Redirects may be detected as broken links when safe_mode is on."
|
701 |
msgstr ""
|
702 |
|
703 |
-
#: core.php:
|
704 |
msgid "Off"
|
705 |
msgstr ""
|
706 |
|
707 |
-
#: core.php:
|
708 |
#, php-format
|
709 |
msgid "On ( %s )"
|
710 |
msgstr ""
|
711 |
|
712 |
-
#: core.php:
|
713 |
msgid "Redirects may be detected as broken links when open_basedir is on."
|
714 |
msgstr ""
|
715 |
|
716 |
-
#: core.php:
|
717 |
msgid "Can't create a lockfile. Please specify a custom temporary directory."
|
718 |
msgstr ""
|
719 |
|
720 |
-
#: core.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
721 |
#, php-format
|
722 |
msgid "[%s] Broken links detected"
|
723 |
msgstr ""
|
724 |
|
725 |
-
#: core.php:
|
726 |
#, php-format
|
727 |
msgid "Broken Link Checker has detected %d new broken link on your site."
|
728 |
msgid_plural ""
|
@@ -730,447 +610,858 @@ msgid_plural ""
|
|
730 |
msgstr[0] ""
|
731 |
msgstr[1] ""
|
732 |
|
733 |
-
#: core.php:
|
734 |
#, php-format
|
735 |
msgid "Here's a list of the first %d broken links:"
|
736 |
msgid_plural "Here's a list of the first %d broken links:"
|
737 |
msgstr[0] ""
|
738 |
msgstr[1] ""
|
739 |
|
740 |
-
#: core.php:
|
741 |
msgid "Here's a list of the new broken links: "
|
742 |
msgstr ""
|
743 |
|
744 |
-
#: core.php:
|
745 |
#, php-format
|
746 |
msgid "Link text : %s"
|
747 |
msgstr ""
|
748 |
|
749 |
-
#: core.php:
|
750 |
#, php-format
|
751 |
msgid "Link URL : <a href=\"%s\">%s</a>"
|
752 |
msgstr ""
|
753 |
|
754 |
-
#: core.php:
|
755 |
#, php-format
|
756 |
msgid "Source : %s"
|
757 |
msgstr ""
|
758 |
|
759 |
-
#: core.php:
|
760 |
msgid "You can see all broken links here:"
|
761 |
msgstr ""
|
762 |
|
763 |
-
#:
|
764 |
-
msgid "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
765 |
msgstr ""
|
766 |
|
767 |
-
#: includes/admin/links-page-js.php:
|
768 |
-
msgid "
|
769 |
msgstr ""
|
770 |
|
771 |
-
#: includes/admin/links-page-js.php:
|
772 |
-
|
|
|
773 |
msgstr ""
|
774 |
|
775 |
-
#: includes/admin/links-page-js.php:
|
776 |
#, php-format
|
777 |
msgid "%d instances of the link were successfully modified."
|
778 |
msgstr ""
|
779 |
|
780 |
-
#: includes/admin/links-page-js.php:
|
781 |
#, php-format
|
782 |
msgid ""
|
783 |
"However, %d instances couldn't be edited and still point to the old URL."
|
784 |
msgstr ""
|
785 |
|
786 |
-
#: includes/admin/links-page-js.php:
|
787 |
msgid "The link could not be modified."
|
788 |
msgstr ""
|
789 |
|
790 |
-
#: includes/admin/links-page-js.php:
|
791 |
msgid "The following error(s) occured :"
|
792 |
msgstr ""
|
793 |
|
794 |
-
#: includes/admin/links-page-js.php:
|
795 |
#, php-format
|
796 |
msgid "%d instances of the link were successfully unlinked."
|
797 |
msgstr ""
|
798 |
|
799 |
-
#: includes/admin/links-page-js.php:
|
800 |
#, php-format
|
801 |
msgid "However, %d instances couldn't be removed."
|
802 |
msgstr ""
|
803 |
|
804 |
-
#: includes/admin/links-page-js.php:
|
805 |
msgid "The plugin failed to remove the link."
|
806 |
msgstr ""
|
807 |
|
808 |
-
#: includes/admin/links-page-js.php:
|
|
|
|
|
|
|
|
|
|
|
809 |
msgid "Enter a name for the new custom filter"
|
810 |
msgstr ""
|
811 |
|
812 |
-
#: includes/admin/links-page-js.php:
|
813 |
msgid ""
|
814 |
"You are about to delete the current filter.\n"
|
815 |
"'Cancel' to stop, 'OK' to delete"
|
816 |
msgstr ""
|
817 |
|
818 |
-
#: includes/admin/links-page-js.php:
|
819 |
msgid ""
|
820 |
"Are you sure you want to delete all posts, bookmarks or other items that "
|
821 |
"contain any of the selected links? This action can't be undone.\n"
|
822 |
"'Cancel' to stop, 'OK' to delete"
|
823 |
msgstr ""
|
824 |
|
825 |
-
#: includes/admin/
|
|
|
|
|
|
|
|
|
826 |
msgid "Save This Search As a Filter"
|
827 |
msgstr ""
|
828 |
|
829 |
-
#: includes/admin/search-form.php:
|
830 |
msgid "Delete This Filter"
|
831 |
msgstr ""
|
832 |
|
833 |
-
#: includes/admin/search-form.php:
|
834 |
msgid "Search"
|
835 |
msgstr ""
|
836 |
|
837 |
-
#: includes/admin/search-form.php:
|
838 |
msgid "Link text"
|
839 |
msgstr ""
|
840 |
|
841 |
-
#: includes/admin/search-form.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
842 |
msgid "Link status"
|
843 |
msgstr ""
|
844 |
|
845 |
-
#: includes/admin/search-form.php:
|
846 |
msgid "Link type"
|
847 |
msgstr ""
|
848 |
|
849 |
-
#: includes/admin/search-form.php:
|
850 |
msgid "Any"
|
851 |
msgstr ""
|
852 |
|
853 |
-
#: includes/admin/search-form.php:
|
854 |
-
msgid "
|
855 |
msgstr ""
|
856 |
|
857 |
-
#: includes/admin/search-form.php:
|
858 |
-
msgid "
|
859 |
msgstr ""
|
860 |
|
861 |
-
#: includes/admin/search-form.php:
|
862 |
-
|
|
|
863 |
msgstr ""
|
864 |
|
865 |
-
#: includes/admin/
|
866 |
-
msgid "
|
867 |
msgstr ""
|
868 |
|
869 |
-
#: includes/admin/
|
870 |
-
msgid "
|
871 |
msgstr ""
|
872 |
|
873 |
-
#: includes/admin/
|
874 |
-
msgid "
|
875 |
msgstr ""
|
876 |
|
877 |
-
#: includes/
|
878 |
-
|
879 |
-
msgid "HTTP code : %d"
|
880 |
msgstr ""
|
881 |
|
882 |
-
#: includes/
|
883 |
-
msgid "
|
884 |
msgstr ""
|
885 |
|
886 |
-
#: includes/
|
887 |
-
msgid "
|
888 |
msgstr ""
|
889 |
|
890 |
-
#: includes/
|
891 |
-
msgid "
|
892 |
msgstr ""
|
893 |
|
894 |
-
#: includes/
|
895 |
-
msgid "
|
896 |
msgstr ""
|
897 |
|
898 |
-
#: includes/
|
899 |
-
|
900 |
-
msgid "Container type '%s' not recognized"
|
901 |
msgstr ""
|
902 |
|
903 |
-
#: includes/
|
904 |
-
|
905 |
-
|
906 |
-
msgid_plural "%d '%s' have been deleted"
|
907 |
-
msgstr[0] ""
|
908 |
-
msgstr[1] ""
|
909 |
|
910 |
-
#: includes/
|
911 |
-
msgid "
|
912 |
msgstr ""
|
913 |
|
914 |
-
#: includes/
|
915 |
-
|
916 |
-
|
|
|
|
|
|
|
917 |
msgstr ""
|
918 |
|
919 |
-
#: includes/
|
920 |
#, php-format
|
921 |
-
msgid ""
|
922 |
-
"You are about to delete this link '%s'\n"
|
923 |
-
" 'Cancel' to stop, 'OK' to delete."
|
924 |
msgstr ""
|
925 |
|
926 |
-
#: includes/
|
927 |
-
|
928 |
-
msgid "Delete"
|
929 |
msgstr ""
|
930 |
|
931 |
-
#: includes/
|
932 |
-
|
933 |
-
msgid "Nothing to update"
|
934 |
msgstr ""
|
935 |
|
936 |
-
#: includes/
|
937 |
-
|
938 |
-
msgid "Updating bookmark %d failed"
|
939 |
msgstr ""
|
940 |
|
941 |
-
#: includes/
|
|
|
|
|
|
|
|
|
942 |
#, php-format
|
943 |
-
msgid "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
944 |
msgstr ""
|
945 |
|
946 |
-
#: includes/
|
|
|
|
|
|
|
|
|
947 |
#, php-format
|
948 |
-
msgid "%d
|
949 |
-
msgid_plural "%d
|
950 |
msgstr[0] ""
|
951 |
msgstr[1] ""
|
952 |
|
953 |
-
#: includes/
|
954 |
#, php-format
|
955 |
-
msgid "
|
956 |
msgstr ""
|
957 |
|
958 |
-
#: includes/
|
959 |
-
|
960 |
-
msgid "Failed to delete comment %d"
|
961 |
msgstr ""
|
962 |
|
963 |
-
#: includes/
|
964 |
-
msgid "
|
965 |
msgstr ""
|
966 |
|
967 |
-
#: includes/
|
968 |
-
msgid "
|
969 |
msgstr ""
|
970 |
|
971 |
-
#: includes/
|
972 |
-
msgid "
|
973 |
msgstr ""
|
974 |
|
975 |
-
#: includes/
|
976 |
-
|
977 |
-
msgid "Trash"
|
978 |
msgstr ""
|
979 |
|
980 |
-
#: includes/
|
981 |
-
msgid "
|
982 |
msgstr ""
|
983 |
|
984 |
-
#: includes/
|
985 |
-
|
986 |
-
msgid "View"
|
987 |
msgstr ""
|
988 |
|
989 |
-
#: includes/
|
990 |
-
|
991 |
-
|
992 |
-
msgid_plural "%d comments moved to the trash"
|
993 |
-
msgstr[0] ""
|
994 |
-
msgstr[1] ""
|
995 |
|
996 |
-
#: includes/
|
997 |
-
|
998 |
-
msgid "
|
999 |
-
|
1000 |
-
|
1001 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1002 |
|
1003 |
-
#: includes/
|
1004 |
#, php-format
|
1005 |
-
msgid "
|
1006 |
msgstr ""
|
1007 |
|
1008 |
-
#: includes/
|
|
|
|
|
|
|
|
|
1009 |
#, php-format
|
1010 |
-
msgid "
|
1011 |
msgstr ""
|
1012 |
|
1013 |
-
#: includes/
|
1014 |
-
#:
|
1015 |
-
msgid "
|
1016 |
msgstr ""
|
1017 |
|
1018 |
-
#: includes/containers/custom_field.php:
|
1019 |
msgid "Edit this item"
|
1020 |
msgstr ""
|
1021 |
|
1022 |
-
#: includes/containers/
|
1023 |
-
|
|
|
1024 |
msgstr ""
|
1025 |
|
1026 |
-
#: includes/
|
1027 |
-
|
|
|
1028 |
msgstr ""
|
1029 |
|
1030 |
-
#: includes/
|
1031 |
-
|
|
|
1032 |
msgstr ""
|
1033 |
|
1034 |
-
#: includes/
|
1035 |
#, php-format
|
1036 |
msgid ""
|
1037 |
-
"
|
1038 |
-
"
|
1039 |
msgstr ""
|
1040 |
|
1041 |
-
#: includes/
|
1042 |
#, php-format
|
1043 |
-
msgid "
|
1044 |
msgstr ""
|
1045 |
|
1046 |
-
#: includes/
|
1047 |
#, php-format
|
1048 |
-
msgid "
|
1049 |
-
|
|
|
|
|
1050 |
|
1051 |
-
#: includes/
|
1052 |
#, php-format
|
1053 |
-
msgid "%d
|
1054 |
-
msgid_plural "%d
|
1055 |
msgstr[0] ""
|
1056 |
msgstr[1] ""
|
1057 |
|
1058 |
-
#: includes/
|
1059 |
#, php-format
|
1060 |
-
msgid "%d
|
1061 |
-
msgid_plural "%d
|
1062 |
msgstr[0] ""
|
1063 |
msgstr[1] ""
|
1064 |
|
1065 |
-
#: includes/
|
1066 |
#, php-format
|
1067 |
-
msgid "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1068 |
msgstr ""
|
1069 |
|
1070 |
-
#: includes/
|
1071 |
-
|
|
|
1072 |
msgstr ""
|
1073 |
|
1074 |
-
#: includes/
|
1075 |
-
|
1076 |
-
msgid "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1077 |
msgstr ""
|
1078 |
|
1079 |
-
#: includes/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1080 |
#, php-format
|
1081 |
msgid "Container %s[%d] not found"
|
1082 |
msgstr ""
|
1083 |
|
1084 |
-
#: includes/instances.php:111 includes/instances.php:
|
1085 |
#, php-format
|
1086 |
msgid "Parser '%s' not found."
|
1087 |
msgstr ""
|
1088 |
|
1089 |
-
#: includes/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1090 |
msgid "The plugin script was terminated while trying to check the link."
|
1091 |
msgstr ""
|
1092 |
|
1093 |
-
#: includes/links.php:
|
1094 |
msgid "The plugin doesn't know how to check this type of link."
|
1095 |
msgstr ""
|
1096 |
|
1097 |
-
#: includes/links.php:
|
1098 |
msgid "Link is valid."
|
1099 |
msgstr ""
|
1100 |
|
1101 |
-
#: includes/links.php:
|
1102 |
msgid "Link is broken."
|
1103 |
msgstr ""
|
1104 |
|
1105 |
-
#: includes/links.php:
|
1106 |
msgid "Link is not valid"
|
1107 |
msgstr ""
|
1108 |
|
1109 |
-
#: includes/links.php:
|
1110 |
msgid ""
|
1111 |
"This link can not be edited because it is not used anywhere on this site."
|
1112 |
msgstr ""
|
1113 |
|
1114 |
-
#: includes/links.php:
|
1115 |
msgid "Failed to create a DB entry for the new URL."
|
1116 |
msgstr ""
|
1117 |
|
1118 |
-
#: includes/links.php:
|
1119 |
msgid "This link is not a redirect"
|
1120 |
msgstr ""
|
1121 |
|
1122 |
-
#: includes/links.php:
|
1123 |
msgid "Couldn't delete the link's database record"
|
1124 |
msgstr ""
|
1125 |
|
1126 |
-
#: includes/links.php:
|
1127 |
-
|
|
|
1128 |
msgstr ""
|
1129 |
|
1130 |
-
#: includes/links.php:
|
1131 |
-
msgid "
|
1132 |
msgstr ""
|
1133 |
|
1134 |
-
#: includes/links.php:
|
1135 |
-
msgid "
|
1136 |
msgstr ""
|
1137 |
|
1138 |
-
#: includes/links.php:
|
1139 |
-
msgid "
|
1140 |
msgstr ""
|
1141 |
|
1142 |
-
#: includes/links.php:
|
1143 |
-
|
|
|
1144 |
msgstr ""
|
1145 |
|
1146 |
-
#: includes/
|
1147 |
-
|
|
|
1148 |
msgstr ""
|
1149 |
|
1150 |
-
#: includes/
|
1151 |
-
|
|
|
1152 |
msgstr ""
|
1153 |
|
1154 |
-
#: includes/
|
1155 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1156 |
msgstr ""
|
1157 |
|
1158 |
-
#:
|
1159 |
-
msgid "
|
1160 |
msgstr ""
|
1161 |
|
1162 |
-
#:
|
1163 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1164 |
msgstr ""
|
1165 |
|
1166 |
-
#:
|
|
|
|
|
|
|
|
|
1167 |
#, php-format
|
1168 |
-
msgid "
|
|
|
|
|
1169 |
msgstr ""
|
1170 |
|
1171 |
-
#:
|
1172 |
#, php-format
|
1173 |
-
msgid "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1174 |
msgstr ""
|
1175 |
|
1176 |
#. Plugin URI of the plugin/theme
|
1 |
+
# Translation of the WordPress plugin Broken Link Checker 0.9.5-alpha by Janis Elsts.
|
2 |
# Copyright (C) 2010 Janis Elsts
|
3 |
# This file is distributed under the same license as the Broken Link Checker package.
|
4 |
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
|
6 |
#, fuzzy
|
7 |
msgid ""
|
8 |
msgstr ""
|
9 |
+
"Project-Id-Version: Broken Link Checker 0.9.5-alpha\n"
|
10 |
"Report-Msgid-Bugs-To: http://wordpress.org/tag/broken-link-checker\n"
|
11 |
+
"POT-Creation-Date: 2010-08-04 07:17+0000\n"
|
12 |
"PO-Revision-Date: 2010-MO-DA HO:MI+ZONE\n"
|
13 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14 |
"Language-Team: LANGUAGE <LL@li.org>\n"
|
15 |
"MIME-Version: 1.0\n"
|
16 |
"Content-Type: text/plain; charset=utf-8\n"
|
17 |
"Content-Transfer-Encoding: 8bit\n"
|
18 |
+
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
19 |
|
20 |
+
#: core/core.php:152 includes/admin/links-page-js.php:37
|
21 |
+
msgid "Loading..."
|
22 |
msgstr ""
|
23 |
|
24 |
+
#: core/core.php:176 includes/admin/options-page-js.php:18
|
25 |
+
msgid "[ Network error ]"
|
26 |
msgstr ""
|
27 |
|
28 |
+
#: core/core.php:201
|
29 |
+
msgid "Automatically expand the widget if broken links have been detected"
|
30 |
msgstr ""
|
31 |
|
32 |
+
#: core/core.php:459
|
33 |
+
msgid "Link Checker Settings"
|
34 |
msgstr ""
|
35 |
|
36 |
+
#: core/core.php:460
|
37 |
+
msgid "Link Checker"
|
38 |
msgstr ""
|
39 |
|
40 |
+
#: core/core.php:465 includes/link-query.php:26
|
41 |
+
msgid "Broken Links"
|
42 |
msgstr ""
|
43 |
|
44 |
+
#: core/core.php:481
|
45 |
+
msgid "View Broken Links"
|
|
|
46 |
msgstr ""
|
47 |
|
48 |
+
#: core/core.php:518
|
49 |
+
msgid "Settings"
|
|
|
|
|
|
|
50 |
msgstr ""
|
51 |
|
52 |
+
#: core/core.php:530 core/core.php:1312
|
53 |
#, php-format
|
54 |
+
msgid ""
|
55 |
+
"Error: The plugin's database tables are not up to date! (Current version : %"
|
56 |
+
"d, expected : %d)"
|
57 |
msgstr ""
|
58 |
|
59 |
+
#: core/core.php:674
|
60 |
+
msgid "Settings saved."
|
61 |
msgstr ""
|
62 |
|
63 |
+
#: core/core.php:681
|
64 |
+
msgid "Complete site recheck started."
|
65 |
msgstr ""
|
66 |
|
67 |
+
#: core/core.php:693 core/core.php:2806 includes/admin/table-printer.php:521
|
68 |
+
msgid "Details"
|
69 |
msgstr ""
|
70 |
|
71 |
+
#: core/core.php:707
|
72 |
+
msgid "General"
|
73 |
msgstr ""
|
74 |
|
75 |
+
#: core/core.php:708
|
76 |
+
msgid "Look For Links In"
|
|
|
77 |
msgstr ""
|
78 |
|
79 |
+
#: core/core.php:709
|
80 |
+
msgid "Which Links To Check"
|
81 |
msgstr ""
|
82 |
|
83 |
+
#: core/core.php:710
|
84 |
+
msgid "Protocols & APIs"
|
|
|
|
|
|
|
85 |
msgstr ""
|
86 |
|
87 |
+
#: core/core.php:711
|
88 |
+
msgid "Advanced"
|
89 |
msgstr ""
|
90 |
|
91 |
+
#: core/core.php:715
|
92 |
msgid "Broken Link Checker Options"
|
93 |
msgstr ""
|
94 |
|
95 |
+
#: core/core.php:741 includes/admin/table-printer.php:181
|
96 |
msgid "Status"
|
97 |
msgstr ""
|
98 |
|
99 |
+
#: core/core.php:743 includes/admin/options-page-js.php:56
|
100 |
msgid "Show debug info"
|
101 |
msgstr ""
|
102 |
|
103 |
+
#: core/core.php:771
|
|
|
|
|
|
|
|
|
104 |
msgid "Check each link"
|
105 |
msgstr ""
|
106 |
|
107 |
+
#: core/core.php:776
|
108 |
#, php-format
|
109 |
msgid "Every %s hours"
|
110 |
msgstr ""
|
111 |
|
112 |
+
#: core/core.php:785
|
113 |
msgid ""
|
114 |
"Existing links will be checked this often. New links will usually be checked "
|
115 |
"ASAP."
|
116 |
msgstr ""
|
117 |
|
118 |
+
#: core/core.php:792
|
119 |
+
msgid "E-mail notifications"
|
|
|
|
|
|
|
|
|
120 |
msgstr ""
|
121 |
|
122 |
+
#: core/core.php:798
|
123 |
+
msgid "Send me e-mail notifications about newly detected broken links"
|
124 |
msgstr ""
|
125 |
|
126 |
+
#: core/core.php:805
|
127 |
+
msgid "Link tweaks"
|
128 |
msgstr ""
|
129 |
|
130 |
+
#: core/core.php:811
|
131 |
+
msgid "Apply custom formatting to broken links"
|
132 |
msgstr ""
|
133 |
|
134 |
+
#: core/core.php:815 core/core.php:843
|
135 |
+
msgid "Edit CSS"
|
136 |
msgstr ""
|
137 |
|
138 |
+
#: core/core.php:839
|
139 |
+
msgid "Apply custom formatting to removed links"
|
140 |
msgstr ""
|
141 |
|
142 |
+
#: core/core.php:867
|
143 |
+
msgid "Stop search engines from following broken links"
|
|
|
144 |
msgstr ""
|
145 |
|
146 |
+
#: core/core.php:884
|
147 |
+
msgid "Look for links in"
|
148 |
msgstr ""
|
149 |
|
150 |
+
#: core/core.php:895
|
151 |
+
msgid "Post statuses"
|
152 |
msgstr ""
|
153 |
|
154 |
+
#: core/core.php:928
|
155 |
+
msgid "Link types"
|
156 |
msgstr ""
|
157 |
|
158 |
+
#: core/core.php:934
|
159 |
+
msgid "Error : All link parsers missing!"
|
160 |
msgstr ""
|
161 |
|
162 |
+
#: core/core.php:941
|
163 |
+
msgid "Exclusion list"
|
164 |
msgstr ""
|
165 |
|
166 |
+
#: core/core.php:942
|
167 |
+
msgid ""
|
168 |
+
"Don't check links where the URL contains any of these words (one per line) :"
|
169 |
msgstr ""
|
170 |
|
171 |
+
#: core/core.php:960
|
172 |
+
msgid "Check links using"
|
173 |
msgstr ""
|
174 |
|
175 |
+
#: core/core.php:979 includes/links.php:855
|
176 |
msgid "Timeout"
|
177 |
msgstr ""
|
178 |
|
179 |
+
#: core/core.php:985 core/core.php:1031 core/core.php:2933
|
180 |
#, php-format
|
181 |
msgid "%s seconds"
|
182 |
msgstr ""
|
183 |
|
184 |
+
#: core/core.php:994
|
185 |
msgid "Links that take longer than this to load will be marked as broken."
|
186 |
msgstr ""
|
187 |
|
188 |
+
#: core/core.php:1001
|
189 |
msgid "Link monitor"
|
190 |
msgstr ""
|
191 |
|
192 |
+
#: core/core.php:1009
|
193 |
msgid "Run continuously while the Dashboard is open"
|
194 |
msgstr ""
|
195 |
|
196 |
+
#: core/core.php:1017
|
197 |
msgid "Run hourly in the background"
|
198 |
msgstr ""
|
199 |
|
200 |
+
#: core/core.php:1025
|
201 |
msgid "Max. execution time"
|
202 |
msgstr ""
|
203 |
|
204 |
+
#: core/core.php:1042
|
205 |
msgid ""
|
206 |
"The plugin works by periodically launching a background job that parses your "
|
207 |
"posts for links, checks the discovered URLs, and performs other time-"
|
209 |
"may run each time before stopping."
|
210 |
msgstr ""
|
211 |
|
212 |
+
#: core/core.php:1052
|
213 |
msgid "Custom temporary directory"
|
214 |
msgstr ""
|
215 |
|
216 |
+
#: core/core.php:1061
|
217 |
msgid "OK"
|
218 |
msgstr ""
|
219 |
|
220 |
+
#: core/core.php:1064
|
221 |
msgid "Error : This directory isn't writable by PHP."
|
222 |
msgstr ""
|
223 |
|
224 |
+
#: core/core.php:1069
|
225 |
msgid "Error : This directory doesn't exist."
|
226 |
msgstr ""
|
227 |
|
228 |
+
#: core/core.php:1077
|
229 |
msgid ""
|
230 |
"Set this field if you want the plugin to use a custom directory for its "
|
231 |
"lockfiles. Otherwise, leave it blank."
|
232 |
msgstr ""
|
233 |
|
234 |
+
#: core/core.php:1084
|
235 |
msgid "Server load limit"
|
236 |
msgstr ""
|
237 |
|
238 |
+
#: core/core.php:1102
|
239 |
#, php-format
|
240 |
msgid ""
|
241 |
"Link checking will be suspended if the average <a href=\"%s\">server load</"
|
242 |
"a> rises above this number. Leave this field blank to disable load limiting."
|
243 |
msgstr ""
|
244 |
|
245 |
+
#: core/core.php:1112
|
246 |
msgid ""
|
247 |
"Load limiting only works on Linux-like systems where <code>/proc/loadavg</"
|
248 |
"code> is present and accessible."
|
249 |
msgstr ""
|
250 |
|
251 |
+
#: core/core.php:1120
|
252 |
+
msgid "Forced recheck"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
msgstr ""
|
254 |
|
255 |
+
#: core/core.php:1123
|
256 |
+
msgid "Re-check all pages"
|
|
|
|
|
|
|
|
|
257 |
msgstr ""
|
258 |
|
259 |
+
#: core/core.php:1127
|
260 |
+
msgid ""
|
261 |
+
"The \"Nuclear Option\". Click this button to make the plugin empty its link "
|
262 |
+
"database and recheck the entire site from scratch."
|
263 |
msgstr ""
|
264 |
|
265 |
+
#: core/core.php:1138
|
266 |
+
msgid "Save Changes"
|
267 |
msgstr ""
|
268 |
|
269 |
+
#: core/core.php:1183
|
270 |
+
msgid "Configure"
|
271 |
msgstr ""
|
272 |
|
273 |
+
#: core/core.php:1243
|
274 |
+
msgid "Upgrade to Pro to enable this feature"
|
275 |
msgstr ""
|
276 |
|
277 |
+
#: core/core.php:1278
|
278 |
+
msgid "Check URLs entered in these custom fields (one per line) :"
|
279 |
msgstr ""
|
280 |
|
281 |
+
#: core/core.php:1414 core/core.php:1497 core/core.php:1529
|
282 |
#, php-format
|
283 |
+
msgid "Database error : %s"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
284 |
msgstr ""
|
285 |
|
286 |
+
#: core/core.php:1479
|
287 |
msgid "You must enter a filter name!"
|
288 |
msgstr ""
|
289 |
|
290 |
+
#: core/core.php:1483
|
291 |
msgid "Invalid search query."
|
292 |
msgstr ""
|
293 |
|
294 |
+
#: core/core.php:1492
|
295 |
#, php-format
|
296 |
msgid "Filter \"%s\" created"
|
297 |
msgstr ""
|
298 |
|
299 |
+
#: core/core.php:1519
|
300 |
msgid "Filter ID not specified."
|
301 |
msgstr ""
|
302 |
|
303 |
+
#: core/core.php:1526
|
304 |
msgid "Filter deleted"
|
305 |
msgstr ""
|
306 |
|
307 |
+
#: core/core.php:1574
|
308 |
#, php-format
|
309 |
msgid "Replaced %d redirect with a direct link"
|
310 |
msgid_plural "Replaced %d redirects with direct links"
|
311 |
msgstr[0] ""
|
312 |
msgstr[1] ""
|
313 |
|
314 |
+
#: core/core.php:1585
|
315 |
#, php-format
|
316 |
msgid "Failed to fix %d redirect"
|
317 |
msgid_plural "Failed to fix %d redirects"
|
318 |
msgstr[0] ""
|
319 |
msgstr[1] ""
|
320 |
|
321 |
+
#: core/core.php:1595
|
322 |
msgid "None of the selected links are redirects!"
|
323 |
msgstr ""
|
324 |
|
325 |
+
#: core/core.php:1641
|
326 |
#, php-format
|
327 |
msgid "%d link removed"
|
328 |
msgid_plural "%d links removed"
|
329 |
msgstr[0] ""
|
330 |
msgstr[1] ""
|
331 |
|
332 |
+
#: core/core.php:1652
|
333 |
#, php-format
|
334 |
msgid "Failed to remove %d link"
|
335 |
msgid_plural "Failed to remove %d links"
|
336 |
msgstr[0] ""
|
337 |
msgstr[1] ""
|
338 |
|
339 |
+
#: core/core.php:1761
|
340 |
+
#, php-format
|
341 |
+
msgid ""
|
342 |
+
"%d item was skipped because it can't be moved to the Trash. You need to "
|
343 |
+
"delete it manually."
|
344 |
+
msgid_plural ""
|
345 |
+
"%d items were skipped because they can't be moved to the Trash. You need to "
|
346 |
+
"delete them manually."
|
347 |
+
msgstr[0] ""
|
348 |
+
msgstr[1] ""
|
349 |
+
|
350 |
+
#: core/core.php:1782
|
351 |
msgid "Didn't find anything to delete!"
|
352 |
msgstr ""
|
353 |
|
354 |
+
#: core/core.php:1810
|
355 |
#, php-format
|
356 |
msgid "%d link scheduled for rechecking"
|
357 |
msgid_plural "%d links scheduled for rechecking"
|
358 |
msgstr[0] ""
|
359 |
msgstr[1] ""
|
360 |
|
361 |
+
#: core/core.php:1855 core/core.php:2460
|
362 |
msgid "This link was manually marked as working by the user."
|
363 |
msgstr ""
|
364 |
|
365 |
+
#: core/core.php:1862
|
366 |
#, php-format
|
367 |
msgid "Couldn't modify link %d"
|
368 |
msgstr ""
|
369 |
|
370 |
+
#: core/core.php:1873
|
371 |
#, php-format
|
372 |
msgid "%d link marked as not broken"
|
373 |
msgid_plural "%d links marked as not broken"
|
374 |
msgstr[0] ""
|
375 |
msgstr[1] ""
|
376 |
|
377 |
+
#: core/core.php:1913
|
378 |
+
msgid "Table columns"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
379 |
msgstr ""
|
380 |
|
381 |
+
#: core/core.php:1932
|
382 |
+
msgid "Show on screen"
|
|
|
383 |
msgstr ""
|
384 |
|
385 |
+
#: core/core.php:1939
|
386 |
+
msgid "links"
|
387 |
msgstr ""
|
388 |
|
389 |
+
#: core/core.php:1940 includes/admin/table-printer.php:134
|
390 |
+
msgid "Apply"
|
391 |
msgstr ""
|
392 |
|
393 |
+
#: core/core.php:1944
|
394 |
+
msgid "Misc"
|
395 |
msgstr ""
|
396 |
|
397 |
+
#: core/core.php:1959
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
398 |
#, php-format
|
399 |
+
msgid "Highlight links broken for at least %s days"
|
400 |
msgstr ""
|
401 |
|
402 |
+
#: core/core.php:1968
|
403 |
+
msgid "Color-code status codes"
|
404 |
msgstr ""
|
405 |
|
406 |
+
#: core/core.php:1985 core/core.php:2445 core/core.php:2481 core/core.php:2544
|
407 |
+
msgid "You're not allowed to do that!"
|
408 |
msgstr ""
|
409 |
|
410 |
+
#: core/core.php:2326
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
411 |
msgid "View broken links"
|
412 |
msgstr ""
|
413 |
|
414 |
+
#: core/core.php:2327
|
415 |
#, php-format
|
416 |
msgid "Found %d broken link"
|
417 |
msgid_plural "Found %d broken links"
|
418 |
msgstr[0] ""
|
419 |
msgstr[1] ""
|
420 |
|
421 |
+
#: core/core.php:2333
|
422 |
msgid "No broken links found."
|
423 |
msgstr ""
|
424 |
|
425 |
+
#: core/core.php:2340
|
426 |
#, php-format
|
427 |
msgid "%d URL in the work queue"
|
428 |
msgid_plural "%d URLs in the work queue"
|
429 |
msgstr[0] ""
|
430 |
msgstr[1] ""
|
431 |
|
432 |
+
#: core/core.php:2343
|
433 |
msgid "No URLs in the work queue."
|
434 |
msgstr ""
|
435 |
|
436 |
+
#: core/core.php:2349
|
437 |
#, php-format
|
438 |
msgid "Detected %d unique URL"
|
439 |
msgid_plural "Detected %d unique URLs"
|
440 |
msgstr[0] ""
|
441 |
msgstr[1] ""
|
442 |
|
443 |
+
#: core/core.php:2350
|
444 |
#, php-format
|
445 |
msgid "in %d link"
|
446 |
msgid_plural "in %d links"
|
447 |
msgstr[0] ""
|
448 |
msgstr[1] ""
|
449 |
|
450 |
+
#: core/core.php:2355
|
451 |
msgid "and still searching..."
|
452 |
msgstr ""
|
453 |
|
454 |
+
#: core/core.php:2361
|
455 |
msgid "Searching your blog for links..."
|
456 |
msgstr ""
|
457 |
|
458 |
+
#: core/core.php:2363
|
459 |
msgid "No links detected."
|
460 |
msgstr ""
|
461 |
|
462 |
+
#: core/core.php:2389
|
463 |
+
msgctxt "current load"
|
464 |
+
msgid "Unknown"
|
465 |
msgstr ""
|
466 |
|
467 |
+
#: core/core.php:2453 core/core.php:2491 core/core.php:2554
|
468 |
#, php-format
|
469 |
msgid "Oops, I can't find the link %d"
|
470 |
msgstr ""
|
471 |
|
472 |
+
#: core/core.php:2466
|
473 |
msgid "Oops, couldn't modify the link!"
|
474 |
msgstr ""
|
475 |
|
476 |
+
#: core/core.php:2469 core/core.php:2580
|
477 |
msgid "Error : link_id not specified"
|
478 |
msgstr ""
|
479 |
|
480 |
+
#: core/core.php:2501
|
481 |
msgid "Oops, the new URL is invalid!"
|
482 |
msgstr ""
|
483 |
|
484 |
+
#: core/core.php:2512 core/core.php:2563
|
485 |
msgid "An unexpected error occured!"
|
486 |
msgstr ""
|
487 |
|
488 |
+
#: core/core.php:2530
|
489 |
msgid "Error : link_id or new_url not specified"
|
490 |
msgstr ""
|
491 |
|
492 |
+
#: core/core.php:2589
|
493 |
msgid "You don't have sufficient privileges to access this information!"
|
494 |
msgstr ""
|
495 |
|
496 |
+
#: core/core.php:2602
|
497 |
msgid "Error : link ID not specified"
|
498 |
msgstr ""
|
499 |
|
500 |
+
#: core/core.php:2616
|
501 |
#, php-format
|
502 |
msgid "Failed to load link details (%s)"
|
503 |
msgstr ""
|
504 |
|
505 |
+
#. #-#-#-#-# plugin.pot (Broken Link Checker 0.9.5-alpha) #-#-#-#-#
|
506 |
#. Plugin Name of the plugin/theme
|
507 |
+
#: core/core.php:2778
|
508 |
msgid "Broken Link Checker"
|
509 |
msgstr ""
|
510 |
|
511 |
+
#: core/core.php:2792
|
512 |
#, php-format
|
513 |
msgid ""
|
514 |
"The current temporary directory is not accessible; please <a href=\"%s\">set "
|
515 |
"a different one</a>."
|
516 |
msgstr ""
|
517 |
|
518 |
+
#: core/core.php:2797
|
519 |
#, php-format
|
520 |
msgid ""
|
521 |
"Please make the directory <code>%1$s</code> writable by plugins or <a href="
|
522 |
"\"%2$s\">set a custom temporary directory</a>."
|
523 |
msgstr ""
|
524 |
|
525 |
+
#: core/core.php:2804
|
526 |
msgid "Broken Link Checker can't create a lockfile."
|
527 |
msgstr ""
|
528 |
|
529 |
+
#: core/core.php:2809
|
530 |
msgid ""
|
531 |
"The plugin uses a file-based locking mechanism to ensure that only one "
|
532 |
"instance of the resource-heavy link checking algorithm is running at any "
|
537 |
"specify a custom temporary directory in the plugin's settings."
|
538 |
msgstr ""
|
539 |
|
540 |
+
#: core/core.php:2828
|
541 |
msgid "PHP version"
|
542 |
msgstr ""
|
543 |
|
544 |
+
#: core/core.php:2834
|
545 |
msgid "MySQL version"
|
546 |
msgstr ""
|
547 |
|
548 |
+
#: core/core.php:2847
|
549 |
msgid ""
|
550 |
"You have an old version of CURL. Redirect detection may not work properly."
|
551 |
msgstr ""
|
552 |
|
553 |
+
#: core/core.php:2859 core/core.php:2875 core/core.php:2880
|
554 |
msgid "Not installed"
|
555 |
msgstr ""
|
556 |
|
557 |
+
#: core/core.php:2862
|
558 |
msgid "CURL version"
|
559 |
msgstr ""
|
560 |
|
561 |
+
#: core/core.php:2868
|
562 |
msgid "Installed"
|
563 |
msgstr ""
|
564 |
|
565 |
+
#: core/core.php:2881
|
566 |
msgid "You must have either CURL or Snoopy installed for the plugin to work!"
|
567 |
msgstr ""
|
568 |
|
569 |
+
#: core/core.php:2892
|
570 |
msgid "On"
|
571 |
msgstr ""
|
572 |
|
573 |
+
#: core/core.php:2893
|
574 |
msgid "Redirects may be detected as broken links when safe_mode is on."
|
575 |
msgstr ""
|
576 |
|
577 |
+
#: core/core.php:2898 core/core.php:2912
|
578 |
msgid "Off"
|
579 |
msgstr ""
|
580 |
|
581 |
+
#: core/core.php:2906
|
582 |
#, php-format
|
583 |
msgid "On ( %s )"
|
584 |
msgstr ""
|
585 |
|
586 |
+
#: core/core.php:2907
|
587 |
msgid "Redirects may be detected as broken links when open_basedir is on."
|
588 |
msgstr ""
|
589 |
|
590 |
+
#: core/core.php:2926
|
591 |
msgid "Can't create a lockfile. Please specify a custom temporary directory."
|
592 |
msgstr ""
|
593 |
|
594 |
+
#: core/core.php:2950
|
595 |
+
msgid ""
|
596 |
+
"If this value is zero even after several page reloads you have probably "
|
597 |
+
"encountered a bug."
|
598 |
+
msgstr ""
|
599 |
+
|
600 |
+
#: core/core.php:3006
|
601 |
#, php-format
|
602 |
msgid "[%s] Broken links detected"
|
603 |
msgstr ""
|
604 |
|
605 |
+
#: core/core.php:3012
|
606 |
#, php-format
|
607 |
msgid "Broken Link Checker has detected %d new broken link on your site."
|
608 |
msgid_plural ""
|
610 |
msgstr[0] ""
|
611 |
msgstr[1] ""
|
612 |
|
613 |
+
#: core/core.php:3027
|
614 |
#, php-format
|
615 |
msgid "Here's a list of the first %d broken links:"
|
616 |
msgid_plural "Here's a list of the first %d broken links:"
|
617 |
msgstr[0] ""
|
618 |
msgstr[1] ""
|
619 |
|
620 |
+
#: core/core.php:3035
|
621 |
msgid "Here's a list of the new broken links: "
|
622 |
msgstr ""
|
623 |
|
624 |
+
#: core/core.php:3047
|
625 |
#, php-format
|
626 |
msgid "Link text : %s"
|
627 |
msgstr ""
|
628 |
|
629 |
+
#: core/core.php:3048
|
630 |
#, php-format
|
631 |
msgid "Link URL : <a href=\"%s\">%s</a>"
|
632 |
msgstr ""
|
633 |
|
634 |
+
#: core/core.php:3049
|
635 |
#, php-format
|
636 |
msgid "Source : %s"
|
637 |
msgstr ""
|
638 |
|
639 |
+
#: core/core.php:3063
|
640 |
msgid "You can see all broken links here:"
|
641 |
msgstr ""
|
642 |
|
643 |
+
#: core/init.php:230
|
644 |
+
msgid "Once Weekly"
|
645 |
+
msgstr ""
|
646 |
+
|
647 |
+
#: core/init.php:236
|
648 |
+
msgid "Twice a Month"
|
649 |
+
msgstr ""
|
650 |
+
|
651 |
+
#: core/init.php:259
|
652 |
+
msgid "Broken Link Checker installation failed"
|
653 |
+
msgstr ""
|
654 |
+
|
655 |
+
#: includes/admin/db-upgrade.php:95
|
656 |
+
#, php-format
|
657 |
+
msgid "Failed to delete old DB tables. Database error : %s"
|
658 |
msgstr ""
|
659 |
|
660 |
+
#: includes/admin/links-page-js.php:58 includes/admin/links-page-js.php:301
|
661 |
+
msgid "Wait..."
|
662 |
msgstr ""
|
663 |
|
664 |
+
#: includes/admin/links-page-js.php:99 includes/admin/table-printer.php:530
|
665 |
+
#: includes/admin/table-printer.php:620
|
666 |
+
msgid "Not broken"
|
667 |
msgstr ""
|
668 |
|
669 |
+
#: includes/admin/links-page-js.php:213
|
670 |
#, php-format
|
671 |
msgid "%d instances of the link were successfully modified."
|
672 |
msgstr ""
|
673 |
|
674 |
+
#: includes/admin/links-page-js.php:219
|
675 |
#, php-format
|
676 |
msgid ""
|
677 |
"However, %d instances couldn't be edited and still point to the old URL."
|
678 |
msgstr ""
|
679 |
|
680 |
+
#: includes/admin/links-page-js.php:225
|
681 |
msgid "The link could not be modified."
|
682 |
msgstr ""
|
683 |
|
684 |
+
#: includes/admin/links-page-js.php:228 includes/admin/links-page-js.php:353
|
685 |
msgid "The following error(s) occured :"
|
686 |
msgstr ""
|
687 |
|
688 |
+
#: includes/admin/links-page-js.php:339
|
689 |
#, php-format
|
690 |
msgid "%d instances of the link were successfully unlinked."
|
691 |
msgstr ""
|
692 |
|
693 |
+
#: includes/admin/links-page-js.php:345
|
694 |
#, php-format
|
695 |
msgid "However, %d instances couldn't be removed."
|
696 |
msgstr ""
|
697 |
|
698 |
+
#: includes/admin/links-page-js.php:350
|
699 |
msgid "The plugin failed to remove the link."
|
700 |
msgstr ""
|
701 |
|
702 |
+
#: includes/admin/links-page-js.php:361 includes/admin/table-printer.php:249
|
703 |
+
#: includes/admin/table-printer.php:524 includes/admin/table-printer.php:614
|
704 |
+
msgid "Unlink"
|
705 |
+
msgstr ""
|
706 |
+
|
707 |
+
#: includes/admin/links-page-js.php:405
|
708 |
msgid "Enter a name for the new custom filter"
|
709 |
msgstr ""
|
710 |
|
711 |
+
#: includes/admin/links-page-js.php:416
|
712 |
msgid ""
|
713 |
"You are about to delete the current filter.\n"
|
714 |
"'Cancel' to stop, 'OK' to delete"
|
715 |
msgstr ""
|
716 |
|
717 |
+
#: includes/admin/links-page-js.php:439
|
718 |
msgid ""
|
719 |
"Are you sure you want to delete all posts, bookmarks or other items that "
|
720 |
"contain any of the selected links? This action can't be undone.\n"
|
721 |
"'Cancel' to stop, 'OK' to delete"
|
722 |
msgstr ""
|
723 |
|
724 |
+
#: includes/admin/options-page-js.php:54
|
725 |
+
msgid "Hide debug info"
|
726 |
+
msgstr ""
|
727 |
+
|
728 |
+
#: includes/admin/search-form.php:16
|
729 |
msgid "Save This Search As a Filter"
|
730 |
msgstr ""
|
731 |
|
732 |
+
#: includes/admin/search-form.php:26
|
733 |
msgid "Delete This Filter"
|
734 |
msgstr ""
|
735 |
|
736 |
+
#: includes/admin/search-form.php:32 includes/link-query.php:53
|
737 |
msgid "Search"
|
738 |
msgstr ""
|
739 |
|
740 |
+
#: includes/admin/search-form.php:42
|
741 |
msgid "Link text"
|
742 |
msgstr ""
|
743 |
|
744 |
+
#: includes/admin/search-form.php:45 includes/admin/table-printer.php:176
|
745 |
+
#: includes/admin/table-printer.php:186
|
746 |
+
msgid "URL"
|
747 |
+
msgstr ""
|
748 |
+
|
749 |
+
#: includes/admin/search-form.php:48 includes/admin/table-printer.php:422
|
750 |
+
msgid "HTTP code"
|
751 |
+
msgstr ""
|
752 |
+
|
753 |
+
#: includes/admin/search-form.php:51
|
754 |
msgid "Link status"
|
755 |
msgstr ""
|
756 |
|
757 |
+
#: includes/admin/search-form.php:68 includes/admin/search-form.php:85
|
758 |
msgid "Link type"
|
759 |
msgstr ""
|
760 |
|
761 |
+
#: includes/admin/search-form.php:70
|
762 |
msgid "Any"
|
763 |
msgstr ""
|
764 |
|
765 |
+
#: includes/admin/search-form.php:74
|
766 |
+
msgid "Links used in"
|
767 |
msgstr ""
|
768 |
|
769 |
+
#: includes/admin/search-form.php:112
|
770 |
+
msgid "Search Links"
|
771 |
msgstr ""
|
772 |
|
773 |
+
#: includes/admin/search-form.php:113 includes/admin/table-printer.php:540
|
774 |
+
#: includes/admin/table-printer.php:628 includes/admin/table-printer.php:634
|
775 |
+
msgid "Cancel"
|
776 |
msgstr ""
|
777 |
|
778 |
+
#: includes/admin/table-printer.php:147
|
779 |
+
msgid "Compact View"
|
780 |
msgstr ""
|
781 |
|
782 |
+
#: includes/admin/table-printer.php:148
|
783 |
+
msgid "Detailed View"
|
784 |
msgstr ""
|
785 |
|
786 |
+
#: includes/admin/table-printer.php:165
|
787 |
+
msgid "Source"
|
788 |
msgstr ""
|
789 |
|
790 |
+
#: includes/admin/table-printer.php:171 includes/admin/table-printer.php:197
|
791 |
+
msgid "Link Text"
|
|
|
792 |
msgstr ""
|
793 |
|
794 |
+
#: includes/admin/table-printer.php:191
|
795 |
+
msgid "Used in"
|
796 |
msgstr ""
|
797 |
|
798 |
+
#: includes/admin/table-printer.php:245
|
799 |
+
msgid "Bulk Actions"
|
800 |
msgstr ""
|
801 |
|
802 |
+
#: includes/admin/table-printer.php:246
|
803 |
+
msgid "Recheck"
|
804 |
msgstr ""
|
805 |
|
806 |
+
#: includes/admin/table-printer.php:247
|
807 |
+
msgid "Fix redirects"
|
808 |
msgstr ""
|
809 |
|
810 |
+
#: includes/admin/table-printer.php:248
|
811 |
+
msgid "Mark as not broken"
|
|
|
812 |
msgstr ""
|
813 |
|
814 |
+
#: includes/admin/table-printer.php:252
|
815 |
+
msgid "Move sources to Trash"
|
816 |
+
msgstr ""
|
|
|
|
|
|
|
817 |
|
818 |
+
#: includes/admin/table-printer.php:254
|
819 |
+
msgid "Delete sources"
|
820 |
msgstr ""
|
821 |
|
822 |
+
#: includes/admin/table-printer.php:269
|
823 |
+
msgid "«"
|
824 |
+
msgstr ""
|
825 |
+
|
826 |
+
#: includes/admin/table-printer.php:270
|
827 |
+
msgid "»"
|
828 |
msgstr ""
|
829 |
|
830 |
+
#: includes/admin/table-printer.php:278
|
831 |
#, php-format
|
832 |
+
msgid "Displaying %s–%s of <span class=\"current-link-count\">%s</span>"
|
|
|
|
|
833 |
msgstr ""
|
834 |
|
835 |
+
#: includes/admin/table-printer.php:407
|
836 |
+
msgid "Post published on"
|
|
|
837 |
msgstr ""
|
838 |
|
839 |
+
#: includes/admin/table-printer.php:412
|
840 |
+
msgid "Link last checked"
|
|
|
841 |
msgstr ""
|
842 |
|
843 |
+
#: includes/admin/table-printer.php:416
|
844 |
+
msgid "Never"
|
|
|
845 |
msgstr ""
|
846 |
|
847 |
+
#: includes/admin/table-printer.php:427
|
848 |
+
msgid "Response time"
|
849 |
+
msgstr ""
|
850 |
+
|
851 |
+
#: includes/admin/table-printer.php:429
|
852 |
#, php-format
|
853 |
+
msgid "%2.3f seconds"
|
854 |
+
msgstr ""
|
855 |
+
|
856 |
+
#: includes/admin/table-printer.php:432
|
857 |
+
msgid "Final URL"
|
858 |
+
msgstr ""
|
859 |
+
|
860 |
+
#: includes/admin/table-printer.php:437
|
861 |
+
msgid "Redirect count"
|
862 |
msgstr ""
|
863 |
|
864 |
+
#: includes/admin/table-printer.php:442
|
865 |
+
msgid "Instance count"
|
866 |
+
msgstr ""
|
867 |
+
|
868 |
+
#: includes/admin/table-printer.php:451
|
869 |
#, php-format
|
870 |
+
msgid "This link has failed %d time."
|
871 |
+
msgid_plural "This link has failed %d times."
|
872 |
msgstr[0] ""
|
873 |
msgstr[1] ""
|
874 |
|
875 |
+
#: includes/admin/table-printer.php:459
|
876 |
#, php-format
|
877 |
+
msgid "This link has been broken for %s."
|
878 |
msgstr ""
|
879 |
|
880 |
+
#: includes/admin/table-printer.php:470
|
881 |
+
msgid "Log"
|
|
|
882 |
msgstr ""
|
883 |
|
884 |
+
#: includes/admin/table-printer.php:506 includes/admin/table-printer.php:657
|
885 |
+
msgid "[An orphaned link! This is a bug.]"
|
886 |
msgstr ""
|
887 |
|
888 |
+
#: includes/admin/table-printer.php:521 includes/admin/table-printer.php:557
|
889 |
+
msgid "Show more info about this link"
|
890 |
msgstr ""
|
891 |
|
892 |
+
#: includes/admin/table-printer.php:523 includes/admin/table-printer.php:613
|
893 |
+
msgid "Remove this link from all posts"
|
894 |
msgstr ""
|
895 |
|
896 |
+
#: includes/admin/table-printer.php:529 includes/admin/table-printer.php:619
|
897 |
+
msgid "Remove this link from the list of broken links and mark it as valid"
|
|
|
898 |
msgstr ""
|
899 |
|
900 |
+
#: includes/admin/table-printer.php:534 includes/admin/table-printer.php:611
|
901 |
+
msgid "Edit link URL"
|
902 |
msgstr ""
|
903 |
|
904 |
+
#: includes/admin/table-printer.php:534 includes/admin/table-printer.php:611
|
905 |
+
msgid "Edit URL"
|
|
|
906 |
msgstr ""
|
907 |
|
908 |
+
#: includes/admin/table-printer.php:540 includes/admin/table-printer.php:628
|
909 |
+
msgid "Cancel URL editing"
|
910 |
+
msgstr ""
|
|
|
|
|
|
|
911 |
|
912 |
+
#: includes/admin/table-printer.php:575
|
913 |
+
msgctxt "checked how long ago"
|
914 |
+
msgid "Checked"
|
915 |
+
msgstr ""
|
916 |
+
|
917 |
+
#: includes/admin/table-printer.php:591
|
918 |
+
msgid "Broken for"
|
919 |
+
msgstr ""
|
920 |
+
|
921 |
+
#: includes/admin/table-printer.php:635
|
922 |
+
msgid "Update URL"
|
923 |
+
msgstr ""
|
924 |
+
|
925 |
+
#: includes/any-post.php:384 modules/containers/blogroll.php:46
|
926 |
+
#: modules/containers/comment.php:153 modules/containers/custom_field.php:197
|
927 |
+
msgid "Edit"
|
928 |
+
msgstr ""
|
929 |
+
|
930 |
+
#: includes/any-post.php:392 modules/containers/custom_field.php:203
|
931 |
+
msgid "Move this item to the Trash"
|
932 |
+
msgstr ""
|
933 |
+
|
934 |
+
#: includes/any-post.php:394 modules/containers/custom_field.php:205
|
935 |
+
msgid "Trash"
|
936 |
+
msgstr ""
|
937 |
+
|
938 |
+
#: includes/any-post.php:399 modules/containers/custom_field.php:210
|
939 |
+
msgid "Delete this item permanently"
|
940 |
+
msgstr ""
|
941 |
+
|
942 |
+
#: includes/any-post.php:401 modules/containers/blogroll.php:47
|
943 |
+
#: modules/containers/custom_field.php:212
|
944 |
+
msgid "Delete"
|
945 |
+
msgstr ""
|
946 |
|
947 |
+
#: includes/any-post.php:414
|
948 |
#, php-format
|
949 |
+
msgid "Preview “%s”"
|
950 |
msgstr ""
|
951 |
|
952 |
+
#: includes/any-post.php:415
|
953 |
+
msgid "Preview"
|
954 |
+
msgstr ""
|
955 |
+
|
956 |
+
#: includes/any-post.php:422
|
957 |
#, php-format
|
958 |
+
msgid "View “%s”"
|
959 |
msgstr ""
|
960 |
|
961 |
+
#: includes/any-post.php:423 modules/containers/comment.php:166
|
962 |
+
#: modules/containers/custom_field.php:217
|
963 |
+
msgid "View"
|
964 |
msgstr ""
|
965 |
|
966 |
+
#: includes/any-post.php:442 modules/containers/custom_field.php:197
|
967 |
msgid "Edit this item"
|
968 |
msgstr ""
|
969 |
|
970 |
+
#: includes/any-post.php:506 modules/containers/blogroll.php:83
|
971 |
+
#: modules/containers/comment.php:43
|
972 |
+
msgid "Nothing to update"
|
973 |
msgstr ""
|
974 |
|
975 |
+
#: includes/any-post.php:516
|
976 |
+
#, php-format
|
977 |
+
msgid "Updating post %d failed"
|
978 |
msgstr ""
|
979 |
|
980 |
+
#: includes/any-post.php:551 modules/containers/custom_field.php:284
|
981 |
+
#, php-format
|
982 |
+
msgid "Failed to delete post \"%s\" (%d)"
|
983 |
msgstr ""
|
984 |
|
985 |
+
#: includes/any-post.php:570 modules/containers/custom_field.php:303
|
986 |
#, php-format
|
987 |
msgid ""
|
988 |
+
"Can't move post \"%s\" (%d) to the trash because the trash feature is "
|
989 |
+
"disabled"
|
990 |
msgstr ""
|
991 |
|
992 |
+
#: includes/any-post.php:590 modules/containers/custom_field.php:322
|
993 |
#, php-format
|
994 |
+
msgid "Failed to move post \"%s\" (%d) to the trash"
|
995 |
msgstr ""
|
996 |
|
997 |
+
#: includes/any-post.php:698
|
998 |
#, php-format
|
999 |
+
msgid "%d post deleted."
|
1000 |
+
msgid_plural "%d posts deleted."
|
1001 |
+
msgstr[0] ""
|
1002 |
+
msgstr[1] ""
|
1003 |
|
1004 |
+
#: includes/any-post.php:700
|
1005 |
#, php-format
|
1006 |
+
msgid "%d page deleted."
|
1007 |
+
msgid_plural "%d pages deleted."
|
1008 |
msgstr[0] ""
|
1009 |
msgstr[1] ""
|
1010 |
|
1011 |
+
#: includes/any-post.php:702
|
1012 |
#, php-format
|
1013 |
+
msgid "%d \"%s\" deleted."
|
1014 |
+
msgid_plural "%d \"%s\" deleted."
|
1015 |
msgstr[0] ""
|
1016 |
msgstr[1] ""
|
1017 |
|
1018 |
+
#: includes/any-post.php:721
|
1019 |
#, php-format
|
1020 |
+
msgid "%d post moved to the Trash."
|
1021 |
+
msgid_plural "%d posts moved to the Trash."
|
1022 |
+
msgstr[0] ""
|
1023 |
+
msgstr[1] ""
|
1024 |
+
|
1025 |
+
#: includes/any-post.php:723
|
1026 |
+
#, php-format
|
1027 |
+
msgid "%d page moved to the Trash."
|
1028 |
+
msgid_plural "%d pages moved to the Trash."
|
1029 |
+
msgstr[0] ""
|
1030 |
+
msgstr[1] ""
|
1031 |
+
|
1032 |
+
#: includes/any-post.php:725
|
1033 |
+
#, php-format
|
1034 |
+
msgid "%d \"%s\" moved to the Trash."
|
1035 |
+
msgid_plural "%d \"%s\" moved to the Trash."
|
1036 |
+
msgstr[0] ""
|
1037 |
+
msgstr[1] ""
|
1038 |
+
|
1039 |
+
#: includes/containers.php:122
|
1040 |
+
#, php-format
|
1041 |
+
msgid "%d '%s' has been deleted"
|
1042 |
+
msgid_plural "%d '%s' have been deleted"
|
1043 |
+
msgstr[0] ""
|
1044 |
+
msgstr[1] ""
|
1045 |
+
|
1046 |
+
#: includes/containers.php:876 includes/containers.php:894
|
1047 |
+
#, php-format
|
1048 |
+
msgid "Container type '%s' not recognized"
|
1049 |
msgstr ""
|
1050 |
|
1051 |
+
#: includes/extra-strings.php:2
|
1052 |
+
msgctxt "module name"
|
1053 |
+
msgid "Basic HTTP"
|
1054 |
msgstr ""
|
1055 |
|
1056 |
+
#: includes/extra-strings.php:3
|
1057 |
+
msgctxt "module name"
|
1058 |
+
msgid "Blogroll items"
|
1059 |
+
msgstr ""
|
1060 |
+
|
1061 |
+
#: includes/extra-strings.php:4
|
1062 |
+
msgctxt "module name"
|
1063 |
+
msgid "Comments"
|
1064 |
+
msgstr ""
|
1065 |
+
|
1066 |
+
#: includes/extra-strings.php:5
|
1067 |
+
msgctxt "module name"
|
1068 |
+
msgid "Custom fields"
|
1069 |
+
msgstr ""
|
1070 |
+
|
1071 |
+
#: includes/extra-strings.php:6
|
1072 |
+
msgctxt "module name"
|
1073 |
+
msgid "Embedded DailyMotion videos"
|
1074 |
+
msgstr ""
|
1075 |
+
|
1076 |
+
#: includes/extra-strings.php:7
|
1077 |
+
msgctxt "module name"
|
1078 |
+
msgid "Embedded Vimeo videos"
|
1079 |
+
msgstr ""
|
1080 |
+
|
1081 |
+
#: includes/extra-strings.php:8
|
1082 |
+
msgctxt "module name"
|
1083 |
+
msgid "Embedded YouTube videos"
|
1084 |
+
msgstr ""
|
1085 |
+
|
1086 |
+
#: includes/extra-strings.php:9
|
1087 |
+
msgctxt "module name"
|
1088 |
+
msgid "HTML images"
|
1089 |
+
msgstr ""
|
1090 |
+
|
1091 |
+
#: includes/extra-strings.php:10
|
1092 |
+
msgctxt "module name"
|
1093 |
+
msgid "HTML links"
|
1094 |
+
msgstr ""
|
1095 |
+
|
1096 |
+
#: includes/extra-strings.php:11
|
1097 |
+
msgctxt "module name"
|
1098 |
+
msgid "MediaFire API"
|
1099 |
+
msgstr ""
|
1100 |
+
|
1101 |
+
#: includes/extra-strings.php:12
|
1102 |
+
msgctxt "module name"
|
1103 |
+
msgid "MegaUpload API"
|
1104 |
msgstr ""
|
1105 |
|
1106 |
+
#: includes/extra-strings.php:13
|
1107 |
+
msgctxt "module name"
|
1108 |
+
msgid "Plaintext URLs"
|
1109 |
+
msgstr ""
|
1110 |
+
|
1111 |
+
#: includes/extra-strings.php:14
|
1112 |
+
msgctxt "module name"
|
1113 |
+
msgid "RapidShare API"
|
1114 |
+
msgstr ""
|
1115 |
+
|
1116 |
+
#: includes/extra-strings.php:15
|
1117 |
+
msgctxt "module name"
|
1118 |
+
msgid "YouTube API"
|
1119 |
+
msgstr ""
|
1120 |
+
|
1121 |
+
#: includes/extra-strings.php:16
|
1122 |
+
msgctxt "module name"
|
1123 |
+
msgid "Posts"
|
1124 |
+
msgstr ""
|
1125 |
+
|
1126 |
+
#: includes/extra-strings.php:17
|
1127 |
+
msgctxt "module name"
|
1128 |
+
msgid "Pages"
|
1129 |
+
msgstr ""
|
1130 |
+
|
1131 |
+
#: includes/instances.php:102 includes/instances.php:158
|
1132 |
#, php-format
|
1133 |
msgid "Container %s[%d] not found"
|
1134 |
msgstr ""
|
1135 |
|
1136 |
+
#: includes/instances.php:111 includes/instances.php:167
|
1137 |
#, php-format
|
1138 |
msgid "Parser '%s' not found."
|
1139 |
msgstr ""
|
1140 |
|
1141 |
+
#: includes/link-query.php:25
|
1142 |
+
msgid "Broken"
|
1143 |
+
msgstr ""
|
1144 |
+
|
1145 |
+
#: includes/link-query.php:27
|
1146 |
+
msgid "No broken links found"
|
1147 |
+
msgstr ""
|
1148 |
+
|
1149 |
+
#: includes/link-query.php:34
|
1150 |
+
msgid "Redirects"
|
1151 |
+
msgstr ""
|
1152 |
+
|
1153 |
+
#: includes/link-query.php:35
|
1154 |
+
msgid "Redirected Links"
|
1155 |
+
msgstr ""
|
1156 |
+
|
1157 |
+
#: includes/link-query.php:36
|
1158 |
+
msgid "No redirects found"
|
1159 |
+
msgstr ""
|
1160 |
+
|
1161 |
+
#: includes/link-query.php:44
|
1162 |
+
msgid "All"
|
1163 |
+
msgstr ""
|
1164 |
+
|
1165 |
+
#: includes/link-query.php:45
|
1166 |
+
msgid "Detected Links"
|
1167 |
+
msgstr ""
|
1168 |
+
|
1169 |
+
#: includes/link-query.php:46
|
1170 |
+
msgid "No links found (yet)"
|
1171 |
+
msgstr ""
|
1172 |
+
|
1173 |
+
#: includes/link-query.php:54
|
1174 |
+
msgid "Search Results"
|
1175 |
+
msgstr ""
|
1176 |
+
|
1177 |
+
#: includes/link-query.php:55 includes/link-query.php:106
|
1178 |
+
msgid "No links found for your query"
|
1179 |
+
msgstr ""
|
1180 |
+
|
1181 |
+
#: includes/links.php:213
|
1182 |
msgid "The plugin script was terminated while trying to check the link."
|
1183 |
msgstr ""
|
1184 |
|
1185 |
+
#: includes/links.php:259
|
1186 |
msgid "The plugin doesn't know how to check this type of link."
|
1187 |
msgstr ""
|
1188 |
|
1189 |
+
#: includes/links.php:347
|
1190 |
msgid "Link is valid."
|
1191 |
msgstr ""
|
1192 |
|
1193 |
+
#: includes/links.php:349
|
1194 |
msgid "Link is broken."
|
1195 |
msgstr ""
|
1196 |
|
1197 |
+
#: includes/links.php:562 includes/links.php:664 includes/links.php:699
|
1198 |
msgid "Link is not valid"
|
1199 |
msgstr ""
|
1200 |
|
1201 |
+
#: includes/links.php:579
|
1202 |
msgid ""
|
1203 |
"This link can not be edited because it is not used anywhere on this site."
|
1204 |
msgstr ""
|
1205 |
|
1206 |
+
#: includes/links.php:605
|
1207 |
msgid "Failed to create a DB entry for the new URL."
|
1208 |
msgstr ""
|
1209 |
|
1210 |
+
#: includes/links.php:677
|
1211 |
msgid "This link is not a redirect"
|
1212 |
msgstr ""
|
1213 |
|
1214 |
+
#: includes/links.php:726 includes/links.php:763
|
1215 |
msgid "Couldn't delete the link's database record"
|
1216 |
msgstr ""
|
1217 |
|
1218 |
+
#: includes/links.php:837
|
1219 |
+
msgctxt "link status"
|
1220 |
+
msgid "Unknown"
|
1221 |
msgstr ""
|
1222 |
|
1223 |
+
#: includes/links.php:851 modules/checkers/http.php:255
|
1224 |
+
msgid "Unknown Error"
|
1225 |
msgstr ""
|
1226 |
|
1227 |
+
#: includes/links.php:875
|
1228 |
+
msgid "Not checked"
|
1229 |
msgstr ""
|
1230 |
|
1231 |
+
#: includes/links.php:878
|
1232 |
+
msgid "False positive"
|
1233 |
msgstr ""
|
1234 |
|
1235 |
+
#: includes/links.php:881
|
1236 |
+
msgctxt "link status"
|
1237 |
+
msgid "OK"
|
1238 |
msgstr ""
|
1239 |
|
1240 |
+
#: includes/parsers.php:106
|
1241 |
+
#, php-format
|
1242 |
+
msgid "Editing is not implemented in the '%s' parser"
|
1243 |
msgstr ""
|
1244 |
|
1245 |
+
#: includes/parsers.php:121
|
1246 |
+
#, php-format
|
1247 |
+
msgid "Unlinking is not implemented in the '%s' parser"
|
1248 |
msgstr ""
|
1249 |
|
1250 |
+
#: includes/utility-class.php:291
|
1251 |
+
#, php-format
|
1252 |
+
msgid "%d second"
|
1253 |
+
msgid_plural "%d seconds"
|
1254 |
+
msgstr[0] ""
|
1255 |
+
msgstr[1] ""
|
1256 |
+
|
1257 |
+
#: includes/utility-class.php:292
|
1258 |
+
#, php-format
|
1259 |
+
msgid "%d second ago"
|
1260 |
+
msgid_plural "%d seconds ago"
|
1261 |
+
msgstr[0] ""
|
1262 |
+
msgstr[1] ""
|
1263 |
+
|
1264 |
+
#: includes/utility-class.php:295
|
1265 |
+
#, php-format
|
1266 |
+
msgid "%d minute"
|
1267 |
+
msgid_plural "%d minutes"
|
1268 |
+
msgstr[0] ""
|
1269 |
+
msgstr[1] ""
|
1270 |
+
|
1271 |
+
#: includes/utility-class.php:296
|
1272 |
+
#, php-format
|
1273 |
+
msgid "%d minute ago"
|
1274 |
+
msgid_plural "%d minutes ago"
|
1275 |
+
msgstr[0] ""
|
1276 |
+
msgstr[1] ""
|
1277 |
+
|
1278 |
+
#: includes/utility-class.php:299
|
1279 |
+
#, php-format
|
1280 |
+
msgid "%d hour"
|
1281 |
+
msgid_plural "%d hours"
|
1282 |
+
msgstr[0] ""
|
1283 |
+
msgstr[1] ""
|
1284 |
+
|
1285 |
+
#: includes/utility-class.php:300
|
1286 |
+
#, php-format
|
1287 |
+
msgid "%d hour ago"
|
1288 |
+
msgid_plural "%d hours ago"
|
1289 |
+
msgstr[0] ""
|
1290 |
+
msgstr[1] ""
|
1291 |
+
|
1292 |
+
#: includes/utility-class.php:303
|
1293 |
+
#, php-format
|
1294 |
+
msgid "%d day"
|
1295 |
+
msgid_plural "%d days"
|
1296 |
+
msgstr[0] ""
|
1297 |
+
msgstr[1] ""
|
1298 |
+
|
1299 |
+
#: includes/utility-class.php:304
|
1300 |
+
#, php-format
|
1301 |
+
msgid "%d day ago"
|
1302 |
+
msgid_plural "%d days ago"
|
1303 |
+
msgstr[0] ""
|
1304 |
+
msgstr[1] ""
|
1305 |
+
|
1306 |
+
#: includes/utility-class.php:307
|
1307 |
+
#, php-format
|
1308 |
+
msgid "%d month"
|
1309 |
+
msgid_plural "%d months"
|
1310 |
+
msgstr[0] ""
|
1311 |
+
msgstr[1] ""
|
1312 |
+
|
1313 |
+
#: includes/utility-class.php:308
|
1314 |
+
#, php-format
|
1315 |
+
msgid "%d month ago"
|
1316 |
+
msgid_plural "%d months ago"
|
1317 |
+
msgstr[0] ""
|
1318 |
+
msgstr[1] ""
|
1319 |
+
|
1320 |
+
#: modules/checkers/http.php:241
|
1321 |
+
msgid "Server Not Found"
|
1322 |
msgstr ""
|
1323 |
|
1324 |
+
#: modules/checkers/http.php:250
|
1325 |
+
msgid "Connection Failed"
|
1326 |
msgstr ""
|
1327 |
|
1328 |
+
#: modules/checkers/http.php:284 modules/checkers/http.php:354
|
1329 |
+
#, php-format
|
1330 |
+
msgid "HTTP code : %d"
|
1331 |
+
msgstr ""
|
1332 |
+
|
1333 |
+
#: modules/checkers/http.php:286 modules/checkers/http.php:356
|
1334 |
+
msgid "(No response)"
|
1335 |
+
msgstr ""
|
1336 |
+
|
1337 |
+
#: modules/checkers/http.php:292
|
1338 |
+
msgid "Most likely the connection timed out or the domain doesn't exist."
|
1339 |
+
msgstr ""
|
1340 |
+
|
1341 |
+
#: modules/checkers/http.php:363
|
1342 |
+
msgid "Request timed out."
|
1343 |
+
msgstr ""
|
1344 |
+
|
1345 |
+
#: modules/checkers/http.php:381
|
1346 |
+
msgid "Using Snoopy"
|
1347 |
+
msgstr ""
|
1348 |
+
|
1349 |
+
#: modules/containers/blogroll.php:21
|
1350 |
+
msgid "Bookmark"
|
1351 |
msgstr ""
|
1352 |
|
1353 |
+
#: modules/containers/blogroll.php:27 modules/containers/blogroll.php:46
|
1354 |
+
msgid "Edit this bookmark"
|
1355 |
+
msgstr ""
|
1356 |
+
|
1357 |
+
#: modules/containers/blogroll.php:47
|
1358 |
#, php-format
|
1359 |
+
msgid ""
|
1360 |
+
"You are about to delete this link '%s'\n"
|
1361 |
+
" 'Cancel' to stop, 'OK' to delete."
|
1362 |
msgstr ""
|
1363 |
|
1364 |
+
#: modules/containers/blogroll.php:97
|
1365 |
#, php-format
|
1366 |
+
msgid "Updating bookmark %d failed"
|
1367 |
+
msgstr ""
|
1368 |
+
|
1369 |
+
#: modules/containers/blogroll.php:128
|
1370 |
+
#, php-format
|
1371 |
+
msgid "Failed to delete blogroll link \"%s\" (%d)"
|
1372 |
+
msgstr ""
|
1373 |
+
|
1374 |
+
#: modules/containers/blogroll.php:299
|
1375 |
+
#, php-format
|
1376 |
+
msgid "%d blogroll link deleted."
|
1377 |
+
msgid_plural "%d blogroll links deleted."
|
1378 |
+
msgstr[0] ""
|
1379 |
+
msgstr[1] ""
|
1380 |
+
|
1381 |
+
#: modules/containers/comment.php:53
|
1382 |
+
#, php-format
|
1383 |
+
msgid "Updating comment %d failed"
|
1384 |
+
msgstr ""
|
1385 |
+
|
1386 |
+
#: modules/containers/comment.php:74
|
1387 |
+
#, php-format
|
1388 |
+
msgid "Failed to delete comment %d"
|
1389 |
+
msgstr ""
|
1390 |
+
|
1391 |
+
#: modules/containers/comment.php:95
|
1392 |
+
#, php-format
|
1393 |
+
msgid "Can't move comment %d to the trash"
|
1394 |
+
msgstr ""
|
1395 |
+
|
1396 |
+
#: modules/containers/comment.php:153 modules/containers/comment.php:195
|
1397 |
+
msgid "Edit comment"
|
1398 |
+
msgstr ""
|
1399 |
+
|
1400 |
+
#: modules/containers/comment.php:160
|
1401 |
+
msgid "Delete Permanently"
|
1402 |
+
msgstr ""
|
1403 |
+
|
1404 |
+
#: modules/containers/comment.php:162
|
1405 |
+
msgid "Move this comment to the trash"
|
1406 |
+
msgstr ""
|
1407 |
+
|
1408 |
+
#: modules/containers/comment.php:162
|
1409 |
+
msgctxt "verb"
|
1410 |
+
msgid "Trash"
|
1411 |
+
msgstr ""
|
1412 |
+
|
1413 |
+
#: modules/containers/comment.php:166
|
1414 |
+
msgid "View comment"
|
1415 |
+
msgstr ""
|
1416 |
+
|
1417 |
+
#: modules/containers/comment.php:183
|
1418 |
+
msgid "Comment"
|
1419 |
+
msgstr ""
|
1420 |
+
|
1421 |
+
#: modules/containers/comment.php:360
|
1422 |
+
#, php-format
|
1423 |
+
msgid "%d comment has been deleted."
|
1424 |
+
msgid_plural "%d comments have been deleted."
|
1425 |
+
msgstr[0] ""
|
1426 |
+
msgstr[1] ""
|
1427 |
+
|
1428 |
+
#: modules/containers/comment.php:379
|
1429 |
+
#, php-format
|
1430 |
+
msgid "%d comment moved to the Trash."
|
1431 |
+
msgid_plural "%d comments moved to the Trash."
|
1432 |
+
msgstr[0] ""
|
1433 |
+
msgstr[1] ""
|
1434 |
+
|
1435 |
+
#: modules/containers/custom_field.php:84
|
1436 |
+
#, php-format
|
1437 |
+
msgid "Failed to update the meta field '%s' on %s [%d]"
|
1438 |
+
msgstr ""
|
1439 |
+
|
1440 |
+
#: modules/containers/custom_field.php:110
|
1441 |
+
#, php-format
|
1442 |
+
msgid "Failed to delete the meta field '%s' on %s [%d]"
|
1443 |
+
msgstr ""
|
1444 |
+
|
1445 |
+
#: modules/containers/custom_field.php:187
|
1446 |
+
msgid "Edit this post"
|
1447 |
+
msgstr ""
|
1448 |
+
|
1449 |
+
#: modules/containers/custom_field.php:217
|
1450 |
+
#, php-format
|
1451 |
+
msgid "View \"%s\""
|
1452 |
+
msgstr ""
|
1453 |
+
|
1454 |
+
#: modules/containers/dummy.php:34 modules/containers/dummy.php:45
|
1455 |
+
#, php-format
|
1456 |
+
msgid "I don't know how to edit a '%s' [%d]."
|
1457 |
+
msgstr ""
|
1458 |
+
|
1459 |
+
#: modules/parsers/image.php:156
|
1460 |
+
msgid "Image"
|
1461 |
+
msgstr ""
|
1462 |
+
|
1463 |
+
#: modules/parsers/metadata.php:117
|
1464 |
+
msgid "Custom field"
|
1465 |
msgstr ""
|
1466 |
|
1467 |
#. Plugin URI of the plugin/theme
|
{includes → modules}/checkers/http.php
RENAMED
@@ -1,14 +1,75 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
/**
|
4 |
* Base class for checkers that deal with HTTP(S) URLs.
|
5 |
*
|
6 |
* @package Broken Link Checker
|
7 |
* @access public
|
8 |
*/
|
9 |
-
class
|
10 |
-
|
11 |
-
var $priority = -1;
|
12 |
|
13 |
function clean_url($url){
|
14 |
$url = html_entity_decode($url);
|
@@ -19,7 +80,7 @@ class blcHttpChecker extends blcChecker{
|
|
19 |
'/&/', //convert improper HTML entities
|
20 |
'/([\?&]sid=\w+)$/i' //remove another flavour of session ID
|
21 |
),
|
22 |
-
array('','','&',''
|
23 |
$url
|
24 |
);
|
25 |
$url = trim($url);
|
@@ -57,7 +118,7 @@ class blcHttpChecker extends blcChecker{
|
|
57 |
function urlencodefix($url){
|
58 |
//TODO: Remove/fix this. Probably not a good idea to "fix" invalid URLs like that.
|
59 |
return preg_replace_callback(
|
60 |
-
'|[^a-z0-9\+\-\/\\#:.,;=?!&%@()$\|*~]|i',
|
61 |
create_function('$str','return rawurlencode($str[0]);'),
|
62 |
$url
|
63 |
);
|
@@ -65,8 +126,7 @@ class blcHttpChecker extends blcChecker{
|
|
65 |
|
66 |
}
|
67 |
|
68 |
-
|
69 |
-
class blcCurlHttp extends blcHttpChecker {
|
70 |
|
71 |
var $last_headers = '';
|
72 |
|
@@ -105,6 +165,7 @@ class blcCurlHttp extends blcHttpChecker {
|
|
105 |
|
106 |
//Set the timeout
|
107 |
curl_setopt($ch, CURLOPT_TIMEOUT, $conf->options['timeout']);
|
|
|
108 |
|
109 |
//Set the proxy configuration. The user can provide this in wp-config.php
|
110 |
if (defined('WP_PROXY_HOST')) {
|
@@ -129,8 +190,8 @@ class blcCurlHttp extends blcHttpChecker {
|
|
129 |
|
130 |
$parts = @parse_url($url);
|
131 |
if( $parts['scheme'] == 'https' ){
|
132 |
-
|
133 |
-
curl_setopt($ch,
|
134 |
$nobody = false; //Can't use HEAD with HTTPS.
|
135 |
}
|
136 |
|
@@ -152,11 +213,9 @@ class blcCurlHttp extends blcHttpChecker {
|
|
152 |
$measured_request_duration = microtime_float() - $start_time;
|
153 |
|
154 |
$info = curl_getinfo($ch);
|
155 |
-
curl_close($ch);
|
156 |
|
157 |
//Store the results
|
158 |
$result['http_code'] = intval( $info['http_code'] );
|
159 |
-
$result['timeout'] = ($result['http_code'] == 0); //If the code is 0 then it's probably a timeout
|
160 |
$result['final_url'] = $info['url'];
|
161 |
$result['request_duration'] = $info['total_time'];
|
162 |
$result['redirect_count'] = $info['redirect_count'];
|
@@ -168,7 +227,46 @@ class blcCurlHttp extends blcHttpChecker {
|
|
168 |
}
|
169 |
|
170 |
//Determine if the link counts as "broken"
|
171 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
|
173 |
if ( $nobody && $result['broken'] ){
|
174 |
//The site in question might be expecting GET instead of HEAD, so lets retry the request
|
@@ -189,7 +287,6 @@ class blcCurlHttp extends blcHttpChecker {
|
|
189 |
}
|
190 |
|
191 |
//Build the log from HTTP code and headers.
|
192 |
-
//TODO: Put some kind of a color-coded error explanation at the top of the log, not a cryptic HTTP code.
|
193 |
$log .= '=== ';
|
194 |
if ( $result['http_code'] ){
|
195 |
$log .= sprintf( __('HTTP code : %d', 'broken-link-checker'), $result['http_code']);
|
@@ -224,13 +321,15 @@ class blcCurlHttp extends blcHttpChecker {
|
|
224 |
|
225 |
}
|
226 |
|
227 |
-
class blcSnoopyHttp extends
|
228 |
|
229 |
function check($url){
|
230 |
-
$url = $this->clean_url($url);
|
|
|
231 |
|
232 |
$result = array(
|
233 |
'broken' => false,
|
|
|
234 |
);
|
235 |
$log = '';
|
236 |
|
@@ -244,8 +343,9 @@ class blcSnoopyHttp extends blcHttpChecker {
|
|
244 |
$snoopy = new Snoopy;
|
245 |
$snoopy->read_timeout = $timeout; //read timeout in seconds
|
246 |
$snoopy->agent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"; //masquerade as IE 7
|
|
|
247 |
$snoopy->maxlength = 1024*5; //load up to 5 kilobytes
|
248 |
-
$snoopy->fetch($url);
|
249 |
|
250 |
$result['request_duration'] = microtime_float() - $start_time;
|
251 |
|
@@ -303,23 +403,4 @@ class blcSnoopyHttp extends blcHttpChecker {
|
|
303 |
|
304 |
}
|
305 |
|
306 |
-
if ( function_exists('curl_init') ) {
|
307 |
-
blc_register_checker('blcCurlHttp');
|
308 |
-
} else {
|
309 |
-
//Try to load Snoopy.
|
310 |
-
if ( !class_exists('Snoopy') ){
|
311 |
-
$snoopy_file = ABSPATH. WPINC . '/class-snoopy.php';
|
312 |
-
if (file_exists($snoopy_file) ){
|
313 |
-
include $snoopy_file;
|
314 |
-
}
|
315 |
-
}
|
316 |
-
|
317 |
-
//If Snoopy is available, it will be used in place of CURL.
|
318 |
-
if ( class_exists('Snoopy') ){
|
319 |
-
blc_register_checker('blcSnoopyHttp');
|
320 |
-
}
|
321 |
-
}
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
?>
|
1 |
<?php
|
2 |
|
3 |
+
/*
|
4 |
+
Plugin Name: Basic HTTP
|
5 |
+
Description: Check all links that have the HTTP/HTTPS protocol.
|
6 |
+
Version: 1.0
|
7 |
+
Author: Janis Elsts
|
8 |
+
|
9 |
+
ModuleID: http
|
10 |
+
ModuleCategory: checker
|
11 |
+
ModuleContext: on-demand
|
12 |
+
ModuleLazyInit: true
|
13 |
+
ModuleClassName: blcHttpChecker
|
14 |
+
ModulePriority: -1
|
15 |
+
*/
|
16 |
+
|
17 |
+
//TODO: Rewrite sub-classes as transports, not stand-alone checkers
|
18 |
+
class blcHttpChecker extends blcChecker {
|
19 |
+
var $implementation;
|
20 |
+
|
21 |
+
function init(){
|
22 |
+
parent::init();
|
23 |
+
|
24 |
+
if ( function_exists('curl_init') ) {
|
25 |
+
$this->implementation = new blcCurlHttp(
|
26 |
+
$this->module_id,
|
27 |
+
$this->cached_header,
|
28 |
+
$this->plugin_conf,
|
29 |
+
$this->module_manager
|
30 |
+
);
|
31 |
+
} else {
|
32 |
+
//Try to load Snoopy.
|
33 |
+
if ( !class_exists('Snoopy') ){
|
34 |
+
$snoopy_file = ABSPATH. WPINC . '/class-snoopy.php';
|
35 |
+
if (file_exists($snoopy_file) ){
|
36 |
+
include $snoopy_file;
|
37 |
+
}
|
38 |
+
}
|
39 |
+
|
40 |
+
//If Snoopy is available, it will be used in place of CURL.
|
41 |
+
if ( class_exists('Snoopy') ){
|
42 |
+
$this->implementation = new blcSnoopyHttp(
|
43 |
+
$this->module_id,
|
44 |
+
$this->cached_header,
|
45 |
+
$this->plugin_conf,
|
46 |
+
$this->module_manager
|
47 |
+
);
|
48 |
+
}
|
49 |
+
}
|
50 |
+
}
|
51 |
+
|
52 |
+
function can_check($url, $parsed){
|
53 |
+
if ( isset($this->implementation) ){
|
54 |
+
return $this->implementation->can_check($url, $parsed);
|
55 |
+
} else {
|
56 |
+
return false;
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
function check($url, $use_get = false){
|
61 |
+
return $this->implementation->check($url, $use_get);
|
62 |
+
}
|
63 |
+
}
|
64 |
+
|
65 |
+
|
66 |
/**
|
67 |
* Base class for checkers that deal with HTTP(S) URLs.
|
68 |
*
|
69 |
* @package Broken Link Checker
|
70 |
* @access public
|
71 |
*/
|
72 |
+
class blcHttpCheckerBase extends blcChecker {
|
|
|
|
|
73 |
|
74 |
function clean_url($url){
|
75 |
$url = html_entity_decode($url);
|
80 |
'/&/', //convert improper HTML entities
|
81 |
'/([\?&]sid=\w+)$/i' //remove another flavour of session ID
|
82 |
),
|
83 |
+
array('','','&',''),
|
84 |
$url
|
85 |
);
|
86 |
$url = trim($url);
|
118 |
function urlencodefix($url){
|
119 |
//TODO: Remove/fix this. Probably not a good idea to "fix" invalid URLs like that.
|
120 |
return preg_replace_callback(
|
121 |
+
'|[^a-z0-9\+\-\/\\#:.,;=?!&%@()$\|*~_]|i',
|
122 |
create_function('$str','return rawurlencode($str[0]);'),
|
123 |
$url
|
124 |
);
|
126 |
|
127 |
}
|
128 |
|
129 |
+
class blcCurlHttp extends blcHttpCheckerBase {
|
|
|
130 |
|
131 |
var $last_headers = '';
|
132 |
|
165 |
|
166 |
//Set the timeout
|
167 |
curl_setopt($ch, CURLOPT_TIMEOUT, $conf->options['timeout']);
|
168 |
+
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $conf->options['timeout']);
|
169 |
|
170 |
//Set the proxy configuration. The user can provide this in wp-config.php
|
171 |
if (defined('WP_PROXY_HOST')) {
|
190 |
|
191 |
$parts = @parse_url($url);
|
192 |
if( $parts['scheme'] == 'https' ){
|
193 |
+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //Required to make HTTPS URLs work.
|
194 |
+
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
195 |
$nobody = false; //Can't use HEAD with HTTPS.
|
196 |
}
|
197 |
|
213 |
$measured_request_duration = microtime_float() - $start_time;
|
214 |
|
215 |
$info = curl_getinfo($ch);
|
|
|
216 |
|
217 |
//Store the results
|
218 |
$result['http_code'] = intval( $info['http_code'] );
|
|
|
219 |
$result['final_url'] = $info['url'];
|
220 |
$result['request_duration'] = $info['total_time'];
|
221 |
$result['redirect_count'] = $info['redirect_count'];
|
227 |
}
|
228 |
|
229 |
//Determine if the link counts as "broken"
|
230 |
+
if ( $result['http_code'] == 0 ){
|
231 |
+
$result['broken'] = true;
|
232 |
+
|
233 |
+
$error_code = curl_errno($ch);
|
234 |
+
$log .= sprintf( "%s [Error #%d]\n", curl_error($ch), $error_code );
|
235 |
+
|
236 |
+
//We only handle a couple of CURL error codes; most are highly esoteric.
|
237 |
+
//libcurl "CURLE_" constants can't be used here because some of them have
|
238 |
+
//different names or values in PHP.
|
239 |
+
switch( $error_code ) {
|
240 |
+
case 6: //CURLE_COULDNT_RESOLVE_HOST
|
241 |
+
$result['status_code'] = BLC_LINK_STATUS_WARNING;
|
242 |
+
$result['status_text'] = __('Server Not Found', 'broken-link-checker');
|
243 |
+
break;
|
244 |
+
|
245 |
+
case 28: //CURLE_OPERATION_TIMEDOUT
|
246 |
+
$result['timeout'] = true;
|
247 |
+
break;
|
248 |
+
|
249 |
+
case 7: //CURLE_COULDNT_CONNECT
|
250 |
+
//More often than not, this error code indicates that the connection attempt
|
251 |
+
//timed out. This heuristic tries to distinguish between connections that fail
|
252 |
+
//due to timeouts and those that fail due to other causes.
|
253 |
+
if ( $result['request_duration'] >= 0.9*$conf->options['timeout'] ){
|
254 |
+
$result['timeout'] = true;
|
255 |
+
} else {
|
256 |
+
$result['status_code'] = BLC_LINK_STATUS_WARNING;
|
257 |
+
$result['status_text'] = __('Connection Failed', 'broken-link-checker');
|
258 |
+
}
|
259 |
+
break;
|
260 |
+
|
261 |
+
default:
|
262 |
+
$result['status_code'] = BLC_LINK_STATUS_WARNING;
|
263 |
+
$result['status_text'] = __('Unknown Error', 'broken-link-checker');
|
264 |
+
}
|
265 |
+
|
266 |
+
} else {
|
267 |
+
$result['broken'] = $this->is_error_code($result['http_code']);
|
268 |
+
}
|
269 |
+
curl_close($ch);
|
270 |
|
271 |
if ( $nobody && $result['broken'] ){
|
272 |
//The site in question might be expecting GET instead of HEAD, so lets retry the request
|
287 |
}
|
288 |
|
289 |
//Build the log from HTTP code and headers.
|
|
|
290 |
$log .= '=== ';
|
291 |
if ( $result['http_code'] ){
|
292 |
$log .= sprintf( __('HTTP code : %d', 'broken-link-checker'), $result['http_code']);
|
321 |
|
322 |
}
|
323 |
|
324 |
+
class blcSnoopyHttp extends blcHttpCheckerBase {
|
325 |
|
326 |
function check($url){
|
327 |
+
$url = $this->clean_url($url);
|
328 |
+
//Note : Snoopy doesn't work too well with HTTPS URLs.
|
329 |
|
330 |
$result = array(
|
331 |
'broken' => false,
|
332 |
+
'timeout' => false,
|
333 |
);
|
334 |
$log = '';
|
335 |
|
343 |
$snoopy = new Snoopy;
|
344 |
$snoopy->read_timeout = $timeout; //read timeout in seconds
|
345 |
$snoopy->agent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"; //masquerade as IE 7
|
346 |
+
$snoopy->referer = get_option('home'); //valid referer helps circumvent some hotlink protection schemes
|
347 |
$snoopy->maxlength = 1024*5; //load up to 5 kilobytes
|
348 |
+
$snoopy->fetch( $this->urlencodefix($url) );
|
349 |
|
350 |
$result['request_duration'] = microtime_float() - $start_time;
|
351 |
|
403 |
|
404 |
}
|
405 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
406 |
?>
|
{includes → modules}/containers/blogroll.php
RENAMED
@@ -1,10 +1,18 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
class blcBookmark extends blcContainer{
|
4 |
|
5 |
-
|
6 |
-
|
7 |
-
function ui_get_source($container_field, $context = 'display'){
|
8 |
$bookmark = $this->get_wrapped_object();
|
9 |
|
10 |
$image = sprintf(
|
@@ -29,7 +37,7 @@ class blcBookmark extends blcContainer{
|
|
29 |
|
30 |
function ui_get_action_links($container_field){
|
31 |
//Inline action links for bookmarks
|
32 |
-
$bookmark =
|
33 |
|
34 |
$delete_url = admin_url( wp_nonce_url("link.php?action=delete&link_id={$this->container_id}", 'delete-bookmark_' . $this->container_id) );
|
35 |
|
@@ -124,7 +132,15 @@ class blcBookmark extends blcContainer{
|
|
124 |
|
125 |
return new WP_Error( 'delete_failed', $msg );
|
126 |
};
|
127 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
|
129 |
/**
|
130 |
* Get the default link text. For bookmarks, this is the bookmark name.
|
@@ -150,6 +166,7 @@ class blcBookmark extends blcContainer{
|
|
150 |
|
151 |
class blcBookmarkManager extends blcContainerManager{
|
152 |
var $container_class_name = 'blcBookmark';
|
|
|
153 |
|
154 |
/**
|
155 |
* Set up hooks that monitor added/modified/deleted bookmarks.
|
@@ -157,6 +174,8 @@ class blcBookmarkManager extends blcContainerManager{
|
|
157 |
* @return void
|
158 |
*/
|
159 |
function init(){
|
|
|
|
|
160 |
add_action('add_link', array(&$this,'hook_add_link'));
|
161 |
add_action('edit_link', array(&$this,'hook_edit_link'));
|
162 |
add_action('delete_link', array(&$this,'hook_delete_link'));
|
@@ -231,7 +250,7 @@ class blcBookmarkManager extends blcContainerManager{
|
|
231 |
* @return void
|
232 |
*/
|
233 |
function hook_add_link( $link_id ){
|
234 |
-
$container =
|
235 |
$container->mark_as_unsynched();
|
236 |
}
|
237 |
|
@@ -253,7 +272,7 @@ class blcBookmarkManager extends blcContainerManager{
|
|
253 |
*/
|
254 |
function hook_delete_link( $link_id ){
|
255 |
//Get the container object.
|
256 |
-
$container =
|
257 |
//Get the link(s) associated with it.
|
258 |
$links = $container->get_links();
|
259 |
|
@@ -277,8 +296,8 @@ class blcBookmarkManager extends blcContainerManager{
|
|
277 |
function ui_bulk_delete_message($n){
|
278 |
return sprintf(
|
279 |
_n(
|
280 |
-
"%d blogroll link deleted",
|
281 |
-
"%d blogroll links deleted",
|
282 |
$n,
|
283 |
'broken-link-checker'
|
284 |
),
|
@@ -287,6 +306,4 @@ class blcBookmarkManager extends blcContainerManager{
|
|
287 |
}
|
288 |
}
|
289 |
|
290 |
-
blc_register_container('blogroll', 'blcBookmarkManager');
|
291 |
-
|
292 |
?>
|
1 |
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: Blogroll items
|
4 |
+
Description:
|
5 |
+
Version: 1.0
|
6 |
+
Author: Janis Elsts
|
7 |
+
|
8 |
+
ModuleID: blogroll
|
9 |
+
ModuleCategory: container
|
10 |
+
ModuleClassName: blcBookmarkManager
|
11 |
+
*/
|
12 |
|
13 |
class blcBookmark extends blcContainer{
|
14 |
|
15 |
+
function ui_get_source($container_field = '', $context = 'display'){
|
|
|
|
|
16 |
$bookmark = $this->get_wrapped_object();
|
17 |
|
18 |
$image = sprintf(
|
37 |
|
38 |
function ui_get_action_links($container_field){
|
39 |
//Inline action links for bookmarks
|
40 |
+
$bookmark = &$this->get_wrapped_object();
|
41 |
|
42 |
$delete_url = admin_url( wp_nonce_url("link.php?action=delete&link_id={$this->container_id}", 'delete-bookmark_' . $this->container_id) );
|
43 |
|
132 |
|
133 |
return new WP_Error( 'delete_failed', $msg );
|
134 |
};
|
135 |
+
}
|
136 |
+
|
137 |
+
function current_user_can_delete(){
|
138 |
+
return current_user_can('manage_links');
|
139 |
+
}
|
140 |
+
|
141 |
+
function can_be_trashed(){
|
142 |
+
return false;
|
143 |
+
}
|
144 |
|
145 |
/**
|
146 |
* Get the default link text. For bookmarks, this is the bookmark name.
|
166 |
|
167 |
class blcBookmarkManager extends blcContainerManager{
|
168 |
var $container_class_name = 'blcBookmark';
|
169 |
+
var $fields = array('link_url' => 'url_field');
|
170 |
|
171 |
/**
|
172 |
* Set up hooks that monitor added/modified/deleted bookmarks.
|
174 |
* @return void
|
175 |
*/
|
176 |
function init(){
|
177 |
+
parent::init();
|
178 |
+
|
179 |
add_action('add_link', array(&$this,'hook_add_link'));
|
180 |
add_action('edit_link', array(&$this,'hook_edit_link'));
|
181 |
add_action('delete_link', array(&$this,'hook_delete_link'));
|
250 |
* @return void
|
251 |
*/
|
252 |
function hook_add_link( $link_id ){
|
253 |
+
$container = & blcContainerHelper::get_container( array($this->container_type, $link_id) );
|
254 |
$container->mark_as_unsynched();
|
255 |
}
|
256 |
|
272 |
*/
|
273 |
function hook_delete_link( $link_id ){
|
274 |
//Get the container object.
|
275 |
+
$container = & blcContainerHelper::get_container( array($this->container_type, $link_id) );
|
276 |
//Get the link(s) associated with it.
|
277 |
$links = $container->get_links();
|
278 |
|
296 |
function ui_bulk_delete_message($n){
|
297 |
return sprintf(
|
298 |
_n(
|
299 |
+
"%d blogroll link deleted.",
|
300 |
+
"%d blogroll links deleted.",
|
301 |
$n,
|
302 |
'broken-link-checker'
|
303 |
),
|
306 |
}
|
307 |
}
|
308 |
|
|
|
|
|
309 |
?>
|
{includes → modules}/containers/comment.php
RENAMED
@@ -1,10 +1,17 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
class blcComment extends blcContainer{
|
4 |
-
var $fields = array(
|
5 |
-
'comment_author_url' => 'url_field',
|
6 |
-
'comment_content' => 'html',
|
7 |
-
);
|
8 |
|
9 |
/**
|
10 |
* Retrieve the comment wrapped by this container.
|
@@ -38,7 +45,6 @@ class blcComment extends blcContainer{
|
|
38 |
}
|
39 |
|
40 |
$data = (array)$this->wrapped_object;
|
41 |
-
//FB::info($data, sprintf("Attempting to update comment %d with data", $this->container_id));
|
42 |
if ( wp_update_comment($data) ){
|
43 |
return true;
|
44 |
} else {
|
@@ -56,17 +62,56 @@ class blcComment extends blcContainer{
|
|
56 |
* @return bool|WP_error
|
57 |
*/
|
58 |
function delete_wrapped_object(){
|
59 |
-
if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
return true;
|
61 |
} else {
|
62 |
return new WP_Error(
|
63 |
-
'
|
64 |
sprintf(
|
65 |
-
__('
|
66 |
$this->container_id
|
67 |
)
|
68 |
);
|
69 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
}
|
71 |
|
72 |
/**
|
@@ -112,9 +157,9 @@ class blcComment extends blcContainer{
|
|
112 |
$delete_url = esc_url( admin_url("comment.php?action=deletecomment&p=$post->ID&c=$comment->comment_ID&$del_nonce") );
|
113 |
|
114 |
if ( !constant('EMPTY_TRASH_DAYS') ) {
|
115 |
-
$actions['delete'] = "<a href='$delete_url' class='delete:the-comment-list:comment-$comment->comment_ID::delete=1 delete vim-d vim-destructive'>" . __('Delete Permanently') . '</a>';
|
116 |
} else {
|
117 |
-
$actions['trash'] = "<a href='$trash_url' class='delete:the-comment-list:comment-$comment->comment_ID::trash=1 delete vim-d vim-destructive' title='" . esc_attr__( 'Move this comment to the trash' ) . "'>" . _x('Trash', 'verb') . '</a>';
|
118 |
}
|
119 |
}
|
120 |
|
@@ -123,7 +168,7 @@ class blcComment extends blcContainer{
|
|
123 |
return $actions;
|
124 |
}
|
125 |
|
126 |
-
function ui_get_source($container_field, $context = 'display'){
|
127 |
//Display a comment icon.
|
128 |
if ( $container_field == 'comment_author_url' ){
|
129 |
$image = 'user_comment.png';
|
@@ -168,7 +213,14 @@ class blcComment extends blcContainer{
|
|
168 |
class blcCommentManager extends blcContainerManager {
|
169 |
var $container_class_name = 'blcComment';
|
170 |
|
|
|
|
|
|
|
|
|
|
|
171 |
function init(){
|
|
|
|
|
172 |
add_action('edit_comment', array(&$this, 'hook_modified_comment'));
|
173 |
add_action('unspammed_comment', array(&$this, 'hook_modified_comment'));
|
174 |
add_action('untrashed_comment', array(&$this, 'hook_modified_comment'));
|
@@ -180,20 +232,23 @@ class blcCommentManager extends blcContainerManager {
|
|
180 |
add_action('trashed_comment', array(&$this, 'hook_deleted_comment'));
|
181 |
|
182 |
add_action('transition_comment_status', array(&$this, 'hook_comment_status'), 10, 3);
|
|
|
|
|
|
|
183 |
}
|
184 |
|
185 |
function hook_modified_comment($comment_id){
|
186 |
$comment = get_comment($comment_id);
|
187 |
|
188 |
if ( $comment->comment_approved == '1'){
|
189 |
-
$container =
|
190 |
$container->mark_as_unsynched();
|
191 |
}
|
192 |
}
|
193 |
|
194 |
function hook_wp_insert_comment($comment_id, $comment){
|
195 |
if ( $comment->comment_approved == '1'){
|
196 |
-
$container =
|
197 |
$container->mark_as_unsynched();
|
198 |
}
|
199 |
}
|
@@ -204,7 +259,7 @@ class blcCommentManager extends blcContainerManager {
|
|
204 |
}
|
205 |
|
206 |
foreach($comment_ids as $comment_id){
|
207 |
-
$container =
|
208 |
$container->delete();
|
209 |
}
|
210 |
//Clean up any dangling links
|
@@ -212,7 +267,7 @@ class blcCommentManager extends blcContainerManager {
|
|
212 |
}
|
213 |
|
214 |
function hook_comment_status($new_status, $old_status, $comment){
|
215 |
-
$container =
|
216 |
if ( $new_status == 'approved' ){
|
217 |
$container->mark_as_unsynched();
|
218 |
} else {
|
@@ -221,6 +276,27 @@ class blcCommentManager extends blcContainerManager {
|
|
221 |
}
|
222 |
}
|
223 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
224 |
/**
|
225 |
* Create or update synchronization records for all comments.
|
226 |
*
|
@@ -239,13 +315,15 @@ class blcCommentManager extends blcContainerManager {
|
|
239 |
{$wpdb->comments}.comment_approved = '1'";
|
240 |
$wpdb->query( $q );
|
241 |
} else {
|
242 |
-
//Delete synch records corresponding to comments that no longer exist
|
|
|
243 |
$q = "DELETE synch.*
|
244 |
FROM
|
245 |
{$wpdb->prefix}blc_synch AS synch LEFT JOIN {$wpdb->comments} AS comments
|
246 |
ON comments.comment_ID = synch.container_id
|
247 |
WHERE
|
248 |
-
synch.container_type = '{$this->container_type}'
|
|
|
249 |
$wpdb->query( $q );
|
250 |
|
251 |
//Create synch. records for comments that don't have them.
|
@@ -271,24 +349,16 @@ class blcCommentManager extends blcContainerManager {
|
|
271 |
* Get the message to display after $n comments have been deleted.
|
272 |
*
|
273 |
* @param int $n Number of deleted comments.
|
274 |
-
* @return string A delete confirmation message, e.g. "5 comments were
|
275 |
*/
|
276 |
function ui_bulk_delete_message($n){
|
277 |
if ( EMPTY_TRASH_DAYS ){
|
278 |
-
return
|
279 |
-
_n(
|
280 |
-
"%d comment moved to the trash",
|
281 |
-
"%d comments moved to the trash",
|
282 |
-
$n,
|
283 |
-
'broken-link-checker'
|
284 |
-
),
|
285 |
-
$n
|
286 |
-
);
|
287 |
} else {
|
288 |
return sprintf(
|
289 |
_n(
|
290 |
-
"%d comment has been deleted",
|
291 |
-
"%d comments have been deleted",
|
292 |
$n,
|
293 |
'broken-link-checker'
|
294 |
),
|
@@ -297,6 +367,24 @@ class blcCommentManager extends blcContainerManager {
|
|
297 |
}
|
298 |
}
|
299 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
300 |
/**
|
301 |
* Instantiate multiple containers of the container type managed by this class.
|
302 |
*
|
@@ -340,5 +428,4 @@ class blcCommentManager extends blcContainerManager {
|
|
340 |
}
|
341 |
}
|
342 |
|
343 |
-
blc_register_container('comment', 'blcCommentManager');
|
344 |
?>
|
1 |
<?php
|
2 |
|
3 |
+
/*
|
4 |
+
Plugin Name: Comments
|
5 |
+
Description:
|
6 |
+
Version: 1.0
|
7 |
+
Author: Janis Elsts
|
8 |
+
|
9 |
+
ModuleID: comment
|
10 |
+
ModuleCategory: container
|
11 |
+
ModuleClassName: blcCommentManager
|
12 |
+
*/
|
13 |
+
|
14 |
class blcComment extends blcContainer{
|
|
|
|
|
|
|
|
|
15 |
|
16 |
/**
|
17 |
* Retrieve the comment wrapped by this container.
|
45 |
}
|
46 |
|
47 |
$data = (array)$this->wrapped_object;
|
|
|
48 |
if ( wp_update_comment($data) ){
|
49 |
return true;
|
50 |
} else {
|
62 |
* @return bool|WP_error
|
63 |
*/
|
64 |
function delete_wrapped_object(){
|
65 |
+
if ( EMPTY_TRASH_DAYS ){
|
66 |
+
return $this->trash_wrapped_object();
|
67 |
+
} else {
|
68 |
+
if ( wp_delete_comment($this->container_id, true) ){
|
69 |
+
return true;
|
70 |
+
} else {
|
71 |
+
return new WP_Error(
|
72 |
+
'delete_failed',
|
73 |
+
sprintf(
|
74 |
+
__('Failed to delete comment %d', 'broken-link-checker'),
|
75 |
+
$this->container_id
|
76 |
+
)
|
77 |
+
);
|
78 |
+
};
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Delete the comment corresponding to this container.
|
84 |
+
* This will actually move the comment to the trash in newer versions of WP.
|
85 |
+
*
|
86 |
+
* @return bool|WP_error
|
87 |
+
*/
|
88 |
+
function trash_wrapped_object(){
|
89 |
+
if ( wp_trash_comment($this->container_id) ){
|
90 |
return true;
|
91 |
} else {
|
92 |
return new WP_Error(
|
93 |
+
'trash_failed',
|
94 |
sprintf(
|
95 |
+
__('Can\'t move comment %d to the trash', 'broken-link-checker'),
|
96 |
$this->container_id
|
97 |
)
|
98 |
);
|
99 |
};
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Check if the current user can delete/trash this comment.
|
104 |
+
*
|
105 |
+
* @return bool
|
106 |
+
*/
|
107 |
+
function current_user_can_delete(){
|
108 |
+
//TODO: Fix for custom post types? WP itself doesn't care, at least in 3.0.
|
109 |
+
$comment = &$this->get_wrapped_object();
|
110 |
+
return current_user_can('edit_post', $comment->comment_post_ID);
|
111 |
+
}
|
112 |
+
|
113 |
+
function can_be_trashed(){
|
114 |
+
return defined('EMPTY_TRASH_DAYS') && EMPTY_TRASH_DAYS;
|
115 |
}
|
116 |
|
117 |
/**
|
157 |
$delete_url = esc_url( admin_url("comment.php?action=deletecomment&p=$post->ID&c=$comment->comment_ID&$del_nonce") );
|
158 |
|
159 |
if ( !constant('EMPTY_TRASH_DAYS') ) {
|
160 |
+
$actions['delete'] = "<a href='$delete_url' class='delete:the-comment-list:comment-$comment->comment_ID::delete=1 delete vim-d vim-destructive submitdelete'>" . __('Delete Permanently') . '</a>';
|
161 |
} else {
|
162 |
+
$actions['trash'] = "<a href='$trash_url' class='delete:the-comment-list:comment-$comment->comment_ID::trash=1 delete vim-d vim-destructive submitdelete' title='" . esc_attr__( 'Move this comment to the trash' ) . "'>" . _x('Trash', 'verb') . '</a>';
|
163 |
}
|
164 |
}
|
165 |
|
168 |
return $actions;
|
169 |
}
|
170 |
|
171 |
+
function ui_get_source($container_field = '', $context = 'display'){
|
172 |
//Display a comment icon.
|
173 |
if ( $container_field == 'comment_author_url' ){
|
174 |
$image = 'user_comment.png';
|
213 |
class blcCommentManager extends blcContainerManager {
|
214 |
var $container_class_name = 'blcComment';
|
215 |
|
216 |
+
var $fields = array(
|
217 |
+
'comment_author_url' => 'url_field',
|
218 |
+
'comment_content' => 'html',
|
219 |
+
);
|
220 |
+
|
221 |
function init(){
|
222 |
+
parent::init();
|
223 |
+
|
224 |
add_action('edit_comment', array(&$this, 'hook_modified_comment'));
|
225 |
add_action('unspammed_comment', array(&$this, 'hook_modified_comment'));
|
226 |
add_action('untrashed_comment', array(&$this, 'hook_modified_comment'));
|
232 |
add_action('trashed_comment', array(&$this, 'hook_deleted_comment'));
|
233 |
|
234 |
add_action('transition_comment_status', array(&$this, 'hook_comment_status'), 10, 3);
|
235 |
+
|
236 |
+
add_action('trashed_post_comments', array(&$this, 'hook_trashed_post_comments'), 10, 2);
|
237 |
+
add_action('untrash_post_comments', array(&$this, 'hook_untrash_post_comments'));
|
238 |
}
|
239 |
|
240 |
function hook_modified_comment($comment_id){
|
241 |
$comment = get_comment($comment_id);
|
242 |
|
243 |
if ( $comment->comment_approved == '1'){
|
244 |
+
$container = & blcContainerHelper::get_container(array($this->container_type, $comment_id));
|
245 |
$container->mark_as_unsynched();
|
246 |
}
|
247 |
}
|
248 |
|
249 |
function hook_wp_insert_comment($comment_id, $comment){
|
250 |
if ( $comment->comment_approved == '1'){
|
251 |
+
$container = & blcContainerHelper::get_container(array($this->container_type, $comment_id));
|
252 |
$container->mark_as_unsynched();
|
253 |
}
|
254 |
}
|
259 |
}
|
260 |
|
261 |
foreach($comment_ids as $comment_id){
|
262 |
+
$container = & blcContainerHelper::get_container(array($this->container_type, $comment_id));
|
263 |
$container->delete();
|
264 |
}
|
265 |
//Clean up any dangling links
|
267 |
}
|
268 |
|
269 |
function hook_comment_status($new_status, $old_status, $comment){
|
270 |
+
$container = & blcContainerHelper::get_container(array($this->container_type, $comment->comment_ID));
|
271 |
if ( $new_status == 'approved' ){
|
272 |
$container->mark_as_unsynched();
|
273 |
} else {
|
276 |
}
|
277 |
}
|
278 |
|
279 |
+
function hook_trashed_post_comments($post_id, $statuses){
|
280 |
+
$comment_ids = array_keys($statuses);
|
281 |
+
$this->hook_deleted_comment($comment_ids);
|
282 |
+
}
|
283 |
+
|
284 |
+
function hook_untrash_post_comments($post_id){
|
285 |
+
//Unlike with the 'trashed_post_comments' hook, WP doesn't pass the list of (un)trashed
|
286 |
+
//comments to callbacks assigned to the 'untrash_post_comments' and 'untrashed_post_comments'
|
287 |
+
//actions. Therefore, we must read it from the appropriate metadata entry.
|
288 |
+
$statuses = get_post_meta($post_id, '_wp_trash_meta_comments_status', true);
|
289 |
+
if ( empty($statuses) || !is_array($statuses) ) return;
|
290 |
+
|
291 |
+
$comment_ids = array();
|
292 |
+
foreach ( $statuses as $comment_id => $comment_status ){
|
293 |
+
if ( $comment_status == '1' ){ //if approved
|
294 |
+
$container = & blcContainerHelper::get_container(array($this->container_type, $comment_id));
|
295 |
+
$container->mark_as_unsynched();
|
296 |
+
}
|
297 |
+
}
|
298 |
+
}
|
299 |
+
|
300 |
/**
|
301 |
* Create or update synchronization records for all comments.
|
302 |
*
|
315 |
{$wpdb->comments}.comment_approved = '1'";
|
316 |
$wpdb->query( $q );
|
317 |
} else {
|
318 |
+
//Delete synch records corresponding to comments that no longer exist
|
319 |
+
//or have been trashed/spammed/unapproved.
|
320 |
$q = "DELETE synch.*
|
321 |
FROM
|
322 |
{$wpdb->prefix}blc_synch AS synch LEFT JOIN {$wpdb->comments} AS comments
|
323 |
ON comments.comment_ID = synch.container_id
|
324 |
WHERE
|
325 |
+
synch.container_type = '{$this->container_type}'
|
326 |
+
AND (comments.comment_ID IS NULL OR comments.comment_approved <> '1')";
|
327 |
$wpdb->query( $q );
|
328 |
|
329 |
//Create synch. records for comments that don't have them.
|
349 |
* Get the message to display after $n comments have been deleted.
|
350 |
*
|
351 |
* @param int $n Number of deleted comments.
|
352 |
+
* @return string A delete confirmation message, e.g. "5 comments were deleted"
|
353 |
*/
|
354 |
function ui_bulk_delete_message($n){
|
355 |
if ( EMPTY_TRASH_DAYS ){
|
356 |
+
return $this->ui_bulk_trash_message($n);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
357 |
} else {
|
358 |
return sprintf(
|
359 |
_n(
|
360 |
+
"%d comment has been deleted.",
|
361 |
+
"%d comments have been deleted.",
|
362 |
$n,
|
363 |
'broken-link-checker'
|
364 |
),
|
367 |
}
|
368 |
}
|
369 |
|
370 |
+
/**
|
371 |
+
* Get the message to display after $n comments have been moved to the trash.
|
372 |
+
*
|
373 |
+
* @param int $n Number of trashed comments.
|
374 |
+
* @return string A delete confirmation message, e.g. "5 comments were moved to trash"
|
375 |
+
*/
|
376 |
+
function ui_bulk_trash_message($n){
|
377 |
+
return sprintf(
|
378 |
+
_n(
|
379 |
+
"%d comment moved to the Trash.",
|
380 |
+
"%d comments moved to the Trash.",
|
381 |
+
$n,
|
382 |
+
'broken-link-checker'
|
383 |
+
),
|
384 |
+
$n
|
385 |
+
);
|
386 |
+
}
|
387 |
+
|
388 |
/**
|
389 |
* Instantiate multiple containers of the container type managed by this class.
|
390 |
*
|
428 |
}
|
429 |
}
|
430 |
|
|
|
431 |
?>
|
{includes → modules}/containers/custom_field.php
RENAMED
@@ -1,5 +1,16 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
//Note : If it ever becomes necessary to check metadata on objects other than posts, it will
|
4 |
//be fairly easy to extract a more general metadata container class from blcPostMeta.
|
5 |
|
@@ -31,7 +42,7 @@ class blcPostMeta extends blcContainer {
|
|
31 |
*/
|
32 |
function get_wrapped_object($ensure_consistency = false){
|
33 |
if ( is_null($this->wrapped_object) || $ensure_consistency ) {
|
34 |
-
$
|
35 |
}
|
36 |
return $this->wrapped_object;
|
37 |
}
|
@@ -169,22 +180,7 @@ class blcPostMeta extends blcContainer {
|
|
169 |
return $field;
|
170 |
}
|
171 |
|
172 |
-
function ui_get_source($container_field, $context = 'display'){
|
173 |
-
$image_html = sprintf(
|
174 |
-
'<img src="%s/broken-link-checker/images/script_code.png" class="blc-small-image" title="%2$s" alt="%2$s"> ',
|
175 |
-
WP_PLUGIN_URL,
|
176 |
-
__('Custom field', 'broken-link-checker')
|
177 |
-
);
|
178 |
-
|
179 |
-
$field_html = sprintf(
|
180 |
-
'<code>%s</code>',
|
181 |
-
$container_field
|
182 |
-
);
|
183 |
-
|
184 |
-
if ( $context != 'email' ){
|
185 |
-
$field_html = $image_html . $field_html;
|
186 |
-
}
|
187 |
-
|
188 |
$post_html = sprintf(
|
189 |
'<a class="row-title" href="%s" title="%s">%s</a>',
|
190 |
esc_url($this->get_edit_url()),
|
@@ -192,7 +188,7 @@ class blcPostMeta extends blcContainer {
|
|
192 |
get_the_title($this->container_id)
|
193 |
);
|
194 |
|
195 |
-
return
|
196 |
}
|
197 |
|
198 |
function ui_get_action_links($container_field){
|
@@ -200,13 +196,25 @@ class blcPostMeta extends blcContainer {
|
|
200 |
if ( current_user_can('edit_post', $this->container_id) ) {
|
201 |
$actions['edit'] = '<span class="edit"><a href="' . $this->get_edit_url() . '" title="' . esc_attr(__('Edit this item')) . '">' . __('Edit') . '</a>';
|
202 |
|
203 |
-
if (
|
204 |
-
|
205 |
-
|
206 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
}
|
208 |
}
|
209 |
-
$actions['view'] = '<span class="view"><a href="' . get_permalink($this->container_id) . '" title="' . esc_attr(sprintf(__('View "%s"', 'broken-link-checker'), get_the_title($this->container_id))) . '" rel="permalink">' . __('View') . '</a>';
|
210 |
|
211 |
return $actions;
|
212 |
}
|
@@ -227,56 +235,24 @@ class blcPostMeta extends blcContainer {
|
|
227 |
executed by Cron.
|
228 |
*/
|
229 |
|
230 |
-
if (
|
231 |
return '';
|
232 |
}
|
233 |
|
234 |
$context = 'display';
|
235 |
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
return '';
|
246 |
-
}
|
247 |
-
|
248 |
-
return apply_filters( 'get_edit_post_link', admin_url( sprintf($post_type_object->_edit_link . $action, $post->ID) ), $post->ID, $context );
|
249 |
-
|
250 |
-
} else {
|
251 |
-
//WP 2.9.x
|
252 |
-
if ( 'display' == $context )
|
253 |
-
$action = 'action=edit&';
|
254 |
-
else
|
255 |
-
$action = 'action=edit&';
|
256 |
-
|
257 |
-
switch ( $post->post_type ) :
|
258 |
-
case 'page' :
|
259 |
-
$file = 'page';
|
260 |
-
$var = 'post';
|
261 |
-
break;
|
262 |
-
case 'attachment' :
|
263 |
-
$file = 'media';
|
264 |
-
$var = 'attachment_id';
|
265 |
-
break;
|
266 |
-
case 'revision' :
|
267 |
-
$file = 'revision';
|
268 |
-
$var = 'revision';
|
269 |
-
$action = '';
|
270 |
-
break;
|
271 |
-
default :
|
272 |
-
$file = 'post';
|
273 |
-
$var = 'post';
|
274 |
-
break;
|
275 |
-
endswitch;
|
276 |
-
|
277 |
-
return apply_filters( 'get_edit_post_link', admin_url("$file.php?{$action}$var=$post->ID"), $post->ID, $context );
|
278 |
-
|
279 |
}
|
|
|
|
|
280 |
}
|
281 |
|
282 |
/**
|
@@ -290,18 +266,60 @@ class blcPostMeta extends blcContainer {
|
|
290 |
}
|
291 |
|
292 |
/**
|
293 |
-
* Delete the post corresponding to this container.
|
|
|
294 |
*
|
295 |
* @return bool|WP_error
|
296 |
*/
|
297 |
function delete_wrapped_object(){
|
298 |
-
if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
299 |
return true;
|
300 |
} else {
|
301 |
return new WP_Error(
|
302 |
-
'
|
303 |
sprintf(
|
304 |
-
__('Failed to
|
305 |
get_the_title($this->container_id),
|
306 |
$this->container_id
|
307 |
)
|
@@ -309,6 +327,15 @@ class blcPostMeta extends blcContainer {
|
|
309 |
};
|
310 |
}
|
311 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
312 |
}
|
313 |
|
314 |
class blcPostMetaManager extends blcContainerManager {
|
@@ -316,6 +343,8 @@ class blcPostMetaManager extends blcContainerManager {
|
|
316 |
var $meta_type = 'post';
|
317 |
|
318 |
function init(){
|
|
|
|
|
319 |
//Intercept 2.9+ style metadata modification actions
|
320 |
add_action( "added_{$this->meta_type}_meta", array(&$this, 'meta_modified'), 10, 4 );
|
321 |
add_action( "updated_{$this->meta_type}_meta", array(&$this, 'meta_modified'), 10, 4 );
|
@@ -335,27 +364,22 @@ class blcPostMetaManager extends blcContainerManager {
|
|
335 |
}
|
336 |
|
337 |
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
$container = parent::get_container($container);
|
346 |
-
|
347 |
-
//Set up the parseable fields
|
348 |
$fields = array();
|
349 |
|
350 |
-
|
351 |
-
|
352 |
-
foreach($conf->options['custom_fields'] as $meta_name){
|
353 |
$fields[$meta_name] = 'metadata';
|
354 |
}
|
355 |
}
|
356 |
|
357 |
-
|
358 |
-
return $container;
|
359 |
}
|
360 |
|
361 |
/**
|
@@ -489,7 +513,7 @@ class blcPostMetaManager extends blcContainerManager {
|
|
489 |
return;
|
490 |
}
|
491 |
|
492 |
-
$container =
|
493 |
$container->mark_as_unsynched();
|
494 |
}
|
495 |
|
@@ -501,7 +525,7 @@ class blcPostMetaManager extends blcContainerManager {
|
|
501 |
*/
|
502 |
function post_deleted($post_id){
|
503 |
//Get the associated container object
|
504 |
-
$container =
|
505 |
//Delete it
|
506 |
$container->delete();
|
507 |
//Clean up any dangling links
|
@@ -517,29 +541,31 @@ class blcPostMetaManager extends blcContainerManager {
|
|
517 |
*/
|
518 |
function post_untrashed($post_id){
|
519 |
//Get the associated container object
|
520 |
-
$container =
|
521 |
$container->mark_as_unsynched();
|
522 |
}
|
523 |
|
524 |
/**
|
525 |
* Get the message to display after $n posts have been deleted.
|
526 |
*
|
527 |
-
* @
|
528 |
*
|
529 |
* @param int $n Number of deleted posts.
|
530 |
* @return string A delete confirmation message, e.g. "5 posts were moved to the trash"
|
531 |
*/
|
532 |
function ui_bulk_delete_message($n){
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
|
|
|
|
|
|
|
|
540 |
}
|
541 |
}
|
542 |
|
543 |
-
blc_register_container('custom_field', 'blcPostMetaManager');
|
544 |
-
|
545 |
?>
|
1 |
<?php
|
2 |
|
3 |
+
/*
|
4 |
+
Plugin Name: Custom fields
|
5 |
+
Description: Container module for post metadata.
|
6 |
+
Version: 1.0
|
7 |
+
Author: Janis Elsts
|
8 |
+
|
9 |
+
ModuleID: custom_field
|
10 |
+
ModuleCategory: container
|
11 |
+
ModuleClassName: blcPostMetaManager
|
12 |
+
*/
|
13 |
+
|
14 |
//Note : If it ever becomes necessary to check metadata on objects other than posts, it will
|
15 |
//be fairly easy to extract a more general metadata container class from blcPostMeta.
|
16 |
|
42 |
*/
|
43 |
function get_wrapped_object($ensure_consistency = false){
|
44 |
if ( is_null($this->wrapped_object) || $ensure_consistency ) {
|
45 |
+
$this->wrapped_object = get_metadata($this->meta_type, $this->container_id);
|
46 |
}
|
47 |
return $this->wrapped_object;
|
48 |
}
|
180 |
return $field;
|
181 |
}
|
182 |
|
183 |
+
function ui_get_source($container_field = '', $context = 'display'){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
$post_html = sprintf(
|
185 |
'<a class="row-title" href="%s" title="%s">%s</a>',
|
186 |
esc_url($this->get_edit_url()),
|
188 |
get_the_title($this->container_id)
|
189 |
);
|
190 |
|
191 |
+
return $post_html;
|
192 |
}
|
193 |
|
194 |
function ui_get_action_links($container_field){
|
196 |
if ( current_user_can('edit_post', $this->container_id) ) {
|
197 |
$actions['edit'] = '<span class="edit"><a href="' . $this->get_edit_url() . '" title="' . esc_attr(__('Edit this item')) . '">' . __('Edit') . '</a>';
|
198 |
|
199 |
+
if ( $this->current_user_can_delete() ){
|
200 |
+
if ( $this->can_be_trashed() ) {
|
201 |
+
$actions['trash'] = sprintf(
|
202 |
+
"<span><a class='submitdelete' title='%s' href='%s'>%s</a>",
|
203 |
+
esc_attr(__('Move this item to the Trash')),
|
204 |
+
get_delete_post_link($this->container_id, '', false),
|
205 |
+
__('Trash')
|
206 |
+
);
|
207 |
+
} else {
|
208 |
+
$actions['delete'] = sprintf(
|
209 |
+
"<span><a class='submitdelete' title='%s' href='%s'>%s</a>",
|
210 |
+
esc_attr(__('Delete this item permanently')),
|
211 |
+
get_delete_post_link($this->container_id, '', true),
|
212 |
+
__('Delete')
|
213 |
+
);
|
214 |
+
}
|
215 |
}
|
216 |
}
|
217 |
+
$actions['view'] = '<span class="view"><a href="' . esc_url(get_permalink($this->container_id)) . '" title="' . esc_attr(sprintf(__('View "%s"', 'broken-link-checker'), get_the_title($this->container_id))) . '" rel="permalink">' . __('View') . '</a>';
|
218 |
|
219 |
return $actions;
|
220 |
}
|
235 |
executed by Cron.
|
236 |
*/
|
237 |
|
238 |
+
if ( !($post = &get_post( $this->container_id )) ){
|
239 |
return '';
|
240 |
}
|
241 |
|
242 |
$context = 'display';
|
243 |
|
244 |
+
//WP 3.0
|
245 |
+
if ( 'display' == $context )
|
246 |
+
$action = '&action=edit';
|
247 |
+
else
|
248 |
+
$action = '&action=edit';
|
249 |
+
|
250 |
+
$post_type_object = get_post_type_object( $post->post_type );
|
251 |
+
if ( !$post_type_object ){
|
252 |
+
return '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
}
|
254 |
+
|
255 |
+
return apply_filters( 'get_edit_post_link', admin_url( sprintf($post_type_object->_edit_link . $action, $post->ID) ), $post->ID, $context );
|
256 |
}
|
257 |
|
258 |
/**
|
266 |
}
|
267 |
|
268 |
/**
|
269 |
+
* Delete or trash the post corresponding to this container. If trash is enabled,
|
270 |
+
* will always move the post to the trash instead of deleting.
|
271 |
*
|
272 |
* @return bool|WP_error
|
273 |
*/
|
274 |
function delete_wrapped_object(){
|
275 |
+
if ( EMPTY_TRASH_DAYS ){
|
276 |
+
return $this->trash_wrapped_object();
|
277 |
+
} else {
|
278 |
+
if ( wp_delete_post($this->container_id) ){
|
279 |
+
return true;
|
280 |
+
} else {
|
281 |
+
return new WP_Error(
|
282 |
+
'delete_failed',
|
283 |
+
sprintf(
|
284 |
+
__('Failed to delete post "%s" (%d)', 'broken-link-checker'),
|
285 |
+
get_the_title($this->container_id),
|
286 |
+
$this->container_id
|
287 |
+
)
|
288 |
+
);
|
289 |
+
};
|
290 |
+
}
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* Move the post corresponding to this custom field to the Trash.
|
295 |
+
*
|
296 |
+
* @return bool|WP_Error
|
297 |
+
*/
|
298 |
+
function trash_wrapped_object(){
|
299 |
+
if ( !EMPTY_TRASH_DAYS ){
|
300 |
+
return new WP_Error(
|
301 |
+
'trash_disabled',
|
302 |
+
sprintf(
|
303 |
+
__('Can\'t move post "%s" (%d) to the trash because the trash feature is disabled', 'broken-link-checker'),
|
304 |
+
get_the_title($this->container_id),
|
305 |
+
$this->container_id
|
306 |
+
)
|
307 |
+
);
|
308 |
+
}
|
309 |
+
|
310 |
+
$post = &get_post($this->container_id);
|
311 |
+
if ( $post->post_status == 'trash' ){
|
312 |
+
//Prevent conflicts between post and custom field containers trying to trash the same post.
|
313 |
+
return true;
|
314 |
+
}
|
315 |
+
|
316 |
+
if ( wp_trash_post($this->container_id) ){
|
317 |
return true;
|
318 |
} else {
|
319 |
return new WP_Error(
|
320 |
+
'trash_failed',
|
321 |
sprintf(
|
322 |
+
__('Failed to move post "%s" (%d) to the trash', 'broken-link-checker'),
|
323 |
get_the_title($this->container_id),
|
324 |
$this->container_id
|
325 |
)
|
327 |
};
|
328 |
}
|
329 |
|
330 |
+
function current_user_can_delete(){
|
331 |
+
$post = &get_post($this->container_id);
|
332 |
+
$post_type_object = get_post_type_object($post->post_type);
|
333 |
+
return current_user_can( $post_type_object->cap->delete_post, $this->container_id );
|
334 |
+
}
|
335 |
+
|
336 |
+
function can_be_trashed(){
|
337 |
+
return defined('EMPTY_TRASH_DAYS') && EMPTY_TRASH_DAYS;
|
338 |
+
}
|
339 |
}
|
340 |
|
341 |
class blcPostMetaManager extends blcContainerManager {
|
343 |
var $meta_type = 'post';
|
344 |
|
345 |
function init(){
|
346 |
+
parent::init();
|
347 |
+
|
348 |
//Intercept 2.9+ style metadata modification actions
|
349 |
add_action( "added_{$this->meta_type}_meta", array(&$this, 'meta_modified'), 10, 4 );
|
350 |
add_action( "updated_{$this->meta_type}_meta", array(&$this, 'meta_modified'), 10, 4 );
|
364 |
}
|
365 |
|
366 |
|
367 |
+
/**
|
368 |
+
* Get a list of parseable fields.
|
369 |
+
*
|
370 |
+
* @return array
|
371 |
+
*/
|
372 |
+
function get_parseable_fields(){
|
373 |
+
//Fields = custom field names as entered by the user.
|
|
|
|
|
|
|
374 |
$fields = array();
|
375 |
|
376 |
+
if ( is_array($this->plugin_conf->options['custom_fields']) ){
|
377 |
+
foreach($this->plugin_conf->options['custom_fields'] as $meta_name){
|
|
|
378 |
$fields[$meta_name] = 'metadata';
|
379 |
}
|
380 |
}
|
381 |
|
382 |
+
return $fields;
|
|
|
383 |
}
|
384 |
|
385 |
/**
|
513 |
return;
|
514 |
}
|
515 |
|
516 |
+
$container = & blcContainerHelper::get_container( array($this->container_type, intval($object_id)) );
|
517 |
$container->mark_as_unsynched();
|
518 |
}
|
519 |
|
525 |
*/
|
526 |
function post_deleted($post_id){
|
527 |
//Get the associated container object
|
528 |
+
$container = & blcContainerHelper::get_container( array($this->container_type, intval($post_id)) );
|
529 |
//Delete it
|
530 |
$container->delete();
|
531 |
//Clean up any dangling links
|
541 |
*/
|
542 |
function post_untrashed($post_id){
|
543 |
//Get the associated container object
|
544 |
+
$container = & blcContainerHelper::get_container( array($this->container_type, intval($post_id)) );
|
545 |
$container->mark_as_unsynched();
|
546 |
}
|
547 |
|
548 |
/**
|
549 |
* Get the message to display after $n posts have been deleted.
|
550 |
*
|
551 |
+
* @uses blcAnyPostContainerManager::ui_bulk_delete_message()
|
552 |
*
|
553 |
* @param int $n Number of deleted posts.
|
554 |
* @return string A delete confirmation message, e.g. "5 posts were moved to the trash"
|
555 |
*/
|
556 |
function ui_bulk_delete_message($n){
|
557 |
+
return blcAnyPostContainerManager::ui_bulk_delete_message($n);
|
558 |
+
}
|
559 |
+
|
560 |
+
/**
|
561 |
+
* Get the message to display after $n posts have been trashed.
|
562 |
+
*
|
563 |
+
* @param int $n Number of deleted posts.
|
564 |
+
* @return string A confirmation message, e.g. "5 posts were moved to trash"
|
565 |
+
*/
|
566 |
+
function ui_bulk_trash_message($n){
|
567 |
+
return blcAnyPostContainerManager::ui_bulk_trash_message($n);
|
568 |
}
|
569 |
}
|
570 |
|
|
|
|
|
571 |
?>
|
{includes → modules}/containers/dummy.php
RENAMED
@@ -1,5 +1,18 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
/**
|
4 |
* A "dummy" container class that can be used as a fallback when the real container class can't be found.
|
5 |
*
|
@@ -61,6 +74,4 @@ class blcDummyManager extends blcContainerManager {
|
|
61 |
}
|
62 |
}
|
63 |
|
64 |
-
blc_register_container('dummy', 'blcDummyManager');
|
65 |
-
|
66 |
?>
|
1 |
<?php
|
2 |
|
3 |
+
/*
|
4 |
+
Plugin Name: Dummy
|
5 |
+
Description:
|
6 |
+
Version: 1.0
|
7 |
+
Author: Janis Elsts
|
8 |
+
|
9 |
+
ModuleID: dummy
|
10 |
+
ModuleCategory: container
|
11 |
+
ModuleClassName: blcDummyManager
|
12 |
+
ModuleAlwaysActive: true
|
13 |
+
ModuleHidden: true
|
14 |
+
*/
|
15 |
+
|
16 |
/**
|
17 |
* A "dummy" container class that can be used as a fallback when the real container class can't be found.
|
18 |
*
|
74 |
}
|
75 |
}
|
76 |
|
|
|
|
|
77 |
?>
|
modules/extras/dailymotion-embed.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
ModuleID: dailymotion-embed
|
4 |
+
ModuleCategory: parser
|
5 |
+
ModuleContext: on-demand
|
6 |
+
ModuleLazyInit: true
|
7 |
+
ModuleClassName: blcDailyMotionEmbed
|
8 |
+
ModulePriority: 0
|
9 |
+
ModuleCheckerUrlPattern:
|
10 |
+
ModuleHidden: false
|
11 |
+
ModuleAlwaysActive: false
|
12 |
+
ModuleRequiresPro: true
|
13 |
+
Version: 1.0
|
14 |
+
Description: Parse embedded videos from DailyMotion
|
15 |
+
Plugin Name: Embedded DailyMotion videos
|
16 |
+
*/
|
17 |
+
?>
|
modules/extras/mediafire.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
ModuleID: mediafire-checker
|
4 |
+
ModuleCategory: checker
|
5 |
+
ModuleContext: on-demand
|
6 |
+
ModuleLazyInit: true
|
7 |
+
ModuleClassName: blcMediaFireChecker
|
8 |
+
ModulePriority: 100
|
9 |
+
ModuleCheckerUrlPattern: @^http://(?:www\.)?mediafire\.com/(?:download\.php)?\?([0-9a-zA-Z]{11})(?:$|[^0-9a-zA-Z])@
|
10 |
+
ModuleHidden: false
|
11 |
+
ModuleAlwaysActive: false
|
12 |
+
ModuleRequiresPro: true
|
13 |
+
Version: 1.0
|
14 |
+
Description: Check links to files hosted on MediaFire.
|
15 |
+
Plugin Name: MediaFire API
|
16 |
+
*/
|
17 |
+
?>
|
modules/extras/megaupload.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
ModuleID: megaupload-checker
|
4 |
+
ModuleCategory: checker
|
5 |
+
ModuleContext: on-demand
|
6 |
+
ModuleLazyInit: true
|
7 |
+
ModuleClassName: blcMegaUploadChecker
|
8 |
+
ModulePriority: 100
|
9 |
+
ModuleCheckerUrlPattern: @^http://[\w\.]*?megaupload\.com/.*?(?:\?|&)d=([0-9A-Za-z]+)@
|
10 |
+
ModuleHidden: false
|
11 |
+
ModuleAlwaysActive: false
|
12 |
+
ModuleRequiresPro: true
|
13 |
+
Version: 1.0
|
14 |
+
Description: Check links to MegaUpload files.
|
15 |
+
Plugin Name: MegaUpload API
|
16 |
+
*/
|
17 |
+
?>
|
modules/extras/plaintext-url.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
ModuleID: plaintext-url
|
4 |
+
ModuleCategory: parser
|
5 |
+
ModuleContext: on-demand
|
6 |
+
ModuleLazyInit: true
|
7 |
+
ModuleClassName: blcPlaintextURL
|
8 |
+
ModulePriority: 800
|
9 |
+
ModuleCheckerUrlPattern:
|
10 |
+
ModuleHidden: false
|
11 |
+
ModuleAlwaysActive: false
|
12 |
+
ModuleRequiresPro: true
|
13 |
+
Version: 1.0
|
14 |
+
Description: Parse plaintext URLs as links
|
15 |
+
Plugin Name: Plaintext URLs
|
16 |
+
*/
|
17 |
+
?>
|
modules/extras/rapidshare.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
ModuleID: rapidshare-checker
|
4 |
+
ModuleCategory: checker
|
5 |
+
ModuleContext: on-demand
|
6 |
+
ModuleLazyInit: true
|
7 |
+
ModuleClassName: blcRapidShareChecker
|
8 |
+
ModulePriority: 100
|
9 |
+
ModuleCheckerUrlPattern: @^https?://(?:[\w\d]+\.)*rapidshare\.\w+/files/(\d+)/([^&?#/]+?)(?:$|[&?#/])@i
|
10 |
+
ModuleHidden: false
|
11 |
+
ModuleAlwaysActive: false
|
12 |
+
ModuleRequiresPro: true
|
13 |
+
Version: 1.0
|
14 |
+
Description: Check links to RapidShare files using the RapidShare API.
|
15 |
+
Plugin Name: RapidShare API
|
16 |
+
*/
|
17 |
+
?>
|
modules/extras/vimeo-embed.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
ModuleID: vimeo-embed
|
4 |
+
ModuleCategory: parser
|
5 |
+
ModuleContext: on-demand
|
6 |
+
ModuleLazyInit: true
|
7 |
+
ModuleClassName: blcVimeoEmbed
|
8 |
+
ModulePriority: 0
|
9 |
+
ModuleCheckerUrlPattern:
|
10 |
+
ModuleHidden: false
|
11 |
+
ModuleAlwaysActive: false
|
12 |
+
ModuleRequiresPro: true
|
13 |
+
Version: 1.0
|
14 |
+
Description: Parse embedded videos from Vimeo
|
15 |
+
Plugin Name: Embedded Vimeo videos
|
16 |
+
*/
|
17 |
+
?>
|
modules/extras/youtube-embed.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
ModuleID: youtube-embed
|
4 |
+
ModuleCategory: parser
|
5 |
+
ModuleContext: on-demand
|
6 |
+
ModuleLazyInit: true
|
7 |
+
ModuleClassName: blcYouTubeEmbed
|
8 |
+
ModulePriority: 0
|
9 |
+
ModuleCheckerUrlPattern:
|
10 |
+
ModuleHidden: false
|
11 |
+
ModuleAlwaysActive: false
|
12 |
+
ModuleRequiresPro: true
|
13 |
+
Version: 1.0
|
14 |
+
Description: Parse embedded videos from YouTube
|
15 |
+
Plugin Name: Embedded YouTube videos
|
16 |
+
*/
|
17 |
+
?>
|
modules/extras/youtube.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
ModuleID: youtube-checker
|
4 |
+
ModuleCategory: checker
|
5 |
+
ModuleContext: on-demand
|
6 |
+
ModuleLazyInit: true
|
7 |
+
ModuleClassName: blcYouTubeChecker
|
8 |
+
ModulePriority: 100
|
9 |
+
ModuleCheckerUrlPattern: @^http://([\w\d]+\.)*youtube\.[^/]+/watch\?.*v=[^/#]@i
|
10 |
+
ModuleHidden: false
|
11 |
+
ModuleAlwaysActive: false
|
12 |
+
ModuleRequiresPro: true
|
13 |
+
Version: 1.0
|
14 |
+
Description: Check links to YouTube videos using the YouTube API.
|
15 |
+
Plugin Name: YouTube API
|
16 |
+
*/
|
17 |
+
?>
|
{includes → modules}/parsers/html_link.php
RENAMED
@@ -1,5 +1,20 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
class blcHTMLLink extends blcParser {
|
4 |
var $supported_formats = array('html');
|
5 |
|
@@ -323,6 +338,4 @@ class blcHTMLLink extends blcParser {
|
|
323 |
}
|
324 |
}
|
325 |
|
326 |
-
blc_register_parser('link', 'blcHTMLLink');
|
327 |
-
|
328 |
?>
|
1 |
<?php
|
2 |
|
3 |
+
/*
|
4 |
+
Plugin Name: HTML links
|
5 |
+
Description: Example : <code><a href="http://example.com/">link text</a></code>
|
6 |
+
Version: 1.0
|
7 |
+
Author: Janis Elsts
|
8 |
+
|
9 |
+
ModuleID: link
|
10 |
+
ModuleCategory: parser
|
11 |
+
ModuleClassName: blcHTMLLink
|
12 |
+
ModuleContext: on-demand
|
13 |
+
ModuleLazyInit: true
|
14 |
+
|
15 |
+
ModulePriority: 1000
|
16 |
+
*/
|
17 |
+
|
18 |
class blcHTMLLink extends blcParser {
|
19 |
var $supported_formats = array('html');
|
20 |
|
338 |
}
|
339 |
}
|
340 |
|
|
|
|
|
341 |
?>
|
{includes → modules}/parsers/image.php
RENAMED
@@ -1,4 +1,18 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
//TODO: Update image parser to use the same HTML tag parsing routine as the HTML link parser.
|
4 |
class blcHTMLImage extends blcParser {
|
@@ -142,8 +156,8 @@ class blcHTMLImage extends blcParser {
|
|
142 |
$text = __('Image', 'broken-link-checker');
|
143 |
|
144 |
$image = sprintf(
|
145 |
-
'<img src="%s
|
146 |
-
|
147 |
esc_attr($text)
|
148 |
);
|
149 |
|
@@ -155,7 +169,4 @@ class blcHTMLImage extends blcParser {
|
|
155 |
}
|
156 |
}
|
157 |
|
158 |
-
blc_register_parser('image', 'blcHTMLImage');
|
159 |
-
|
160 |
-
|
161 |
?>
|
1 |
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: HTML images
|
4 |
+
Description: e.g. <code><img src="http://example.com/fluffy.jpg"></code>
|
5 |
+
Version: 1.0
|
6 |
+
Author: Janis Elsts
|
7 |
+
|
8 |
+
ModuleID: image
|
9 |
+
ModuleCategory: parser
|
10 |
+
ModuleClassName: blcHTMLImage
|
11 |
+
ModuleContext: on-demand
|
12 |
+
ModuleLazyInit: true
|
13 |
+
|
14 |
+
ModulePriority: 900
|
15 |
+
*/
|
16 |
|
17 |
//TODO: Update image parser to use the same HTML tag parsing routine as the HTML link parser.
|
18 |
class blcHTMLImage extends blcParser {
|
156 |
$text = __('Image', 'broken-link-checker');
|
157 |
|
158 |
$image = sprintf(
|
159 |
+
'<img src="%s" class="blc-small-image" alt="%2$s" title="%2$s"> ',
|
160 |
+
esc_attr(plugins_url('/images/image.png', blc_get_plugin_file())),
|
161 |
esc_attr($text)
|
162 |
);
|
163 |
|
169 |
}
|
170 |
}
|
171 |
|
|
|
|
|
|
|
172 |
?>
|
{includes → modules}/parsers/metadata.php
RENAMED
@@ -1,4 +1,18 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
class blcMetadataParser extends blcParser {
|
4 |
var $supported_formats = array('metadata');
|
@@ -89,9 +103,31 @@ class blcMetadataParser extends blcParser {
|
|
89 |
'raw_url' => $new_url,
|
90 |
);
|
91 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
}
|
93 |
|
94 |
-
blc_register_parser('metadata', 'blcMetadataParser');
|
95 |
-
|
96 |
-
|
97 |
?>
|
1 |
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: Metadata
|
4 |
+
Description: Parses metadata (AKA custom fields)
|
5 |
+
Version: 1.0
|
6 |
+
Author: Janis Elsts
|
7 |
+
|
8 |
+
ModuleID: metadata
|
9 |
+
ModuleCategory: parser
|
10 |
+
ModuleClassName: blcMetadataParser
|
11 |
+
ModuleContext: on-demand
|
12 |
+
ModuleLazyInit: true
|
13 |
+
ModuleAlwaysActive: true
|
14 |
+
ModuleHidden: true
|
15 |
+
*/
|
16 |
|
17 |
class blcMetadataParser extends blcParser {
|
18 |
var $supported_formats = array('metadata');
|
103 |
'raw_url' => $new_url,
|
104 |
);
|
105 |
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Get the link text for printing in the "Broken Links" table.
|
109 |
+
*
|
110 |
+
* @param blcLinkInstance $instance
|
111 |
+
* @return string HTML
|
112 |
+
*/
|
113 |
+
function ui_get_link_text(&$instance, $context = 'display'){
|
114 |
+
$image_html = sprintf(
|
115 |
+
'<img src="%s" class="blc-small-image" title="%2$s" alt="%2$s"> ',
|
116 |
+
esc_attr( plugins_url('/images/script_code.png', blc_get_plugin_file()) ),
|
117 |
+
__('Custom field', 'broken-link-checker')
|
118 |
+
);
|
119 |
+
|
120 |
+
$field_html = sprintf(
|
121 |
+
'<code>%s</code>',
|
122 |
+
$instance->container_field
|
123 |
+
);
|
124 |
+
|
125 |
+
if ( $context != 'email' ){
|
126 |
+
$field_html = $image_html . $field_html;
|
127 |
+
}
|
128 |
+
|
129 |
+
return $field_html;
|
130 |
+
}
|
131 |
}
|
132 |
|
|
|
|
|
|
|
133 |
?>
|
{includes → modules}/parsers/url_field.php
RENAMED
@@ -1,4 +1,18 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
/**
|
4 |
* A "parser" for data fields that contain a single, plaintext URL.
|
@@ -81,7 +95,4 @@ class blcUrlField extends blcParser {
|
|
81 |
}
|
82 |
}
|
83 |
|
84 |
-
blc_register_parser('url_field', 'blcUrlField');
|
85 |
-
|
86 |
-
|
87 |
?>
|
1 |
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: URL fields
|
4 |
+
Description: Parses data fields that contain a single, plaintext URL.
|
5 |
+
Version: 1.0
|
6 |
+
Author: Janis Elsts
|
7 |
+
|
8 |
+
ModuleID: url_field
|
9 |
+
ModuleCategory: parser
|
10 |
+
ModuleClassName: blcUrlField
|
11 |
+
ModuleContext: on-demand
|
12 |
+
ModuleLazyInit: true
|
13 |
+
ModuleAlwaysActive: true
|
14 |
+
ModuleHidden: true
|
15 |
+
*/
|
16 |
|
17 |
/**
|
18 |
* A "parser" for data fields that contain a single, plaintext URL.
|
95 |
}
|
96 |
}
|
97 |
|
|
|
|
|
|
|
98 |
?>
|
readme.txt
CHANGED
@@ -2,11 +2,11 @@
|
|
2 |
Contributors: whiteshadow
|
3 |
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A6P9S6CE3SRSW
|
4 |
Tags: links, broken, maintenance, blogroll, custom fields, admin, comments, posts
|
5 |
-
Requires at least:
|
6 |
-
Tested up to: 3.
|
7 |
-
Stable tag: 0.9.
|
8 |
|
9 |
-
This plugin will check your posts, comments and other
|
10 |
|
11 |
== Description ==
|
12 |
This plugin will monitor your blog looking for broken links and let you know if any are found.
|
@@ -14,33 +14,32 @@ This plugin will monitor your blog looking for broken links and let you know if
|
|
14 |
**Features**
|
15 |
|
16 |
* Monitors links in your posts, pages, comments, the blogroll, and custom fields (optional).
|
17 |
-
* Detects links that don't work
|
18 |
-
* Notifies you
|
19 |
-
* Also detects redirected links.
|
20 |
* Makes broken links display differently in posts (optional).
|
21 |
-
*
|
22 |
-
*
|
23 |
-
*
|
24 |
-
*
|
25 |
-
* Each link can be edited or unlinked directly via the plugin's page, without manually editing each post.
|
26 |
|
27 |
[Suggest new features and improvements here](http://feedback.w-shadow.com/forums/58400-broken-link-checker)
|
28 |
|
29 |
**Basic Usage**
|
30 |
|
31 |
-
Once installed, the plugin will begin parsing your posts, bookmarks (AKA blogroll)
|
32 |
|
33 |
-
The broken links, if any are found, will show up in a new tab of the WP admin panel - *Tools -> Broken Links*. A notification will also appear in the "Broken Link Checker" widget on the Dashboard. To save display space, you can keep the widget closed and configure it to expand automatically when problematic links are detected.
|
34 |
|
35 |
The "Broken Links" tab will by default display a list of broken links that have been detected so far. However, you can use the links on that page to view redirects or see a listing of all links - working or not - instead. You can also create new link filters by performing a search and clicking the "Create Custom Filter" button. For example, this can be used to create a filter that only shows comment links.
|
36 |
|
37 |
There are several actions associated with each link. They show up when you move your mouse over to one of the links listed the aforementioned tab -
|
38 |
|
39 |
-
* "
|
40 |
-
* "Edit URL" lets you change the URL of that link. If the link is present in more than one place (e.g. both in a post and in the blogroll) then all occurrences of that URL will be changed.
|
41 |
* "Unlink" removes the link but leaves the link text intact.
|
42 |
* "Not broken" lets you manually mark a "broken" link as working. This is useful if you know it was incorrectly detected as broken due to a network glitch or a bug. The marked link will still be checked periodically, but the plugin won't consider it broken unless it gets a new result.
|
43 |
|
|
|
|
|
44 |
**Translations**
|
45 |
|
46 |
* Belorussian - [M. Comfi](http://www.comfi.com/)
|
@@ -58,16 +57,22 @@ There are several actions associated with each link. They show up when you move
|
|
58 |
* Spanish - [Neoshinji](http://blog.tuayudainformatica.com/traducciones-de-plugins-wordpress/)
|
59 |
* Ukrainian - [Stas Mykhajlyuk](http://www.kosivart.com/)
|
60 |
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
== Installation ==
|
62 |
|
63 |
To do a new installation of the plugin, please follow these steps
|
64 |
|
65 |
-
1. Download the broken-link-checker.zip file to your
|
66 |
1. Unzip the file
|
67 |
1. Upload `broken-link-checker` folder to the `/wp-content/plugins/` directory
|
68 |
1. Activate the plugin through the 'Plugins' menu in WordPress
|
69 |
|
70 |
-
|
71 |
|
72 |
To upgrade your installation
|
73 |
|
@@ -79,6 +84,20 @@ To upgrade your installation
|
|
79 |
|
80 |
*This is an automatically generated changelog*
|
81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
= 0.9.4.4 =
|
83 |
* Fixed "Edit URL" and "Unlink" not working on PHP4 servers.
|
84 |
|
2 |
Contributors: whiteshadow
|
3 |
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A6P9S6CE3SRSW
|
4 |
Tags: links, broken, maintenance, blogroll, custom fields, admin, comments, posts
|
5 |
+
Requires at least: 3.0
|
6 |
+
Tested up to: 3.1-alpha
|
7 |
+
Stable tag: 0.9.5
|
8 |
|
9 |
+
This plugin will check your posts, comments and other content for broken links and missing images, and notify you if any are found.
|
10 |
|
11 |
== Description ==
|
12 |
This plugin will monitor your blog looking for broken links and let you know if any are found.
|
14 |
**Features**
|
15 |
|
16 |
* Monitors links in your posts, pages, comments, the blogroll, and custom fields (optional).
|
17 |
+
* Detects links that don't work, missing images and redirects.
|
18 |
+
* Notifies you either via the Dashboard or by email.
|
|
|
19 |
* Makes broken links display differently in posts (optional).
|
20 |
+
* Prevents search engines from following broken links (optional).
|
21 |
+
* You can search and filter links by URL, anchor text and so on.
|
22 |
+
* Links can be edited directly from the plugin's page, without manually updating each post.
|
23 |
+
* Highly configurable.
|
|
|
24 |
|
25 |
[Suggest new features and improvements here](http://feedback.w-shadow.com/forums/58400-broken-link-checker)
|
26 |
|
27 |
**Basic Usage**
|
28 |
|
29 |
+
Once installed, the plugin will begin parsing your posts, bookmarks (AKA blogroll) and other content and looking for links. Depending on the size of your site this can take from a few minutes up to an hour or more. When parsing is complete, the plugin will start checking each link to see if it works. Again, how long this takes depends on how big your site is and how many links there are. You can monitor the progress and tweak various link checking options in *Settings -> Link Checker*.
|
30 |
|
31 |
+
The broken links, if any are found, will show up in a new tab of the WP admin panel - *Tools -> Broken Links*. A notification will also appear in the "Broken Link Checker" widget on the Dashboard. To save display space, you can keep the widget closed and configure it to expand automatically when problematic links are detected. E-mail notifications need to be enabled separately (in *Settings -> Link Checker*).
|
32 |
|
33 |
The "Broken Links" tab will by default display a list of broken links that have been detected so far. However, you can use the links on that page to view redirects or see a listing of all links - working or not - instead. You can also create new link filters by performing a search and clicking the "Create Custom Filter" button. For example, this can be used to create a filter that only shows comment links.
|
34 |
|
35 |
There are several actions associated with each link. They show up when you move your mouse over to one of the links listed the aforementioned tab -
|
36 |
|
37 |
+
* "Edit URL" lets you change the URL of that link. If the link is present in more than one place (e.g. both in a post and in the blogroll), all occurrences of that URL will be changed.
|
|
|
38 |
* "Unlink" removes the link but leaves the link text intact.
|
39 |
* "Not broken" lets you manually mark a "broken" link as working. This is useful if you know it was incorrectly detected as broken due to a network glitch or a bug. The marked link will still be checked periodically, but the plugin won't consider it broken unless it gets a new result.
|
40 |
|
41 |
+
You can also click on the contents of the "Status" or "Link Text" columns to get more info about the status of each link.
|
42 |
+
|
43 |
**Translations**
|
44 |
|
45 |
* Belorussian - [M. Comfi](http://www.comfi.com/)
|
57 |
* Spanish - [Neoshinji](http://blog.tuayudainformatica.com/traducciones-de-plugins-wordpress/)
|
58 |
* Ukrainian - [Stas Mykhajlyuk](http://www.kosivart.com/)
|
59 |
|
60 |
+
*Note: Some translations are not entirely up to date with the latest release, so parts of the interface may appear untranslated.*
|
61 |
+
|
62 |
+
**Other Credits**
|
63 |
+
|
64 |
+
This plugin uses one or more icons from the beautiful ["Silk" icon set](http://www.famfamfam.com/lab/icons/silk/).
|
65 |
+
|
66 |
== Installation ==
|
67 |
|
68 |
To do a new installation of the plugin, please follow these steps
|
69 |
|
70 |
+
1. Download the broken-link-checker.zip file to your computer.
|
71 |
1. Unzip the file
|
72 |
1. Upload `broken-link-checker` folder to the `/wp-content/plugins/` directory
|
73 |
1. Activate the plugin through the 'Plugins' menu in WordPress
|
74 |
|
75 |
+
To enable/disable various features and tweak the plugin's configuration go to *Settings -> Link Checker*.
|
76 |
|
77 |
To upgrade your installation
|
78 |
|
84 |
|
85 |
*This is an automatically generated changelog*
|
86 |
|
87 |
+
= 0.9.5 =
|
88 |
+
* Added the ability to check scheduled, draft and private posts.
|
89 |
+
* Added a way to individually enable/disable the monitoring of posts, pages, comments, the blogroll, and so on.
|
90 |
+
* New "Status" column in the "Broken Links" table.
|
91 |
+
* Visible table columns and the number of links per page can now be selected in the "Screen Options" panel.
|
92 |
+
* Replaced the "Delete sources" action with "Move sources to Trash" (except on blogs where Trash is disabled).
|
93 |
+
* New URL editor interface, now more consistent with the look-n-feel of the inline editor for posts.
|
94 |
+
* New status icon to help distinguish "maybe broken" and "definitely broken" links.
|
95 |
+
* Tweaked table layout - links first, posts/etc last.
|
96 |
+
* Added "Compact" and "Detailed" table views (for now, the differences are quite minor).
|
97 |
+
* Split the settings page into several tabs.
|
98 |
+
* Removed the "Details" links as redundant. To display link details, click the contents of the "Status" or "Link text" columns instead.
|
99 |
+
* Added a way to individually enable/disable the monitoring of various link types, e.g. HTML links, images, etc.
|
100 |
+
|
101 |
= 0.9.4.4 =
|
102 |
* Fixed "Edit URL" and "Unlink" not working on PHP4 servers.
|
103 |
|
uninstall.php
CHANGED
@@ -1,16 +1,17 @@
|
|
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
-
* @author
|
5 |
-
* @copyright
|
6 |
*
|
7 |
* The terrifying uninstallation script.
|
8 |
*/
|
9 |
|
10 |
if( defined( 'ABSPATH') && defined('WP_UNINSTALL_PLUGIN') ) {
|
11 |
|
12 |
-
//Remove the plugin's settings
|
13 |
delete_option('wsblc_options');
|
|
|
14 |
|
15 |
//Remove the database tables
|
16 |
$mywpdb = $GLOBALS['wpdb'];
|
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
+
* @author Janis Elsts
|
5 |
+
* @copyright 2010
|
6 |
*
|
7 |
* The terrifying uninstallation script.
|
8 |
*/
|
9 |
|
10 |
if( defined( 'ABSPATH') && defined('WP_UNINSTALL_PLUGIN') ) {
|
11 |
|
12 |
+
//Remove the plugin's settings & installation log
|
13 |
delete_option('wsblc_options');
|
14 |
+
delete_option('blc_installation_log');
|
15 |
|
16 |
//Remove the database tables
|
17 |
$mywpdb = $GLOBALS['wpdb'];
|