*/ class _404_To_301_Public { /** * The ID of this plugin. * * @since 2.0.0 * @access private * @var string $plugin_name The ID of this plugin. */ private $plugin_name; /** * The version of this plugin. * * @since 2.0.0 * @access private * @var string $version The current version of this plugin. */ private $version; /** * The database table of plugin. * * @since 2.0.0 * @access protected * @var string $table The name of the database table from db. */ private $table; /** * Initialize the class and set its properties. * * @since 2.0.0 * @var string $plugin_name The name of the plugin. * @var string $version The version of this plugin. */ public function __construct($plugin_name, $version, $table) { $this->plugin_name = $plugin_name; $this->version = $version; $this->table = $table; $this->gnrl_options = get_option('i4t3_gnrl_options'); } /** * Create the 404 Log Email to be sent. * * @since 2.0.0 * @uses get_option To get admin email from database. * @uses get_bloginfo To get site title. */ public function i4t3_send_404_log_email($log_data) { // Filter to change the email address used for admin notifications $admin_email = apply_filters('i4t3_notify_admin_email_address', get_option('admin_email')); // Action hook that will be performed before sending 404 error mail do_action('i4t3_before_404_email_log', $log_data); // Get the site name $site_name = get_bloginfo('name'); $headers[] = 'From: ' . $site_name . ' <' . $admin_email . '>' . "\r\n"; $headers[] = 'Content-Type: text/html; charset=UTF-8'; $message = '

' . __('Bummer! You have one more 404', '404-to-301') . '

'; $message .= ''; $message .= ''; $message .= ''; $message .= ''; $message .= ''; $message .= ''; $message .= ''; $message .= ''; $message .= ''; $message .= ''; $message .= ''; $message .= ''; $message .= ''; $message .= '
' . __('IP Address', '404-to-301') . '' . $log_data['ip'] . '
' . __('404 Path', '404-to-301') . '' . $log_data['url'] . '
' . __('User Agent', '404-to-301') . '' . $log_data['ua'] . '
'; $is_sent = wp_mail( $admin_email, __('Snap! One more 404 on ', '404-to-301') . $site_name, $message, $headers ); } /** * The main function to perform redirections and logs on 404s. * Creating log for 404 errors, sending admin notification email if enables, * redirecting visitors to the specific page etc. are done in this function. * * @since 2.0.0 * @uses wp_redirect To redirect to a given link. * @uses do_action To add new action. */ public function i4t3_redirect_404() { // Check if 404 page and not admin side if (is_404() && !is_admin() && !$this->i4t3_excluded_paths()) { // Get the settings options $logging_status = (!empty($this->gnrl_options['redirect_log']) ) ? $this->gnrl_options['redirect_log'] : 0; $redirect_type = ( $this->gnrl_options['redirect_type'] ) ? $this->gnrl_options['redirect_type'] : '301'; // Get the email notification settings $is_email_send = (!empty($this->gnrl_options['email_notify']) && $this->gnrl_options['email_notify'] == 1 ) ? true : false; // Get error details if emailnotification or log is enabled if ($logging_status == 1 || $is_email_send) { // Action hook that will be performed before logging 404 errors do_action('i4t3_before_404_logging'); global $wpdb; $data = array( 'date' => current_time('mysql'), 'url' => $this->get_clear_empty($_SERVER['REQUEST_URI']) ); if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $data['ip'] = $this->get_clear_empty($_SERVER['HTTP_CLIENT_IP']); } else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $data['ip'] = $this->get_clear_empty($_SERVER['HTTP_X_FORWARDED_FOR']); } else { $data['ip'] = $this->get_clear_empty($_SERVER['REMOTE_ADDR']); } $data['ref'] = $this->get_clear_empty($_SERVER['HTTP_REFERER']); $data['ua'] = $this->get_clear_empty($_SERVER['HTTP_USER_AGENT']); // trim stuff foreach (array('url', 'ref', 'ua') as $k) if (isset($data[$k])) $data[$k] = substr($data[$k], 0, 512); } // Add log data to db if log is enabled by user if ($logging_status == 1 && !$this->i4t3_is_bot()) { $wpdb->insert($this->table, $data); // pop old entry if we exceeded the limit //$max = intval( $this->options['max_entries'] ); $max = 500; $cutoff = $wpdb->get_var("SELECT id FROM $this->table ORDER BY id DESC LIMIT $max,1"); if ($cutoff) { $wpdb->delete($this->table, array('id' => intval($cutoff)), array('%d')); } } // Send email notification if enabled if ($is_email_send && !$this->i4t3_is_bot()) { $this->i4t3_send_404_log_email($data); } // Get redirect settings $redirect_to = $this->gnrl_options['redirect_to']; switch ($redirect_to) { // Do not redirect if none is set case 'none': break; // Redirect to an existing WordPress site inside our site case 'page': $url = get_permalink($this->gnrl_options['redirect_page']); break; // Redirect to a custom link given by user case 'link': $naked_url = $this->gnrl_options['redirect_link']; $url = (!preg_match("~^(?:f|ht)tps?://~i", $naked_url)) ? "http://" . $naked_url : $naked_url; break; // If nothing, be chill and do nothing! default: break; } // Perform the redirect if $url is set if (!empty($url)) { // Action hook that will be performed before 404 redirect starts //echo $url; exit(); do_action('i4t3_before_404_redirect'); wp_redirect($url, $redirect_type); exit(); // exit, because WordPress will not exit automatically } // Action hook that will be performed after 404 redirect do_action('i4t3_after_404_redirect'); } } /** * Check if Bot is visiting. * * This function is used to check if a bot is being viewed our site content. * * @reference http://stackoverflow.com/questions/677419/how-to-detect-search-engine-bots-with-php * @since 2.0.5 * @author Joel James */ public function i4t3_is_bot() { $botlist = array("Teoma", "alexa", "froogle", "Gigabot", "inktomi", "looksmart", "URL_Spider_SQL", "Firefly", "NationalDirectory", "Ask Jeeves", "TECNOSEEK", "InfoSeek", "WebFindBot", "girafabot", "crawler", "www.galaxy.com", "Googlebot", "Scooter", "Slurp", "msnbot", "appie", "FAST", "WebBug", "Spade", "ZyBorg", "rabaz", "Baiduspider", "Feedfetcher-Google", "TechnoratiSnoop", "Rankivabot", "Mediapartners-Google", "Sogou web spider", "WebAlta Crawler", "TweetmemeBot", "Butterfly", "Twitturls", "Me.dium", "Twiceler"); foreach ($botlist as $bot) { if (strpos($_SERVER['HTTP_USER_AGENT'], $bot) !== false) return true; // Is a bot } return false; // Not a bot } /** * Exclude specific uri strings/paths from errors * * @retun True if requested uri matches specified one * @since 2.0.8 * @author Joel James */ public function i4t3_excluded_paths() { // Add links to be excluded in this array. $links_string = $this->gnrl_options['exclude_paths']; if (empty($links_string)) { return false; } $links = explode("\n", $links_string); if (!empty($links)) { foreach ($links as $link) { if (strpos($_SERVER['REQUEST_URI'], trim($link)) !== false) return true; } } return false; } /** * Check if value is empty before trying to insert. * * @since 2.0.9.1 * @author Joel James */ public function get_clear_empty($data = null) { return ( $data == null || empty($data) ) ? 'N/A' : $data; } }