'Version'), 'plugin'); self::$version = $plugin_data['version']; self::$plugin_url = plugins_url('', __FILE__) . '/'; } // init // add settings link to plugins page static function plugin_action_links($links) { $settings_link = 'Manage Redirects'; $pro_link = 'Get PRO'; array_unshift($links, $pro_link); array_unshift($links, $settings_link); return $links; } // plugin_action_links static function load_301_redirect_assets($adminpage) { if ($adminpage != 'settings_page_301-redirects') { return; } wp_enqueue_style('redirect_301_bootstrap_css', plugin_dir_url(__FILE__) . 'css/bootstrap.min.css', false, self::$version); wp_enqueue_style('redirect_301_custom_css', plugin_dir_url(__FILE__) . 'css/style.css', false, self::$version); wp_enqueue_script('redirect_301_bootstrap', plugin_dir_url(__FILE__) . 'js/bootstrap.min.js', true, self::$version); wp_enqueue_script('redirect_301_custom_js', plugin_dir_url(__FILE__) . 'js/ts-redirects.js', true, self::$version); wp_enqueue_style('wp-jquery-ui-dialog'); wp_enqueue_script('jquery-ui-dialog'); $options = get_option('ts_301_redirection', array()); $js_localize = array( 'nonce_delete_rule' => wp_create_nonce('redirect_delete_rule'), 'auto_open_pro_dialog' => empty($options['dismiss_auto_pro_modal']), ); wp_localize_script('redirect_301_custom_js', 'redirect', $js_localize); $options['dismiss_auto_pro_modal'] = true; update_option('ts_301_redirection', $options); } //load_301_redirect_assets // additional powered by text in admin footer; only on 301 page static function admin_footer_text($text) { if (!self::is_plugin_page()) { return $text; } $text = 'WP 301 Redirects v' . self::$version . ' by WebFactory Ltd. Please rate the plugin ★★★★★ to help us spread the word. Thank you!'; return $text; } // admin_footer_text // test if we're on plugin's page static function is_plugin_page() { $current_screen = get_current_screen(); if ($current_screen->id == 'settings_page_301-redirects') { return true; } else { return false; } } // is_plugin_page static function check_404() { if (!is_404()) { return; } $log404 = get_option('301_redirects_404_log', array()); if (!is_array($log404)) { $log404 = array(); } $ua = \tsdonatj\UserAgent\parse_user_agent(wp_strip_all_tags(wp_unslash($_SERVER['HTTP_USER_AGENT'] ?? ''))); $agent = trim(@$ua['platform'] . ' ' . @$ua['browser']); if (empty($agent)) { $agent = 'unknown'; } $last['timestamp'] = current_time('timestamp'); $last['url'] = wp_strip_all_tags(wp_unslash($_SERVER['REQUEST_URI'] ?? '')); $last['user_agent'] = $agent; array_unshift($log404, $last); $max = abs(apply_filters('301_redirects_max_404_logs', 50)); $log404 = array_slice($log404, 0, $max); update_option('301_redirects_404_log', $log404); } // check_404 static function redirects_301_do_redirect() { $siteurl = get_bloginfo('url'); $actual_link = self::getUrl(); $all_redirects = $GLOBALS['redirectsplugins']->getAll(); if ($all_redirects) { foreach ($all_redirects as $redirect_id) { $la_redirect = $GLOBALS['redirectsplugins']->getFields($redirect_id); $la_old_link = str_replace($siteurl, "", $la_redirect['old_link']); if ($actual_link == $siteurl . $la_old_link) { header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); header('Cache-Control: post-check=0, pre-check=0', false); header('Pragma: no-cache'); header('Location: ' . $la_redirect['new_link'], true, 301); die(); } } // foreach } } // redirects_301_do_redirect static function ajax_delete_rule() { $redirects = new Redirects; check_ajax_referer('redirect_delete_rule'); if (isset($_POST['custom_id'])) { if ($_POST['custom_id'] == 'all') { $redirects->delete(); die('1'); } else { $custom_id = (int) sanitize_text_field(wp_unslash($_POST['custom_id'])); $redirects->remove($custom_id); die('1'); } } else { die(); } } // ajax_delete_rule static function getUrl() { $https = sanitize_text_field(wp_unslash($_SERVER["HTTPS"] ?? '')); $host = sanitize_text_field(wp_unslash($_SERVER["HTTP_HOST"] ?? '')); $request_url = sanitize_text_field(wp_unslash($_SERVER["REQUEST_URI"] ?? '')); $url = ($https != 'on') ? 'http://' . $host . $request_url : 'https://' . $host . $request_url; return $url; } // getUrl static function redirects_301_options() { $redirects = new Redirects; $savedsuccesfully = false; if (isset($_POST['links_audit_submit']) && check_admin_referer('ts_save_rules')) { $redirects->delete(); if (!empty($_POST['title'])) { //phpcs:ignore $_POST['title'] is an array and each value is sanitized individually below $redirect_arr = $_POST['title']; //phpcs:ignore foreach ($redirect_arr as $key => $redirect_title) { $title = sanitize_text_field($redirect_title); $section = array_key_exists($key, $_POST['section']) ? sanitize_text_field(wp_unslash($_POST['section'][$key] ?? '')) : ''; $new_link = sanitize_url(wp_unslash($_POST['new_link'][$key] ?? '')); $old_link = sanitize_url(wp_unslash($_POST['old_link'][$key] ?? '')); $redirects->edit($title, $section, $new_link, $old_link); } } $savedsuccesfully = true; } ?>

301 Redirects


All redirect rules have been saved.

Add your old path /old-path-from-site/ (don't forget to start with a forward slash) in the old link field, and the new path /new-path-somewhere/ in the new link field. If you're redirecting to an external URL add the https:// prefix.
Name and Section serve only for your organization and convenience.

getAll(); if ($custom_redirects) { $i = 1; foreach ($redirects->getAll() as $custom_id) { $fields = $redirects->getFields($custom_id); ?> '; } if ($i == 12) { echo ''; } $i++; } // foreach } ?>
Name Section Old URL New URL
'; echo '

Are you tired of adding so many redirect rules one-by-one for each URL?
WP 301 Redirects PRO automatically fixes URL typos, has advanced URL matching rules, and watcher over permalink changes so you don\'t have to write so many rules.

'; echo '
'; echo '

Need a better way to organize & monitor your redirect rules?
WP 301 Redirects PRO makes it easy to tag & search rules so it\'s always easy to find them. And with advanced stats for redirects & 404 errors you\'ll always know what\'s going on with your traffic.

'; echo '
    Add a New Redirect Rule    Delete All Redirect Rules

Please rate the plugin ★★★★★ to keep it free & maintained. It only takes a minute to rate. Thank you! 👋

You currently don\'t have any data in the 404 error log. That means that you either just installed the plugin, or that you never had a 404 error happen which is awesome 🚀!

'; } else { echo '
Need a more detailed 404 error log? With more data, more insights, per-day stats & an easier way to create redirect rules from 404 errors? Want to have a centralized log for all your websites in one place? Upgrade to WP 301 Redirects PRO.
'; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; foreach ($log as $l) { echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; } // foreach echo '
Date & Time Target URLUser DeviceUser LocationReferal URL
' . esc_html(human_time_diff(current_time('timestamp'), $l['timestamp'])) . ' ago' . esc_html($l['url']) . '' . esc_html($l['user_agent']) . 'Available in PROAvailable in PRO
'; echo '


By default, the log is limited to the last fifty (chronologically) 404 errors. This is a safe number that ensures the log works on all sites and doesn\'t slow anything down. '; echo 'The code imposes no limits on the log size and you can easily overwrite the default limit by using the 301_redirects_max_404_logs filter. Details are available in the FAQ.

'; echo '

If your site gets hundreds and thousands of 404 errors a day we suggesting upgrading to WP 301 Redirects PRO as it automatically fixes 404 errors caused by URL typos, provides a more robust log that can handle tens of thousands of entries, and offers more tools to manage 404 errors.

'; } // if 404 } // tab_404 // add widget to dashboard static function add_widget() { if (current_user_can('manage_options')) { add_meta_box('wp301_redirects_404_errors', '404 Errors Log', array(__CLASS__, 'widget_content'), 'dashboard', 'side', 'high'); } } // add_widget // render widget static function widget_content() { $log = get_option('301_redirects_404_log', array()); if (!self::check_permalinks()) { echo '

WARNING: 301 Redirects plugin requires that a permalink structure is set. The default (plain) WordPress permalink structure is not compatible with 301 Redirects.
Please update the Permalink Structure.

'; return; } echo ''; if (!sizeof($log)) { echo '

You currently don\'t have any data in the 404 error log. That means that you either just installed the plugin, or that you never had a 404 error happen which is awesome 🚀!

'; echo '

Don\'t like seeing an empty error log? Or just want to see see if the log works? Open any nonexistent URL and then reload this page.

'; } else { echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; $i = 1; foreach ($log as $l) { echo ''; echo ''; echo ''; echo ''; echo ''; $i++; if ($i >= 6) { break; } } // foreach echo '
Date &
Time
Target URLUser Device
' . esc_html(human_time_diff(current_time('timestamp'), $l['timestamp'])) . ' ago' . esc_html($l['url']) . ' ' . esc_html($l['user_agent']) . '
'; echo '

View the entire 404 error log in the 301 Redirects plugin or create new redirect rules to fix 404 errors.

'; } } // widget_content static function pro_dialog() { if (!self::is_plugin_page()) { return; } $out = ''; $out .= ''; ts_redirects::wp_kses_wf($out); } // pro_dialog static function wp_kses_wf($html) { add_filter('safe_style_css', function ($styles) { $styles_wf = array( 'text-align', 'margin', 'color', 'float', 'border', 'background', 'background-color', 'border-bottom', 'border-bottom-color', 'border-bottom-style', 'border-bottom-width', 'border-collapse', 'border-color', 'border-left', 'border-left-color', 'border-left-style', 'border-left-width', 'border-right', 'border-right-color', 'border-right-style', 'border-right-width', 'border-spacing', 'border-style', 'border-top', 'border-top-color', 'border-top-style', 'border-top-width', 'border-width', 'caption-side', 'clear', 'cursor', 'direction', 'font', 'font-family', 'font-size', 'font-style', 'font-variant', 'font-weight', 'height', 'letter-spacing', 'line-height', 'margin-bottom', 'margin-left', 'margin-right', 'margin-top', 'overflow', 'padding', 'padding-bottom', 'padding-left', 'padding-right', 'padding-top', 'text-decoration', 'text-indent', 'vertical-align', 'width', 'display', ); foreach ($styles_wf as $style_wf) { $styles[] = $style_wf; } return $styles; }); $allowed_tags = wp_kses_allowed_html('post'); $allowed_tags['input'] = array( 'type' => true, 'style' => true, 'class' => true, 'id' => true, 'checked' => true, 'disabled' => true, 'name' => true, 'size' => true, 'placeholder' => true, 'value' => true, 'data-*' => true, 'size' => true, 'disabled' => true ); $allowed_tags['textarea'] = array( 'type' => true, 'style' => true, 'class' => true, 'id' => true, 'checked' => true, 'disabled' => true, 'name' => true, 'size' => true, 'placeholder' => true, 'value' => true, 'data-*' => true, 'cols' => true, 'rows' => true, 'disabled' => true, 'autocomplete' => true ); $allowed_tags['select'] = array( 'type' => true, 'style' => true, 'class' => true, 'id' => true, 'checked' => true, 'disabled' => true, 'name' => true, 'size' => true, 'placeholder' => true, 'value' => true, 'data-*' => true, 'multiple' => true, 'disabled' => true ); $allowed_tags['option'] = array( 'type' => true, 'style' => true, 'class' => true, 'id' => true, 'checked' => true, 'disabled' => true, 'name' => true, 'size' => true, 'placeholder' => true, 'value' => true, 'selected' => true, 'data-*' => true ); $allowed_tags['optgroup'] = array( 'type' => true, 'style' => true, 'class' => true, 'id' => true, 'checked' => true, 'disabled' => true, 'name' => true, 'size' => true, 'placeholder' => true, 'value' => true, 'selected' => true, 'data-*' => true, 'label' => true ); $allowed_tags['a'] = array( 'href' => true, 'data-*' => true, 'class' => true, 'style' => true, 'id' => true, 'target' => true, 'data-*' => true, 'role' => true, 'aria-controls' => true, 'aria-selected' => true, 'disabled' => true ); $allowed_tags['div'] = array( 'style' => true, 'class' => true, 'id' => true, 'data-*' => true, 'role' => true, 'aria-labelledby' => true, 'value' => true, 'aria-modal' => true, 'tabindex' => true ); $allowed_tags['li'] = array( 'style' => true, 'class' => true, 'id' => true, 'data-*' => true, 'role' => true, 'aria-labelledby' => true, 'value' => true, 'aria-modal' => true, 'tabindex' => true ); $allowed_tags['span'] = array( 'style' => true, 'class' => true, 'id' => true, 'data-*' => true, 'aria-hidden' => true ); $allowed_tags['style'] = array( 'class' => true, 'id' => true, 'type' => true ); $allowed_tags['fieldset'] = array( 'class' => true, 'id' => true, 'type' => true ); $allowed_tags['link'] = array( 'class' => true, 'id' => true, 'type' => true, 'rel' => true, 'href' => true, 'media' => true ); $allowed_tags['form'] = array( 'style' => true, 'class' => true, 'id' => true, 'method' => true, 'action' => true, 'data-*' => true ); $allowed_tags['script'] = array( 'class' => true, 'id' => true, 'type' => true, 'src' => true ); echo wp_kses($html, $allowed_tags); add_filter('safe_style_css', function ($styles) { $styles_wf = array( 'text-align', 'margin', 'color', 'float', 'border', 'background', 'background-color', 'border-bottom', 'border-bottom-color', 'border-bottom-style', 'border-bottom-width', 'border-collapse', 'border-color', 'border-left', 'border-left-color', 'border-left-style', 'border-left-width', 'border-right', 'border-right-color', 'border-right-style', 'border-right-width', 'border-spacing', 'border-style', 'border-top', 'border-top-color', 'border-top-style', 'border-top-width', 'border-width', 'caption-side', 'clear', 'cursor', 'direction', 'font', 'font-family', 'font-size', 'font-style', 'font-variant', 'font-weight', 'height', 'letter-spacing', 'line-height', 'margin-bottom', 'margin-left', 'margin-right', 'margin-top', 'overflow', 'padding', 'padding-bottom', 'padding-left', 'padding-right', 'padding-top', 'text-decoration', 'text-indent', 'vertical-align', 'width' ); foreach ($styles_wf as $style_wf) { if (($key = array_search($style_wf, $styles)) !== false) { unset($styles[$key]); } } return $styles; }); } static function add_options_page() { add_options_page('301 Redirects', '301 Redirects', 'manage_options', '301-redirects', array(__CLASS__, 'redirects_301_options')); } //redirects_301 static function admin_notices() { if (!self::check_permalinks()) { echo '
'; echo '

WARNING: 301 Redirects plugin requires that a permalink structure is set. The default (plain) WordPress permalink structure is not compatible with 301 Redirects.
Please update the Permalink Structure.

'; echo '
'; } } // admin_notices static function check_permalinks() { global $wp_rewrite; if (!isset($wp_rewrite->permalink_structure) || empty($wp_rewrite->permalink_structure)) { return false; } else { return true; } } // check_permalinks static function _deactivation() { delete_option('ts_301_redirection'); } // _deactivation } // class ts_redirects ts_redirects::init(); register_deactivation_hook(__FILE__, array('ts_redirects', '_deactivation'));