permalink-manager-admin-functions.php
9 years ago
permalink-manager-helper-functions.php
9 years ago
permalink-manager-post-uri-functions.php
9 years ago
permalink-manager-uri-actions.php
9 years ago
permalink-manager-post-uri-functions.php
446 lines
| 1 | <?php |
| 2 | |
| 3 | /** |
| 4 | * Additional functions used in classes and another subclasses |
| 5 | */ |
| 6 | class Permalink_Manager_Post_URI_Functions extends Permalink_Manager_Class { |
| 7 | |
| 8 | public function __construct() { |
| 9 | add_filter( '_get_page_link', array($this, 'custom_post_permalinks'), 999, 2); |
| 10 | add_filter( 'page_link', array($this, 'custom_post_permalinks'), 999, 2); |
| 11 | add_filter( 'post_link', array($this, 'custom_post_permalinks'), 999, 2); |
| 12 | add_filter( 'post_type_link', array($this, 'custom_post_permalinks'), 999, 2); |
| 13 | add_filter( 'permalink-manager-uris', array($this, 'exclude_homepage'), 999, 2); |
| 14 | add_action( 'save_post', array($this, 'update_post_uri'), 10, 3 ); |
| 15 | add_action( 'wp_trash_post', array($this, 'remove_post_uri'), 10, 3 ); |
| 16 | } |
| 17 | |
| 18 | /** |
| 19 | * Change permalinks for posts, pages & custom post types |
| 20 | */ |
| 21 | function custom_post_permalinks($permalink, $post) { |
| 22 | global $wp_rewrite, $permalink_manager_uris; |
| 23 | |
| 24 | $post = (is_integer($post)) ? get_post($post) : $post; |
| 25 | $post_type = $post->post_type; |
| 26 | |
| 27 | // Do not change permalink of frontpage |
| 28 | if(get_option('page_on_front') == $post->ID) { return $permalink; } |
| 29 | if(isset($permalink_manager_uris[$post->ID])) $permalink = home_url('/') . $permalink_manager_uris[$post->ID]; |
| 30 | |
| 31 | return $permalink; |
| 32 | } |
| 33 | |
| 34 | /** |
| 35 | * Display the permalink in a better way |
| 36 | */ |
| 37 | static function get_correct_permalink($id) { |
| 38 | global $permalink_manager_uris; |
| 39 | $permalink = isset($permalink_manager_uris[$id]) ? home_url('/') . $permalink_manager_uris[$id] : get_permalink($id); |
| 40 | |
| 41 | return $permalink; |
| 42 | } |
| 43 | |
| 44 | /** |
| 45 | * Check if the provided slug is unique and then update it with SQL query. |
| 46 | */ |
| 47 | static function update_slug_by_id($slug, $id) { |
| 48 | global $wpdb; |
| 49 | |
| 50 | // Update slug and make it unique |
| 51 | $slug = (empty($slug)) ? sanitize_title(get_the_title($id)) : $slug; |
| 52 | $new_slug = wp_unique_post_slug($slug, $id, get_post_status($id), get_post_type($id), null); |
| 53 | $wpdb->query("UPDATE $wpdb->posts SET post_name = '$new_slug' WHERE ID = '$id'"); |
| 54 | |
| 55 | return $new_slug; |
| 56 | } |
| 57 | |
| 58 | /** |
| 59 | * Get the active URI |
| 60 | */ |
| 61 | static function get_post_uri($post_id) { |
| 62 | global $permalink_manager_uris; |
| 63 | |
| 64 | // Check if input is post object |
| 65 | $post_id = (isset($post_id->ID)) ? $post_id->ID : $post_id; |
| 66 | |
| 67 | $final_uri = isset($permalink_manager_uris[$post_id]) ? $permalink_manager_uris[$post_id] : self::get_default_post_uri($post_id); |
| 68 | return $final_uri; |
| 69 | } |
| 70 | |
| 71 | /** |
| 72 | * Get the default (not overwritten by the user) or native URI (unfiltered) |
| 73 | */ |
| 74 | static function get_default_post_uri($post, $native_uri = false) { |
| 75 | global $permalink_manager_options, $permalink_manager_uris, $permalink_manager_permastructs; |
| 76 | |
| 77 | // Load all bases & post |
| 78 | $post = is_object($post) ? $post : get_post($post); |
| 79 | $post_id = $post->ID; |
| 80 | $post_type = $post->post_type; |
| 81 | $post_name = $post->post_name; |
| 82 | |
| 83 | // Get the permastruct |
| 84 | $default_permastruct = Permalink_Manager_Helper_Functions::get_default_permastruct($post_type); |
| 85 | |
| 86 | if($native_uri) { |
| 87 | $permastruct = $default_permastruct; |
| 88 | } else if($permalink_manager_permastructs) { |
| 89 | $permastruct = isset($permalink_manager_permastructs[$post_type]) ? $permalink_manager_permastructs[$post_type] : $default_permastruct; |
| 90 | } else { |
| 91 | $permastruct = isset($permalink_manager_options['base-editor'][$post_type]) ? $permalink_manager_options['base-editor'][$post_type] : $default_permastruct; |
| 92 | } |
| 93 | $default_base = (!empty($permastruct)) ? trim($permastruct, '/') : ""; |
| 94 | |
| 95 | // 1A. Get the date |
| 96 | $date = explode(" ",date('Y m d H i s', strtotime($post->post_date))); |
| 97 | |
| 98 | // 1B. Get the category slug (if needed) |
| 99 | $category = ''; |
| 100 | if ( strpos($default_base, '%category%') !== false ) { |
| 101 | |
| 102 | // I. Try to use Yoast SEO Primary Term |
| 103 | $category = (Permalink_Manager_Helper_Functions::get_primary_term($post->ID, 'category')); |
| 104 | |
| 105 | // II. Get the first assigned category |
| 106 | if(empty($category)) { |
| 107 | $cats = get_the_category($post->ID); |
| 108 | if ($cats) { |
| 109 | usort($cats, '_usort_terms_by_ID'); // order by ID |
| 110 | $category_object = apply_filters( 'post_link_category', $cats[0], $cats, $post ); |
| 111 | $category_object = get_term( $category_object, 'category' ); |
| 112 | $category = $category_object->slug; |
| 113 | if ( $parent = $category_object->parent ) |
| 114 | $category = get_category_parents($parent, false, '/', true) . $category; |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | // III. Show default category in permalinks, without having to assign it explicitly |
| 119 | if(empty($category)) { |
| 120 | $default_category = get_term( get_option( 'default_category' ), 'category' ); |
| 121 | $category = is_wp_error( $default_category ) ? '' : $default_category->slug; |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | // 1C. Get the author (if needed) |
| 126 | $author = ''; |
| 127 | if ( strpos($default_base, '%author%') !== false ) { |
| 128 | $authordata = get_userdata($post->post_author); |
| 129 | $author = $authordata->user_nicename; |
| 130 | } |
| 131 | |
| 132 | // 2. Fix for hierarchical CPT (start) |
| 133 | $full_slug = get_page_uri($post); |
| 134 | $post_type_tag = Permalink_Manager_Helper_Functions::get_post_tag($post_type); |
| 135 | |
| 136 | // 3A. Do the replacement (post tag is removed now to enable support for hierarchical CPT) |
| 137 | $tags = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', '%post_id%', '%category%', '%author%', $post_type_tag); |
| 138 | $replacements = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->ID, $category, $author, ''); |
| 139 | $default_uri = str_replace($tags, $replacements, "{$default_base}/{$full_slug}"); |
| 140 | |
| 141 | // 3B. Replace custom taxonomies |
| 142 | $terms = get_taxonomies( array('public' => true, '_builtin' => false), 'names', 'and' ); |
| 143 | $taxonomies = $terms; |
| 144 | if ( $taxonomies ) { |
| 145 | foreach($taxonomies as $taxonomy) { |
| 146 | // A. Try to use Yoast SEO Primary Term |
| 147 | $category = (Permalink_Manager_Helper_Functions::get_primary_term($post->ID, $taxonomy)); |
| 148 | |
| 149 | // B. Get the first assigned term to this taxonomy |
| 150 | if(empty($replacement)) { |
| 151 | $terms = wp_get_object_terms($post->ID, $taxonomy); |
| 152 | $replacement = (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) ? $terms[0]->slug : ""; |
| 153 | } |
| 154 | |
| 155 | // Do the replacement |
| 156 | $default_uri = ($replacement) ? str_replace("%{$taxonomy}%", $replacement, $default_uri) : $default_uri; |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | $default_uri = preg_replace('/\s+/', '', $default_uri); |
| 161 | $default_uri = str_replace('//', '/', $default_uri); |
| 162 | $default_uri = trim($default_uri, "/"); |
| 163 | |
| 164 | return $default_uri; |
| 165 | } |
| 166 | |
| 167 | /** |
| 168 | * The homepage should not use URI |
| 169 | */ |
| 170 | function exclude_homepage($uris) { |
| 171 | // Find the homepage URI |
| 172 | $homepage_id = get_option('page_on_front'); |
| 173 | if(isset($uris[$homepage_id])) { unset($uris[$homepage_id]); } |
| 174 | |
| 175 | return $uris; |
| 176 | } |
| 177 | |
| 178 | /** |
| 179 | * Find & replace (bulk action) |
| 180 | */ |
| 181 | static function posts_find_and_replace() { |
| 182 | global $wpdb, $permalink_manager_uris; |
| 183 | |
| 184 | // Reset variables |
| 185 | $updated_slugs_count = 0; |
| 186 | $updated_array = array(); |
| 187 | $alert_type = $alert_content = $errors = ''; |
| 188 | |
| 189 | // Prepare default variables from $_POST object |
| 190 | $old_string = esc_sql($_POST['old_string']); |
| 191 | $new_string = esc_sql($_POST['new_string']); |
| 192 | $mode = isset($_POST['mode']) ? $_POST['mode'] : array('both'); |
| 193 | $post_types_array = ($_POST['post_types']); |
| 194 | $post_statuses_array = ($_POST['post_statuses']); |
| 195 | $post_types = implode("', '", $post_types_array); |
| 196 | $post_statuses = implode("', '", $post_statuses_array); |
| 197 | |
| 198 | // Save the rows before they are updated to an array |
| 199 | $posts_to_update = $wpdb->get_results("SELECT post_title, post_name, ID FROM {$wpdb->posts} WHERE post_status IN ('{$post_statuses}') AND post_type IN ('{$post_types}')", ARRAY_A); |
| 200 | |
| 201 | // Now if the array is not empty use IDs from each subarray as a key |
| 202 | if($posts_to_update && empty($errors)) { |
| 203 | foreach ($posts_to_update as $row) { |
| 204 | |
| 205 | // Prepare variables |
| 206 | $old_post_name = $row['post_name']; |
| 207 | $native_uri = self::get_default_post_uri($row['ID'], true); |
| 208 | $default_uri = self::get_default_post_uri($row['ID']); |
| 209 | $old_uri = (isset($permalink_manager_uris[$row['ID']])) ? $permalink_manager_uris[$row['ID']] : $default_uri; |
| 210 | $old_slug = (strpos($old_uri, '/') !== false) ? substr($old_uri, strrpos($old_uri, '/') + 1) : $old_uri; |
| 211 | $old_base = (strpos($old_uri, '/') !== false) ? substr($old_uri, 0, strrpos( $old_uri, '/') ) : ''; |
| 212 | |
| 213 | // Process URI & slug |
| 214 | $new_slug = str_replace($old_string, $new_string, $old_slug); |
| 215 | $new_base = str_replace($old_string, $new_string, $old_base); |
| 216 | $new_uri = (in_array($mode, array('both'))) ? trim("{$new_base}/{$new_slug}", "/") : trim("{$old_base}/{$new_slug}", "/"); |
| 217 | $new_post_name = (in_array($mode, array('post_names'))) ? str_replace($old_string, $new_string, $old_post_name) : $old_post_name; // Post name is changed only in first mode |
| 218 | |
| 219 | //print_r("{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri} \n"); |
| 220 | |
| 221 | // Check if native slug should be changed |
| 222 | if(in_array($mode, array('post_names')) && ($old_post_name != $new_post_name)) { |
| 223 | self::update_slug_by_id($new_post_name, $row['ID']); |
| 224 | } |
| 225 | |
| 226 | if(($old_uri != $new_uri) || ($old_post_name != $new_post_name)) { |
| 227 | $permalink_manager_uris[$row['ID']] = $new_uri; |
| 228 | $updated_array[] = array('post_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); |
| 229 | $updated_slugs_count++; |
| 230 | } |
| 231 | |
| 232 | // Do not store default values |
| 233 | if(isset($permalink_manager_uris[$row['ID']]) && ($new_uri == $native_uri)) { |
| 234 | unset($permalink_manager_uris[$row['ID']]); |
| 235 | } |
| 236 | } |
| 237 | |
| 238 | // Filter array before saving |
| 239 | $permalink_manager_uris = array_filter($permalink_manager_uris); |
| 240 | update_option('permalink-manager-uris', $permalink_manager_uris); |
| 241 | |
| 242 | $output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count); |
| 243 | wp_reset_postdata(); |
| 244 | } |
| 245 | |
| 246 | return ($output) ? $output : ""; |
| 247 | } |
| 248 | |
| 249 | /** |
| 250 | * Regenerate slugs & bases (bulk action) |
| 251 | */ |
| 252 | static function posts_regenerate_all_permalinks() { |
| 253 | global $wpdb, $permalink_manager_uris, $permalink_manager_permastructs; |
| 254 | |
| 255 | // Setup needed variables |
| 256 | $updated_slugs_count = 0; |
| 257 | $updated_array = array(); |
| 258 | $alert_type = $alert_content = $errors = ''; |
| 259 | |
| 260 | $post_types_array = ($_POST['post_types']) ? ($_POST['post_types']) : ''; |
| 261 | $post_statuses_array = ($_POST['post_statuses']) ? $_POST['post_statuses'] : ''; |
| 262 | $post_types = implode("', '", $post_types_array); |
| 263 | $post_statuses = implode("', '", $post_statuses_array); |
| 264 | $mode = isset($_POST['mode']) ? $_POST['mode'] : 'both'; |
| 265 | |
| 266 | // Save the rows before they are updated to an array |
| 267 | $posts_to_update = $wpdb->get_results("SELECT post_title, post_name, post_type, ID FROM {$wpdb->posts} WHERE post_status IN ('{$post_statuses}') AND post_type IN ('{$post_types}')", ARRAY_A); |
| 268 | |
| 269 | // Now if the array is not empty use IDs from each subarray as a key |
| 270 | if($posts_to_update && empty($errors)) { |
| 271 | foreach ($posts_to_update as $row) { |
| 272 | $updated = 0; |
| 273 | |
| 274 | // Prepare variables |
| 275 | $old_post_name = $row['post_name']; |
| 276 | $native_uri = self::get_default_post_uri($row['ID'], true); |
| 277 | $default_uri = self::get_default_post_uri($row['ID']); |
| 278 | $old_uri = isset($permalink_manager_uris[$row['ID']]) ? trim($permalink_manager_uris[$row['ID']], "/") : $native_uri; |
| 279 | $old_slug = (strpos($old_uri, '/') !== false) ? substr($old_uri, strrpos($old_uri, '/') + 1) : $old_uri; |
| 280 | $correct_slug = sanitize_title($row['post_title']); |
| 281 | |
| 282 | // Process URI & slug |
| 283 | $new_slug = wp_unique_post_slug($correct_slug, $row['ID'], get_post_status($row['ID']), get_post_type($row['ID']), null); |
| 284 | $new_post_name = (in_array($mode, array('post_names'))) ? $new_slug : $old_post_name; // Post name is changed only in first mode |
| 285 | $new_uri = (in_array($mode, array('both'))) ? $default_uri : str_replace($old_slug, $new_slug, $old_uri); |
| 286 | |
| 287 | //print_r("{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri} \n"); |
| 288 | |
| 289 | // Check if native slug should be changed |
| 290 | if(in_array($mode, array('post_names')) && ($old_post_name != $new_post_name)) { |
| 291 | self::update_slug_by_id($new_post_name, $row['ID']); |
| 292 | } |
| 293 | |
| 294 | if(($old_uri != $new_uri) || ($old_post_name != $new_post_name)) { |
| 295 | $permalink_manager_uris[$row['ID']] = $new_uri; |
| 296 | $updated_array[] = array('post_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); |
| 297 | $updated_slugs_count++; |
| 298 | } |
| 299 | |
| 300 | // Do not store default values |
| 301 | if(isset($permalink_manager_uris[$row['ID']]) && ($new_uri == $native_uri)) { |
| 302 | unset($permalink_manager_uris[$row['ID']]); |
| 303 | } |
| 304 | } |
| 305 | |
| 306 | // Filter array before saving |
| 307 | $permalink_manager_uris = array_filter($permalink_manager_uris); |
| 308 | update_option('permalink-manager-uris', $permalink_manager_uris); |
| 309 | |
| 310 | $output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count); |
| 311 | wp_reset_postdata(); |
| 312 | } |
| 313 | |
| 314 | return (!empty($output)) ? $output : ""; |
| 315 | } |
| 316 | |
| 317 | /** |
| 318 | * Update all slugs & bases (bulk action) |
| 319 | */ |
| 320 | static public function posts_update_all_permalinks() { |
| 321 | global $permalink_manager_uris; |
| 322 | |
| 323 | // Setup needed variables |
| 324 | $updated_slugs_count = 0; |
| 325 | $updated_array = array(); |
| 326 | |
| 327 | $old_uris = $permalink_manager_uris; |
| 328 | $new_uris = isset($_POST['uri']) ? $_POST['uri'] : array(); |
| 329 | |
| 330 | // Double check if the slugs and ids are stored in arrays |
| 331 | if (!is_array($new_uris)) $new_uris = explode(',', $new_uris); |
| 332 | |
| 333 | if (!empty($new_uris)) { |
| 334 | foreach($new_uris as $id => $new_uri) { |
| 335 | // Prepare variables |
| 336 | $this_post = get_post($id); |
| 337 | $updated = ''; |
| 338 | |
| 339 | // Get default & native URL |
| 340 | $native_uri = self::get_default_post_uri($id, true); |
| 341 | $default_uri = self::get_default_post_uri($id); |
| 342 | |
| 343 | $old_uri = isset($old_uris[$id]) ? trim($old_uris[$id], "/") : $native_uri; |
| 344 | |
| 345 | // Process new values - empty entries will be treated as default values |
| 346 | $new_uri = preg_replace('/\s+/', '', $new_uri); |
| 347 | $new_uri = (!empty($new_uri)) ? trim($new_uri, "/") : $default_uri; |
| 348 | $new_slug = (strpos($new_uri, '/') !== false) ? substr($new_uri, strrpos($new_uri, '/') + 1) : $new_uri; |
| 349 | |
| 350 | //print_r("{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri} \n"); |
| 351 | |
| 352 | // Do not store native URIs |
| 353 | if($new_uri == $native_uri) { |
| 354 | unset($old_uris[$id]); |
| 355 | } |
| 356 | |
| 357 | if($new_uri != $old_uri) { |
| 358 | $old_uris[$id] = $new_uri; |
| 359 | $updated_array[] = array('post_title' => get_the_title($id), 'ID' => $id, 'old_uri' => $old_uri, 'new_uri' => $new_uri); |
| 360 | $updated_slugs_count++; |
| 361 | } |
| 362 | |
| 363 | } |
| 364 | |
| 365 | // Filter array before saving & append the global |
| 366 | $old_uris = $permalink_manager_uris = array_filter($old_uris); |
| 367 | update_option('permalink-manager-uris', $old_uris); |
| 368 | |
| 369 | $output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count); |
| 370 | } |
| 371 | |
| 372 | return ($output) ? $output : ""; |
| 373 | } |
| 374 | |
| 375 | /** |
| 376 | * Update URI from "Edit Post" admin page |
| 377 | */ |
| 378 | function update_post_uri($post_id, $post, $update) { |
| 379 | global $permalink_manager_uris; |
| 380 | |
| 381 | // Ignore trashed items |
| 382 | if($post->post_status == 'trash') return; |
| 383 | |
| 384 | // Fix for revisions |
| 385 | $is_revision = wp_is_post_revision($post_id); |
| 386 | $post_id = ($is_revision) ? $is_revision : $post_id; |
| 387 | $post = get_post($post_id); |
| 388 | |
| 389 | $native_uri = self::get_default_post_uri($post, true); |
| 390 | $old_uri = (isset($permalink_manager_uris[$post->ID])) ? $permalink_manager_uris[$post->ID] : $native_uri; |
| 391 | $new_uri = ''; |
| 392 | |
| 393 | // Check if user changed URI (available after post is saved) |
| 394 | if(isset($_POST['custom_uri'])) { |
| 395 | $new_uri = trim($_POST['custom_uri'], "/"); |
| 396 | } |
| 397 | |
| 398 | // A little hack (if user removes whole URI from input) ... |
| 399 | $new_uri = ($new_uri) ? $new_uri : self::get_post_uri($post); |
| 400 | |
| 401 | // Do not store default values |
| 402 | if(isset($permalink_manager_uris[$post->ID]) && ($new_uri == $native_uri)) { |
| 403 | unset($permalink_manager_uris[$post->ID]); |
| 404 | } |
| 405 | // Save only changed URIs |
| 406 | else if (($new_uri != $native_uri) && ($new_uri != $old_uri)) { |
| 407 | $permalink_manager_uris[$post->ID] = $new_uri; |
| 408 | } |
| 409 | |
| 410 | update_option('permalink-manager-uris', $permalink_manager_uris); |
| 411 | } |
| 412 | |
| 413 | /** |
| 414 | * Remove URI from options array after post is moved to the trash |
| 415 | */ |
| 416 | function remove_post_uri($post_id) { |
| 417 | global $permalink_manager_uris; |
| 418 | |
| 419 | // Check if the custom permalink is assigned to this post |
| 420 | if(isset($permalink_manager_uris[$post_id])) { |
| 421 | unset($permalink_manager_uris[$post_id]); |
| 422 | } |
| 423 | |
| 424 | update_option('permalink-manager-uris', $permalink_manager_uris); |
| 425 | } |
| 426 | |
| 427 | /** |
| 428 | * Remove URI from options array after post is moved to the trash |
| 429 | */ |
| 430 | function clear_uris($post_id) { |
| 431 | $uris = $this->permalink_manager_uris; |
| 432 | |
| 433 | foreach($uris as $post_id => $uri) { |
| 434 | $post_status = get_post_status($post_id); |
| 435 | if(in_array($post_status, array('auto-draft', 'trash', ''))) { |
| 436 | unset($uris[$post_id]); |
| 437 | } |
| 438 | } |
| 439 | |
| 440 | update_option('permalink-manager-uris', $uris); |
| 441 | } |
| 442 | |
| 443 | } |
| 444 | |
| 445 | ?> |
| 446 |