Guest User

permalink-manager/includes/core/permalink-manager-core-functions.php

a guest
Jan 25th, 2021
43
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2.  
  3. /**
  4. * Core functions
  5. */
  6. class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
  7.  
  8.     public function __construct() {
  9.         add_action( 'init', array($this, 'init_hooks'), 99);
  10.     }
  11.  
  12.     function init_hooks() {
  13.         global $permalink_manager_options;
  14.  
  15.         // Trailing slashes
  16.         add_filter( 'permalink_manager_filter_final_term_permalink', array($this, 'control_trailing_slashes'), 9);
  17.         add_filter( 'permalink_manager_filter_final_post_permalink', array($this, 'control_trailing_slashes'), 9);
  18.         add_filter( 'permalink_manager_filter_post_sample_uri', array($this, 'control_trailing_slashes'), 9);
  19.         add_filter( 'wpseo_canonical', array($this, 'control_trailing_slashes'), 9);
  20.         add_filter( 'wpseo_opengraph_url', array($this, 'control_trailing_slashes'), 9);
  21.         add_filter( 'paginate_links', array($this, 'control_trailing_slashes'), 9);
  22.  
  23.         /**
  24.          * Detect & canonical URL/redirect functions
  25.          */
  26.         // Do not trigger in back-end
  27.         if(is_admin()) { return false; }
  28.  
  29.         // Do not trigger if Customizer is loaded
  30.         if(function_exists('is_customize_preview') && is_customize_preview()) { return false; }
  31.  
  32.         // Use the URIs set in this plugin
  33.         add_filter( 'request', array($this, 'detect_post'), 0, 1 );
  34.  
  35.         // Redirect from old URIs to new URIs  + adjust canonical redirect settings
  36.         add_action( 'template_redirect', array($this, 'new_uri_redirect_and_404'), 1);
  37.         add_action( 'wp', array($this, 'adjust_canonical_redirect'), 0, 1);
  38.  
  39.         // Case insensitive permalinks
  40.         if(!empty($permalink_manager_options['general']['case_insensitive_permalinks'])) {
  41.             add_action( 'parse_request', array($this, 'case_insensitive_permalinks'), 0);
  42.         }
  43.         // Force 404 on non-existing pagination pages
  44.         if(!empty($permalink_manager_options['general']['pagination_redirect'])) {
  45.             add_action( 'wp', array($this, 'fix_pagination_pages'), 0);
  46.         }
  47.     }
  48.  
  49.     /**
  50.     * The most important Permalink Manager function
  51.     */
  52.     public static function detect_post($query, $request_url = false, $return_object = false) {
  53.         global $wpdb, $wp, $wp_rewrite, $permalink_manager, $permalink_manager_uris, $wp_filter, $permalink_manager_options, $pm_query;
  54.  
  55.         // Check if the array with custom URIs is set
  56.         if(!(is_array($permalink_manager_uris))) return $query;
  57.  
  58.         // Used in debug mode & endpoints
  59.         $old_query = $query;
  60.  
  61.         /**
  62.         * 1. Prepare URL and check if it is correct (make sure that both requested URL & home_url share the same protoocl and get rid of www prefix)
  63.         */
  64.         $request_url = (!empty($request_url)) ? parse_url($request_url, PHP_URL_PATH) : $_SERVER['REQUEST_URI'];
  65.         $request_url = strtok($request_url, "?");
  66.  
  67.         $http_host = (!empty($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : preg_replace('/www\./i', '', $_SERVER['SERVER_NAME']);
  68.         $request_url = sprintf("http://%s%s", str_replace("www.", "", $http_host), $request_url);
  69.         $raw_home_url = trim(get_option('home'));
  70.         $home_url = preg_replace("/http(s)?:\/\/(www\.)?(.+?)\/?$/", "http://$3", $raw_home_url);
  71.  
  72.         if(filter_var($request_url, FILTER_VALIDATE_URL)) {
  73.             // Check if "Deep Detect" is enabled
  74.             $deep_detect_enabled = apply_filters('permalink_manager_deep_uri_detect', $permalink_manager_options['general']['deep_detect']);
  75.  
  76.             // Sanitize the URL
  77.             // $request_url = filter_var($request_url, FILTER_SANITIZE_URL);
  78.  
  79.             // Keep only the URI
  80.             $request_url = str_replace($home_url, "", $request_url);
  81.  
  82.             // Hotfix for language plugins
  83.             if(filter_var($request_url, FILTER_VALIDATE_URL)) {
  84.                 $request_url = parse_url($request_url, PHP_URL_PATH);
  85.             }
  86.  
  87.             $request_url = trim($request_url, "/");
  88.  
  89.             // Get all the endpoints & pattern
  90.             $endpoints = Permalink_Manager_Helper_Functions::get_endpoints();
  91.             $pattern = "/^(.+?)(?|\/({$endpoints})(?|\/(.*)|$)|\/()([\d]+)\/?)?$/i";
  92.  
  93.             // Use default REGEX to detect post
  94.             preg_match($pattern, $request_url, $regex_parts);
  95.             $uri_parts['lang'] = false;
  96.             $uri_parts['uri'] = (!empty($regex_parts[1])) ? $regex_parts[1] : "";
  97.             $uri_parts['endpoint'] = (!empty($regex_parts[2])) ? $regex_parts[2] : "";
  98.             $uri_parts['endpoint_value'] = (!empty($regex_parts[3])) ? $regex_parts[3] : "";
  99.  
  100.             // Allow to filter the results by third-parties + store the URI parts with $pm_query global
  101.             $uri_parts = apply_filters('permalink_manager_detect_uri', $uri_parts, $request_url, $endpoints);
  102.  
  103.             // Support comment pages
  104.             preg_match("/(.*)\/{$wp_rewrite->comments_pagination_base}-([\d]+)/", $request_url, $regex_parts);
  105.             if(!empty($regex_parts[2])) {
  106.                 $uri_parts['uri'] = $regex_parts[1];
  107.                 $uri_parts['endpoint'] = 'cpage';
  108.                 $uri_parts['endpoint_value'] = $regex_parts[2];
  109.             }
  110.  
  111.             // Support pagination endpoint
  112.             if($uri_parts['endpoint'] == $wp_rewrite->pagination_base) {
  113.                 $uri_parts['endpoint'] = 'page';
  114.             }
  115.  
  116.             // Stop the function if $uri_parts is empty
  117.             if(empty($uri_parts)) return $query;
  118.  
  119.             // Store the URI parts in a separate global variable
  120.             $pm_query = $uri_parts;
  121.  
  122.             // Get the URI parts from REGEX parts
  123.             $lang = $uri_parts['lang'];
  124.             $uri = $uri_parts['uri'];
  125.             $endpoint = $uri_parts['endpoint'];
  126.             $endpoint_value = $uri_parts['endpoint_value'];
  127.  
  128.             // Trim slashes
  129.             $uri = trim($uri, "/");
  130.  
  131.             // Ignore URLs with no URI grabbed
  132.             if(empty($uri)) return $query;
  133.  
  134.             // Store an array with custom permalinks in a separate variable
  135.             $all_uris = $permalink_manager_uris;
  136.  
  137.             // Check what content type should be loaded in case of duplicate ("posts" or "terms")
  138.             $duplicates_priority = apply_filters('permalink_manager_duplicates_priority', false);
  139.             if($duplicates_priority !== false) {
  140.                 $uri_count = array_count_values($all_uris);
  141.  
  142.                 foreach($uri_count as $duplicated_uri => $count) {
  143.                     if($count <= 1) { continue; }
  144.  
  145.                     $duplicates_ids = array_keys($all_uris, $duplicated_uri);
  146.  
  147.                     foreach($duplicates_ids as $id) {
  148.                         if($duplicates_priority == 'posts' && !is_numeric($id)) {
  149.                             unset($all_uris[$id]);
  150.                         } else if($duplicates_priority !== 'posts' && is_numeric($id)) {
  151.                             unset($all_uris[$id]);
  152.                         }
  153.                     }
  154.                 }
  155.             }
  156.  
  157.             // Exclude draft posts
  158.             /*$exclude_drafts = apply_filters('permalink_manager_exclude_drafts', false);
  159.             if($exclude_drafts !== false) {
  160.                 $post_ids = $wpdb->get_col("SELECT DISTINCT ID FROM {$wpdb->posts} AS p WHERE p.post_status = 'draft' ORDER BY ID DESC");
  161.                 if(!empty($post_ids)) {
  162.                     foreach($post_ids as $post_id) {
  163.                         unset($permalink_manager_uris[$post_id]);
  164.                     }
  165.                 }
  166.             }*/
  167.  
  168.             // Flip array for better performance
  169.             $all_uris = array_flip($all_uris);
  170.  
  171.             // Attempt 1.
  172.             // Find the element ID
  173.             $element_id = isset($all_uris[$uri]) ? $all_uris[$uri] : false;
  174.  
  175.             // Atempt 2.
  176.             // Decode both request URI & URIs array & make them lowercase (and save in a separate variable)
  177.             if(empty($element_id)) {
  178.                 $uri = strtolower(urldecode($uri));
  179.  
  180.                 foreach($all_uris as $raw_uri => $uri_id) {
  181.                     $raw_uri = urldecode($raw_uri);
  182.                     $all_uris[$raw_uri] = $uri_id;
  183.                 }
  184.  
  185.                 // Convert array keys lowercase
  186.                 $all_uris = array_change_key_case($all_uris, CASE_LOWER);
  187.  
  188.                 $element_id = isset($all_uris[$uri]) ? $all_uris[$uri] : $element_id;
  189.             }
  190.  
  191.             // Atempt 3.
  192.             // Check again in case someone used post/tax IDs instead of slugs
  193.             if($deep_detect_enabled && is_numeric($endpoint_value) && isset($all_uris["{$uri}/{$endpoint_value}"])) {
  194.                 $element_id = $all_uris["{$uri}/{$endpoint_value}"];
  195.                 $endpoint_value = $endpoint = "";
  196.             }
  197.  
  198.             // Atempt 4.
  199.             // Check again for attachment custom URIs
  200.             if(empty($element_id) && isset($old_query['attachment'])) {
  201.                 $element_id = isset($all_uris["{$uri}/{$endpoint}/{$endpoint_value}"]) ? $all_uris["{$uri}/{$endpoint}/{$endpoint_value}"] : $element_id;
  202.  
  203.                 if($element_id) {
  204.                     $endpoint_value = $endpoint = "";
  205.                 }
  206.             }
  207.  
  208.             // Allow to filter the item_id by third-parties after initial detection
  209.             $element_id = apply_filters('permalink_manager_detected_element_id', $element_id, $uri_parts, $request_url);
  210.  
  211.             // Clear the original query before it is filtered
  212.             $query = ($element_id) ? array() : $query;
  213.  
  214.             /**
  215.             * 3A. Custom URI assigned to taxonomy
  216.             */
  217.             if(strpos($element_id, 'tax-') !== false) {
  218.                 // Remove the "tax-" prefix
  219.                 $term_id = intval(preg_replace("/[^0-9]/", "", $element_id));
  220.  
  221.                 // Filter detected post ID
  222.                 $term_id = apply_filters('permalink_manager_detected_term_id', intval($term_id), $uri_parts, true);
  223.  
  224.                 // Get the variables to filter wp_query and double-check if taxonomy exists
  225.                 $term = get_term($term_id);
  226.                 $term_taxonomy = (!empty($term->taxonomy)) ? $term->taxonomy : false;
  227.  
  228.                 // Check if taxonomy is allowed
  229.                 $disabled = ($term_taxonomy && Permalink_Manager_Helper_Functions::is_disabled($term_taxonomy, 'taxonomy')) ? true : false;
  230.  
  231.                 // Proceed only if the term is not removed and its taxonomy is not disabled
  232.                 if(!$disabled && $term_taxonomy) {
  233.                     // Get some term data
  234.                     if($term_taxonomy == 'category') {
  235.                         $query_parameter = 'category_name';
  236.                     } else if($term_taxonomy == 'post_tag') {
  237.                         $query_parameter = 'tag';
  238.                     } else {
  239.                         $query["taxonomy"] = $term_taxonomy;
  240.                         $query_parameter = $term_taxonomy;
  241.                     }
  242.                     $term_ancestors = get_ancestors($term_id, $term_taxonomy);
  243.                     $final_uri = $term->slug;
  244.  
  245.                     // Fix for hierarchical terms
  246.                     if(!empty($term_ancestors)) {
  247.                         foreach ($term_ancestors as $parent_id) {
  248.                             $parent = get_term((int) $parent_id, $term_taxonomy);
  249.                             if(!empty($parent->slug)) {
  250.                                 $final_uri = $parent->slug . '/' . $final_uri;
  251.                             }
  252.                         }
  253.                     }
  254.  
  255.                     //$query["term"] = $final_uri;
  256.                     $query["term"] = $term->slug;
  257.                     //$query[$query_parameter] = $final_uri;
  258.                     $query[$query_parameter] = $term->slug;
  259.                 } else if($disabled) {
  260.                     $broken_uri = true;
  261.                     $query = $old_query;
  262.                 } else {
  263.                     $query = $old_query;
  264.                 }
  265.             }
  266.             /**
  267.             * 3B. Custom URI assigned to post/page/cpt item
  268.             */
  269.             else if(isset($element_id) && is_numeric($element_id)) {
  270.                 // Fix for revisions
  271.                 $is_revision = wp_is_post_revision($element_id);
  272.                 if($is_revision) {
  273.                     $revision_id = $element_id;
  274.                     $element_id = $is_revision;
  275.                 }
  276.  
  277.                 // Filter detected post ID
  278.                 $element_id = apply_filters('permalink_manager_detected_post_id', $element_id, $uri_parts);
  279.  
  280.                 $post_to_load = get_post($element_id);
  281.                 $final_uri = (!empty($post_to_load->post_name)) ? $post_to_load->post_name : false;
  282.                 $post_type = (!empty($post_to_load->post_type)) ? $post_to_load->post_type : false;
  283.  
  284.                 // Check if post type is allowed
  285.                 $disabled = ($post_type && Permalink_Manager_Helper_Functions::is_disabled($post_type, 'post_type')) ? true : false;
  286.  
  287.                 // Proceed only if the term is not removed and its taxonomy is not disabled
  288.                 if(!$disabled && $post_type) {
  289.                     $post_type_object = get_post_type_object($post_type);
  290.  
  291.                     // Fix for hierarchical CPT & pages
  292.                     if(!(empty($post_to_load->ancestors)) && !empty($post_type_object->hierarchical)) {
  293.                         foreach ($post_to_load->ancestors as $parent) {
  294.                             $parent = get_post($parent);
  295.                             if($parent && $parent->post_name) {
  296.                                 $final_uri = $parent->post_name . '/' . $final_uri;
  297.                             }
  298.                         }
  299.                     }
  300.  
  301.                     // Alter query parameters + support drafts URLs
  302.                     if($post_to_load->post_status == 'draft' || empty($final_uri)) {
  303.                         if(is_user_logged_in()) {
  304.                             if($post_type == 'page') {
  305.                                 $query['page_id'] = $element_id;
  306.                             } else {
  307.                                 $query['p'] = $element_id;
  308.                             }
  309.  
  310.                             $query['preview'] = true;
  311.                             $query['post_type'] = $post_type;
  312.                         } else if($post_to_load->post_status == 'draft') {
  313.                             $query['pagename'] = '-';
  314.                             $query['error'] = '404';
  315.  
  316.                             $element_id = 0;
  317.                         } else {
  318.                             $query = $old_query;
  319.                         }
  320.                     } else if($post_type == 'page') {
  321.                         $query['pagename'] = $final_uri;
  322.                         // $query['post_type'] = $post_type;
  323.                     } else if($post_type == 'post') {
  324.                         $query['name'] = $final_uri;
  325.                     } else if($post_type == 'attachment') {
  326.                         $query['attachment'] = $final_uri;
  327.                     } else {
  328.                         // Get the query var
  329.                         $query_var = (!empty($post_type_object->query_var)) ? $post_type_object->query_var : $post_type;
  330.  
  331.                         $query['name'] = $final_uri;
  332.                         $query['post_type'] = $post_type;
  333.                         $query[$query_var] = $final_uri;
  334.                     }
  335.                 } else if($disabled) {
  336.                     $broken_uri = true;
  337.                     $query = $old_query;
  338.                 } else {
  339.                     $query = $old_query;
  340.                 }
  341.             }
  342.  
  343.             /**
  344.              * 4. Auto-remove removed term custom URI & redirects (works if enabled in plugin settings)
  345.              */
  346.             if(!empty($broken_uri) && (!empty($permalink_manager_options['general']['auto_remove_duplicates'])) && $permalink_manager_options['general']['auto_remove_duplicates'] == 1) {
  347.                 $broken_element_id = (!empty($revision_id)) ? $revision_id : $element_id;
  348.                 $remove_broken_uri = Permalink_Manager_Actions::force_clear_single_element_uris_and_redirects($broken_element_id);
  349.  
  350.                 // Reload page if success
  351.                 if($remove_broken_uri && !headers_sent()) {
  352.                     header("Refresh:0");
  353.                     exit();
  354.                 }
  355.             }
  356.  
  357.             /**
  358.              * 5A. Endpoints
  359.              */
  360.             if(!empty($element_id) && (!empty($endpoint) || !empty($endpoint_value))) {
  361.                 if(is_array($endpoint)) {
  362.                     foreach($endpoint as $endpoint_name => $endpoint_value) {
  363.                         $query[$endpoint_name] = $endpoint_value;
  364.                     }
  365.                 } else if($endpoint == 'feed') {
  366.                     $query[$endpoint] = 'feed';
  367.                 } else if($endpoint == 'embed') {
  368.                     $query[$endpoint] = true;
  369.                 } else if($endpoint == 'page') {
  370.                     $endpoint = 'paged';
  371.                     $query[$endpoint] = $endpoint_value;
  372.                 } else if($endpoint == 'trackback') {
  373.                     $endpoint = 'tb';
  374.                     $query[$endpoint] = 1;
  375.                 } else if(empty($endpoint) && is_numeric($endpoint_value)) {
  376.                     $query['page'] = $endpoint_value;
  377.                 } else {
  378.                     $query[$endpoint] = $endpoint_value;
  379.                 }
  380.  
  381.                 // Fix for attachments
  382.                 if(!empty($query['attachment'])) {
  383.                     $query = array('attachment' => $query['attachment'], 'do_not_redirect' => 1);
  384.                 }
  385.             }
  386.  
  387.             /**
  388.              * 5B. Endpoints - check if any endpoint is set with $_GET parameter
  389.              */
  390.             if(!empty($element_id) && $deep_detect_enabled && !empty($_GET)) {
  391.                 $get_endpoints = array_intersect($wp->public_query_vars, array_keys($_GET));
  392.  
  393.                 if(!empty($get_endpoints)) {
  394.                     // Append query vars from $_GET parameters
  395.                     foreach($get_endpoints as $endpoint) {
  396.                         // Numeric endpoints
  397.                         $endpoint_value = (in_array($endpoint, array('page', 'paged', 'attachment_id'))) ? filter_var($_GET[$endpoint], FILTER_SANITIZE_NUMBER_INT) : $_GET[$endpoint];
  398.  
  399.                         // Ignore page endpoint if its value is 1
  400.                         if(in_array($endpoint, array('page', 'paged')) && $endpoint_value == 1) { continue; }
  401.  
  402.                         $query[$endpoint] = sanitize_text_field($endpoint_value);
  403.                     }
  404.                 }
  405.             }
  406.  
  407.             /**
  408.              * 6. Set global with detected item id
  409.              */
  410.             if(!empty($element_id)) {
  411.                 $pm_query['id'] = $element_id;
  412.  
  413.                 // Make the redirects more clever - see new_uri_redirect_and_404() method
  414.                 $query['do_not_redirect'] = 1;
  415.             }
  416.         }
  417.  
  418.         /**
  419.          * 7. Debug data
  420.          */
  421.         if(!empty($taxonomy)) {
  422.             $content_type = "Taxonomy: {$term_taxonomy}";
  423.         } else if(!empty($post_type)) {
  424.             $content_type = "Post type: {$post_type}";
  425.         } else {
  426.             $content_type = '';
  427.         }
  428.         $uri_parts = (!empty($uri_parts)) ? $uri_parts : '';
  429.         $query = apply_filters('permalink_manager_filter_query', $query, $old_query, $uri_parts, $pm_query, $content_type);
  430.  
  431.         if($return_object && !empty($term)) {
  432.             return $term;
  433.         } else if($return_object && !empty($post_to_load)) {
  434.             return $post_to_load;
  435.         } else {
  436.             return $query;
  437.         }
  438.     }
  439.  
  440.     /**
  441.      * Trailing slash & remove BOM and double slashes
  442.      */
  443.     static function control_trailing_slashes($permalink) {
  444.         global $permalink_manager_options;
  445.  
  446.         // Ignore empty permalinks
  447.         if(empty($permalink)) { return $permalink; }
  448.  
  449.         // Keep the original permalink in a separate variable
  450.         $original_permalink = $permalink;
  451.  
  452.         $trailing_slash_setting = (!empty($permalink_manager_options['general']['trailing_slashes'])) ? $permalink_manager_options['general']['trailing_slashes'] : "";
  453.  
  454.         // Remove trailing slashes from URLs that end with file extension (eg. .html)
  455.         //if(preg_match('/.*\.([a-zA-Z]{3,4})\/?$/', $permalink)) {
  456.         if(preg_match('/(http(?:s)?:\/\/(?:[^\/]+)\/.*\.([a-zA-Z]{3,4}))\/?$/', $permalink)) {
  457.             $permalink = preg_replace('/^(?!http(?:s):\/\/[^\/]+\/$)(.+?)([\/]*)(\[\?\#][^\/]+|$)/', '$1$3', $permalink); // Instead of untrailingslashit()
  458.         } else {
  459.             // Add trailing slashes
  460.             if(in_array($trailing_slash_setting, array(1, 10))) {
  461.                 $permalink = preg_replace('/(.+?)([\/]*)(\[\?\#][^\/]+|$)/', '$1/$3', $permalink); // Instead of trailingslashit()
  462.             }
  463.             // Remove trailing slashes
  464.             else if(in_array($trailing_slash_setting, array(2, 20))) {
  465.                 $permalink = preg_replace('/(.+?)([\/]*)(\[\?\#][^\/]+|$)/', '$1$3', $permalink); // Instead of untrailingslashit()
  466.             }
  467.             // Default settings
  468.             else {
  469.                 $permalink = user_trailingslashit($permalink);
  470.             }
  471.         }
  472.  
  473.         // Remove double slashes
  474.         $permalink = preg_replace('/([^:])(\/{2,})/', '$1/', $permalink);
  475.  
  476.         // Remove trailing slashes from URLs that end with query string or anchors
  477.         $permalink = preg_replace('/([\?\#]{1}[^\/]+)([\/]+)$/', '$1', $permalink);
  478.  
  479.         return apply_filters('permalink_manager_control_trailing_slashes', $permalink, $original_permalink);
  480.     }
  481.  
  482.     /**
  483.      * Display 404 if requested page does not exist in pagination
  484.      */
  485.     function fix_pagination_pages() {
  486.         global $wp_query, $pm_query;
  487.  
  488.         // 1. Get the queried object
  489.         $post = get_queried_object();
  490.  
  491.         // 2. Check if post object is defined
  492.         if(!empty($post->post_type) && !empty($post->post_content)) {
  493.             // 2A. Check if pagination is detected
  494.             $current_page = (!empty($wp_query->query_vars['page'])) ? $wp_query->query_vars['page'] : 1;
  495.             $current_page = (empty($wp_query->query_vars['page']) && !empty($wp_query->query_vars['paged'])) ? $wp_query->query_vars['paged'] : $current_page;
  496.  
  497.             // 2B. Count post pages
  498.             $num_pages = (is_home() || is_archive()) ? $wp_query->max_num_pages : substr_count(strtolower($post->post_content), '<!--nextpage-->') + 1;
  499.  
  500.             $is_404 = ($current_page > 1 && ($current_page > $num_pages)) ? true : false;
  501.         }
  502.         // 3. Force 404 if no posts are loaded
  503.         else if(!empty($wp_query->query['paged']) && $wp_query->post_count == 0) {
  504.             $is_404 = true;
  505.         }
  506.         // 4. Force 404 if endpoint value is not set
  507.         else if(!empty($pm_query['endpoint']) && $pm_query['endpoint'] == 'page' && empty($pm_query['endpoint_value'])) {
  508.             $is_404 = true;
  509.         }
  510.  
  511.         // 5. Block non-existent pages (Force 404 error)
  512.         if(!empty($is_404)) {
  513.             $wp_query->is_404 = true;
  514.             $wp_query->query = $wp_query->queried_object = $wp_query->queried_object_id = null;
  515.             $wp_query->set_404();
  516.  
  517.             status_header(404);
  518.             nocache_headers();
  519.             include(get_query_template('404'));
  520.  
  521.             die();
  522.         }
  523.     }
  524.  
  525.     /**
  526.      * Redirects
  527.      */
  528.     function new_uri_redirect_and_404() {
  529.         global $wp_query, $wp, $wp_rewrite, $wpdb, $permalink_manager_uris, $permalink_manager_redirects, $permalink_manager_external_redirects, $permalink_manager_options, $pm_query;
  530.  
  531.         // Get the redirection mode & trailing slashes settings
  532.         $redirect_mode = (!empty($permalink_manager_options['general']['redirect'])) ? $permalink_manager_options['general']['redirect'] : false;
  533.         $trailing_slashes_mode = (!empty($permalink_manager_options['general']['trailing_slashes'])) ? $permalink_manager_options['general']['trailing_slashes'] : false;
  534.         $trailing_slashes_redirect = (!empty($permalink_manager_options['general']['trailing_slashes_redirect'])) ? $permalink_manager_options['general']['trailing_slashes_redirect'] : false;
  535.         $canonical_redirect = (!empty($permalink_manager_options['general']['canonical_redirect'])) ? $permalink_manager_options['general']['canonical_redirect'] : false;
  536.         $old_slug_redirect = (!empty($permalink_manager_options['general']['old_slug_redirect'])) ? $permalink_manager_options['general']['old_slug_redirect'] : false;
  537.         $endpoint_redirect = (!empty($permalink_manager_options['general']['endpoint_redirect'])) ? $permalink_manager_options['general']['endpoint_redirect'] : false;
  538.         $pagination_redirect = (!empty($permalink_manager_options['general']['pagination_redirect'])) ? $permalink_manager_options['general']['pagination_redirect'] : false;
  539.         $redirect_type = '-';
  540.  
  541.         // Get home URL
  542.         $home_url = rtrim(get_option('home'), "/");
  543.         $home_dir = parse_url($home_url, PHP_URL_PATH);
  544.  
  545.         // Set up $correct_permalink variable
  546.         $correct_permalink = '';
  547.  
  548.         // Get query string & URI
  549.         $query_string = (!empty($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : '';
  550.         $old_uri = $_SERVER['REQUEST_URI'];
  551.  
  552.         // Fix for WP installed in directories (remove the directory name from the URI)
  553.         if(!empty($home_dir)) {
  554.             $home_dir_regex = preg_quote(trim($home_dir), "/");
  555.             $old_uri = preg_replace("/{$home_dir_regex}/", "", $old_uri, 1);
  556.         }
  557.  
  558.         // Do not use custom redirects on author pages, search & front page
  559.     if(!is_author() && !is_front_page() && !is_home() && !is_feed() && !is_search() && empty($_GET['s'])) {
  560.             // Unset 404 if custom URI is detected
  561.             if(isset($pm_query['id'])) {
  562.                 $wp_query->is_404 = false;
  563.             }
  564.  
  565.             // Sometimes $wp_query indicates the wrong object if requested directly
  566.             $queried_object = get_queried_object();
  567.  
  568.             /**
  569.              * 1A. External redirect
  570.              */
  571.             if(!empty($pm_query['id']) && !empty($permalink_manager_external_redirects[$pm_query['id']])) {
  572.                 $external_url = $permalink_manager_external_redirects[$pm_query['id']];
  573.  
  574.                 if(filter_var($external_url, FILTER_VALIDATE_URL)) {
  575.                     // Allow redirect
  576.                     $wp_query->query_vars['do_not_redirect'] = 0;
  577.  
  578.                     wp_redirect($external_url, 301, PERMALINK_MANAGER_PLUGIN_NAME);
  579.                     exit();
  580.                 }
  581.             }
  582.  
  583.             /**
  584.              * 1B. Custom redirects
  585.              */
  586.             if(empty($wp_query->query_vars['do_not_redirect']) && !empty($permalink_manager_redirects) && is_array($permalink_manager_redirects) && !empty($wp->request) && !empty($pm_query['uri'])) {
  587.                 $uri = $pm_query['uri'];
  588.                 $endpoint_value = $pm_query['endpoint_value'];
  589.  
  590.                 // Make sure that URIs with non-ASCII characters are also detected + Check the URLs that end with number
  591.                 $decoded_url = urldecode($uri);
  592.                 $endpoint_url = "{$uri}/{$endpoint_value}";
  593.  
  594.                 // Check if the URI is not assigned to any post/term's redirects
  595.                 foreach($permalink_manager_redirects as $element => $redirects) {
  596.                     if(!is_array($redirects)) { continue; }
  597.  
  598.                     if(in_array($uri, $redirects) || in_array($decoded_url, $redirects) || (is_numeric($endpoint_value) && in_array($endpoint_url, $redirects))) {
  599.                         // Post is detected
  600.                         if(is_numeric($element)) {
  601.                             $correct_permalink = get_permalink($element);
  602.                         }
  603.                         // Term is detected
  604.                         else {
  605.                             $term_id = intval(preg_replace("/[^0-9]/", "", $element));
  606.                             $correct_permalink = get_term_link($term_id);
  607.                         }
  608.  
  609.                         // The custom redirect is found so there is no need to query the rest of array
  610.                         continue;
  611.                     }
  612.                 }
  613.  
  614.                 $redirect_type = (!empty($correct_permalink)) ? 'custom_redirect' : $redirect_type;
  615.             }
  616.  
  617.             // Ignore WP-Content links
  618.             if(!empty($_SERVER['REQUEST_URI']) && (strpos($_SERVER['REQUEST_URI'], '/wp-content') !== false)) { return false; }
  619.  
  620.             /**
  621.              * 1C. Pagination redirect
  622.              */
  623.             if($pagination_redirect && ((isset($wp_query->query_vars['paged']) && $wp_query->query_vars['paged'] == 1) || (isset($wp_query->query_vars['page']) && $wp_query->query_vars['page'] == 1 && !empty($pm_query['endpoint_value'])))) {
  624.                 $pm_query['endpoint'] = $pm_query['endpoint_value'] = '';
  625.                 $wp_query->query_vars['do_not_redirect'] = 0;
  626.             }
  627.  
  628.             /**
  629.              * 1D. Enhance native redirect
  630.              */
  631.             if($canonical_redirect && empty($wp_query->query_vars['do_not_redirect']) && !empty($queried_object) && empty($correct_permalink)) {
  632.  
  633.                 // Affect only posts with custom URI and old URIs
  634.                 if(!empty($queried_object->ID) && isset($permalink_manager_uris[$queried_object->ID]) && empty($wp_query->query['preview'])) {
  635.                     // Ignore posts with specific statuses
  636.                     if(!(empty($queried_object->post_status)) && in_array($queried_object->post_status, array('draft', 'pending', 'auto-draft', 'future'))) {
  637.                         return '';
  638.                     }
  639.  
  640.                     // Check if post type is allowed
  641.                     if(Permalink_Manager_Helper_Functions::is_disabled($queried_object->post_type, 'post_type')) { return ''; }
  642.  
  643.                     // Get the real URL
  644.                     $correct_permalink = get_permalink($queried_object->ID);
  645.                 }
  646.                 // Affect only terms with custom URI and old URIs
  647.                 else if(!empty($queried_object->term_id) && isset($permalink_manager_uris["tax-{$queried_object->term_id}"]) && defined('PERMALINK_MANAGER_PRO')) {
  648.                     // Check if taxonomy is allowed
  649.                     if(Permalink_Manager_Helper_Functions::is_disabled($queried_object->taxonomy, "taxonomy")) { return ''; }
  650.  
  651.                     // Get the real URL
  652.                     $correct_permalink = get_term_link($queried_object->term_id, $queried_object->taxonomy);
  653.                 }
  654.  
  655.                 $redirect_type = (!empty($correct_permalink)) ? 'native_redirect' : $redirect_type;
  656.             }
  657.  
  658.             /**
  659.              * 1E. Old slug redirect
  660.              */
  661.             if($old_slug_redirect && !empty($pm_query['uri']) && empty($wp_query->query_vars['do_not_redirect']) && is_404()) {
  662.                 $slug = basename($pm_query['uri']);
  663.  
  664.                 $post_id = $wpdb->get_var($wpdb->prepare("SELECT post_id from {$wpdb->postmeta} WHERE meta_key = '_wp_old_slug' AND meta_value = %s", $slug));
  665.                 if(!empty($post_id)) {
  666.                     $correct_permalink = get_permalink($post_id);
  667.                     $redirect_type = 'old_slug_redirect';
  668.                 }
  669.             }
  670.  
  671.             /**
  672.              * 2. Check if URL contains duplicated slashes
  673.              */
  674.             if(!empty($old_uri) && ($old_uri != '/') && preg_match('/\/{2,}/', $old_uri)) {
  675.                 $new_uri = ltrim(preg_replace('/([^:])([\/]+)/', '$1/', $old_uri), "/");
  676.                 $correct_permalink = "{$home_url}/{$new_uri}";
  677.             }
  678.  
  679.             /**
  680.              * 3. Prevent redirect loop
  681.              */
  682.             if(!empty($correct_permalink) && is_string($correct_permalink) && !empty($wp->request) && !empty($redirect_type) && $redirect_type !== 'slash_redirect') {
  683.                 $current_uri = trim($wp->request, "/");
  684.                 $redirect_uri = trim(parse_url($correct_permalink, PHP_URL_PATH), "/");
  685.  
  686.                 $correct_permalink = ($redirect_uri == $current_uri) ? null : $correct_permalink;
  687.             }
  688.  
  689.             /**
  690.              * 4. Add endpoints to redirect URL
  691.              */
  692.             if(!empty($correct_permalink) && $endpoint_redirect && ($redirect_type !== 'slash_redirect') && (!empty($pm_query['endpoint_value']) || !empty($pm_query['endpoint']))) {
  693.                 $endpoint_value = $pm_query['endpoint_value'];
  694.  
  695.                 if(empty($pm_query['endpoint']) && is_numeric($endpoint_value)) {
  696.                     $correct_permalink = sprintf("%s/%d", trim($correct_permalink, "/"), $endpoint_value);
  697.                 } else if(isset($pm_query['endpoint']) && !empty($endpoint_value)) {
  698.                     if($pm_query['endpoint'] == 'cpage') {
  699.                         $correct_permalink = sprintf("%s/%s-%s", trim($correct_permalink, "/"), $wp_rewrite->comments_pagination_base, $endpoint_value);
  700.                     } else {
  701.                         $correct_permalink = sprintf("%s/%s/%s", trim($correct_permalink, "/"), $pm_query['endpoint'], $endpoint_value);
  702.                     }
  703.                 } else {
  704.                     $correct_permalink = sprintf("%s/%s", trim($correct_permalink, "/"), $pm_query['endpoint']);
  705.                 }
  706.             }
  707.         } else {
  708.             $queried_object = '-';
  709.         }
  710.  
  711.         /**
  712.          * 5. Check trailing slashes (ignore links with query parameters)
  713.          */
  714.         if($trailing_slashes_mode && $trailing_slashes_redirect && empty($correct_permalink) && empty($_SERVER['QUERY_STRING']) && !empty($_SERVER['REQUEST_URI']) && !is_front_page()) {
  715.             // Check if $old_uri ends with slash or not
  716.             $ends_with_slash = (substr($old_uri, -1) == "/") ? true : false;
  717.             $trailing_slashes_mode = (preg_match("/.*\.([a-zA-Z]{3,4})\/?$/", $old_uri) && $trailing_slashes_mode == 1) ? 2 : $trailing_slashes_mode;
  718.  
  719.             // Ignore empty URIs
  720.             if($old_uri != "/") {
  721.                 // 2A. Force trailing slashes
  722.                 if($trailing_slashes_mode == 1 && $ends_with_slash == false) {
  723.                     $correct_permalink = sprintf("%s/%s/", rtrim($home_url, '/'), trim($old_uri, '/'));
  724.                 }
  725.                 // 2B. Remove trailing slashes
  726.                 else if($trailing_slashes_mode == 2 && $ends_with_slash == true) {
  727.                     $correct_permalink = sprintf("%s/%s", rtrim($home_url, '/'), trim($old_uri, '/'));
  728.                 }
  729.                 // 2C. Remove duplicated trailing slashes
  730.                 else if($trailing_slashes_mode == 1 && preg_match('/[\/]{2,}$/', $old_uri)) {
  731.                     $correct_permalink = sprintf("%s/%s/", rtrim($home_url, '/'), trim($old_uri, '/'));
  732.                 }
  733.             }
  734.  
  735.             $redirect_type = (!empty($correct_permalink)) ? 'slash_redirect' : '-';
  736.         }
  737.  
  738.         /**
  739.          * 6. WWW prefix | SSL mismatch redirect
  740.          */
  741.         if(!empty($permalink_manager_options['general']['sslwww_redirect'])) {
  742.             $home_url_has_www = (strpos($home_url, 'www.') !== false) ? true : false;
  743.             $requested_url_has_www = (strpos($_SERVER['HTTP_HOST'], 'www.') !== false) ? true : false;
  744.             $home_url_has_ssl = (strpos($home_url, 'https') !== false) ? true : false;
  745.             $requested_url_has_ssl = is_ssl();
  746.  
  747.             if(($home_url_has_www !== $requested_url_has_www) || ($home_url_has_ssl !== $requested_url_has_ssl)) {
  748.                 $correct_permalink = "{$home_url}/{$old_uri}";
  749.                 $redirect_type = 'www_redirect';
  750.             }
  751.         }
  752.  
  753.         /**
  754.          * 7. Debug redirect
  755.          */
  756.         $correct_permalink = apply_filters('permalink_manager_filter_redirect', $correct_permalink, $redirect_type, $queried_object);
  757.  
  758.         /**
  759.          * 8. Ignore default URIs (or do nothing if redirects are disabled)
  760.          */
  761.         if(!empty($correct_permalink) && is_string($correct_permalink) && !empty($redirect_mode)) {
  762.             // Allow redirect
  763.             $wp_query->query_vars['do_not_redirect'] = 0;
  764.  
  765.             // Append query string
  766.             $correct_permalink = (!empty($query_string)) ? sprintf("%s?%s", strtok($correct_permalink, "?"), $query_string) : $correct_permalink;
  767.  
  768.             // Adjust trailing slashes
  769.             $correct_permalink = self::control_trailing_slashes($correct_permalink);
  770.  
  771.             wp_safe_redirect($correct_permalink, $redirect_mode, PERMALINK_MANAGER_PLUGIN_NAME);
  772.             exit();
  773.         }
  774.     }
  775.  
  776.     function adjust_canonical_redirect() {
  777.         global $permalink_manager_options, $permalink_manager_uris, $wp, $wp_rewrite;
  778.  
  779.         // Adjust rewrite settings for trailing slashes
  780.         $trailing_slash_setting = (!empty($permalink_manager_options['general']['trailing_slashes'])) ? $permalink_manager_options['general']['trailing_slashes'] : "";
  781.         if(in_array($trailing_slash_setting, array(1, 10))) {
  782.             $wp_rewrite->use_trailing_slashes = true;
  783.         } else if(in_array($trailing_slash_setting, array(2, 20))) {
  784.             $wp_rewrite->use_trailing_slashes = false;
  785.         }
  786.  
  787.         // Get endpoints
  788.         $endpoints = Permalink_Manager_Helper_Functions::get_endpoints();
  789.         $endpoints_array = ($endpoints) ? explode("|", $endpoints) : array();
  790.  
  791.         // Check if any endpoint is called (fix for feed and similar endpoints)
  792.         foreach($endpoints_array as $endpoint) {
  793.             if(!empty($wp->query_vars[$endpoint]) && !in_array($endpoint, array('attachment', 'page', 'paged'))) {
  794.                 $wp->query_vars['do_not_redirect'] = 1;
  795.                 break;
  796.             }
  797.         }
  798.  
  799.         // Do nothing for posts and terms without custom URIs (when canonical redirect is enabled)
  800.         if(is_singular() || is_tax() || is_category() || is_tag()) {
  801.             $element = get_queried_object();
  802.             if(!empty($element->ID)) {
  803.                 $custom_uri = (!empty($permalink_manager_uris[$element->ID])) ? $permalink_manager_uris[$element->ID] : "";
  804.             } else if(!empty($element->term_id)) {
  805.                 $custom_uri = (!empty($permalink_manager_uris["tax-{$element->term_id}"])) ? $permalink_manager_uris["tax-{$element->term_id}"] : "";
  806.             }
  807.         }
  808.  
  809.         if(empty($permalink_manager_options['general']['canonical_redirect'])) {
  810.             remove_action('template_redirect', 'redirect_canonical');
  811.         }
  812.  
  813.         if(empty($permalink_manager_options['general']['old_slug_redirect'])) {
  814.             remove_action('template_redirect', 'wp_old_slug_redirect');
  815.         }
  816.  
  817.         if(!empty($wp->query_vars['do_not_redirect'])) {
  818.             // RankMath
  819.             remove_action('template_redirect', 'do_redirection', 11);
  820.             remove_action('wp', 'do_redirection', 11);
  821.  
  822.             // SEOPress
  823.             remove_action('template_redirect', 'seopress_category_redirect', 1);
  824.  
  825.             remove_action('template_redirect', 'wp_old_slug_redirect');
  826.             remove_action('template_redirect', 'redirect_canonical');
  827.             add_filter('wpml_is_redirected', '__return_false', 99, 2);
  828.             add_filter('pll_check_canonical_url', '__return_false', 99, 2);
  829.         }
  830.     }
  831.  
  832.     /**
  833.      * Case insensitive permalinks
  834.      */
  835.     function case_insensitive_permalinks() {
  836.         global $permalink_manager_options, $permalink_manager_uris;
  837.  
  838.         if(!empty($_SERVER['REQUEST_URI'])) {
  839.             $_SERVER['REQUEST_URI'] = strtolower($_SERVER['REQUEST_URI']);
  840.             $permalink_manager_uris = array_map('strtolower', $permalink_manager_uris);
  841.         }
  842.     }
  843.  
  844. }
  845.  
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×