/wp-content/plugins/broken-link-checker/core/core.php
PHP | 3100 lines | 2270 code | 374 blank | 456 comment | 238 complexity | 41a237c91dd4ed7ae616689aa36ee5cb MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, AGPL-1.0
Large files files are truncated, but you can click here to view the full file
- <?php
- /**
- * Simple function to replicate PHP 5 behaviour
- */
- if ( !function_exists( 'microtime_float' ) ) {
- function microtime_float()
- {
- list($usec, $sec) = explode(" ", microtime());
- return ((float)$usec + (float)$sec);
- }
- }
- require BLC_DIRECTORY . '/includes/screen-options/screen-options.php';
- require BLC_DIRECTORY . '/includes/screen-meta-links.php';
- require BLC_DIRECTORY . '/includes/wp-mutex.php';
- if (!class_exists('wsBrokenLinkChecker')) {
- class wsBrokenLinkChecker {
- var $conf;
-
- var $loader;
- var $my_basename = '';
-
- var $db_version; //The required version of the plugin's DB schema.
-
- var $execution_start_time; //Used for a simple internal execution timer in start_timer()/execution_time()
-
- /**
- * wsBrokenLinkChecker::wsBrokenLinkChecker()
- * Class constructor
- *
- * @param string $loader The fully qualified filename of the loader script that WP identifies as the "main" plugin file.
- * @param blcConfigurationManager $conf An instance of the configuration manager
- * @return void
- */
- function wsBrokenLinkChecker ( $loader, &$conf ) {
- global $wpdb;
- $this->db_version = BLC_DATABASE_VERSION;
-
- $this->conf = &$conf;
- $this->loader = $loader;
- $this->my_basename = plugin_basename( $this->loader );
- $this->load_language();
-
- //Unlike the activation hook, the deactivation callback *can* be registered in this file
- //because deactivation happens after this class has already been instantiated (durinng the
- //'init' action).
- register_deactivation_hook($loader, array(&$this, 'deactivation'));
-
- add_action('admin_menu', array(&$this,'admin_menu'));
- //Load jQuery on Dashboard pages (probably redundant as WP already does that)
- add_action('admin_print_scripts', array(&$this,'admin_print_scripts'));
-
- //The dashboard widget
- add_action('wp_dashboard_setup', array(&$this, 'hook_wp_dashboard_setup'));
-
- //AJAXy hooks
- add_action( 'wp_ajax_blc_full_status', array(&$this,'ajax_full_status') );
- add_action( 'wp_ajax_blc_dashboard_status', array(&$this,'ajax_dashboard_status') );
- add_action( 'wp_ajax_blc_work', array(&$this,'ajax_work') );
- add_action( 'wp_ajax_blc_discard', array(&$this,'ajax_discard') );
- add_action( 'wp_ajax_blc_edit', array(&$this,'ajax_edit') );
- add_action( 'wp_ajax_blc_link_details', array(&$this,'ajax_link_details') );
- add_action( 'wp_ajax_blc_unlink', array(&$this,'ajax_unlink') );
- add_action( 'wp_ajax_blc_current_load', array(&$this,'ajax_current_load') );
- add_action( 'wp_ajax_blc_dismiss', array($this, 'ajax_dismiss') );
- add_action( 'wp_ajax_blc_undismiss', array($this, 'ajax_undismiss') );
-
- //Add/remove Cron events
- $this->setup_cron_events();
-
- //Set hooks that listen for our Cron actions
- add_action('blc_cron_email_notifications', array( &$this, 'maybe_send_email_notifications' ));
- add_action('blc_cron_check_links', array(&$this, 'cron_check_links'));
- add_action('blc_cron_database_maintenance', array(&$this, 'database_maintenance'));
- add_action('blc_cron_check_news', array(&$this, 'check_news'));
-
- //Set the footer hook that will call the worker function via AJAX.
- add_action('admin_footer', array(&$this,'admin_footer'));
-
- //Add a "Screen Options" panel to the "Broken Links" page
- add_screen_options_panel(
- 'blc-screen-options',
- '',
- array(&$this, 'screen_options_html'),
- 'tools_page_view-broken-links',
- array(&$this, 'ajax_save_screen_options'),
- true
- );
- }
- /**
- * Output the script that runs the link monitor while the Dashboard is open.
- *
- * @return void
- */
- function admin_footer(){
- if ( !$this->conf->options['run_in_dashboard'] ){
- return;
- }
- ?>
- <!-- wsblc admin footer -->
- <script type='text/javascript'>
- (function($){
-
- //(Re)starts the background worker thread
- function blcDoWork(){
- $.post(
- "<?php echo admin_url('admin-ajax.php'); ?>",
- {
- 'action' : 'blc_work'
- }
- );
- }
- //Call it the first time
- blcDoWork();
-
- //Then call it periodically every X seconds
- setInterval(blcDoWork, <?php echo (intval($this->conf->options['max_execution_time']) + 1 )*1000; ?>);
-
- })(jQuery);
- </script>
- <!-- /wsblc admin footer -->
- <?php
- }
-
- /**
- * Check if an URL matches the exclusion list.
- *
- * @param string $url
- * @return bool
- */
- function is_excluded($url){
- if (!is_array($this->conf->options['exclusion_list'])) return false;
- foreach($this->conf->options['exclusion_list'] as $excluded_word){
- if (stristr($url, $excluded_word)){
- return true;
- }
- }
- return false;
- }
- function dashboard_widget(){
- ?>
- <p id='wsblc_activity_box'><?php _e('Loading...', 'broken-link-checker'); ?></p>
- <script type='text/javascript'>
- jQuery( function($){
- var blc_was_autoexpanded = false;
-
- function blcDashboardStatus(){
- $.getJSON(
- "<?php echo admin_url('admin-ajax.php'); ?>",
- {
- 'action' : 'blc_dashboard_status',
- 'random' : Math.random()
- },
- function (data, textStatus){
- if ( data && ( typeof(data.text) != 'undefined' ) ) {
- $('#wsblc_activity_box').html(data.text);
- <?php if ( $this->conf->options['autoexpand_widget'] ) { ?>
- //Expand the widget if there are broken links.
- //Do this only once per pageload so as not to annoy the user.
- if ( !blc_was_autoexpanded && ( data.status.broken_links > 0 ) ){
- $('#blc_dashboard_widget.postbox').removeClass('closed');
- blc_was_autoexpanded = true;
- }
- <?php } ?>
- } else {
- $('#wsblc_activity_box').html('<?php _e('[ Network error ]', 'broken-link-checker'); ?>');
- }
-
- setTimeout( blcDashboardStatus, 120*1000 ); //...update every two minutes
- }
- );
- }
-
- blcDashboardStatus();//Call it the first time
-
- } );
- </script>
- <?php
- }
- function dashboard_widget_control(
- /** @noinspection PhpUnusedParameterInspection */ $widget_id, $form_inputs = array()
- ){
- if ( 'POST' == $_SERVER['REQUEST_METHOD'] && 'blc_dashboard_widget' == $_POST['widget_id'] ) {
- //It appears $form_inputs isn't used in the current WP version, so lets just use $_POST
- $this->conf->options['autoexpand_widget'] = !empty($_POST['blc-autoexpand']);
- $this->conf->save_options();
- }
-
- ?>
- <p><label for="blc-autoexpand">
- <input id="blc-autoexpand" name="blc-autoexpand" type="checkbox" value="1" <?php if ( $this->conf->options['autoexpand_widget'] ) echo 'checked="checked"'; ?> />
- <?php _e('Automatically expand the widget if broken links have been detected', 'broken-link-checker'); ?>
- </label></p>
- <?php
- }
- function admin_print_scripts(){
- //jQuery is used for triggering the link monitor via AJAX when any admin page is open.
- wp_enqueue_script('jquery');
- }
-
- function enqueue_settings_scripts(){
- //jQuery UI is used on the settings page
- wp_enqueue_script('jquery-ui-core'); //Used for background color animation
- wp_enqueue_script('jquery-ui-dialog');
- wp_enqueue_script('jquery-ui-tabs');
- wp_enqueue_script('jquery-cookie', plugins_url('js/jquery.cookie.js', BLC_PLUGIN_FILE)); //Used for storing last widget states, etc
- }
-
- function enqueue_link_page_scripts(){
- wp_enqueue_script('jquery-ui-core'); //Used for background color animation
- wp_enqueue_script('jquery-ui-dialog'); //Used for the search form
- wp_enqueue_script('sprintf', plugins_url('js/sprintf.js', BLC_PLUGIN_FILE)); //Used in error messages
- }
-
- /**
- * Initiate a full recheck - reparse everything and check all links anew.
- *
- * @return void
- */
- function initiate_recheck(){
- global $wpdb; /** @var wpdb $wpdb */
- //Delete all discovered instances
- $wpdb->query("TRUNCATE {$wpdb->prefix}blc_instances");
-
- //Delete all discovered links
- $wpdb->query("TRUNCATE {$wpdb->prefix}blc_links");
-
- //Mark all posts, custom fields and bookmarks for processing.
- blc_resynch(true);
- }
- /**
- * A hook executed when the plugin is deactivated.
- *
- * @return void
- */
- function deactivation(){
- //Remove our Cron events
- wp_clear_scheduled_hook('blc_cron_check_links');
- wp_clear_scheduled_hook('blc_cron_email_notifications');
- wp_clear_scheduled_hook('blc_cron_database_maintenance');
- wp_clear_scheduled_hook('blc_cron_check_news');
- //Note the deactivation time for each module. This will help them
- //synch up propely if/when the plugin is reactivated.
- $moduleManager = blcModuleManager::getInstance();
- $the_time = current_time('timestamp');
- foreach($moduleManager->get_active_modules() as $module_id => $module){
- $this->conf->options['module_deactivated_when'][$module_id] = $the_time;
- }
- $this->conf->save_options();
- }
-
- /**
- * Perform various database maintenance tasks on the plugin's tables.
- *
- * Removes records that reference disabled containers and parsers,
- * deletes invalid instances and links, optimizes tables, etc.
- *
- * @return void
- */
- function database_maintenance(){
- blcContainerHelper::cleanup_containers();
- blc_cleanup_instances();
- blc_cleanup_links();
-
- blcUtility::optimize_database();
- }
- /**
- * Create the plugin's menu items and enqueue their scripts and CSS.
- * Callback for the 'admin_menu' action.
- *
- * @return void
- */
- function admin_menu(){
- if (current_user_can('manage_options'))
- add_filter('plugin_action_links', array(&$this, 'plugin_action_links'), 10, 2);
-
- $options_page_hook = add_options_page(
- __('Link Checker Settings', 'broken-link-checker'),
- __('Link Checker', 'broken-link-checker'),
- 'manage_options',
- 'link-checker-settings',array(&$this, 'options_page')
- );
-
- $menu_title = __('Broken Links', 'broken-link-checker');
- if ( $this->conf->options['show_link_count_bubble'] ){
- //To make it easier to notice when broken links appear, display the current number of
- //broken links in a little bubble notification in the "Broken Links" menu.
- //(Similar to how the number of plugin updates and unmoderated comments is displayed).
- $blc_link_query = blcLinkQuery::getInstance();
- $broken_links = $blc_link_query->get_filter_links('broken', array('count_only' => true));
- if ( $broken_links > 0 ){
- //TODO: Appropriating existing CSS classes for my own purposes is hacky. Fix eventually.
- $menu_title .= sprintf(
- ' <span class="update-plugins"><span class="update-count blc-menu-bubble">%d</span></span>',
- $broken_links
- );
- }
- }
- $links_page_hook = add_management_page(
- __('View Broken Links', 'broken-link-checker'),
- $menu_title,
- 'edit_others_posts',
- 'view-broken-links',array(&$this, 'links_page')
- );
-
- //Add plugin-specific scripts and CSS only to the it's own pages
- add_action( 'admin_print_styles-' . $options_page_hook, array(&$this, 'options_page_css') );
- add_action( 'admin_print_styles-' . $links_page_hook, array(&$this, 'links_page_css') );
- add_action( 'admin_print_scripts-' . $options_page_hook, array(&$this, 'enqueue_settings_scripts') );
- add_action( 'admin_print_scripts-' . $links_page_hook, array(&$this, 'enqueue_link_page_scripts') );
-
- //Add a "Feedback" button that links to the plugin's UserVoice forum
- add_screen_meta_link(
- 'blc-feedback-widget',
- __('Feedback', 'broken-link-checker'),
- 'http://whiteshadow.uservoice.com/forums/58400-broken-link-checker',
- array($options_page_hook, $links_page_hook)
- );
- //Add a link to the Admin Menu Editor site to the "Broken Links" page.
- if ( !$this->conf->get('user_has_donated') ) {
- //Choose anchor text randomly.
- $possible_anchor_texts = array(
- 'Organize WordPress admin menu',
- 'Simplify WordPress Admin Menu',
- 'Customize WP Admin Menu',
- 'Organize WP Admin: use Admin Menu Editor',
- 'Web Developer? Check out Admin Menu Editor',
- 'Admin Menu Editor for WP',
- 'Organize, Hide And Customize Admin Menus',
- );
- $index = $this->conf->get('view-broken-links-meta-ad', null);
- if ( $index === null ) {
- $index = rand(0, count($possible_anchor_texts) - 1);
- $this->conf->set('view-broken-links-meta-ad', $index);
- $this->conf->save_options();
- }
- add_screen_meta_link(
- 'blc-more-plugins-link',
- $possible_anchor_texts[$index],
- sprintf(
- 'http://w-shadow.com/admin-menu-editor-pro/?utm_source=broken_link_checker&utm_medium=Broken_Links_meta_link&utm_campaign=Plugins&utm_content=copy-a%s',
- urlencode($index)
- ),
- $links_page_hook,
- array('style' => 'font-weight: bold;')
- );
- }
- //Make the Settings page link to the link list
- add_screen_meta_link(
- 'blc-links-page-link',
- __('Go to Broken Links', 'broken-link-checker'),
- admin_url('tools.php?page=view-broken-links'),
- $options_page_hook,
- array('style' => 'font-weight: bold;')
- );
-
- //Add a link to the latest blog post/whatever about this plugin, if any.
- if ( isset($this->conf->options['plugin_news']) && !empty($this->conf->options['plugin_news']) ){
- $news = $this->conf->options['plugin_news'];
- add_screen_meta_link(
- 'blc-plugin-news-link',
- $news[0],
- $news[1],
- array($options_page_hook, $links_page_hook)
- );
- }
- }
-
- /**
- * plugin_action_links()
- * Handler for the 'plugin_action_links' hook. Adds a "Settings" link to this plugin's entry
- * on the plugin list.
- *
- * @param array $links
- * @param string $file
- * @return array
- */
- function plugin_action_links($links, $file) {
- if ($file == $this->my_basename)
- $links[] = "<a href='options-general.php?page=link-checker-settings'>" . __('Settings') . "</a>";
- return $links;
- }
- function options_page(){
- global $blclog;
- $moduleManager = blcModuleManager::getInstance();
- //Prior to 1.5.2 (released 2012-05-27), there was a bug that would cause the donation flag to be
- //set incorrectly. So we'll unset the flag in that case.
- $reset_donation_flag =
- ($this->conf->get('first_installation_timestamp', 0) < strtotime('2012-05-27 00:00')) &&
- !$this->conf->get('donation_flag_fixed', false);
- if ( $reset_donation_flag) {
- $this->conf->set('user_has_donated', false);
- $this->conf->set('donation_flag_fixed', true);
- $this->conf->save_options();
- }
-
- if (isset($_POST['recheck']) && !empty($_POST['recheck']) ){
- $this->initiate_recheck();
-
- //Redirect back to the settings page
- $base_url = remove_query_arg( array('_wpnonce', 'noheader', 'updated', 'error', 'action', 'message') );
- wp_redirect( add_query_arg( array( 'recheck-initiated' => true), $base_url ) );
- die();
- }
-
- if(isset($_POST['submit'])) {
- check_admin_referer('link-checker-options');
-
- //Activate/deactivate modules
- if ( !empty($_POST['module']) ){
- $active = array_keys($_POST['module']);
- $moduleManager->set_active_modules($active);
- }
-
- //Only post statuses that actually exist can be selected
- if ( isset($_POST['enabled_post_statuses']) && is_array($_POST['enabled_post_statuses']) ){
- $available_statuses = get_post_stati();
- $enabled_post_statuses = array_intersect($_POST['enabled_post_statuses'], $available_statuses);
- } else {
- $enabled_post_statuses = array();
- }
- //At least one status must be enabled; defaults to "Published".
- if ( empty($enabled_post_statuses) ){
- $enabled_post_statuses = array('publish');
- }
- $this->conf->options['enabled_post_statuses'] = $enabled_post_statuses;
-
- //The execution time limit must be above zero
- $new_execution_time = intval($_POST['max_execution_time']);
- if( $new_execution_time > 0 ){
- $this->conf->options['max_execution_time'] = $new_execution_time;
- }
- //The check threshold also must be > 0
- $new_check_threshold=intval($_POST['check_threshold']);
- if( $new_check_threshold > 0 ){
- $this->conf->options['check_threshold'] = $new_check_threshold;
- }
-
- $this->conf->options['mark_broken_links'] = !empty($_POST['mark_broken_links']);
- $new_broken_link_css = trim($_POST['broken_link_css']);
- $this->conf->options['broken_link_css'] = $new_broken_link_css;
-
- $this->conf->options['mark_removed_links'] = !empty($_POST['mark_removed_links']);
- $new_removed_link_css = trim($_POST['removed_link_css']);
- $this->conf->options['removed_link_css'] = $new_removed_link_css;
-
- $this->conf->options['nofollow_broken_links'] = !empty($_POST['nofollow_broken_links']);
- $this->conf->options['exclusion_list'] = array_filter(
- preg_split(
- '/[\s\r\n]+/', //split on newlines and whitespace
- $_POST['exclusion_list'],
- -1,
- PREG_SPLIT_NO_EMPTY //skip empty values
- )
- );
-
- //Parse the custom field list
- $new_custom_fields = array_filter(
- preg_split( '/[\r\n]+/', $_POST['blc_custom_fields'], -1, PREG_SPLIT_NO_EMPTY )
- );
-
- //Calculate the difference between the old custom field list and the new one (used later)
- $diff1 = array_diff( $new_custom_fields, $this->conf->options['custom_fields'] );
- $diff2 = array_diff( $this->conf->options['custom_fields'], $new_custom_fields );
- $this->conf->options['custom_fields'] = $new_custom_fields;
-
- //HTTP timeout
- $new_timeout = intval($_POST['timeout']);
- if( $new_timeout > 0 ){
- $this->conf->options['timeout'] = $new_timeout ;
- }
-
- //Server load limit
- if ( isset($_POST['server_load_limit']) ){
- $this->conf->options['server_load_limit'] = floatval($_POST['server_load_limit']);
- if ( $this->conf->options['server_load_limit'] < 0 ){
- $this->conf->options['server_load_limit'] = 0;
- }
-
- $this->conf->options['enable_load_limit'] = $this->conf->options['server_load_limit'] > 0;
- }
-
- //When to run the checker
- $this->conf->options['run_in_dashboard'] = !empty($_POST['run_in_dashboard']);
- $this->conf->options['run_via_cron'] = !empty($_POST['run_via_cron']);
-
- //Email notifications on/off
- $email_notifications = !empty($_POST['send_email_notifications']);
- $send_authors_email_notifications = !empty($_POST['send_authors_email_notifications']);
- if (
- ($email_notifications && !$this->conf->options['send_email_notifications'])
- || ($send_authors_email_notifications && !$this->conf->options['send_authors_email_notifications'])
- ){
- /*
- The plugin should only send notifications about links that have become broken
- since the time when email notifications were turned on. If we don't do this,
- the first email notification will be sent nigh-immediately and list *all* broken
- links that the plugin currently knows about.
- */
- $this->conf->options['last_notification_sent'] = time();
- }
- $this->conf->options['send_email_notifications'] = $email_notifications;
- $this->conf->options['send_authors_email_notifications'] = $send_authors_email_notifications;
- //Make settings that affect our Cron events take effect immediately
- $this->setup_cron_events();
-
- $this->conf->save_options();
-
- /*
- If the list of custom fields was modified then we MUST resynchronize or
- custom fields linked with existing posts may not be detected. This is somewhat
- inefficient.
- */
- if ( ( count($diff1) > 0 ) || ( count($diff2) > 0 ) ){
- $manager = blcContainerHelper::get_manager('custom_field');
- if ( !is_null($manager) ){
- $manager->resynch();
- blc_got_unsynched_items();
- }
- }
-
- //Redirect back to the settings page
- $base_url = remove_query_arg( array('_wpnonce', 'noheader', 'updated', 'error', 'action', 'message') );
- wp_redirect( add_query_arg( array( 'settings-updated' => true), $base_url ) );
- }
-
- //Show a confirmation message when settings are saved.
- if ( !empty($_GET['settings-updated']) ){
- echo '<div id="message" class="updated fade"><p><strong>',__('Settings saved.', 'broken-link-checker'), '</strong></p></div>';
-
- }
-
- //Show a thank-you message when a donation is made.
- if ( !empty($_GET['donated']) ){
- echo '<div id="message" class="updated fade"><p><strong>',__('Thank you for your donation!', 'broken-link-checker'), '</strong></p></div>';
- $this->conf->set('user_has_donated', true);
- $this->conf->save_options();
- }
-
- //Show one when recheck is started, too.
- if ( !empty($_GET['recheck-initiated']) ){
- echo '<div id="message" class="updated fade"><p><strong>',
- __('Complete site recheck started.', 'broken-link-checker'), // -- Yoda
- '</strong></p></div>';
- }
-
- //Cull invalid and missing modules
- $moduleManager->validate_active_modules();
-
- $debug = $this->get_debug_info();
-
- $details_text = __('Details', 'broken-link-checker');
- add_filter('blc-module-settings-custom_field', array(&$this, 'make_custom_field_input'), 10, 2);
-
- //Translate and markup-ify module headers for display
- $modules = $moduleManager->get_modules_by_category('', true, true);
-
- //Output the custom broken link/removed link styles for example links
- printf(
- '<style type="text/css">%s %s</style>',
- $this->conf->options['broken_link_css'],
- $this->conf->options['removed_link_css']
- );
-
- $section_names = array(
- 'general' => __('General', 'broken-link-checker'),
- 'where' => __('Look For Links In', 'broken-link-checker'),
- 'which' => __('Which Links To Check', 'broken-link-checker'),
- 'how' => __('Protocols & APIs', 'broken-link-checker'),
- 'advanced' => __('Advanced', 'broken-link-checker'),
- );
- ?>
-
- <!--[if lte IE 7]>
- <style type="text/css">
- /* Simulate inline-block in IE7 */
- ul.ui-tabs-nav li {
- display: inline;
- zoom: 1;
- }
- </style>
- <![endif]-->
-
- <div class="wrap" id="blc-settings-wrap">
- <?php screen_icon(); ?><h2><?php _e('Broken Link Checker Options', 'broken-link-checker'); ?></h2>
-
-
- <div id="blc-sidebar">
- <div class="metabox-holder">
- <?php include BLC_DIRECTORY . '/includes/admin/sidebar.php'; ?>
- </div>
- </div>
-
-
- <div id="blc-admin-content">
-
- <form name="link_checker_options" id="link_checker_options" method="post" action="<?php
- echo admin_url('options-general.php?page=link-checker-settings&noheader=1');
- ?>">
- <?php
- wp_nonce_field('link-checker-options');
- ?>
-
- <div id="blc-tabs">
-
- <ul class="hide-if-no-js">
- <?php
- foreach($section_names as $section_id => $section_name){
- printf(
- '<li id="tab-button-%s"><a href="#section-%s" title="%s">%s</a></li>',
- esc_attr($section_id),
- esc_attr($section_id),
- esc_attr($section_name),
- $section_name
- );
- }
- ?>
- </ul>
- <div id="section-general" class="blc-section">
- <h3 class="hide-if-js"><?php echo $section_names['general']; ?></h3>
-
- <table class="form-table">
- <tr valign="top">
- <th scope="row">
- <?php _e('Status','broken-link-checker'); ?>
- <br>
- <a href="javascript:void(0)" id="blc-debug-info-toggle"><?php _e('Show debug info', 'broken-link-checker'); ?></a>
- </th>
- <td>
- <div id='wsblc_full_status'>
- <br/><br/><br/>
- </div>
-
- <table id="blc-debug-info">
- <?php
-
- //Output the debug info in a table
- foreach( $debug as $key => $value ){
- printf (
- '<tr valign="top" class="blc-debug-item-%s"><th scope="row">%s</th><td>%s<div class="blc-debug-message">%s</div></td></tr>',
- $value['state'],
- $key,
- $value['value'],
- ( array_key_exists('message', $value)?$value['message']:'')
- );
- }
- ?>
- </table>
-
- </td>
- </tr>
- <tr valign="top">
- <th scope="row"><?php _e('Check each link','broken-link-checker'); ?></th>
- <td>
- <?php
- printf(
- __('Every %s hours','broken-link-checker'),
- sprintf(
- '<input type="text" name="check_threshold" id="check_threshold" value="%d" size="5" maxlength="5" />',
- $this->conf->options['check_threshold']
- )
- );
- ?>
- <br/>
- <span class="description">
- <?php _e('Existing links will be checked this often. New links will usually be checked ASAP.', 'broken-link-checker'); ?>
- </span>
- </td>
- </tr>
-
- <tr valign="top">
- <th scope="row"><?php _e('E-mail notifications', 'broken-link-checker'); ?></th>
- <td>
- <p style="margin-top: 0;">
- <label for='send_email_notifications'>
- <input type="checkbox" name="send_email_notifications" id="send_email_notifications"
- <?php if ($this->conf->options['send_email_notifications']) echo ' checked="checked"'; ?>/>
- <?php _e('Send me e-mail notifications about newly detected broken links', 'broken-link-checker'); ?>
- </label><br />
- </p>
-
- <p>
- <label for='send_authors_email_notifications'>
- <input type="checkbox" name="send_authors_email_notifications" id="send_authors_email_notifications"
- <?php if ($this->conf->options['send_authors_email_notifications']) echo ' checked="checked"'; ?>/>
- <?php _e('Send authors e-mail notifications about broken links in their posts', 'broken-link-checker'); ?>
- </label><br />
- </p>
- </td>
- </tr>
- <tr valign="top">
- <th scope="row"><?php _e('Link tweaks','broken-link-checker'); ?></th>
- <td>
- <p style="margin-top: 0; margin-bottom: 0.5em;">
- <label for='mark_broken_links'>
- <input type="checkbox" name="mark_broken_links" id="mark_broken_links"
- <?php if ($this->conf->options['mark_broken_links']) echo ' checked="checked"'; ?>/>
- <?php _e('Apply custom formatting to broken links', 'broken-link-checker'); ?>
- </label>
- |
- <a id="toggle-broken-link-css-editor" href="#" class="blc-toggle-link"><?php
- _e('Edit CSS', 'broken-link-checker');
- ?></a>
- </p>
-
- <div id="broken-link-css-wrap"<?php
- if ( !blcUtility::get_cookie('broken-link-css-wrap', false) ){
- echo ' class="hidden"';
- }
- ?>>
- <textarea name="broken_link_css" id="broken_link_css" cols='45' rows='4'/><?php
- if( isset($this->conf->options['broken_link_css']) ) {
- echo $this->conf->options['broken_link_css'];
- }
- ?></textarea>
- <p class="description"><?php
- printf(
- __('Example : Lorem ipsum <a %s>broken link</a>, dolor sit amet.', 'broken-link-checker'),
- ' href="#" class="broken_link" onclick="return false;"'
- );
- echo ' ', __('Click "Save Changes" to update example output.', 'broken-link-checker');
- ?></p>
- </div>
-
- <p style="margin-bottom: 0.5em;">
- <label for='mark_removed_links'>
- <input type="checkbox" name="mark_removed_links" id="mark_removed_links"
- <?php if ($this->conf->options['mark_removed_links']) echo ' checked="checked"'; ?>/>
- <?php _e('Apply custom formatting to removed links', 'broken-link-checker'); ?>
- </label>
- |
- <a id="toggle-removed-link-css-editor" href="#" class="blc-toggle-link"><?php
- _e('Edit CSS', 'broken-link-checker');
- ?></a>
- </p>
-
- <div id="removed-link-css-wrap" <?php
- if ( !blcUtility::get_cookie('removed-link-css-wrap', false) ){
- echo ' class="hidden"';
- }
- ?>>
- <textarea name="removed_link_css" id="removed_link_css" cols='45' rows='4'/><?php
- if( isset($this->conf->options['removed_link_css']) )
- echo $this->conf->options['removed_link_css'];
- ?></textarea>
-
- <p class="description"><?php
- printf(
- __('Example : Lorem ipsum <span %s>removed link</span>, dolor sit amet.', 'broken-link-checker'),
- ' class="removed_link"'
- );
- echo ' ', __('Click "Save Changes" to update example output.', 'broken-link-checker');
- ?>
- </p>
- </div>
-
- <p>
- <label for='nofollow_broken_links'>
- <input type="checkbox" name="nofollow_broken_links" id="nofollow_broken_links"
- <?php if ($this->conf->options['nofollow_broken_links']) echo ' checked="checked"'; ?>/>
- <?php _e('Stop search engines from following broken links', 'broken-link-checker'); ?>
- </label>
- </p>
- </td>
- </tr>
-
- </table>
-
- </div>
-
- <div id="section-where" class="blc-section">
- <h3 class="hide-if-js"><?php echo $section_names['where']; ?></h3>
-
- <table class="form-table">
-
- <tr valign="top">
- <th scope="row"><?php _e('Look for links in', 'broken-link-checker'); ?></th>
- <td>
- <?php
- if ( !empty($modules['container']) ){
- uasort($modules['container'], create_function('$a, $b', 'return strcasecmp($a["Name"], $b["Name"]);'));
- $this->print_module_list($modules['container'], $this->conf->options);
- }
- ?>
- </td></tr>
-
- <tr valign="top">
- <th scope="row"><?php _e('Post statuses', 'broken-link-checker'); ?></th>
- <td>
- <?php
- $available_statuses = get_post_stati(array('internal' => false), 'objects');
-
- if ( isset($this->conf->options['enabled_post_statuses']) ){
- $enabled_post_statuses = $this->conf->options['enabled_post_statuses'];
- } else {
- $enabled_post_statuses = array();
- }
-
- foreach($available_statuses as $status => $status_object){
- printf(
- '<p><label><input type="checkbox" name="enabled_post_statuses[]" value="%s"%s> %s</label></p>',
- esc_attr($status),
- in_array($status, $enabled_post_statuses)?' checked="checked"':'',
- $status_object->label
- );
- }
- ?>
- </td></tr>
-
- </table>
-
- </div>
-
-
- <div id="section-which" class="blc-section">
- <h3 class="hide-if-js"><?php echo $section_names['which']; ?></h3>
-
- <table class="form-table">
-
- <tr valign="top">
- <th scope="row"><?php _e('Link types', 'broken-link-checker'); ?></th>
- <td>
- <?php
- if ( !empty($modules['parser']) ){
- $this->print_module_list($modules['parser'], $this->conf->options);
- } else {
- echo __('Error : All link parsers missing!', 'broken-link-checker');
- }
- ?>
- </td>
- </tr>
-
- <tr valign="top">
- <th scope="row"><?php _e('Exclusion list', 'broken-link-checker'); ?></th>
- <td><?php _e("Don't check links where the URL contains any of these words (one per line) :", 'broken-link-checker'); ?><br/>
- <textarea name="exclusion_list" id="exclusion_list" cols='45' rows='4' wrap='off'/><?php
- if( isset($this->conf->options['exclusion_list']) )
- echo implode("\n", $this->conf->options['exclusion_list']);
- ?></textarea>
- </td>
- </tr>
-
- </table>
- </div>
-
- <div id="section-how" class="blc-section">
- <h3 class="hide-if-js"><?php echo $section_names['how']; ?></h3>
-
- <table class="form-table">
-
- <tr valign="top">
- <th scope="row"><?php _e('Check links using', 'broken-link-checker'); ?></th>
- <td>
- <?php
- if ( !empty($modules['checker']) ){
- $modules['checker'] = array_reverse($modules['checker']);
- $this->print_module_list($modules['checker'], $this->conf->options);
- }
- ?>
- </td></tr>
-
- </table>
- </div>
-
- <div id="section-advanced" class="blc-section">
- <h3 class="hide-if-js"><?php echo $section_names['advanced']; ?></h3>
-
- <table class="form-table">
-
- <tr valign="top">
- <th scope="row"><?php _e('Timeout', 'broken-link-checker'); ?></th>
- <td>
- <?php
-
- printf(
- __('%s seconds', 'broken-link-checker'),
- sprintf(
- '<input type="text" name="timeout" id="blc_timeout" value="%d" size="5" maxlength="3" />',
- $this->conf->options['timeout']
- )
- );
-
- ?>
- <br/><span class="description">
- <?php _e('Links that take longer than this to load will be marked as broken.','broken-link-checker'); ?>
- </span>
- </td>
- </tr>
-
- <tr valign="top">
- <th scope="row"><?php _e('Link monitor', 'broken-link-checker'); ?></th>
- <td>
-
- <p>
- <label for='run_in_dashboard'>
-
- <input type="checkbox" name="run_in_dashboard" id="run_in_dashboard"
- <?php if ($this->conf->options['run_in_dashboard']) echo ' checked="checked"'; ?>/>
- <?php _e('Run continuously while the Dashboard is open', 'broken-link-checker'); ?>
- </label>
- </p>
-
- <p>
- <label for='run_via_cron'>
- <input type="checkbox" name="run_via_cron" id="run_via_cron"
- <?php if ($this->conf->options['run_via_cron']) echo ' checked="checked"'; ?>/>
- <?php _e('Run hourly in the background', 'broken-link-checker'); ?>
- </label>
- </p>
- </td>
- </tr>
-
- <tr valign="top">
- <th scope="row"><?php _e('Max. execution time', 'broken-link-checker'); ?></th>
- <td>
- <?php
-
- printf(
- __('%s seconds', 'broken-link-checker'),
- sprintf(
- '<input type="text" name="max_execution_time" id="max_execution_time" value="%d" size="5" maxlength="5" />',
- $this->conf->options['max_execution_time']
- )
- );
-
- ?>
- <br/><span class="description">
- <?php
-
- _e('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.', 'broken-link-checker');
-
- ?>
- </span>
- </td>
- </tr>
-
- <tr valign="top">
- <th scope="row"><?php _e('Server load limit', 'broken-link-checker'); ?></th>
- <td>
- <?php
-
- $load = blcUtility::get_server_load();
- $available = !empty($load);
-
- if ( $available ){
- $value = !empty($this->conf->options['server_load_limit'])?sprintf('%.2f', $this->conf->options['server_load_limit']):'';
- printf(
- '<input type="text" name="server_load_limit" id="server_load_limit" value="%s" size="5" maxlength="5"/> ',
- $value
- );
-
- printf(
- __('Current load : %s', 'broken-link-checker'),
- '<span id="wsblc_current_load">...</span>'
- );
- echo '<br/><span class="description">';
- printf(
- __(
- '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.',
- 'broken-link-checker'
- ),
- 'http://en.wikipedia.org/wiki/Load_(computing)'
- );
- echo '</span>';
-
- } else {
- echo '<input type="text" disabled="disabled" value="', esc_attr(__('Not available', 'broken-link-checker')), '" size="13"/><br>';
- echo '<span class="description">';
- _e('Load limiting only works on Linux-like systems where <code>/proc/loadavg</code> is present and accessible.', 'broken-link-checker');
- echo '</span>';
- }
- ?>
- </td>
- </tr>
-
- <tr valign="top">
- <th scope="row"><?php _e('Forced recheck', 'broken-link-checker'); ?></th>
- <td>
- <input class="button" type="button" name="start-recheck" id="start-recheck"
- value="<?php _e('Re-check all pages', 'broken-link-checker'); ?>" />
- <input type="hidden" name="recheck" value="" id="recheck" />
- <br />
- <span class="description"><?php
- _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');
-
- ?></span>
- </td>
- </tr>
-
- </table>
- </div>
-
- </div>
-
- <p class="submit"><input type="submit" name="submit" class='button-primary' value="<?php _e('Save Changes') ?>" /></p>
- </form>
-
- </div> <!-- First postbox-container -->
-
-
- </div>
-
-
-
- <?php
- //The various JS for this page is stored in a separate file for the purposes readability.
- include dirname($this->loader) . '/includes/admin/options-page-js.php';
- }
-
- /**
- * Output a list of modules and their settings.
- *
- * Each list entry will contain a checkbox that is checked if the module is
- * currently active.
- *
- * @param array $modules Array of modules to display
- * @param array $current_settings
- * @return void
- */
- function print_module_list($modules, $current_settings){
- $moduleManager = blcModuleManager::getInstance();
-
- foreach($modules as $module_id => $module_data){
- $module_id = $module_data['ModuleID'];
-
- $style = $module_data['ModuleHidden']?' style="display:none;"':'';
-
- printf(
- '<div class="module-container" id="module-container-%s"%s>',
- $module_id,
- $style
- );
- $this->print_module_checkbox($module_id, $module_data, $moduleManager->is_active($module_id));
-
- $extra_settings = apply_filters(
- 'blc-module-settings-'.$module_id,
- '',
- $current_settings
- );
-
- if ( !empty($extra_settings) ){
-
- printf(
- ' | <a class="blc-toggle-link toggle-module-settings" id="toggle-module-settings-%s" href="#">%s</a>',
- $module_id,
- __('Configure', 'broken-link-checker')
- );
-
- //The plugin remembers the last open/closed state of module configuration boxes
- $box_id = 'module-extra-settings-' . $module_id;
- $show = blcUtility::get_cookie(
- $box_id,
- $moduleManager->is_active($module_id)
- );
-
- printf(
- '<div class="module-extra-settings%s" id="%s">%s</div>',
- $show?'':' hidden',
- $box_id,
- $extra_settings
- );
- }
-
- echo '</div>';
- }
- }
-
- /**
- * Output a checkbox for a module.
- *
- * Generates a simple checkbox that can be used to mark a module as active/inactive.
- * If the specified module can't be deactivated (ModuleAlwaysActive = true), the checkbox
- * will be displayed in a disabled state and a hidden field will be created to make
- * form submissions work correctly.
- *
- * @param string $module_id Module ID.
- * @param array $module_data Associative array of module data.
- * @param bool $active If true, the newly created checkbox will start out checked.
- * @return void
- */
- function print_module_checkbox($module_id, $module_data, $active = false){
- $disabled = false;
- $name_prefix = 'module';
- $label_class = '';
- $active = $active || $module_data['ModuleAlwaysActive'];
-
- if ( $module_data['ModuleAlwaysActive'] ){
- $disabled = true;
- $name_prefix = 'module-always-active';
- }
-
- $checked = $active ? ' checked="checked"':'';
- if ( $disabled ){
- $checked .= ' disabled="disabled"';
- }
-
- printf(
- '<label class="%s">
- <input type="checkbox" name="%s[%s]" id="module-checkbox-%s"%s /> %s
- </label>',
- esc_attr($label_class),
- $name_prefix,
- esc_attr($module_id),
- esc_attr($module_id),
- $checked,
- $module_data['Name']
- );
-
- if ( $module_data['ModuleAlwaysActive'] ){
- printf(
- '<input type="hidden" name="module[%s]" value="on">',
- esc_attr($module_id)
- );
- }
- }
-
- /**
- * Add extra settings to the "Custom fields" entry on the plugin's config. page.
- *
- * Callback for the 'blc-module-settings-custom_field' filter.
- *
- * @param string $html Current extra HTML
- * @param array $current_settings The current plugin configuration.
- * @return string New extra HTML.
- */
- function make_custom_field_input($html, $current_settings){
- $html .= '<span class="description">' .
- __('Check URLs entered in these custom fields (one per line) :', 'broken-link-checker') .
- '</span>';
- $html .= '<br><textarea name="blc_custom_fields" id="blc_custom_fields" cols="45" rows="4" />';
- if( isset($current_settings['custom_fields']) )
- $html .= implode("\n", $current_settings['custom_fields']);
- $html .= '</textarea>';
-
- return $html;
- }
-
- /**
- * Enqueue CSS file for the plugin's Settings page.
- *
- * @return void
- */
- function options_page_css(){
- wp_enqueue_style('blc-options-page', plugins_url('css/options-page.css', BLC_PLUGIN_FILE), array(), '20120527' );
- wp_enqueue_style('dashboard');
- }
-
- /**
- * Display the "Broken Links" page, listing links detected by the plugin and their status.
- *
- * @return void
- */
- function links_page(){
- global $wpdb, $blclog; /* @var wpdb $wpdb */
-
- $blc_link_query = blcLinkQuery::getInstance();
- //Cull invalid and missing modules so that we don't get dummy links/instances showing up.
- $moduleManager = blcModuleManager::getInstance();
- $moduleManager->validate_active_modules();
-
- if ( defined('BLC_DEBUG') && constant('BLC_DEBUG') ){
- //Make module headers translatable. They need to be formatted corrrectly and
- //placed in a .php file to be visible to the script(s) that generate .pot files.
- $code = $moduleManager->_build_header_translation_code();
- file_put_contents( dirname($this->loader) . '/includes/extra-strings.php', $code );
- }
-
- $action = !empty($_POST['action'])?$_POST['action']:'';
- if ( intval($action) == -1 ){
- //Try the second bulk actions box
- $action = !empty($_POST['action2'])?$_POST['action2']:'';
- }
-
- //Get the list of link IDs selected via checkboxes
- $selected_links = array();
- if ( isset($_POST['selected_links']) && is_array($_POST['selected_links']) ){
- //Convert all link IDs to integers (non-numeric entries are converted to zero)
- $selected_links = array_map('intval', $_POST['selected_links']);
- //Remove all zeroes
- $selected_links = array_filter($selected_links);
- }
-
- $message = '';
- $msg_class = 'updated';
-
- //Run the selected bulk action, if any
- $force_delete = false;
- switch ( $action ){
- case 'create-custom-filter':
- list($message, $msg_class) = $this->do_create_custom_filter();
- break;
-
- case 'delete-custom-filter':
- list($message, $msg_class) = $this->do_delete_custom_filter();
- break;
- /** @noinspection PhpMissingBreakStatementInspection Deliberate fall-through. */
- case 'bulk-delete-sources':
- $force_delete = true;
- case 'bulk-trash-sources':
- list($message, $msg_class) = $this->do_bulk_delete_sources($selected_links, $force_delete);
- break;
-
- case 'bulk-unlink':
- list($message, $msg_class) = $this->do_bulk_unlink($selected_links);
- break;
-
- case 'bulk-deredirect':
- list($message, $msg_class) = $this->do_bulk_deredirect($selected_links);
- break;
-
- case 'bulk-recheck':
- list($message, $msg_class) = $this->do_bulk_recheck($selected_links);
- break;
-
- case 'bulk-not-broken':
- list($message, $msg_class) = $this->do_bulk_discard($selected_links);
- break;
- case 'bulk-edit':
- list($message, $msg_class) = $this->do_bulk_edit($selected_links);
- break;
- }
-
-
- if ( !empty($message) ){
- echo '<div id="message" class="'.$msg_class.' fade"><p>'.$message.'</p></div>';
- }
-
- $start_time = microtime_float();
-
- //Load custom filters, if any
- $blc_link_query->load_custom_filters();
-
- //Calculate the number of links matching each filter
- $blc_link_query->count_filter_results();
-
- //Run the selected filter (defaults to displaying broken links)
- $selected_filter_id = isset($_GET['filter_id'])?$_GET['filter_id']:'broken';
- $current_filter = $blc_link_query->exec_filter(
- $selected_filter_id,
- isset($_GET['paged']) ? intval($_GET['paged']) : 1,
- $this->conf->options['table_links_per_page'],
- 'broken',
- isset($_GET['orderby']) ? $_GET['orderby'] : '',
- isset($_GET['order']) ? $_GET['order'] : ''
- );
- //exec_filter() returns an array with filter data, including the actual filter ID that was used.
- $filter_id = $current_filter['filter_id'];
- //Error?
- if ( empty($current_filter['links']) && !empty($wpdb->last_error) ){
- printf( __('Database error : %s', 'broken-link-checker'), $wpdb->last_error);
- }
- ?>
-
- <script type='text/javascript'>
- var blc_current_filter = '<?php echo $filter_id; ?>';
- var blc_is_broken_filter = <?php echo $current_filter['is_broken_filter'] ? 'true' : 'false'; ?>;
- var blc_current_base_filter = '<?php echo esc_js($current_filter['base_filter']); ?>';
- </script>
-
- <div class="wrap"><?php screen_icon(); ?>
- <?php
- $blc_link_query->print_filter_heading($current_filter);
- $blc_link_query->print_filter_menu($filter_id);
-
- //Display the "Search" form and associated buttons.
- //The form requires the $filter_id and $current_filter variables to be set.
- include dirname($this->loader) . '/includes/admin/search-form.php';
-
- //If the user has decided to switch the table to a different mode (compact/full),
- //save the new setting.
- if ( isset($_GET['compact']) ){
- $this->conf->options['table_compact'] = (bool)$_GET['compact'];
- $this->conf->save_options();
- }
- //Display the links, if any
- if( $current_filter['links'] && ( count($current_filter['links']) > 0 ) ) {
-
- include dirname($this->loader) . '/includes/admin/table-printer.php';
- $table = new blcTablePrinter($this);
- $table->print_table(
- $current_filter,
- $this->conf->options['table_layout'],
- $this->conf->options['table_visible_columns'],
- $this->conf->options['table_compact']
- );
- };
- printf('<!-- Total elapsed : %.4f seconds -->', microtime_float() - $start_time);
-
- //Load assorted JS event handlers and other shinies
- include dirname($this->loader) . '/includes/admin/links-page-js.php';
-
- ?></div><?php
- }
-
- /**
- * Create a custom link filter using params passed in $_POST.
- *
- * @uses $_POST
- * @uses $_GET to replace the current filter ID (if any) with that of the newly created filter.
- *
- * @return array Message and the CSS class to apply to the message.
- */
- function do_create_custom_filter(){
- global $wpdb;
- //Create a custom filter!
- check_admin_referer( 'create-custom-filter' );
- $msg_class = 'updated';
-
- //Filter name must be set
- if ( empty($_POST['name']) ){
- $message = __("You must enter a filter name!", 'broken-link-checker');
- $msg_class = 'error';
- //Filter parameters (a search query) must also be set
- } elseif ( empty($_POST['params']) ){
- $message = __("Invalid search query.", 'broken-link-checker');
- $msg_class = 'error';
- } else {
- //Save the new filter
- $blc_link_query = blcLinkQuery::getInstance();
- $filter_id = $blc_link_query->create_custom_filter($_POST['name'], $_POST['params']);
-
- if ( $filter_id ){
- //Saved
- $message = sprintf( __('Filter "%s" created', 'broken-link-checker'), $_POST['name']);
- //A little hack to make the filter active immediately
- $_GET['filter_id'] = $filter_id;
- } else {
- //Error
- $message = sprintf( __("Database error : %s", 'broken-link-checker'), $wpdb->last_error);
- $msg_class = 'error';
- }
- }
-
- return array($message, $msg_class);
- }
-
- /**
- * Delete a custom link filter.
- *
- * @uses $_POST
- *
- * @return array Message and a CSS class to apply to the message.
- */
- function do_delete_custom_filter(){
- //Delete an existing custom filter!
- check_admin_referer( 'delete-custom-filter' );
- $msg_class = 'updated';
-
- //Filter ID must be set
- if ( empty($_POST['filter_id']) ){
- $message = __("Filter ID not specified.", 'broken-link-checker');
- $msg_class = 'error';
- } else {
- //Try to delete the filter
- $blc_link_query = blcLinkQuery::getInstance();
- if ( $blc_link_query->delete_custom_filter($_POST['filter_id']) ){
- //Success
- $message = __('Filter deleted', 'broken-link-checker');
- } else {
- //Either the ID is wrong or there was some other error
- $message = __('Database error : %s', 'broken-link-checker');
- $msg_class = 'error';
- }
- }
-
- return array($message, $msg_class);
- }
-
- /**
- * Modify multiple links to point to their target URLs.
- *
- * @param array $selected_links
- * @return array The message to display and its CSS class.
- */
- function do_bulk_deredirect($selected_links){
- //For all selected links…
Large files files are truncated, but you can click here to view the full file