Advertisement
Guest User

permalink-manager-uri-functions-post.php

a guest
Jan 29th, 2020
484
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 33.38 KB | None | 0 0
  1. <?php
  2.  
  3. /**
  4. * Additional functions used in classes and another subclasses
  5. */
  6. class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
  7.  
  8.     public function __construct() {
  9.         add_action( 'admin_init', array($this, 'admin_init'), 99, 3);
  10.  
  11.         add_filter( '_get_page_link', array($this, 'custom_post_permalinks'), 99, 2);
  12.         add_filter( 'page_link', array($this, 'custom_post_permalinks'), 99, 2);
  13.         add_filter( 'post_link', array($this, 'custom_post_permalinks'), 99, 2);
  14.         add_filter( 'post_type_link', array($this, 'custom_post_permalinks'), 99, 2);
  15.         add_filter( 'attachment_link', array($this, 'custom_post_permalinks'), 99, 2);
  16.  
  17.         add_filter( 'permalink_manager_uris', array($this, 'exclude_homepage'), 99);
  18.  
  19.         // Support url_to_postid
  20.         add_filter( 'url_to_postid', array($this, 'url_to_postid'), 99);
  21.  
  22.         /**
  23.          * URI Editor
  24.          */
  25.         add_filter( 'get_sample_permalink_html', array($this, 'edit_uri_box'), 99, 5 );
  26.  
  27.         add_action( 'save_post', array($this, 'update_post_uri'), 99, 1);
  28.         add_action( 'edit_attachment', array($this, 'update_post_uri'), 99, 1 );
  29.         add_action( 'wp_insert_post', array($this, 'new_post_uri'), 99, 1 );
  30.         add_action( 'add_attachment', array($this, 'new_post_uri'), 99, 1 );
  31.         add_action( 'wp_trash_post', array($this, 'remove_post_uri'), 100, 1 );
  32.  
  33.         add_action( 'quick_edit_custom_box', array($this, 'quick_edit_column_form'), 99, 3);
  34.     }
  35.  
  36.     /**
  37.      * Init
  38.      */
  39.     function admin_init() {
  40.         $post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
  41.  
  42.         // Add "URI Editor" to "Quick Edit" for all post_types
  43.         foreach($post_types as $post_type => $label) {
  44.             add_filter( "manage_{$post_type}_posts_columns" , array($this, 'quick_edit_column') );
  45.             add_filter( "manage_{$post_type}_posts_custom_column" , array($this, 'quick_edit_column_content'), 10, 2 );
  46.         }
  47.     }
  48.  
  49.     /**
  50.     * Change permalinks for posts, pages & custom post types
  51.     */
  52.     function custom_post_permalinks($permalink, $post) {
  53.         global $wp_rewrite, $permalink_manager_uris, $permalink_manager_options;
  54.  
  55.         // Do not filter permalinks in Customizer
  56.         if((function_exists('is_customize_preview') && is_customize_preview())) { return $permalink; }
  57.  
  58.         // Do not filter in WPML String Editor
  59.         if(!empty($_REQUEST['icl_ajx_action']) && $_REQUEST['icl_ajx_action'] == 'icl_st_save_translation') { return $permalink; }
  60.  
  61.         $post = (is_integer($post)) ? get_post($post) : $post;
  62.  
  63.         // Start with homepage URL
  64.         $home_url = Permalink_Manager_Helper_Functions::get_permalink_base($post);
  65.  
  66.         // 1. Check if post type is allowed
  67.         if(!empty($post->post_type) && Permalink_Manager_Helper_Functions::is_disabled($post->post_type, 'post_type')) { return $permalink; }
  68.  
  69.         // 2A. Do not change permalink of frontpage
  70.         if(Permalink_Manager_Helper_Functions::is_front_page($post->ID)) {
  71.             return $permalink;
  72.         }
  73.         // 2B. Do not change permalink for drafts and future posts (+ remove trailing slash from them)
  74.         else if(in_array($post->post_status, array('draft', 'pending', 'auto-draft', 'future'))) {
  75.             return $permalink;
  76.         }
  77.  
  78.         // 3. Save the old permalink to separate variable
  79.         $old_permalink = $permalink;
  80.  
  81.         // 4. Filter only the posts with custom permalink assigned
  82.         if(isset($permalink_manager_uris[$post->ID])) {
  83.             // Encode URI?
  84.             if(!empty($permalink_manager_options['general']['decode_uris'])) {
  85.                 $permalink = "{$home_url}/" . rawurldecode("/{$permalink_manager_uris[$post->ID]}");
  86.             } else {
  87.                 $permalink = "{$home_url}/" . Permalink_Manager_Helper_Functions::encode_uri("{$permalink_manager_uris[$post->ID]}");
  88.             }
  89.         } else if($post->post_type == 'attachment' && $post->post_parent > 0 && $post->post_parent != $post->ID && !empty($permalink_manager_uris[$post->post_parent])) {
  90.             $permalink = "{$home_url}/{$permalink_manager_uris[$post->post_parent]}/attachment/{$post->post_name}";
  91.         } else if(!empty($permalink_manager_options['general']['decode_uris'])) {
  92.             $permalink = "{$home_url}/" . rawurldecode("/{$permalink}");
  93.         }
  94.  
  95.         // 5. Allow to filter (do not filter in Customizer)
  96.         if(!(function_exists('is_customize_preview') && is_customize_preview())) {
  97.             return apply_filters('permalink_manager_filter_final_post_permalink', $permalink, $post, $old_permalink);
  98.         } else {
  99.             return $old_permalink;
  100.         }
  101.     }
  102.  
  103.     /**
  104.     * Check if the provided slug is unique and then update it with SQL query.
  105.     */
  106.     static function update_slug_by_id($slug, $id) {
  107.         global $wpdb;
  108.  
  109.         // Update slug and make it unique
  110.         $slug = (empty($slug)) ? get_the_title($id) : $slug;
  111.         $slug = sanitize_title($slug);
  112.  
  113.         $new_slug = wp_unique_post_slug($slug, $id, get_post_status($id), get_post_type($id), null);
  114.         $wpdb->query("UPDATE $wpdb->posts SET post_name = '$new_slug' WHERE ID = '$id'");
  115.  
  116.         return $new_slug;
  117.     }
  118.  
  119.     /**
  120.     * Get the active URI
  121.     */
  122.     public static function get_post_uri($post_id, $native_uri = false, $is_draft = false) {
  123.         global $permalink_manager_uris;
  124.  
  125.         // Check if input is post object
  126.         $post_id = (isset($post_id->ID)) ? $post_id->ID : $post_id;
  127.  
  128.         if(!empty($permalink_manager_uris[$post_id])) {
  129.             $final_uri = $permalink_manager_uris[$post_id];
  130.         } else if(!$is_draft) {
  131.             $final_uri = self::get_default_post_uri($post_id, $native_uri);
  132.         } else {
  133.             $final_uri = '';
  134.         }
  135.  
  136.         return $final_uri;
  137.     }
  138.  
  139.     /**
  140.     * Get the default (not overwritten by the user) or native URI (unfiltered)
  141.     */
  142.     public static function get_default_post_uri($post, $native_uri = false, $check_if_disabled = false) {
  143.         global $permalink_manager_options, $permalink_manager_uris, $permalink_manager_permastructs, $wp_post_types;
  144.  
  145.         // Load all bases & post
  146.         $post = is_object($post) ? $post : get_post($post);
  147.  
  148.         // Check if post ID is defined (and front page permalinks should be empty)
  149.         if(empty($post->ID) || Permalink_Manager_Helper_Functions::is_front_page($post->ID)) { return ''; }
  150.  
  151.         $post_id = $post->ID;
  152.         $post_type = $post->post_type;
  153.         $post_name = (empty($post->post_name)) ? Permalink_Manager_Helper_Functions::sanitize_title($post->post_title) : $post->post_name;
  154.  
  155.         // 1A. Check if post type is allowed
  156.         if($check_if_disabled && Permalink_Manager_Helper_Functions::is_disabled($post_type, 'post_type')) { return ''; }
  157.  
  158.         // 1A. Get the native permastructure
  159.         if($post_type == 'attachment') {
  160.             $parent_page = ($post->post_parent > 0 && $post->post_parent != $post->ID) ? get_post($post->post_parent) : false;
  161.  
  162.             if(!empty($parent_page->ID)) {
  163.                 $parent_page_uri = (!empty($permalink_manager_uris[$parent_page->ID])) ? $permalink_manager_uris[$parent_page->ID] : get_page_uri($parent_page->ID);
  164.             } else {
  165.                 $parent_page_uri = "";
  166.             }
  167.  
  168.             $native_permastructure = ($parent_page) ? trim($parent_page_uri, "/") . "/attachment" : "";
  169.         } else {
  170.             $native_permastructure = Permalink_Manager_Helper_Functions::get_default_permastruct($post_type);
  171.         }
  172.  
  173.         // 1B. Get the permastructure
  174.         if($native_uri || empty($permalink_manager_permastructs['post_types'][$post_type])) {
  175.             $permastructure = $native_permastructure;
  176.         } else {
  177.             $permastructure = apply_filters('permalink_manager_filter_permastructure', $permalink_manager_permastructs['post_types'][$post_type], $post);
  178.         }
  179.  
  180.         // 1C. Set the permastructure
  181.         $default_base = (!empty($permastructure)) ? trim($permastructure, '/') : "";
  182.  
  183.         // 2A. Get the date
  184.         $date = explode(" ", date('Y m d H i s', strtotime($post->post_date)));
  185.         $monthname = sanitize_title(date_i18n('F', strtotime($post->post_date)));
  186.  
  187.         // 2B. Get the author (if needed)
  188.         $author = '';
  189.         if(strpos($default_base, '%author%') !== false) {
  190.             $authordata = get_userdata($post->post_author);
  191.             $author = $authordata->user_nicename;
  192.         }
  193.  
  194.         // 2C. Get the post type slug
  195.         if(!empty($wp_post_types[$post_type])) {
  196.             if(!empty($wp_post_types[$post_type]->rewrite['slug'])) {
  197.                 $post_type_slug = $wp_post_types[$post_type]->rewrite['slug'];
  198.             } else if(is_string($wp_post_types[$post_type]->rewrite)) {
  199.                 $post_type_slug = $wp_post_types[$post_type]->rewrite;
  200.             }
  201.         }
  202.  
  203.         $post_type_slug = (!empty($post_type_slug)) ? $post_type_slug : $post_type;
  204.         $post_type_slug = apply_filters('permalink_manager_filter_post_type_slug', $post_type_slug, $post, $post_type);
  205.         $post_type_slug = preg_replace('/(%([^%]+)%\/?)/', '', $post_type_slug);
  206.  
  207.         // 3B. Get the full slug
  208.         $post_name = Permalink_Manager_Helper_Functions::remove_slashes($post_name);
  209.         $custom_slug = $full_custom_slug = Permalink_Manager_Helper_Functions::force_custom_slugs($post_name, $post);
  210.         $full_native_slug = $post_name;
  211.  
  212.         // 3A. Fix for hierarchical CPT (start)
  213.         // $full_slug = (is_post_type_hierarchical($post_type)) ? get_page_uri($post) : $post_name;
  214.         if($post->ancestors && is_post_type_hierarchical($post_type)) {
  215.             foreach($post->ancestors as $parent) {
  216.         $parent = get_post($parent);
  217.         if($parent && $parent->post_name) {
  218.                     $full_native_slug = $parent->post_name . '/' . $full_native_slug;
  219.                     $full_custom_slug = Permalink_Manager_Helper_Functions::force_custom_slugs($parent->post_name, $parent) . '/' . $full_custom_slug;
  220.         }
  221.         }
  222.         }
  223.  
  224.         // 3B. Allow filter the default slug (only custom permalinks)
  225.         if(!$native_uri) {
  226.             $full_slug = apply_filters('permalink_manager_filter_default_post_slug', $full_custom_slug, $post, $post_name);
  227.         } else {
  228.             $full_slug = $full_native_slug;
  229.         }
  230.  
  231.         $post_type_tag = Permalink_Manager_Helper_Functions::get_post_tag($post_type);
  232.  
  233.         // 3C. Get the standard tags and replace them with their values
  234.         $tags = array('%year%', '%monthnum%', '%monthname%', '%day%', '%hour%', '%minute%', '%second%', '%post_id%', '%author%', '%post_type%');
  235.         $tags_replacements = array($date[0], $date[1], $monthname, $date[2], $date[3], $date[4], $date[5], $post->ID, $author, $post_type_slug);
  236.         $default_uri = str_replace($tags, $tags_replacements, $default_base);
  237.  
  238.         // 3D. Get the slug tags
  239.         $slug_tags = array($post_type_tag, "%postname%", "%postname_flat%", "%{$post_type}_flat%", "%native_slug%");
  240.         $slug_tags_replacement = array($full_slug, $full_slug, $custom_slug, $custom_slug, $full_native_slug);
  241.  
  242.         // 3E. Check if any post tag is present in custom permastructure
  243.         $do_not_append_slug = (!empty($permalink_manager_options['permastructure-settings']['do_not_append_slug']['post_types'][$post_type])) ? true : false;
  244.         $do_not_append_slug = apply_filters("permalink_manager_do_not_append_slug", $do_not_append_slug, $post_type, $post);
  245.         if($do_not_append_slug == false) {
  246.             foreach($slug_tags as $tag) {
  247.                 if(strpos($default_uri, $tag) !== false) {
  248.                     $do_not_append_slug = true;
  249.                     break;
  250.                 }
  251.             }
  252.         }
  253.  
  254.         // 3F. Replace the post tags with slugs or rppend the slug if no post tag is defined
  255.         if(!empty($do_not_append_slug)) {
  256.             $default_uri = str_replace($slug_tags, $slug_tags_replacement, $default_uri);
  257.         } else {
  258.             $default_uri .= "/{$full_slug}";
  259.         }
  260.  
  261.         // 4. Replace taxonomies
  262.         $taxonomies = get_taxonomies();
  263.  
  264.         if($taxonomies) {
  265.             foreach($taxonomies as $taxonomy) {
  266.                 // 1. Reset $replacement
  267.                 $replacement = $replacement_term = "";
  268.                 $terms = wp_get_object_terms($post->ID, $taxonomy);
  269.  
  270.                 // 2. Try to use Yoast SEO Primary Term
  271.                 $replacement_term = $primary_term = Permalink_Manager_Helper_Functions::get_primary_term($post->ID, $taxonomy, false);
  272.  
  273.                 // 3. Get the first assigned term to this taxonomy
  274.                 if(empty($replacement_term)) {
  275.                     $replacement_term = (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) ? Permalink_Manager_Helper_Functions::get_lowest_element($terms[0], $terms) : "";
  276.                     $replacement_term = apply_filters('permalink_manager_filter_post_terms', $replacement_term, $post, $terms, $taxonomy, $native_uri);
  277.                 }
  278.  
  279.                 // 4A. Custom URI as term base
  280.                 if(!empty($replacement_term->term_id) && strpos($default_uri, "%{$taxonomy}_custom_uri%") !== false && !empty($permalink_manager_uris["tax-{$replacement_term->term_id}"])) {
  281.                     $mode = 1;
  282.                 }
  283.                 // 4B. Hierarhcical term base
  284.                 else if(!empty($replacement_term->term_id) && strpos($default_uri, "%{$taxonomy}_flat%") === false && is_taxonomy_hierarchical($taxonomy)) {
  285.                     $mode = 2;
  286.                 }
  287.                 // 4C. Force flat/non-hierarchical term base - get highgest level term (if %taxonomy_flat% tag is used and primary term is not set)
  288.                 else if(!$native_uri && strpos($default_uri, "%{$taxonomy}_flat%") !== false && !empty($terms) && empty($primary_term->slug)) {
  289.                     $mode = 3;
  290.                 }
  291.                 // 4D. Flat/non-hierarchical term base - get first term (if primary term not set)
  292.                 else if(empty($primary_term->slug)) {
  293.                     $mode = 4;
  294.                 }
  295.                 // 4E. Flat/non-hierarchical term base - get and force primary term (if set)
  296.                 else {
  297.                     $mode = 5;
  298.                     $replacement_term = $primary_term;
  299.                 }
  300.  
  301.                 // Get the replacement slug (custom + native)
  302.                 $replacement = Permalink_Manager_Helper_Functions::get_term_full_slug($replacement_term, $terms, $mode, $native_uri);
  303.                 $native_replacement = Permalink_Manager_Helper_Functions::get_term_full_slug($replacement_term, $terms, $mode, true);
  304.  
  305.                 // Filter final category slug
  306.                 $replacement = apply_filters('permalink_manager_filter_term_slug', $replacement, $replacement_term, $post, $terms, $taxonomy, $native_uri);
  307.  
  308.                 // 4. Do the replacement
  309.                 $default_uri = (!empty($replacement)) ? str_replace(array("%{$taxonomy}%", "%{$taxonomy}_flat%", "%{$taxonomy}_custom_uri%", "%{$taxonomy}_native_slug%"), array($replacement, $replacement, $replacement, $native_replacement), $default_uri) : $default_uri;
  310.             }
  311.         }
  312.  
  313.         return apply_filters('permalink_manager_filter_default_post_uri', $default_uri, $post->post_name, $post, $post_name, $native_uri);
  314.     }
  315.  
  316.     /**
  317.     * The homepage should not use URI
  318.     */
  319.     function exclude_homepage($uris) {
  320.         // Find the homepage URI
  321.         $homepage_id = get_option('page_on_front');
  322.  
  323.         if(is_array($uris) && !empty($uris[$homepage_id])) {
  324.             unset($uris[$homepage_id]);
  325.         }
  326.  
  327.         return $uris;
  328.     }
  329.  
  330.     /**
  331.      * Support url_to_postid
  332.      */
  333.     public function url_to_postid($url) {
  334.         global $pm_query;
  335.  
  336.         // Filter only defined URLs
  337.         if(empty($url)) { return $url; }
  338.  
  339.         // Make sure that $pm_query global is not changed
  340.         $old_pm_query = $pm_query;
  341.         $post = Permalink_Manager_Core_Functions::detect_post(null, $url, true);
  342.         $pm_query = $old_pm_query;
  343.  
  344.         if(!empty($post->ID)) {
  345.             $native_uri = self::get_default_post_uri($post->ID, true);
  346.             $native_url = sprintf("%s/%s", trim(home_url(), "/"), $native_uri);
  347.         } else {
  348.             $native_uri = '';
  349.         }
  350.  
  351.         return (!empty($native_uri)) ? $native_uri : $url;
  352.     }
  353.  
  354.     /**
  355.      * Bulk tools
  356.      */
  357.     public static function get_items() {
  358.         global $wpdb;
  359.  
  360.         // Check if post types & statuses are not empty
  361.         if(empty($_POST['post_types']) || empty($_POST['post_statuses'])) { return false; }
  362.  
  363.         $post_types_array = ($_POST['post_types']);
  364.         $post_statuses_array = ($_POST['post_statuses']);
  365.         $post_types = implode("', '", $post_types_array);
  366.         $post_statuses = implode("', '", $post_statuses_array);
  367.  
  368.         // Filter the posts by IDs
  369.         $where = '';
  370.         if(!empty($_POST['ids'])) {
  371.             // Remove whitespaces and prepare array with IDs and/or ranges
  372.             $ids = esc_sql(preg_replace('/\s*/m', '', $_POST['ids']));
  373.             preg_match_all("/([\d]+(?:-?[\d]+)?)/x", $ids, $groups);
  374.  
  375.             // Prepare the extra ID filters
  376.             $where .= "AND (";
  377.             foreach($groups[0] as $group) {
  378.                 $where .= ($group == reset($groups[0])) ? "" : " OR ";
  379.                 // A. Single number
  380.                 if(is_numeric($group)) {
  381.                     $where .= "(ID = {$group})";
  382.                 }
  383.                 // B. Range
  384.                 else if(substr_count($group, '-')) {
  385.                     $range_edges = explode("-", $group);
  386.                     $where .= "(ID BETWEEN {$range_edges[0]} AND {$range_edges[1]})";
  387.                 }
  388.             }
  389.             $where .= ")";
  390.         }
  391.  
  392.         // Get excluded items
  393.         $exclude_posts = $wpdb->get_col("SELECT post_ID FROM {$wpdb->postmeta} AS pm LEFT JOIN {$wpdb->posts} AS p ON (pm.post_ID = p.ID) WHERE pm.meta_key = 'auto_update_uri' AND pm.meta_value = '-2' AND post_type IN ('{$post_types}')");
  394.         if(!empty($exclude_posts)) {
  395.             $where .= sprintf(" AND ID NOT IN ('%s') ", implode("', '", $exclude_posts));
  396.         }
  397.  
  398.         // Support for attachments
  399.         $attachment_support = (in_array('attachment', $post_types_array)) ? " OR (post_type = 'attachment')" : "";
  400.  
  401.         // Get the rows before they are altered
  402.         return $wpdb->get_results("SELECT post_type, post_title, post_name, ID FROM {$wpdb->posts} WHERE ((post_status IN ('{$post_statuses}') AND post_type IN ('{$post_types}')){$attachment_support}) {$where}", ARRAY_A);
  403.     }
  404.  
  405.     /**
  406.     * Find & replace (bulk action)
  407.     */
  408.     public static function find_and_replace($chunk = null, $mode = '', $old_string = '', $new_string = '') {
  409.         global $wpdb, $permalink_manager_uris;
  410.  
  411.         // Reset variables
  412.         $updated_slugs_count = 0;
  413.         $updated_array = array();
  414.         $alert_type = $alert_content = $errors = '';
  415.  
  416.         // Get the rows before they are altered
  417.         $posts_to_update = ($chunk) ? $chunk : self::get_items();
  418.  
  419.         // Now if the array is not empty use IDs from each subarray as a key
  420.         if($posts_to_update && empty($errors)) {
  421.             foreach ($posts_to_update as $row) {
  422.                 // Get default & native URL
  423.                 $native_uri = self::get_default_post_uri($row['ID'], true);
  424.                 $default_uri = self::get_default_post_uri($row['ID']);
  425.  
  426.                 $old_post_name = $row['post_name'];
  427.                 $old_uri = (isset($permalink_manager_uris[$row['ID']])) ? $permalink_manager_uris[$row['ID']] : $native_uri;
  428.  
  429.                 // Do replacement on slugs (non-REGEX)
  430.                 if(preg_match("/^\/.+\/[a-z]*$/i", $old_string)) {
  431.                     $regex = stripslashes(trim(sanitize_text_field($_POST['old_string']), "/"));
  432.                     $regex = preg_quote($regex, '~');
  433.                     $pattern = "~{$regex}~";
  434.  
  435.                     $new_post_name = ($mode == 'slugs') ? preg_replace($pattern, $new_string, $old_post_name) : $old_post_name;
  436.                     $new_uri = ($mode != 'slugs') ? preg_replace($pattern, $new_string, $old_uri) : $old_uri;
  437.                 } else {
  438.                     $new_post_name = ($mode == 'slugs') ? str_replace($old_string, $new_string, $old_post_name) : $old_post_name; // Post name is changed only in first mode
  439.                     $new_uri = ($mode != 'slugs') ? str_replace($old_string, $new_string, $old_uri) : $old_uri;
  440.                 }
  441.  
  442.                 // echo "{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri} \n";
  443.  
  444.                 // Check if native slug should be changed
  445.                 if(($mode == 'slugs') && ($old_post_name != $new_post_name)) {
  446.                     self::update_slug_by_id($new_post_name, $row['ID']);
  447.                 }
  448.  
  449.                 if(($old_uri != $new_uri) || ($old_post_name != $new_post_name) && !(empty($new_uri))) {
  450.                     $permalink_manager_uris[$row['ID']] = $new_uri;
  451.                     $updated_array[] = array('item_title' => $row['post_title'], 'ID' => $row['ID'], 'old_uri' => $old_uri, 'new_uri' => $new_uri, 'old_slug' => $old_post_name, 'new_slug' => $new_post_name);
  452.                     $updated_slugs_count++;
  453.                 }
  454.  
  455.                 do_action('permalink-manager-updated-post-uri', $row['ID'], $new_uri, $old_uri, $native_uri, $default_uri);
  456.             }
  457.  
  458.             // Filter array before saving
  459.             $permalink_manager_uris = array_filter($permalink_manager_uris);
  460.             update_option('permalink-manager-uris', $permalink_manager_uris);
  461.  
  462.             $output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count);
  463.             wp_reset_postdata();
  464.         }
  465.  
  466.         return ($output) ? $output : "";
  467.     }
  468.  
  469.     /**
  470.     * Regenerate slugs & bases (bulk action)
  471.     */
  472.     static function regenerate_all_permalinks($chunk = null, $mode = '') {
  473.         global $wpdb, $permalink_manager_uris;
  474.  
  475.         // Reset variables
  476.         $updated_slugs_count = 0;
  477.         $updated_array = array();
  478.         $alert_type = $alert_content = $errors = '';
  479.  
  480.         // Get the rows before they are altered
  481.         $posts_to_update = ($chunk) ? $chunk : self::get_items();
  482.  
  483.         // Now if the array is not empty use IDs from each subarray as a key
  484.         if($posts_to_update && empty($errors)) {
  485.             foreach ($posts_to_update as $row) {
  486.                 // Get default & native URL
  487.                 $native_uri = self::get_default_post_uri($row['ID'], true);
  488.                 $default_uri = self::get_default_post_uri($row['ID']);
  489.                 $old_post_name = $row['post_name'];
  490.                 $old_uri = isset($permalink_manager_uris[$row['ID']]) ? trim($permalink_manager_uris[$row['ID']], "/") : '';
  491.                 $correct_slug = ($mode == 'slugs') ? sanitize_title($row['post_title']) : Permalink_Manager_Helper_Functions::sanitize_title($row['post_title']);
  492.  
  493.                 // Process URI & slug
  494.                 $new_slug = wp_unique_post_slug($correct_slug, $row['ID'], get_post_status($row['ID']), get_post_type($row['ID']), null);
  495.                 $new_post_name = ($mode == 'slugs') ? $new_slug : $old_post_name; // Post name is changed only in first mode
  496.  
  497.                 // Prepare the new URI
  498.                 if($mode == 'slugs') {
  499.                     $new_uri = ($old_uri) ? $old_uri : $native_uri;
  500.                 } else if($mode == 'native') {
  501.                     $new_uri = $native_uri;
  502.                 } else {
  503.                     $new_uri = $default_uri;
  504.                 }
  505.  
  506.                 //print_r("{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri} / - {$new_slug} - {$new_post_name} \n");
  507.  
  508.                 // Check if native slug should be changed
  509.                 if(($mode == 'slugs') && ($old_post_name != $new_post_name)) {
  510.                     self::update_slug_by_id($new_post_name, $row['ID']);
  511.                 }
  512.  
  513.                 if(($old_uri != $new_uri) || ($old_post_name != $new_post_name)) {
  514.                     $permalink_manager_uris[$row['ID']] = $new_uri;
  515.                     $updated_array[] = array('item_title' => $row['post_title'], 'ID' => $row['ID'], 'old_uri' => $old_uri, 'new_uri' => $new_uri, 'old_slug' => $old_post_name, 'new_slug' => $new_post_name);
  516.                     $updated_slugs_count++;
  517.                 }
  518.  
  519.                 do_action('permalink-manager-updated-post-uri', $row['ID'], $new_uri, $old_uri, $native_uri, $default_uri);
  520.             }
  521.  
  522.             // Filter array before saving
  523.             $permalink_manager_uris = array_filter($permalink_manager_uris);
  524.             update_option('permalink-manager-uris', $permalink_manager_uris);
  525.  
  526.             $output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count);
  527.             wp_reset_postdata();
  528.         }
  529.  
  530.         return (!empty($output)) ? $output : "";
  531.     }
  532.  
  533.     /**
  534.     * Update all slugs & bases (bulk action)
  535.     */
  536.     static public function update_all_permalinks() {
  537.         global $permalink_manager_uris;
  538.  
  539.         // Setup needed variables
  540.         $updated_slugs_count = 0;
  541.         $updated_array = array();
  542.  
  543.         $old_uris = $permalink_manager_uris;
  544.         $new_uris = isset($_POST['uri']) ? $_POST['uri'] : array();
  545.  
  546.         // Double check if the slugs and ids are stored in arrays
  547.         if (!is_array($new_uris)) $new_uris = explode(',', $new_uris);
  548.  
  549.         if (!empty($new_uris)) {
  550.             foreach($new_uris as $id => $new_uri) {
  551.                 // Prepare variables
  552.                 $this_post = get_post($id);
  553.                 $updated = '';
  554.  
  555.                 // Get default & native URL
  556.                 $native_uri = self::get_default_post_uri($id, true);
  557.                 $default_uri = self::get_default_post_uri($id);
  558.  
  559.                 $old_uri = isset($old_uris[$id]) ? trim($old_uris[$id], "/") : "";
  560.  
  561.                 // Process new values - empty entries will be treated as default values
  562.                 $new_uri = preg_replace('/\s+/', '', $new_uri);
  563.                 $new_uri = (!empty($new_uri)) ? trim($new_uri, "/") : $default_uri;
  564.                 $new_slug = (strpos($new_uri, '/') !== false) ? substr($new_uri, strrpos($new_uri, '/') + 1) : $new_uri;
  565.  
  566.                 //print_r("{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri}\n");
  567.  
  568.                 if($new_uri != $old_uri) {
  569.                     $old_uris[$id] = $new_uri;
  570.                     $updated_array[] = array('item_title' => get_the_title($id), 'ID' => $id, 'old_uri' => $old_uri, 'new_uri' => $new_uri);
  571.                     $updated_slugs_count++;
  572.                 }
  573.  
  574.                 do_action('permalink-manager-updated-post-uri', $id, $new_uri, $old_uri, $native_uri, $default_uri);
  575.             }
  576.  
  577.             // Filter array before saving & append the global
  578.             $permalink_manager_uris = array_filter($old_uris);
  579.             update_option('permalink-manager-uris', $permalink_manager_uris);
  580.  
  581.             $output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count);
  582.         }
  583.  
  584.         return ($output) ? $output : "";
  585.     }
  586.  
  587.     /**
  588.     * Allow to edit URIs from "Edit Post" admin pages
  589.     */
  590.     function edit_uri_box($html, $id, $new_title, $new_slug, $post) {
  591.         global $permalink_manager_uris, $permalink_manager_options;
  592.  
  593.         // Detect auto drafts
  594.         $autosave = (!empty($new_title) && empty($new_slug)) ? true : false;
  595.  
  596.         // Check if post type is disabled
  597.         if(Permalink_Manager_Helper_Functions::is_disabled($post->post_type, 'post_type')) { return $html; }
  598.  
  599.         // Stop the hook (if needed)
  600.         $show_uri_editor = apply_filters("permalink_manager_hide_uri_editor_post_{$post->post_type}", true);
  601.         if(!$show_uri_editor) { return $html; }
  602.  
  603.         $new_html = preg_replace("/(<strong>(.*)<\/strong>)(.*)/is", "$1 ", $html);
  604.         $default_uri = self::get_default_post_uri($id);
  605.         $native_uri = self::get_default_post_uri($id, true);
  606.  
  607.         // Make sure that home URL ends with slash
  608.         $home_url = Permalink_Manager_Helper_Functions::get_permalink_base($post);
  609.  
  610.         // A. Display original permalink on front-page editor
  611.         if(Permalink_Manager_Helper_Functions::is_front_page($id)) {
  612.             preg_match('/href="([^"]+)"/mi', $html, $matches);
  613.             $sample_permalink = (!empty($matches[1])) ? $matches[1] : "";
  614.         }
  615.         else {
  616.             // B. Do not change anything if post is not saved yet (display sample permalink instead)
  617.             if($autosave || empty($post->post_status)) {
  618.                 $sample_permalink_uri = $default_uri;
  619.             }
  620.             // C. Display custom URI if set
  621.             else {
  622.                 $sample_permalink_uri = (!empty($permalink_manager_uris[$id])) ? $permalink_manager_uris[$id] : $native_uri;
  623.             }
  624.  
  625.             // Decode URI & allow to filter it
  626.             $sample_permalink_uri = apply_filters('permalink_manager_filter_post_sample_uri', rawurldecode($sample_permalink_uri), $post);
  627.  
  628.             // Prepare the sample & default permalink
  629.             $sample_permalink = sprintf("%s/<span class=\"editable\">%s</span>", $home_url, str_replace("//", "/", $sample_permalink_uri));
  630.  
  631.             // Allow to filter the sample permalink URL
  632.             // $sample_permalink = apply_filters('permalink_manager_filter_post_sample_permalink', $sample_permalink, $post);
  633.         }
  634.  
  635.         // Append new HTML output
  636.         $new_html .= sprintf("<span class=\"sample-permalink-span\"><a id=\"sample-permalink\" href=\"%s\">%s</a></span>&nbsp;", strip_tags($sample_permalink), $sample_permalink);
  637.         $new_html .= (!$autosave) ? Permalink_Manager_Admin_Functions::display_uri_box($post) : "";
  638.  
  639.         // Append hidden field with native slug
  640.         $new_html .= (!empty($post->post_name)) ? "<span id=\"editable-post-name-full\">{$post->post_name}</span>" : "";
  641.  
  642.         return $new_html;
  643.     }
  644.  
  645.     /**
  646.      * "Quick Edit" form
  647.      */
  648.     function quick_edit_column($columns) {
  649.         global $current_screen;
  650.  
  651.         // Get post type
  652.         $post_type = (!empty($current_screen->post_type)) ? $current_screen->post_type : false;
  653.  
  654.         // Check if post type is disabled
  655.         if($post_type && Permalink_Manager_Helper_Functions::is_disabled($post_type, 'post_type')) { return $columns; }
  656.  
  657.         return (is_array($columns)) ? array_merge($columns, array('permalink-manager-col' => __( 'Current URI', 'permalink-manager'))) : $columns;
  658.     }
  659.  
  660.     function quick_edit_column_content($column_name, $post_id) {
  661.         global $permalink_manager_uris, $permalink_manager_options;
  662.  
  663.         if($column_name == "permalink-manager-col") {
  664.             // Get auto-update settings
  665.             $auto_update_val = get_post_meta($post_id, "auto_update_uri", true);
  666.             $auto_update_uri = (!empty($auto_update_val)) ? $auto_update_val : $permalink_manager_options["general"]["auto_update_uris"];
  667.  
  668.             $uri = (!empty($permalink_manager_uris[$post_id])) ? rawurldecode($permalink_manager_uris[$post_id]) : self::get_post_uri($post_id, true);
  669.             printf('<span class="permalink-manager-col-uri" data-auto_update="%s">%s</span>', intval($auto_update_uri), $uri);
  670.         }
  671.     }
  672.  
  673.     function quick_edit_column_form($column_name, $post_type, $taxonomy = '') {
  674.         if(!$taxonomy && $column_name == 'permalink-manager-col') {
  675.             echo Permalink_Manager_Admin_Functions::quick_edit_column_form();
  676.         }
  677.     }
  678.  
  679.     /**
  680.      * Update URI when new post is added
  681.      */
  682.     function new_post_uri($post_id) {
  683.         global $post, $permalink_manager_uris, $permalink_manager_options, $permalink_manager_before_sections_html;
  684.  
  685.         // Do not trigger if post is a revision or imported via WP All Import (URI should be set after the post meta is added)
  686.         if(wp_is_post_revision($post_id) || (!empty($_REQUEST['page']) && $_REQUEST['page'] == 'pmxi-admin-import')) { return $post_id; }
  687.  
  688.         // Prevent language mismatch in MultilingualPress plugin
  689.         if(is_admin() && !empty($post->ID) && $post->ID != $post_id) { return $post_id; }
  690.  
  691.         // Stop when products are imported with WooCommerce importer
  692.         if(!empty($_REQUEST['action']) && $_REQUEST['action'] == 'woocommerce_do_ajax_product_import') { return $post_id; }
  693.  
  694.         // Do not do anything if post is autosaved
  695.         if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return $post_id; }
  696.  
  697.         // Do not do anything on in "Bulk Edit"
  698.         if(!empty($_REQUEST['bulk_edit'])) { return $post_id; }
  699.  
  700.         // Hotfix
  701.         if(isset($_POST['custom_uri']) || isset($_POST['permalink-manager-quick-edit']) || isset($permalink_manager_uris[$post_id])) { return $post_id; }
  702.  
  703.         $post_object = get_post($post_id);
  704.  
  705.         // Check if post type is allowed
  706.         if(Permalink_Manager_Helper_Functions::is_disabled($post_object->post_type, 'post_type') || empty($post_object->post_type)) { return $post_id; };
  707.  
  708.         // Stop the hook (if needed)
  709.         $allow_update_post_type = apply_filters("permalink_manager_new_post_uri_{$post_object->post_type}", true);
  710.         if(!$allow_update_post_type) { return $post_id; }
  711.  
  712.         // Ignore menu items
  713.         if($post_object->post_type == 'nav_menu_item') { return $post_id; }
  714.  
  715.         // Ignore auto-drafts & removed posts
  716.         if(in_array($post_object->post_status, array('auto-draft', 'trash'))) { return; }
  717.  
  718.         $native_uri = self::get_default_post_uri($post_id, true);
  719.         $new_uri = self::get_default_post_uri($post_id);
  720.         $permalink_manager_uris[$post_object->ID] = $new_uri;
  721.  
  722.         update_option('permalink-manager-uris', $permalink_manager_uris);
  723.  
  724.         do_action('permalink-manager-new-post-uri', $post_id, $new_uri, $native_uri);
  725.     }
  726.  
  727.     /**
  728.      * Update URI from "Edit Post" admin page
  729.      */
  730.     static public function update_post_uri($post_id) {
  731.         global $permalink_manager_uris, $permalink_manager_options, $permalink_manager_before_sections_html;
  732.  
  733.         // Verify nonce at first
  734.         if(!isset($_POST['permalink-manager-nonce']) || !wp_verify_nonce($_POST['permalink-manager-nonce'], 'permalink-manager-edit-uri-box')) { return $post_id; }
  735.  
  736.         // Do not do anything if post is autosaved
  737.         if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return $post_id; }
  738.  
  739.         // Do not do anything on in "Bulk Edit" or when the post is imported via WP All Import
  740.         if(!empty($_REQUEST['bulk_edit']) || (!empty($_REQUEST['page']) && $_REQUEST['page'] == 'pmxi-admin-import')) { return $post_id; }
  741.  
  742.         // Do not do anything if the field with URI or element ID are not present
  743.         if(!isset($_POST['custom_uri']) || empty($_POST['permalink-manager-edit-uri-element-id'])) { return $post_id; }
  744.  
  745.         // Hotfix
  746.         if($_POST['permalink-manager-edit-uri-element-id'] != $post_id) { return $post_id; }
  747.  
  748.         // Fix for revisions
  749.         $is_revision = wp_is_post_revision($post_id);
  750.         $post_id = ($is_revision) ? $is_revision : $post_id;
  751.         $post = get_post($post_id);
  752.  
  753.         // Check if post type is allowed
  754.         if(Permalink_Manager_Helper_Functions::is_disabled($post->post_type, 'post_type') || empty($post->post_type)) { return $post_id; };
  755.  
  756.         // Stop the hook (if needed)
  757.         $allow_update_post_type = apply_filters("permalink_manager_update_post_uri_{$post->post_type}", true);
  758.         if(!$allow_update_post_type) { return $post_id; }
  759.  
  760.         // Hotfix for menu items
  761.         if($post->post_type == 'nav_menu_item') { return $post_id; }
  762.  
  763.         // Ignore auto-drafts & removed posts
  764.         if(in_array($post->post_status, array('auto-draft', 'trash'))) { return $post_id; }
  765.  
  766.         // Get auto-update URI setting (if empty use global setting)
  767.         if(!empty($_POST["auto_update_uri"])) {
  768.             $auto_update_uri_current = intval($_POST["auto_update_uri"]);
  769.         } else if(!empty($_POST["action"]) && $_POST['action'] == 'inline-save') {
  770.             $auto_update_uri_current = get_post_meta($post_id, "auto_update_uri", true);
  771.         }
  772.         $auto_update_uri = (!empty($auto_update_uri_current)) ? $auto_update_uri_current : $permalink_manager_options["general"]["auto_update_uris"];
  773.  
  774.         $default_uri = self::get_default_post_uri($post_id);
  775.         $native_uri = self::get_default_post_uri($post_id, true);
  776.         $old_uri = (isset($permalink_manager_uris[$post->ID])) ? $permalink_manager_uris[$post->ID] : $native_uri;
  777.  
  778.         // Use default URI if URI is cleared by user OR URI should be automatically updated
  779.         $new_uri = (($_POST['custom_uri'] == '') || $auto_update_uri == 1) ? $default_uri : Permalink_Manager_Helper_Functions::sanitize_title($_POST['custom_uri'], true);
  780.  
  781.         // Save or remove "Auto-update URI" settings
  782.         if(!empty($auto_update_uri_current)) {
  783.             update_post_meta($post_id, "auto_update_uri", $auto_update_uri_current);
  784.         } elseif(isset($_POST['auto_update_uri'])) {
  785.             delete_post_meta($post_id, "auto_update_uri");
  786.         }
  787.  
  788.         // Save only changed URIs
  789.         $permalink_manager_uris[$post_id] = $new_uri;
  790.         update_option('permalink-manager-uris', $permalink_manager_uris);
  791.  
  792.         // Update the slug (if changed)
  793.         if(isset($_POST['permalink-manager-edit-uri-element-slug']) && isset($_POST['native_slug']) && ($_POST['native_slug'] !== $_POST['permalink-manager-edit-uri-element-slug'])) {
  794.             self::update_slug_by_id($_POST['native_slug'], $post_id);
  795.         }
  796.  
  797.         do_action('permalink-manager-updated-post-uri', $post_id, $new_uri, $old_uri, $native_uri, $default_uri, $single_update = true);
  798.     }
  799.  
  800.     /**
  801.     * Remove URI from options array after post is moved to the trash
  802.     */
  803.     function remove_post_uri($post_id) {
  804.         global $permalink_manager_uris;
  805.  
  806.         // Check if the custom permalink is assigned to this post
  807.         if(isset($permalink_manager_uris[$post_id])) {
  808.             unset($permalink_manager_uris[$post_id]);
  809.         }
  810.  
  811.         update_option('permalink-manager-uris', $permalink_manager_uris);
  812.     }
  813.  
  814. }
  815.  
  816. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement