PageRenderTime 56ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/broken-link-checker/core/core.php

https://bitbucket.org/lgorence/quickpress
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

  1. <?php
  2. /**
  3. * Simple function to replicate PHP 5 behaviour
  4. */
  5. if ( !function_exists( 'microtime_float' ) ) {
  6. function microtime_float()
  7. {
  8. list($usec, $sec) = explode(" ", microtime());
  9. return ((float)$usec + (float)$sec);
  10. }
  11. }
  12. require BLC_DIRECTORY . '/includes/screen-options/screen-options.php';
  13. require BLC_DIRECTORY . '/includes/screen-meta-links.php';
  14. require BLC_DIRECTORY . '/includes/wp-mutex.php';
  15. if (!class_exists('wsBrokenLinkChecker')) {
  16. class wsBrokenLinkChecker {
  17. var $conf;
  18. var $loader;
  19. var $my_basename = '';
  20. var $db_version; //The required version of the plugin's DB schema.
  21. var $execution_start_time; //Used for a simple internal execution timer in start_timer()/execution_time()
  22. /**
  23. * wsBrokenLinkChecker::wsBrokenLinkChecker()
  24. * Class constructor
  25. *
  26. * @param string $loader The fully qualified filename of the loader script that WP identifies as the "main" plugin file.
  27. * @param blcConfigurationManager $conf An instance of the configuration manager
  28. * @return void
  29. */
  30. function wsBrokenLinkChecker ( $loader, &$conf ) {
  31. global $wpdb;
  32. $this->db_version = BLC_DATABASE_VERSION;
  33. $this->conf = &$conf;
  34. $this->loader = $loader;
  35. $this->my_basename = plugin_basename( $this->loader );
  36. $this->load_language();
  37. //Unlike the activation hook, the deactivation callback *can* be registered in this file
  38. //because deactivation happens after this class has already been instantiated (durinng the
  39. //'init' action).
  40. register_deactivation_hook($loader, array(&$this, 'deactivation'));
  41. add_action('admin_menu', array(&$this,'admin_menu'));
  42. //Load jQuery on Dashboard pages (probably redundant as WP already does that)
  43. add_action('admin_print_scripts', array(&$this,'admin_print_scripts'));
  44. //The dashboard widget
  45. add_action('wp_dashboard_setup', array(&$this, 'hook_wp_dashboard_setup'));
  46. //AJAXy hooks
  47. add_action( 'wp_ajax_blc_full_status', array(&$this,'ajax_full_status') );
  48. add_action( 'wp_ajax_blc_dashboard_status', array(&$this,'ajax_dashboard_status') );
  49. add_action( 'wp_ajax_blc_work', array(&$this,'ajax_work') );
  50. add_action( 'wp_ajax_blc_discard', array(&$this,'ajax_discard') );
  51. add_action( 'wp_ajax_blc_edit', array(&$this,'ajax_edit') );
  52. add_action( 'wp_ajax_blc_link_details', array(&$this,'ajax_link_details') );
  53. add_action( 'wp_ajax_blc_unlink', array(&$this,'ajax_unlink') );
  54. add_action( 'wp_ajax_blc_current_load', array(&$this,'ajax_current_load') );
  55. add_action( 'wp_ajax_blc_dismiss', array($this, 'ajax_dismiss') );
  56. add_action( 'wp_ajax_blc_undismiss', array($this, 'ajax_undismiss') );
  57. //Add/remove Cron events
  58. $this->setup_cron_events();
  59. //Set hooks that listen for our Cron actions
  60. add_action('blc_cron_email_notifications', array( &$this, 'maybe_send_email_notifications' ));
  61. add_action('blc_cron_check_links', array(&$this, 'cron_check_links'));
  62. add_action('blc_cron_database_maintenance', array(&$this, 'database_maintenance'));
  63. add_action('blc_cron_check_news', array(&$this, 'check_news'));
  64. //Set the footer hook that will call the worker function via AJAX.
  65. add_action('admin_footer', array(&$this,'admin_footer'));
  66. //Add a "Screen Options" panel to the "Broken Links" page
  67. add_screen_options_panel(
  68. 'blc-screen-options',
  69. '',
  70. array(&$this, 'screen_options_html'),
  71. 'tools_page_view-broken-links',
  72. array(&$this, 'ajax_save_screen_options'),
  73. true
  74. );
  75. }
  76. /**
  77. * Output the script that runs the link monitor while the Dashboard is open.
  78. *
  79. * @return void
  80. */
  81. function admin_footer(){
  82. if ( !$this->conf->options['run_in_dashboard'] ){
  83. return;
  84. }
  85. ?>
  86. <!-- wsblc admin footer -->
  87. <script type='text/javascript'>
  88. (function($){
  89. //(Re)starts the background worker thread
  90. function blcDoWork(){
  91. $.post(
  92. "<?php echo admin_url('admin-ajax.php'); ?>",
  93. {
  94. 'action' : 'blc_work'
  95. }
  96. );
  97. }
  98. //Call it the first time
  99. blcDoWork();
  100. //Then call it periodically every X seconds
  101. setInterval(blcDoWork, <?php echo (intval($this->conf->options['max_execution_time']) + 1 )*1000; ?>);
  102. })(jQuery);
  103. </script>
  104. <!-- /wsblc admin footer -->
  105. <?php
  106. }
  107. /**
  108. * Check if an URL matches the exclusion list.
  109. *
  110. * @param string $url
  111. * @return bool
  112. */
  113. function is_excluded($url){
  114. if (!is_array($this->conf->options['exclusion_list'])) return false;
  115. foreach($this->conf->options['exclusion_list'] as $excluded_word){
  116. if (stristr($url, $excluded_word)){
  117. return true;
  118. }
  119. }
  120. return false;
  121. }
  122. function dashboard_widget(){
  123. ?>
  124. <p id='wsblc_activity_box'><?php _e('Loading...', 'broken-link-checker'); ?></p>
  125. <script type='text/javascript'>
  126. jQuery( function($){
  127. var blc_was_autoexpanded = false;
  128. function blcDashboardStatus(){
  129. $.getJSON(
  130. "<?php echo admin_url('admin-ajax.php'); ?>",
  131. {
  132. 'action' : 'blc_dashboard_status',
  133. 'random' : Math.random()
  134. },
  135. function (data, textStatus){
  136. if ( data && ( typeof(data.text) != 'undefined' ) ) {
  137. $('#wsblc_activity_box').html(data.text);
  138. <?php if ( $this->conf->options['autoexpand_widget'] ) { ?>
  139. //Expand the widget if there are broken links.
  140. //Do this only once per pageload so as not to annoy the user.
  141. if ( !blc_was_autoexpanded && ( data.status.broken_links > 0 ) ){
  142. $('#blc_dashboard_widget.postbox').removeClass('closed');
  143. blc_was_autoexpanded = true;
  144. }
  145. <?php } ?>
  146. } else {
  147. $('#wsblc_activity_box').html('<?php _e('[ Network error ]', 'broken-link-checker'); ?>');
  148. }
  149. setTimeout( blcDashboardStatus, 120*1000 ); //...update every two minutes
  150. }
  151. );
  152. }
  153. blcDashboardStatus();//Call it the first time
  154. } );
  155. </script>
  156. <?php
  157. }
  158. function dashboard_widget_control(
  159. /** @noinspection PhpUnusedParameterInspection */ $widget_id, $form_inputs = array()
  160. ){
  161. if ( 'POST' == $_SERVER['REQUEST_METHOD'] && 'blc_dashboard_widget' == $_POST['widget_id'] ) {
  162. //It appears $form_inputs isn't used in the current WP version, so lets just use $_POST
  163. $this->conf->options['autoexpand_widget'] = !empty($_POST['blc-autoexpand']);
  164. $this->conf->save_options();
  165. }
  166. ?>
  167. <p><label for="blc-autoexpand">
  168. <input id="blc-autoexpand" name="blc-autoexpand" type="checkbox" value="1" <?php if ( $this->conf->options['autoexpand_widget'] ) echo 'checked="checked"'; ?> />
  169. <?php _e('Automatically expand the widget if broken links have been detected', 'broken-link-checker'); ?>
  170. </label></p>
  171. <?php
  172. }
  173. function admin_print_scripts(){
  174. //jQuery is used for triggering the link monitor via AJAX when any admin page is open.
  175. wp_enqueue_script('jquery');
  176. }
  177. function enqueue_settings_scripts(){
  178. //jQuery UI is used on the settings page
  179. wp_enqueue_script('jquery-ui-core'); //Used for background color animation
  180. wp_enqueue_script('jquery-ui-dialog');
  181. wp_enqueue_script('jquery-ui-tabs');
  182. wp_enqueue_script('jquery-cookie', plugins_url('js/jquery.cookie.js', BLC_PLUGIN_FILE)); //Used for storing last widget states, etc
  183. }
  184. function enqueue_link_page_scripts(){
  185. wp_enqueue_script('jquery-ui-core'); //Used for background color animation
  186. wp_enqueue_script('jquery-ui-dialog'); //Used for the search form
  187. wp_enqueue_script('sprintf', plugins_url('js/sprintf.js', BLC_PLUGIN_FILE)); //Used in error messages
  188. }
  189. /**
  190. * Initiate a full recheck - reparse everything and check all links anew.
  191. *
  192. * @return void
  193. */
  194. function initiate_recheck(){
  195. global $wpdb; /** @var wpdb $wpdb */
  196. //Delete all discovered instances
  197. $wpdb->query("TRUNCATE {$wpdb->prefix}blc_instances");
  198. //Delete all discovered links
  199. $wpdb->query("TRUNCATE {$wpdb->prefix}blc_links");
  200. //Mark all posts, custom fields and bookmarks for processing.
  201. blc_resynch(true);
  202. }
  203. /**
  204. * A hook executed when the plugin is deactivated.
  205. *
  206. * @return void
  207. */
  208. function deactivation(){
  209. //Remove our Cron events
  210. wp_clear_scheduled_hook('blc_cron_check_links');
  211. wp_clear_scheduled_hook('blc_cron_email_notifications');
  212. wp_clear_scheduled_hook('blc_cron_database_maintenance');
  213. wp_clear_scheduled_hook('blc_cron_check_news');
  214. //Note the deactivation time for each module. This will help them
  215. //synch up propely if/when the plugin is reactivated.
  216. $moduleManager = blcModuleManager::getInstance();
  217. $the_time = current_time('timestamp');
  218. foreach($moduleManager->get_active_modules() as $module_id => $module){
  219. $this->conf->options['module_deactivated_when'][$module_id] = $the_time;
  220. }
  221. $this->conf->save_options();
  222. }
  223. /**
  224. * Perform various database maintenance tasks on the plugin's tables.
  225. *
  226. * Removes records that reference disabled containers and parsers,
  227. * deletes invalid instances and links, optimizes tables, etc.
  228. *
  229. * @return void
  230. */
  231. function database_maintenance(){
  232. blcContainerHelper::cleanup_containers();
  233. blc_cleanup_instances();
  234. blc_cleanup_links();
  235. blcUtility::optimize_database();
  236. }
  237. /**
  238. * Create the plugin's menu items and enqueue their scripts and CSS.
  239. * Callback for the 'admin_menu' action.
  240. *
  241. * @return void
  242. */
  243. function admin_menu(){
  244. if (current_user_can('manage_options'))
  245. add_filter('plugin_action_links', array(&$this, 'plugin_action_links'), 10, 2);
  246. $options_page_hook = add_options_page(
  247. __('Link Checker Settings', 'broken-link-checker'),
  248. __('Link Checker', 'broken-link-checker'),
  249. 'manage_options',
  250. 'link-checker-settings',array(&$this, 'options_page')
  251. );
  252. $menu_title = __('Broken Links', 'broken-link-checker');
  253. if ( $this->conf->options['show_link_count_bubble'] ){
  254. //To make it easier to notice when broken links appear, display the current number of
  255. //broken links in a little bubble notification in the "Broken Links" menu.
  256. //(Similar to how the number of plugin updates and unmoderated comments is displayed).
  257. $blc_link_query = blcLinkQuery::getInstance();
  258. $broken_links = $blc_link_query->get_filter_links('broken', array('count_only' => true));
  259. if ( $broken_links > 0 ){
  260. //TODO: Appropriating existing CSS classes for my own purposes is hacky. Fix eventually.
  261. $menu_title .= sprintf(
  262. ' <span class="update-plugins"><span class="update-count blc-menu-bubble">%d</span></span>',
  263. $broken_links
  264. );
  265. }
  266. }
  267. $links_page_hook = add_management_page(
  268. __('View Broken Links', 'broken-link-checker'),
  269. $menu_title,
  270. 'edit_others_posts',
  271. 'view-broken-links',array(&$this, 'links_page')
  272. );
  273. //Add plugin-specific scripts and CSS only to the it's own pages
  274. add_action( 'admin_print_styles-' . $options_page_hook, array(&$this, 'options_page_css') );
  275. add_action( 'admin_print_styles-' . $links_page_hook, array(&$this, 'links_page_css') );
  276. add_action( 'admin_print_scripts-' . $options_page_hook, array(&$this, 'enqueue_settings_scripts') );
  277. add_action( 'admin_print_scripts-' . $links_page_hook, array(&$this, 'enqueue_link_page_scripts') );
  278. //Add a "Feedback" button that links to the plugin's UserVoice forum
  279. add_screen_meta_link(
  280. 'blc-feedback-widget',
  281. __('Feedback', 'broken-link-checker'),
  282. 'http://whiteshadow.uservoice.com/forums/58400-broken-link-checker',
  283. array($options_page_hook, $links_page_hook)
  284. );
  285. //Add a link to the Admin Menu Editor site to the "Broken Links" page.
  286. if ( !$this->conf->get('user_has_donated') ) {
  287. //Choose anchor text randomly.
  288. $possible_anchor_texts = array(
  289. 'Organize WordPress admin menu',
  290. 'Simplify WordPress Admin Menu',
  291. 'Customize WP Admin Menu',
  292. 'Organize WP Admin: use Admin Menu Editor',
  293. 'Web Developer? Check out Admin Menu Editor',
  294. 'Admin Menu Editor for WP',
  295. 'Organize, Hide And Customize Admin Menus',
  296. );
  297. $index = $this->conf->get('view-broken-links-meta-ad', null);
  298. if ( $index === null ) {
  299. $index = rand(0, count($possible_anchor_texts) - 1);
  300. $this->conf->set('view-broken-links-meta-ad', $index);
  301. $this->conf->save_options();
  302. }
  303. add_screen_meta_link(
  304. 'blc-more-plugins-link',
  305. $possible_anchor_texts[$index],
  306. sprintf(
  307. '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',
  308. urlencode($index)
  309. ),
  310. $links_page_hook,
  311. array('style' => 'font-weight: bold;')
  312. );
  313. }
  314. //Make the Settings page link to the link list
  315. add_screen_meta_link(
  316. 'blc-links-page-link',
  317. __('Go to Broken Links', 'broken-link-checker'),
  318. admin_url('tools.php?page=view-broken-links'),
  319. $options_page_hook,
  320. array('style' => 'font-weight: bold;')
  321. );
  322. //Add a link to the latest blog post/whatever about this plugin, if any.
  323. if ( isset($this->conf->options['plugin_news']) && !empty($this->conf->options['plugin_news']) ){
  324. $news = $this->conf->options['plugin_news'];
  325. add_screen_meta_link(
  326. 'blc-plugin-news-link',
  327. $news[0],
  328. $news[1],
  329. array($options_page_hook, $links_page_hook)
  330. );
  331. }
  332. }
  333. /**
  334. * plugin_action_links()
  335. * Handler for the 'plugin_action_links' hook. Adds a "Settings" link to this plugin's entry
  336. * on the plugin list.
  337. *
  338. * @param array $links
  339. * @param string $file
  340. * @return array
  341. */
  342. function plugin_action_links($links, $file) {
  343. if ($file == $this->my_basename)
  344. $links[] = "<a href='options-general.php?page=link-checker-settings'>" . __('Settings') . "</a>";
  345. return $links;
  346. }
  347. function options_page(){
  348. global $blclog;
  349. $moduleManager = blcModuleManager::getInstance();
  350. //Prior to 1.5.2 (released 2012-05-27), there was a bug that would cause the donation flag to be
  351. //set incorrectly. So we'll unset the flag in that case.
  352. $reset_donation_flag =
  353. ($this->conf->get('first_installation_timestamp', 0) < strtotime('2012-05-27 00:00')) &&
  354. !$this->conf->get('donation_flag_fixed', false);
  355. if ( $reset_donation_flag) {
  356. $this->conf->set('user_has_donated', false);
  357. $this->conf->set('donation_flag_fixed', true);
  358. $this->conf->save_options();
  359. }
  360. if (isset($_POST['recheck']) && !empty($_POST['recheck']) ){
  361. $this->initiate_recheck();
  362. //Redirect back to the settings page
  363. $base_url = remove_query_arg( array('_wpnonce', 'noheader', 'updated', 'error', 'action', 'message') );
  364. wp_redirect( add_query_arg( array( 'recheck-initiated' => true), $base_url ) );
  365. die();
  366. }
  367. if(isset($_POST['submit'])) {
  368. check_admin_referer('link-checker-options');
  369. //Activate/deactivate modules
  370. if ( !empty($_POST['module']) ){
  371. $active = array_keys($_POST['module']);
  372. $moduleManager->set_active_modules($active);
  373. }
  374. //Only post statuses that actually exist can be selected
  375. if ( isset($_POST['enabled_post_statuses']) && is_array($_POST['enabled_post_statuses']) ){
  376. $available_statuses = get_post_stati();
  377. $enabled_post_statuses = array_intersect($_POST['enabled_post_statuses'], $available_statuses);
  378. } else {
  379. $enabled_post_statuses = array();
  380. }
  381. //At least one status must be enabled; defaults to "Published".
  382. if ( empty($enabled_post_statuses) ){
  383. $enabled_post_statuses = array('publish');
  384. }
  385. $this->conf->options['enabled_post_statuses'] = $enabled_post_statuses;
  386. //The execution time limit must be above zero
  387. $new_execution_time = intval($_POST['max_execution_time']);
  388. if( $new_execution_time > 0 ){
  389. $this->conf->options['max_execution_time'] = $new_execution_time;
  390. }
  391. //The check threshold also must be > 0
  392. $new_check_threshold=intval($_POST['check_threshold']);
  393. if( $new_check_threshold > 0 ){
  394. $this->conf->options['check_threshold'] = $new_check_threshold;
  395. }
  396. $this->conf->options['mark_broken_links'] = !empty($_POST['mark_broken_links']);
  397. $new_broken_link_css = trim($_POST['broken_link_css']);
  398. $this->conf->options['broken_link_css'] = $new_broken_link_css;
  399. $this->conf->options['mark_removed_links'] = !empty($_POST['mark_removed_links']);
  400. $new_removed_link_css = trim($_POST['removed_link_css']);
  401. $this->conf->options['removed_link_css'] = $new_removed_link_css;
  402. $this->conf->options['nofollow_broken_links'] = !empty($_POST['nofollow_broken_links']);
  403. $this->conf->options['exclusion_list'] = array_filter(
  404. preg_split(
  405. '/[\s\r\n]+/', //split on newlines and whitespace
  406. $_POST['exclusion_list'],
  407. -1,
  408. PREG_SPLIT_NO_EMPTY //skip empty values
  409. )
  410. );
  411. //Parse the custom field list
  412. $new_custom_fields = array_filter(
  413. preg_split( '/[\r\n]+/', $_POST['blc_custom_fields'], -1, PREG_SPLIT_NO_EMPTY )
  414. );
  415. //Calculate the difference between the old custom field list and the new one (used later)
  416. $diff1 = array_diff( $new_custom_fields, $this->conf->options['custom_fields'] );
  417. $diff2 = array_diff( $this->conf->options['custom_fields'], $new_custom_fields );
  418. $this->conf->options['custom_fields'] = $new_custom_fields;
  419. //HTTP timeout
  420. $new_timeout = intval($_POST['timeout']);
  421. if( $new_timeout > 0 ){
  422. $this->conf->options['timeout'] = $new_timeout ;
  423. }
  424. //Server load limit
  425. if ( isset($_POST['server_load_limit']) ){
  426. $this->conf->options['server_load_limit'] = floatval($_POST['server_load_limit']);
  427. if ( $this->conf->options['server_load_limit'] < 0 ){
  428. $this->conf->options['server_load_limit'] = 0;
  429. }
  430. $this->conf->options['enable_load_limit'] = $this->conf->options['server_load_limit'] > 0;
  431. }
  432. //When to run the checker
  433. $this->conf->options['run_in_dashboard'] = !empty($_POST['run_in_dashboard']);
  434. $this->conf->options['run_via_cron'] = !empty($_POST['run_via_cron']);
  435. //Email notifications on/off
  436. $email_notifications = !empty($_POST['send_email_notifications']);
  437. $send_authors_email_notifications = !empty($_POST['send_authors_email_notifications']);
  438. if (
  439. ($email_notifications && !$this->conf->options['send_email_notifications'])
  440. || ($send_authors_email_notifications && !$this->conf->options['send_authors_email_notifications'])
  441. ){
  442. /*
  443. The plugin should only send notifications about links that have become broken
  444. since the time when email notifications were turned on. If we don't do this,
  445. the first email notification will be sent nigh-immediately and list *all* broken
  446. links that the plugin currently knows about.
  447. */
  448. $this->conf->options['last_notification_sent'] = time();
  449. }
  450. $this->conf->options['send_email_notifications'] = $email_notifications;
  451. $this->conf->options['send_authors_email_notifications'] = $send_authors_email_notifications;
  452. //Make settings that affect our Cron events take effect immediately
  453. $this->setup_cron_events();
  454. $this->conf->save_options();
  455. /*
  456. If the list of custom fields was modified then we MUST resynchronize or
  457. custom fields linked with existing posts may not be detected. This is somewhat
  458. inefficient.
  459. */
  460. if ( ( count($diff1) > 0 ) || ( count($diff2) > 0 ) ){
  461. $manager = blcContainerHelper::get_manager('custom_field');
  462. if ( !is_null($manager) ){
  463. $manager->resynch();
  464. blc_got_unsynched_items();
  465. }
  466. }
  467. //Redirect back to the settings page
  468. $base_url = remove_query_arg( array('_wpnonce', 'noheader', 'updated', 'error', 'action', 'message') );
  469. wp_redirect( add_query_arg( array( 'settings-updated' => true), $base_url ) );
  470. }
  471. //Show a confirmation message when settings are saved.
  472. if ( !empty($_GET['settings-updated']) ){
  473. echo '<div id="message" class="updated fade"><p><strong>',__('Settings saved.', 'broken-link-checker'), '</strong></p></div>';
  474. }
  475. //Show a thank-you message when a donation is made.
  476. if ( !empty($_GET['donated']) ){
  477. echo '<div id="message" class="updated fade"><p><strong>',__('Thank you for your donation!', 'broken-link-checker'), '</strong></p></div>';
  478. $this->conf->set('user_has_donated', true);
  479. $this->conf->save_options();
  480. }
  481. //Show one when recheck is started, too.
  482. if ( !empty($_GET['recheck-initiated']) ){
  483. echo '<div id="message" class="updated fade"><p><strong>',
  484. __('Complete site recheck started.', 'broken-link-checker'), // -- Yoda
  485. '</strong></p></div>';
  486. }
  487. //Cull invalid and missing modules
  488. $moduleManager->validate_active_modules();
  489. $debug = $this->get_debug_info();
  490. $details_text = __('Details', 'broken-link-checker');
  491. add_filter('blc-module-settings-custom_field', array(&$this, 'make_custom_field_input'), 10, 2);
  492. //Translate and markup-ify module headers for display
  493. $modules = $moduleManager->get_modules_by_category('', true, true);
  494. //Output the custom broken link/removed link styles for example links
  495. printf(
  496. '<style type="text/css">%s %s</style>',
  497. $this->conf->options['broken_link_css'],
  498. $this->conf->options['removed_link_css']
  499. );
  500. $section_names = array(
  501. 'general' => __('General', 'broken-link-checker'),
  502. 'where' => __('Look For Links In', 'broken-link-checker'),
  503. 'which' => __('Which Links To Check', 'broken-link-checker'),
  504. 'how' => __('Protocols & APIs', 'broken-link-checker'),
  505. 'advanced' => __('Advanced', 'broken-link-checker'),
  506. );
  507. ?>
  508. <!--[if lte IE 7]>
  509. <style type="text/css">
  510. /* Simulate inline-block in IE7 */
  511. ul.ui-tabs-nav li {
  512. display: inline;
  513. zoom: 1;
  514. }
  515. </style>
  516. <![endif]-->
  517. <div class="wrap" id="blc-settings-wrap">
  518. <?php screen_icon(); ?><h2><?php _e('Broken Link Checker Options', 'broken-link-checker'); ?></h2>
  519. <div id="blc-sidebar">
  520. <div class="metabox-holder">
  521. <?php include BLC_DIRECTORY . '/includes/admin/sidebar.php'; ?>
  522. </div>
  523. </div>
  524. <div id="blc-admin-content">
  525. <form name="link_checker_options" id="link_checker_options" method="post" action="<?php
  526. echo admin_url('options-general.php?page=link-checker-settings&noheader=1');
  527. ?>">
  528. <?php
  529. wp_nonce_field('link-checker-options');
  530. ?>
  531. <div id="blc-tabs">
  532. <ul class="hide-if-no-js">
  533. <?php
  534. foreach($section_names as $section_id => $section_name){
  535. printf(
  536. '<li id="tab-button-%s"><a href="#section-%s" title="%s">%s</a></li>',
  537. esc_attr($section_id),
  538. esc_attr($section_id),
  539. esc_attr($section_name),
  540. $section_name
  541. );
  542. }
  543. ?>
  544. </ul>
  545. <div id="section-general" class="blc-section">
  546. <h3 class="hide-if-js"><?php echo $section_names['general']; ?></h3>
  547. <table class="form-table">
  548. <tr valign="top">
  549. <th scope="row">
  550. <?php _e('Status','broken-link-checker'); ?>
  551. <br>
  552. <a href="javascript:void(0)" id="blc-debug-info-toggle"><?php _e('Show debug info', 'broken-link-checker'); ?></a>
  553. </th>
  554. <td>
  555. <div id='wsblc_full_status'>
  556. <br/><br/><br/>
  557. </div>
  558. <table id="blc-debug-info">
  559. <?php
  560. //Output the debug info in a table
  561. foreach( $debug as $key => $value ){
  562. printf (
  563. '<tr valign="top" class="blc-debug-item-%s"><th scope="row">%s</th><td>%s<div class="blc-debug-message">%s</div></td></tr>',
  564. $value['state'],
  565. $key,
  566. $value['value'],
  567. ( array_key_exists('message', $value)?$value['message']:'')
  568. );
  569. }
  570. ?>
  571. </table>
  572. </td>
  573. </tr>
  574. <tr valign="top">
  575. <th scope="row"><?php _e('Check each link','broken-link-checker'); ?></th>
  576. <td>
  577. <?php
  578. printf(
  579. __('Every %s hours','broken-link-checker'),
  580. sprintf(
  581. '<input type="text" name="check_threshold" id="check_threshold" value="%d" size="5" maxlength="5" />',
  582. $this->conf->options['check_threshold']
  583. )
  584. );
  585. ?>
  586. <br/>
  587. <span class="description">
  588. <?php _e('Existing links will be checked this often. New links will usually be checked ASAP.', 'broken-link-checker'); ?>
  589. </span>
  590. </td>
  591. </tr>
  592. <tr valign="top">
  593. <th scope="row"><?php _e('E-mail notifications', 'broken-link-checker'); ?></th>
  594. <td>
  595. <p style="margin-top: 0;">
  596. <label for='send_email_notifications'>
  597. <input type="checkbox" name="send_email_notifications" id="send_email_notifications"
  598. <?php if ($this->conf->options['send_email_notifications']) echo ' checked="checked"'; ?>/>
  599. <?php _e('Send me e-mail notifications about newly detected broken links', 'broken-link-checker'); ?>
  600. </label><br />
  601. </p>
  602. <p>
  603. <label for='send_authors_email_notifications'>
  604. <input type="checkbox" name="send_authors_email_notifications" id="send_authors_email_notifications"
  605. <?php if ($this->conf->options['send_authors_email_notifications']) echo ' checked="checked"'; ?>/>
  606. <?php _e('Send authors e-mail notifications about broken links in their posts', 'broken-link-checker'); ?>
  607. </label><br />
  608. </p>
  609. </td>
  610. </tr>
  611. <tr valign="top">
  612. <th scope="row"><?php _e('Link tweaks','broken-link-checker'); ?></th>
  613. <td>
  614. <p style="margin-top: 0; margin-bottom: 0.5em;">
  615. <label for='mark_broken_links'>
  616. <input type="checkbox" name="mark_broken_links" id="mark_broken_links"
  617. <?php if ($this->conf->options['mark_broken_links']) echo ' checked="checked"'; ?>/>
  618. <?php _e('Apply custom formatting to broken links', 'broken-link-checker'); ?>
  619. </label>
  620. |
  621. <a id="toggle-broken-link-css-editor" href="#" class="blc-toggle-link"><?php
  622. _e('Edit CSS', 'broken-link-checker');
  623. ?></a>
  624. </p>
  625. <div id="broken-link-css-wrap"<?php
  626. if ( !blcUtility::get_cookie('broken-link-css-wrap', false) ){
  627. echo ' class="hidden"';
  628. }
  629. ?>>
  630. <textarea name="broken_link_css" id="broken_link_css" cols='45' rows='4'/><?php
  631. if( isset($this->conf->options['broken_link_css']) ) {
  632. echo $this->conf->options['broken_link_css'];
  633. }
  634. ?></textarea>
  635. <p class="description"><?php
  636. printf(
  637. __('Example : Lorem ipsum <a %s>broken link</a>, dolor sit amet.', 'broken-link-checker'),
  638. ' href="#" class="broken_link" onclick="return false;"'
  639. );
  640. echo ' ', __('Click "Save Changes" to update example output.', 'broken-link-checker');
  641. ?></p>
  642. </div>
  643. <p style="margin-bottom: 0.5em;">
  644. <label for='mark_removed_links'>
  645. <input type="checkbox" name="mark_removed_links" id="mark_removed_links"
  646. <?php if ($this->conf->options['mark_removed_links']) echo ' checked="checked"'; ?>/>
  647. <?php _e('Apply custom formatting to removed links', 'broken-link-checker'); ?>
  648. </label>
  649. |
  650. <a id="toggle-removed-link-css-editor" href="#" class="blc-toggle-link"><?php
  651. _e('Edit CSS', 'broken-link-checker');
  652. ?></a>
  653. </p>
  654. <div id="removed-link-css-wrap" <?php
  655. if ( !blcUtility::get_cookie('removed-link-css-wrap', false) ){
  656. echo ' class="hidden"';
  657. }
  658. ?>>
  659. <textarea name="removed_link_css" id="removed_link_css" cols='45' rows='4'/><?php
  660. if( isset($this->conf->options['removed_link_css']) )
  661. echo $this->conf->options['removed_link_css'];
  662. ?></textarea>
  663. <p class="description"><?php
  664. printf(
  665. __('Example : Lorem ipsum <span %s>removed link</span>, dolor sit amet.', 'broken-link-checker'),
  666. ' class="removed_link"'
  667. );
  668. echo ' ', __('Click "Save Changes" to update example output.', 'broken-link-checker');
  669. ?>
  670. </p>
  671. </div>
  672. <p>
  673. <label for='nofollow_broken_links'>
  674. <input type="checkbox" name="nofollow_broken_links" id="nofollow_broken_links"
  675. <?php if ($this->conf->options['nofollow_broken_links']) echo ' checked="checked"'; ?>/>
  676. <?php _e('Stop search engines from following broken links', 'broken-link-checker'); ?>
  677. </label>
  678. </p>
  679. </td>
  680. </tr>
  681. </table>
  682. </div>
  683. <div id="section-where" class="blc-section">
  684. <h3 class="hide-if-js"><?php echo $section_names['where']; ?></h3>
  685. <table class="form-table">
  686. <tr valign="top">
  687. <th scope="row"><?php _e('Look for links in', 'broken-link-checker'); ?></th>
  688. <td>
  689. <?php
  690. if ( !empty($modules['container']) ){
  691. uasort($modules['container'], create_function('$a, $b', 'return strcasecmp($a["Name"], $b["Name"]);'));
  692. $this->print_module_list($modules['container'], $this->conf->options);
  693. }
  694. ?>
  695. </td></tr>
  696. <tr valign="top">
  697. <th scope="row"><?php _e('Post statuses', 'broken-link-checker'); ?></th>
  698. <td>
  699. <?php
  700. $available_statuses = get_post_stati(array('internal' => false), 'objects');
  701. if ( isset($this->conf->options['enabled_post_statuses']) ){
  702. $enabled_post_statuses = $this->conf->options['enabled_post_statuses'];
  703. } else {
  704. $enabled_post_statuses = array();
  705. }
  706. foreach($available_statuses as $status => $status_object){
  707. printf(
  708. '<p><label><input type="checkbox" name="enabled_post_statuses[]" value="%s"%s> %s</label></p>',
  709. esc_attr($status),
  710. in_array($status, $enabled_post_statuses)?' checked="checked"':'',
  711. $status_object->label
  712. );
  713. }
  714. ?>
  715. </td></tr>
  716. </table>
  717. </div>
  718. <div id="section-which" class="blc-section">
  719. <h3 class="hide-if-js"><?php echo $section_names['which']; ?></h3>
  720. <table class="form-table">
  721. <tr valign="top">
  722. <th scope="row"><?php _e('Link types', 'broken-link-checker'); ?></th>
  723. <td>
  724. <?php
  725. if ( !empty($modules['parser']) ){
  726. $this->print_module_list($modules['parser'], $this->conf->options);
  727. } else {
  728. echo __('Error : All link parsers missing!', 'broken-link-checker');
  729. }
  730. ?>
  731. </td>
  732. </tr>
  733. <tr valign="top">
  734. <th scope="row"><?php _e('Exclusion list', 'broken-link-checker'); ?></th>
  735. <td><?php _e("Don't check links where the URL contains any of these words (one per line) :", 'broken-link-checker'); ?><br/>
  736. <textarea name="exclusion_list" id="exclusion_list" cols='45' rows='4' wrap='off'/><?php
  737. if( isset($this->conf->options['exclusion_list']) )
  738. echo implode("\n", $this->conf->options['exclusion_list']);
  739. ?></textarea>
  740. </td>
  741. </tr>
  742. </table>
  743. </div>
  744. <div id="section-how" class="blc-section">
  745. <h3 class="hide-if-js"><?php echo $section_names['how']; ?></h3>
  746. <table class="form-table">
  747. <tr valign="top">
  748. <th scope="row"><?php _e('Check links using', 'broken-link-checker'); ?></th>
  749. <td>
  750. <?php
  751. if ( !empty($modules['checker']) ){
  752. $modules['checker'] = array_reverse($modules['checker']);
  753. $this->print_module_list($modules['checker'], $this->conf->options);
  754. }
  755. ?>
  756. </td></tr>
  757. </table>
  758. </div>
  759. <div id="section-advanced" class="blc-section">
  760. <h3 class="hide-if-js"><?php echo $section_names['advanced']; ?></h3>
  761. <table class="form-table">
  762. <tr valign="top">
  763. <th scope="row"><?php _e('Timeout', 'broken-link-checker'); ?></th>
  764. <td>
  765. <?php
  766. printf(
  767. __('%s seconds', 'broken-link-checker'),
  768. sprintf(
  769. '<input type="text" name="timeout" id="blc_timeout" value="%d" size="5" maxlength="3" />',
  770. $this->conf->options['timeout']
  771. )
  772. );
  773. ?>
  774. <br/><span class="description">
  775. <?php _e('Links that take longer than this to load will be marked as broken.','broken-link-checker'); ?>
  776. </span>
  777. </td>
  778. </tr>
  779. <tr valign="top">
  780. <th scope="row"><?php _e('Link monitor', 'broken-link-checker'); ?></th>
  781. <td>
  782. <p>
  783. <label for='run_in_dashboard'>
  784. <input type="checkbox" name="run_in_dashboard" id="run_in_dashboard"
  785. <?php if ($this->conf->options['run_in_dashboard']) echo ' checked="checked"'; ?>/>
  786. <?php _e('Run continuously while the Dashboard is open', 'broken-link-checker'); ?>
  787. </label>
  788. </p>
  789. <p>
  790. <label for='run_via_cron'>
  791. <input type="checkbox" name="run_via_cron" id="run_via_cron"
  792. <?php if ($this->conf->options['run_via_cron']) echo ' checked="checked"'; ?>/>
  793. <?php _e('Run hourly in the background', 'broken-link-checker'); ?>
  794. </label>
  795. </p>
  796. </td>
  797. </tr>
  798. <tr valign="top">
  799. <th scope="row"><?php _e('Max. execution time', 'broken-link-checker'); ?></th>
  800. <td>
  801. <?php
  802. printf(
  803. __('%s seconds', 'broken-link-checker'),
  804. sprintf(
  805. '<input type="text" name="max_execution_time" id="max_execution_time" value="%d" size="5" maxlength="5" />',
  806. $this->conf->options['max_execution_time']
  807. )
  808. );
  809. ?>
  810. <br/><span class="description">
  811. <?php
  812. _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');
  813. ?>
  814. </span>
  815. </td>
  816. </tr>
  817. <tr valign="top">
  818. <th scope="row"><?php _e('Server load limit', 'broken-link-checker'); ?></th>
  819. <td>
  820. <?php
  821. $load = blcUtility::get_server_load();
  822. $available = !empty($load);
  823. if ( $available ){
  824. $value = !empty($this->conf->options['server_load_limit'])?sprintf('%.2f', $this->conf->options['server_load_limit']):'';
  825. printf(
  826. '<input type="text" name="server_load_limit" id="server_load_limit" value="%s" size="5" maxlength="5"/> ',
  827. $value
  828. );
  829. printf(
  830. __('Current load : %s', 'broken-link-checker'),
  831. '<span id="wsblc_current_load">...</span>'
  832. );
  833. echo '<br/><span class="description">';
  834. printf(
  835. __(
  836. '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.',
  837. 'broken-link-checker'
  838. ),
  839. 'http://en.wikipedia.org/wiki/Load_(computing)'
  840. );
  841. echo '</span>';
  842. } else {
  843. echo '<input type="text" disabled="disabled" value="', esc_attr(__('Not available', 'broken-link-checker')), '" size="13"/><br>';
  844. echo '<span class="description">';
  845. _e('Load limiting only works on Linux-like systems where <code>/proc/loadavg</code> is present and accessible.', 'broken-link-checker');
  846. echo '</span>';
  847. }
  848. ?>
  849. </td>
  850. </tr>
  851. <tr valign="top">
  852. <th scope="row"><?php _e('Forced recheck', 'broken-link-checker'); ?></th>
  853. <td>
  854. <input class="button" type="button" name="start-recheck" id="start-recheck"
  855. value="<?php _e('Re-check all pages', 'broken-link-checker'); ?>" />
  856. <input type="hidden" name="recheck" value="" id="recheck" />
  857. <br />
  858. <span class="description"><?php
  859. _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');
  860. ?></span>
  861. </td>
  862. </tr>
  863. </table>
  864. </div>
  865. </div>
  866. <p class="submit"><input type="submit" name="submit" class='button-primary' value="<?php _e('Save Changes') ?>" /></p>
  867. </form>
  868. </div> <!-- First postbox-container -->
  869. </div>
  870. <?php
  871. //The various JS for this page is stored in a separate file for the purposes readability.
  872. include dirname($this->loader) . '/includes/admin/options-page-js.php';
  873. }
  874. /**
  875. * Output a list of modules and their settings.
  876. *
  877. * Each list entry will contain a checkbox that is checked if the module is
  878. * currently active.
  879. *
  880. * @param array $modules Array of modules to display
  881. * @param array $current_settings
  882. * @return void
  883. */
  884. function print_module_list($modules, $current_settings){
  885. $moduleManager = blcModuleManager::getInstance();
  886. foreach($modules as $module_id => $module_data){
  887. $module_id = $module_data['ModuleID'];
  888. $style = $module_data['ModuleHidden']?' style="display:none;"':'';
  889. printf(
  890. '<div class="module-container" id="module-container-%s"%s>',
  891. $module_id,
  892. $style
  893. );
  894. $this->print_module_checkbox($module_id, $module_data, $moduleManager->is_active($module_id));
  895. $extra_settings = apply_filters(
  896. 'blc-module-settings-'.$module_id,
  897. '',
  898. $current_settings
  899. );
  900. if ( !empty($extra_settings) ){
  901. printf(
  902. ' | <a class="blc-toggle-link toggle-module-settings" id="toggle-module-settings-%s" href="#">%s</a>',
  903. $module_id,
  904. __('Configure', 'broken-link-checker')
  905. );
  906. //The plugin remembers the last open/closed state of module configuration boxes
  907. $box_id = 'module-extra-settings-' . $module_id;
  908. $show = blcUtility::get_cookie(
  909. $box_id,
  910. $moduleManager->is_active($module_id)
  911. );
  912. printf(
  913. '<div class="module-extra-settings%s" id="%s">%s</div>',
  914. $show?'':' hidden',
  915. $box_id,
  916. $extra_settings
  917. );
  918. }
  919. echo '</div>';
  920. }
  921. }
  922. /**
  923. * Output a checkbox for a module.
  924. *
  925. * Generates a simple checkbox that can be used to mark a module as active/inactive.
  926. * If the specified module can't be deactivated (ModuleAlwaysActive = true), the checkbox
  927. * will be displayed in a disabled state and a hidden field will be created to make
  928. * form submissions work correctly.
  929. *
  930. * @param string $module_id Module ID.
  931. * @param array $module_data Associative array of module data.
  932. * @param bool $active If true, the newly created checkbox will start out checked.
  933. * @return void
  934. */
  935. function print_module_checkbox($module_id, $module_data, $active = false){
  936. $disabled = false;
  937. $name_prefix = 'module';
  938. $label_class = '';
  939. $active = $active || $module_data['ModuleAlwaysActive'];
  940. if ( $module_data['ModuleAlwaysActive'] ){
  941. $disabled = true;
  942. $name_prefix = 'module-always-active';
  943. }
  944. $checked = $active ? ' checked="checked"':'';
  945. if ( $disabled ){
  946. $checked .= ' disabled="disabled"';
  947. }
  948. printf(
  949. '<label class="%s">
  950. <input type="checkbox" name="%s[%s]" id="module-checkbox-%s"%s /> %s
  951. </label>',
  952. esc_attr($label_class),
  953. $name_prefix,
  954. esc_attr($module_id),
  955. esc_attr($module_id),
  956. $checked,
  957. $module_data['Name']
  958. );
  959. if ( $module_data['ModuleAlwaysActive'] ){
  960. printf(
  961. '<input type="hidden" name="module[%s]" value="on">',
  962. esc_attr($module_id)
  963. );
  964. }
  965. }
  966. /**
  967. * Add extra settings to the "Custom fields" entry on the plugin's config. page.
  968. *
  969. * Callback for the 'blc-module-settings-custom_field' filter.
  970. *
  971. * @param string $html Current extra HTML
  972. * @param array $current_settings The current plugin configuration.
  973. * @return string New extra HTML.
  974. */
  975. function make_custom_field_input($html, $current_settings){
  976. $html .= '<span class="description">' .
  977. __('Check URLs entered in these custom fields (one per line) :', 'broken-link-checker') .
  978. '</span>';
  979. $html .= '<br><textarea name="blc_custom_fields" id="blc_custom_fields" cols="45" rows="4" />';
  980. if( isset($current_settings['custom_fields']) )
  981. $html .= implode("\n", $current_settings['custom_fields']);
  982. $html .= '</textarea>';
  983. return $html;
  984. }
  985. /**
  986. * Enqueue CSS file for the plugin's Settings page.
  987. *
  988. * @return void
  989. */
  990. function options_page_css(){
  991. wp_enqueue_style('blc-options-page', plugins_url('css/options-page.css', BLC_PLUGIN_FILE), array(), '20120527' );
  992. wp_enqueue_style('dashboard');
  993. }
  994. /**
  995. * Display the "Broken Links" page, listing links detected by the plugin and their status.
  996. *
  997. * @return void
  998. */
  999. function links_page(){
  1000. global $wpdb, $blclog; /* @var wpdb $wpdb */
  1001. $blc_link_query = blcLinkQuery::getInstance();
  1002. //Cull invalid and missing modules so that we don't get dummy links/instances showing up.
  1003. $moduleManager = blcModuleManager::getInstance();
  1004. $moduleManager->validate_active_modules();
  1005. if ( defined('BLC_DEBUG') && constant('BLC_DEBUG') ){
  1006. //Make module headers translatable. They need to be formatted corrrectly and
  1007. //placed in a .php file to be visible to the script(s) that generate .pot files.
  1008. $code = $moduleManager->_build_header_translation_code();
  1009. file_put_contents( dirname($this->loader) . '/includes/extra-strings.php', $code );
  1010. }
  1011. $action = !empty($_POST['action'])?$_POST['action']:'';
  1012. if ( intval($action) == -1 ){
  1013. //Try the second bulk actions box
  1014. $action = !empty($_POST['action2'])?$_POST['action2']:'';
  1015. }
  1016. //Get the list of link IDs selected via checkboxes
  1017. $selected_links = array();
  1018. if ( isset($_POST['selected_links']) && is_array($_POST['selected_links']) ){
  1019. //Convert all link IDs to integers (non-numeric entries are converted to zero)
  1020. $selected_links = array_map('intval', $_POST['selected_links']);
  1021. //Remove all zeroes
  1022. $selected_links = array_filter($selected_links);
  1023. }
  1024. $message = '';
  1025. $msg_class = 'updated';
  1026. //Run the selected bulk action, if any
  1027. $force_delete = false;
  1028. switch ( $action ){
  1029. case 'create-custom-filter':
  1030. list($message, $msg_class) = $this->do_create_custom_filter();
  1031. break;
  1032. case 'delete-custom-filter':
  1033. list($message, $msg_class) = $this->do_delete_custom_filter();
  1034. break;
  1035. /** @noinspection PhpMissingBreakStatementInspection Deliberate fall-through. */
  1036. case 'bulk-delete-sources':
  1037. $force_delete = true;
  1038. case 'bulk-trash-sources':
  1039. list($message, $msg_class) = $this->do_bulk_delete_sources($selected_links, $force_delete);
  1040. break;
  1041. case 'bulk-unlink':
  1042. list($message, $msg_class) = $this->do_bulk_unlink($selected_links);
  1043. break;
  1044. case 'bulk-deredirect':
  1045. list($message, $msg_class) = $this->do_bulk_deredirect($selected_links);
  1046. break;
  1047. case 'bulk-recheck':
  1048. list($message, $msg_class) = $this->do_bulk_recheck($selected_links);
  1049. break;
  1050. case 'bulk-not-broken':
  1051. list($message, $msg_class) = $this->do_bulk_discard($selected_links);
  1052. break;
  1053. case 'bulk-edit':
  1054. list($message, $msg_class) = $this->do_bulk_edit($selected_links);
  1055. break;
  1056. }
  1057. if ( !empty($message) ){
  1058. echo '<div id="message" class="'.$msg_class.' fade"><p>'.$message.'</p></div>';
  1059. }
  1060. $start_time = microtime_float();
  1061. //Load custom filters, if any
  1062. $blc_link_query->load_custom_filters();
  1063. //Calculate the number of links matching each filter
  1064. $blc_link_query->count_filter_results();
  1065. //Run the selected filter (defaults to displaying broken links)
  1066. $selected_filter_id = isset($_GET['filter_id'])?$_GET['filter_id']:'broken';
  1067. $current_filter = $blc_link_query->exec_filter(
  1068. $selected_filter_id,
  1069. isset($_GET['paged']) ? intval($_GET['paged']) : 1,
  1070. $this->conf->options['table_links_per_page'],
  1071. 'broken',
  1072. isset($_GET['orderby']) ? $_GET['orderby'] : '',
  1073. isset($_GET['order']) ? $_GET['order'] : ''
  1074. );
  1075. //exec_filter() returns an array with filter data, including the actual filter ID that was used.
  1076. $filter_id = $current_filter['filter_id'];
  1077. //Error?
  1078. if ( empty($current_filter['links']) && !empty($wpdb->last_error) ){
  1079. printf( __('Database error : %s', 'broken-link-checker'), $wpdb->last_error);
  1080. }
  1081. ?>
  1082. <script type='text/javascript'>
  1083. var blc_current_filter = '<?php echo $filter_id; ?>';
  1084. var blc_is_broken_filter = <?php echo $current_filter['is_broken_filter'] ? 'true' : 'false'; ?>;
  1085. var blc_current_base_filter = '<?php echo esc_js($current_filter['base_filter']); ?>';
  1086. </script>
  1087. <div class="wrap"><?php screen_icon(); ?>
  1088. <?php
  1089. $blc_link_query->print_filter_heading($current_filter);
  1090. $blc_link_query->print_filter_menu($filter_id);
  1091. //Display the "Search" form and associated buttons.
  1092. //The form requires the $filter_id and $current_filter variables to be set.
  1093. include dirname($this->loader) . '/includes/admin/search-form.php';
  1094. //If the user has decided to switch the table to a different mode (compact/full),
  1095. //save the new setting.
  1096. if ( isset($_GET['compact']) ){
  1097. $this->conf->options['table_compact'] = (bool)$_GET['compact'];
  1098. $this->conf->save_options();
  1099. }
  1100. //Display the links, if any
  1101. if( $current_filter['links'] && ( count($current_filter['links']) > 0 ) ) {
  1102. include dirname($this->loader) . '/includes/admin/table-printer.php';
  1103. $table = new blcTablePrinter($this);
  1104. $table->print_table(
  1105. $current_filter,
  1106. $this->conf->options['table_layout'],
  1107. $this->conf->options['table_visible_columns'],
  1108. $this->conf->options['table_compact']
  1109. );
  1110. };
  1111. printf('<!-- Total elapsed : %.4f seconds -->', microtime_float() - $start_time);
  1112. //Load assorted JS event handlers and other shinies
  1113. include dirname($this->loader) . '/includes/admin/links-page-js.php';
  1114. ?></div><?php
  1115. }
  1116. /**
  1117. * Create a custom link filter using params passed in $_POST.
  1118. *
  1119. * @uses $_POST
  1120. * @uses $_GET to replace the current filter ID (if any) with that of the newly created filter.
  1121. *
  1122. * @return array Message and the CSS class to apply to the message.
  1123. */
  1124. function do_create_custom_filter(){
  1125. global $wpdb;
  1126. //Create a custom filter!
  1127. check_admin_referer( 'create-custom-filter' );
  1128. $msg_class = 'updated';
  1129. //Filter name must be set
  1130. if ( empty($_POST['name']) ){
  1131. $message = __("You must enter a filter name!", 'broken-link-checker');
  1132. $msg_class = 'error';
  1133. //Filter parameters (a search query) must also be set
  1134. } elseif ( empty($_POST['params']) ){
  1135. $message = __("Invalid search query.", 'broken-link-checker');
  1136. $msg_class = 'error';
  1137. } else {
  1138. //Save the new filter
  1139. $blc_link_query = blcLinkQuery::getInstance();
  1140. $filter_id = $blc_link_query->create_custom_filter($_POST['name'], $_POST['params']);
  1141. if ( $filter_id ){
  1142. //Saved
  1143. $message = sprintf( __('Filter "%s" created', 'broken-link-checker'), $_POST['name']);
  1144. //A little hack to make the filter active immediately
  1145. $_GET['filter_id'] = $filter_id;
  1146. } else {
  1147. //Error
  1148. $message = sprintf( __("Database error : %s", 'broken-link-checker'), $wpdb->last_error);
  1149. $msg_class = 'error';
  1150. }
  1151. }
  1152. return array($message, $msg_class);
  1153. }
  1154. /**
  1155. * Delete a custom link filter.
  1156. *
  1157. * @uses $_POST
  1158. *
  1159. * @return array Message and a CSS class to apply to the message.
  1160. */
  1161. function do_delete_custom_filter(){
  1162. //Delete an existing custom filter!
  1163. check_admin_referer( 'delete-custom-filter' );
  1164. $msg_class = 'updated';
  1165. //Filter ID must be set
  1166. if ( empty($_POST['filter_id']) ){
  1167. $message = __("Filter ID not specified.", 'broken-link-checker');
  1168. $msg_class = 'error';
  1169. } else {
  1170. //Try to delete the filter
  1171. $blc_link_query = blcLinkQuery::getInstance();
  1172. if ( $blc_link_query->delete_custom_filter($_POST['filter_id']) ){
  1173. //Success
  1174. $message = __('Filter deleted', 'broken-link-checker');
  1175. } else {
  1176. //Either the ID is wrong or there was some other error
  1177. $message = __('Database error : %s', 'broken-link-checker');
  1178. $msg_class = 'error';
  1179. }
  1180. }
  1181. return array($message, $msg_class);
  1182. }
  1183. /**
  1184. * Modify multiple links to point to their target URLs.
  1185. *
  1186. * @param array $selected_links
  1187. * @return array The message to display and its CSS class.
  1188. */
  1189. function do_bulk_deredirect($selected_links){
  1190. //For all selected links…

Large files files are truncated, but you can click here to view the full file