plugin_name = '404page'; $this->plugin_slug = '404page'; $this->version = '2.3'; $this->get_settings(); $this->init(); } // get all settings private function get_settings() { $this->settings = array(); $this->settings['404page_page_id'] = $this->get_404page_id(); $this->settings['404page_hide'] = $this->get_404page_hide(); $this->settings['404page_fire_error'] = $this->get_404page_fire_error(); // $this->settings['404page_method'] = $this->get_404page_method(); --> moved to set_mode in v 2.2 because this may be too early here $this->settings['404page_native'] = false; } // do plugin init private function init() { // as of v 2.2 always call set_mode add_action( 'init', array( $this, 'set_mode' ) ); if ( !is_admin() ) { add_action( 'pre_get_posts', array ( $this, 'exclude_404page' ) ); add_filter( 'get_pages', array ( $this, 'remove_404page_from_array' ), 10, 2 ); } else { add_action( 'admin_init', array( $this, 'admin_init' ) ); add_action( 'admin_menu', array( $this, 'admin_menu' ) ); add_action( 'admin_head', array( $this, 'admin_css' ) ); add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'add_settings_link' ) ); if ( $this->settings['404page_hide'] and $this->settings['404page_page_id'] > 0 ) { add_action( 'pre_get_posts' ,array ( $this, 'exclude_404page' ) ); } } } // init filters function set_mode() { $this->settings['404page_method'] = $this->get_404page_method(); if ( !is_admin() ) { if ( defined( 'CUSTOMIZR_VER' ) ) { // Customizr Compatibility Mode add_filter( 'tc_404_header_content', array( $this, 'show404title_customizr_mode' ), 999 ); add_filter( 'tc_404_content', array( $this, 'show404_customizr_mode' ), 999 ); add_filter( 'tc_404_selectors', array( $this, 'show404articleselectors_customizr_mode' ), 999 ); } elseif ( $this->settings['404page_method'] != 'STD' ) { // Compatibility Mode add_filter( 'posts_results', array( $this, 'show404_compatiblity_mode' ), 999 ); } else { // Standard Mode add_filter( '404_template', array( $this, 'show404_standard_mode' ), 999 ); if ( $this->settings['404page_fire_error'] ) { add_action( 'template_redirect', array( $this, 'do_404_header_standard_mode' ) ); } } } } // show 404 page - Standard Mode function show404_standard_mode( $template ) { global $wp_query; $pageid = $this->settings['404page_page_id']; if ( $pageid > 0 ) { if ( ! $this->settings['404page_native'] ) { $wp_query = null; $wp_query = new WP_Query(); $wp_query->query( 'page_id=' . $pageid ); $wp_query->the_post(); $template = get_page_template(); rewind_posts(); add_filter( 'body_class', array( $this, 'add_404_body_class' ) ); } $this->do_404page_action(); } return $template; } // show 404 page - Compatibility Mode function show404_compatiblity_mode( $posts ) { // remove the filter so we handle only the first query - no custom queries remove_filter( 'posts_results', array( $this, 'show404_compatiblity_mode' ), 999 ); $pageid = $this->settings['404page_page_id']; if ( $pageid > 0 && ! $this->settings['404page_native'] ) { if ( empty( $posts ) && is_main_query() && !is_robots() && !is_home() && !is_feed() && !is_search() && !is_archive() && ( !defined('DOING_AJAX') || !DOING_AJAX ) ) { // we need to get the 404 page $pageid = $this->get_page_id( $pageid ); // as of v2.1 we do not alter the posts argument here because this does not work with SiteOrigin's Page Builder Plugin, template_include filter introduced $this->postid = $pageid; $this->template = get_page_template_slug( $pageid ); if ( $this->template == '' ) { $this->template = get_page_template(); } add_action( 'wp', array( $this, 'do_404_header' ) ); add_filter( 'body_class', array( $this, 'add_404_body_class' ) ); add_filter( 'template_include', array( $this, 'change_404_template' ), 999 ); $posts[] = get_post( $pageid ); $this->do_404page_action(); } elseif ( 1 == count( $posts ) && 'page' == $posts[0]->post_type ) { // Do a 404 if the 404 page is opened directly if ( $this->settings['404page_fire_error'] ) { $curpageid = $posts[0]->ID; if ( defined( 'ICL_SITEPRESS_VERSION' ) ) { // WPML is active - get the post ID of the default language global $sitepress; $curpageid = apply_filters( 'wpml_object_id', $curpageid, 'page', $sitepress->get_default_language() ); $pageid = apply_filters( 'wpml_object_id', $pageid, 'page', $sitepress->get_default_language() ); } elseif ( defined( 'POLYLANG_VERSION' ) ) { // Polylang is active - get the post ID of the default language $curpageid = pll_get_post( $curpageid, pll_default_language() ); $pageid = pll_get_post( $pageid, pll_default_language() ); } if ( $pageid == $curpageid ) { add_action( 'wp', array( $this, 'do_404_header' ) ); add_filter( 'body_class', array( $this, 'add_404_body_class' ) ); $this->do_404page_action(); } } } } elseif ( $pageid > 0 && $this->settings['404page_native'] ) { $this->do_404page_action(); } return $posts; } // this function overrides the page template in compatibilty mode function change_404_template( $template ) { // we have to check if the template file is there because if the theme was changed maybe a wrong template is stored in the database $new_template = locate_template( array( $this->template ) ); if ( '' != $new_template ) { return $new_template ; } return $template; } // send a 404 HTTP header - Standard Mode function do_404_header_standard_mode() { if ( is_page() && get_the_ID() == $this->settings['404page_page_id'] && !is_404() ) { status_header( 404 ); nocache_headers(); $this->do_404page_action(); } } // send a 404 HTTP header - Compatibility Mode function do_404_header() { // remove the action so we handle only the first query - no custom queries remove_action( 'wp', array( $this, 'do_404_header' ) ); status_header( 404 ); nocache_headers(); } // adds the error404 class to the body classes function add_404_body_class( $classes ) { $classes[] = 'error404'; return $classes; } // show title - Customizr Compatibility Mode function show404title_customizr_mode( $title ) { if ( ! $this->settings['404page_native'] ) { return '
'; } // handle the settings field hide function admin_hide() { echo '
settings['404page_hide'], false ) . '/>'; echo '
'; echo '' . __( 'For Administrators the page is always visible.', '404page' ) . '
'; } // handle the settings field fire 404 error function admin_fire404() { echo 'settings['404page_fire_error'], false ) . '/>'; echo '
'; echo '' . __( 'Uncheck this if you want the selected page to be accessible.', '404page' ) . '
'; if ( function_exists( 'wpsupercache_activate' ) ) { echo ' ' . __( 'WP Super Cache Plugin detected', '404page' ) . '. ' . __ ( 'If the page you selected as 404 error page is in cache, always a HTTP code 200 is sent. To avoid this and send a HTTP code 404 you have to exlcude this page from caching', '404page' ) . ' (' . __( 'Click here', '404page' ) . ').
(' . __( 'Read more', '404page' ) . ')
' . __( 'This setting is not available because the Theme you are using natively supports the 404page plugin.', '404page' ) . ' (' . __( 'Read more', '404page' ) . ')
'; } elseif ( defined( 'CUSTOMIZR_VER' ) ) { echo '' . __( 'This setting is not availbe because the 404page Plugin works in Customizr Compatibility Mode.', '404page' ) . ' (' . __( 'Read more', '404page' ) . ')
'; } elseif ( defined( 'ICL_SITEPRESS_VERSION' ) ) { echo '' . __( 'This setting is not availbe because the 404page Plugin works in WPML Mode.', '404page' ) . ' (' . __( 'Read more', '404page' ) . ')
'; } elseif ( defined( 'POLYLANG_VERSION' ) ) { echo '' . __( 'This setting is not availbe because the 404page Plugin works in Polylang Mode.', '404page' ) . ' (' . __( 'Read more', '404page' ) . ')
'; } else { echo 'settings['404page_method'], false ) . ' />'; echo '
'; echo 'settings['404page_method'], false ) . '/>'; echo '
'; echo '' . __( 'Standard Mode uses the WordPress Template System and should work in most cases. If the 404page plugin does not work properly, probably you are using a theme or plugin that modifies the WordPress Template System. In this case the Compatibility Mode maybe can fix the problem, although it cannot be guaranteed that every possible configuration can be handled by Compatibility Mode. Standard Mode is the recommended method, only switch to Compatibility Mode if you have any problems.', '404page' ) . '
'; } } // this function hides the selected page from the list of pages function exclude_404page( $query ) { if ( $this->settings['404page_page_id'] > 0 ) { global $pagenow; $post_type = $query->get( 'post_type' ); // as of v 2.3 we check the post_type on front end if( ( is_admin() && ( 'edit.php' == $pagenow && !current_user_can( 'create_users' ) ) ) || ( ! is_admin() && ( !empty( $post_type) && ( ('page' === $post_type || 'any' === $post_type) || ( is_array( $post_type ) && in_array( 'page', $post_type ) ) ) )) ) { $pageid = $this->settings['404page_page_id']; if ( ! is_admin() ) { $pageid = $this->get_page_id( $pageid ); } // as of v 2.3 we add the ID of the 404 page to post__not_in // using just $query->set() overrides existing settings but not adds a new setting $query->set( 'post__not_in', array_merge( (array)$query->get( 'post__not_in', array() ), array( $pageid ) ) ); } } } // this function removes the 404 page from get_pages result array function remove_404page_from_array( $pages, $r ) { if ( $this->settings['404page_page_id'] > 0 ) { $pageid = $this->get_page_id( $this->settings['404page_page_id'] ); for ( $i = 0; $i < sizeof( $pages ); $i++ ) { if ( $pages[$i]->ID == $pageid ) { unset( $pages[$i] ); break; } } } return array_values( $pages ); } // adds the options page to admin menu function admin_menu() { $page_handle = add_theme_page ( __( '404 Error Page', "404page" ), __( '404 Error Page', '404page' ), 'manage_options', '404pagesettings', array( $this, 'admin_page' ) ); add_action( 'admin_print_scripts', array( $this, 'admin_js' ) ); } // adds javascript to the 404page settings page function admin_js() { wp_enqueue_script( '404pagejs', plugins_url( '/404page.js', __FILE__ ), 'jquery', $this->version, true ); } // creates the options page function admin_page() { if ( !current_user_can( 'manage_options' ) ) { wp_die( __( 'You do not have sufficient permissions to access this page.' ) ); } ?> post_status != 'publish' ) { $pageid = -1; } } return $pageid; } // returns the selected method private function get_404page_method() { if ( defined( 'ICL_SITEPRESS_VERSION' ) || defined( 'POLYLANG_VERSION' ) ) { // WPML or Polylang is active return 'CMP'; } else { return get_option( '404page_method', 'STD' ); } } // should we hide the selected 404 page from the page list? private function get_404page_hide() { return (bool)get_option( '404page_hide', false ); } // should we fire an 404 error if the selected page is accessed directly? private function get_404page_fire_error() { return (bool)get_option( '404page_fire_error', true ); } // this function gets the id of the translated page if WPML or Polylang is active - otherwise the original pageid is returned private function get_page_id( $pageid ) { if ( defined( 'ICL_SITEPRESS_VERSION' ) ) { // WPML is active $pageid = apply_filters( 'wpml_object_id', $pageid, 'page', true ); } elseif ( defined( 'POLYLANG_VERSION' ) ) { // Polylang is active $translatedpageid = pll_get_post( $pageid ); if ( !empty( $translatedpageid ) && 'publish' == get_post_status( $translatedpageid ) ) { $pageid = $translatedpageid; } } return $pageid; } // make plugin expandable function do_404page_action() { do_action( '404page_after_404' ); } // show meta boxes function show_meta_boxes() { ?>