PluginProbe ʕ •ᴥ•ʔ
Permalink Manager Lite / 2.5.1.2
Permalink Manager Lite v2.5.1.2
2.5.4 2.5.3.4 2.2.18 2.2.19.2 2.2.19.3 2.2.19.3.1 2.2.2 2.2.20 2.2.20.1 2.2.20.3 2.2.4 2.2.5 2.2.6 2.2.7.2 2.2.7.3 2.2.7.5 2.2.7.6 2.2.8.4 2.2.8.5 2.2.8.6 2.2.8.7 2.2.8.9 2.2.9.1 2.2.9.2 2.2.9.2.1 2.2.9.3 2.2.9.4 2.2.9.6 2.2.9.7 2.2.9.9 2.3.0 2.3.1.1 2.4.0 2.4.1 2.4.1.2 2.4.1.3 2.4.1.4 2.4.1.5 2.4.1.6 2.4.2 2.4.2.1 2.4.3 2.4.3.1 2.4.3.2 2.4.3.3 2.4.3.4 2.4.4 2.4.4.1 2.4.4.2 2.4.4.3 2.5.0 2.5.1 2.5.1.1 2.5.1.2 2.5.1.3 2.5.1.4 2.5.2 2.5.2.1 2.5.2.2 2.5.2.3 2.5.2.4 2.5.3 2.5.3.1 2.5.3.2 2.5.3.3 trunk 0.2 0.3 0.3.1 0.3.2 0.3.3 0.3.4 0.4 0.4.1 0.4.2 0.4.3 0.4.4 0.4.6 0.4.7 0.4.8 0.4.9 0.5.3 0.5.4 1.0.0 1.0.1 1.0.4 1.1.0 1.1.1 1.1.2 1.11.6.3 2.0.0 2.0.3 2.0.4 2.0.4.3 2.0.5.1 2.0.5.2 2.0.5.3 2.0.5.3.1 2.0.5.4 2.0.5.4a 2.0.5.5 2.0.5.6 2.0.5.6.1 2.0.5.7 2.0.5.9a 2.0.6.2.1 2.0.6.2a 2.0.6.3 2.1.0 2.1.1 2.1.2.4 2.2.0 2.2.1.1 2.2.1.2 2.2.11 2.2.12 2.2.13.1 2.2.14 2.2.15.1 2.2.16 2.2.17
permalink-manager / includes / core / permalink-manager-actions.php
permalink-manager / includes / core Last commit date
permalink-manager-actions.php 1 year ago permalink-manager-admin-functions.php 1 year ago permalink-manager-core-functions.php 1 year ago permalink-manager-debug.php 1 year ago permalink-manager-gutenberg.php 1 year ago permalink-manager-helper-functions.php 1 year ago permalink-manager-permastructures-functions.php 1 year ago permalink-manager-uri-functions-post.php 1 year ago permalink-manager-uri-functions.php 1 year ago
permalink-manager-actions.php
757 lines
1 <?php
2
3 /**
4 * Additional hooks for "Permalink Manager Pro"
5 */
6 class Permalink_Manager_Actions {
7
8 public function __construct() {
9 add_action( 'admin_init', array( $this, 'trigger_action' ), 9 );
10 add_action( 'admin_init', array( $this, 'extra_actions' ) );
11
12 // Ajax-based functions
13 if ( is_admin() ) {
14 add_action( 'wp_ajax_pm_bulk_tools', array( $this, 'ajax_bulk_tools' ) );
15 add_action( 'wp_ajax_pm_save_permalink', array( $this, 'ajax_save_permalink' ) );
16 add_action( 'wp_ajax_pm_detect_duplicates', array( $this, 'ajax_detect_duplicates' ) );
17 add_action( 'wp_ajax_pm_dismissed_notice_handler', array( $this, 'ajax_hide_global_notice' ) );
18 }
19 }
20
21 /**
22 * Route the requests to functions that save datasets with associated callbacks
23 */
24 public function trigger_action() {
25 global $permalink_manager_after_sections_html;
26
27 // 1. Check if the form was submitted
28 if ( empty( $_POST ) ) {
29 return;
30 }
31
32 // 2. Do nothing if search query is not empty
33 if ( isset( $_REQUEST['search-submit'] ) || isset( $_REQUEST['filter-button'] ) ) {
34 if ( wp_verify_nonce( $_POST[ 'uri_editor' ], 'permalink-manager' ) ) {
35 $this->trigger_filter_action();
36 }
37
38 return;
39 }
40
41 $actions_map = array(
42 'uri_editor' => array( 'function' => 'update_all_permalinks', 'display_uri_table' => true ),
43 'permalink_manager_options' => array( 'function' => 'save_settings' ),
44 'permalink_manager_permastructs' => array( 'function' => 'save_permastructures' ),
45 'import' => array( 'function' => 'import_custom_permalinks_uris' ),
46 );
47
48 // 3. Find the action
49 foreach ( $actions_map as $action => $map ) {
50 if ( isset( $_POST[ $action ] ) && wp_verify_nonce( $_POST[ $action ], 'permalink-manager' ) ) {
51 // Execute the function
52 $output = call_user_func( array( $this, $map['function'] ) );
53
54 // Get list of updated URIs
55 if ( ! empty( $map['display_uri_table'] ) ) {
56 $updated_slugs_count = ( isset( $output['updated_count'] ) && $output['updated_count'] > 0 ) ? $output['updated_count'] : false;
57 $updated_slugs_array = ( $updated_slugs_count ) ? $output['updated'] : '';
58 }
59
60 // Trigger only one function
61 break;
62 }
63 }
64
65 // 4. Display the slugs table (and append the globals)
66 if ( isset( $updated_slugs_count ) && isset( $updated_slugs_array ) ) {
67 $permalink_manager_after_sections_html .= Permalink_Manager_UI_Elements::display_updated_slugs( $updated_slugs_array );
68 }
69 }
70
71 /**
72 * Adjust the Bulk URI Editor filter URL
73 *
74 * @return void
75 */
76 public function trigger_filter_action() {
77 $query_args = array(
78 'langcode' => ! empty( $_REQUEST['langcode'] ) ? $_REQUEST['langcode'] : null,
79 'month' => ! empty( $_REQUEST['month'] ) ? $_REQUEST['month'] : null,
80 's' => ! empty( $_REQUEST['s'] ) ? $_REQUEST['s'] : null,
81 );
82
83 if ( ! empty( $query_args ) ) {
84 $sendback = remove_query_arg( array_keys( $query_args ), wp_get_referer() );
85 $sendback = add_query_arg( array_filter( $query_args ), $sendback );
86
87 wp_redirect( $sendback );
88 exit;
89 }
90 }
91
92 /**
93 * Route the requests to the additional tools-related functions with the relevant callbacks
94 */
95 public static function extra_actions() {
96 global $permalink_manager_before_sections_html;
97
98 if ( current_user_can( 'manage_options' ) && ! empty( $_GET['permalink-manager-nonce'] ) ) {
99 // Check if the nonce field is correct
100 $nonce = sanitize_key( $_GET['permalink-manager-nonce'] );
101
102 if ( ! wp_verify_nonce( $nonce, 'permalink-manager' ) ) {
103 $permalink_manager_before_sections_html = Permalink_Manager_UI_Elements::get_alert_message( __( 'You are not allowed to remove Permalink Manager data!', 'permalink-manager' ), 'error updated_slugs' );
104
105 return;
106 }
107
108 if ( isset( $_GET['clear-permalink-manager-uris'] ) ) {
109 self::clear_all_uris();
110 } else if ( isset( $_GET['remove-permalink-manager-settings'] ) ) {
111 $option_name = sanitize_text_field( $_GET['remove-permalink-manager-settings'] );
112 self::remove_plugin_data( $option_name );
113 } else if ( ! empty( $_REQUEST['remove-uri'] ) ) {
114 $uri_key = sanitize_text_field( $_REQUEST['remove-uri'] );
115 self::force_clear_single_element_uris_and_redirects( $uri_key );
116 } else if ( ! empty( $_REQUEST['remove-redirect'] ) ) {
117 $redirect_key = sanitize_text_field( $_REQUEST['remove-redirect'] );
118 self::force_clear_single_redirect( $redirect_key );
119 }
120 } else if ( ! empty( $_POST['screen-options-apply'] ) ) {
121 self::save_screen_options();
122 }
123 }
124
125 /**
126 * Bulk remove obsolete custom permalinks and redirects
127 */
128 public static function clear_all_uris() {
129 global $permalink_manager_redirects, $permalink_manager_before_sections_html;
130
131 // Get all custom permalinks & redirects
132 $custom_permalinks = Permalink_Manager_URI_Functions::get_all_uris();
133 $custom_redirects = (array) $permalink_manager_redirects;
134
135 // Check if array with custom URIs exists
136 if ( empty( $custom_permalinks ) ) {
137 return;
138 }
139
140 // Count removed URIs & redirects
141 $removed_uris = 0;
142 $removed_redirects = 0;
143
144 // Get all element IDs
145 $element_ids = array_merge( array_keys( $custom_permalinks ), array_keys( $custom_redirects ) );
146
147 // 1. Remove unused custom URI & redirects for deleted post or term
148 foreach ( $element_ids as $element_id ) {
149 $count = self::clear_single_element_uris_and_redirects( $element_id, true );
150
151 $removed_uris = ( ! empty( $count[0] ) ) ? $count[0] + $removed_uris : $removed_uris;
152 $removed_redirects = ( ! empty( $count[1] ) ) ? $count[1] + $removed_redirects : $removed_redirects;
153 }
154
155 // 2. Keep only a single redirect
156 $removed_redirects += self::clear_redirects_array();
157
158 // 3. Save cleared URIs & Redirects
159 if ( $removed_uris > 0 || $removed_redirects > 0 ) {
160 Permalink_Manager_URI_Functions::save_all_uris();
161 update_option( 'permalink-manager-redirects', array_filter( $permalink_manager_redirects ) );
162
163 // Translators: 1: Number of custom URIs, 2: Number of custom redirects.
164 $permalink_manager_before_sections_html .= Permalink_Manager_UI_Elements::get_alert_message( sprintf( __( '%1$d Custom URIs and %2$d Custom Redirects were removed!', 'permalink-manager' ), $removed_uris, $removed_redirects ), 'updated updated_slugs' );
165 } else {
166 $permalink_manager_before_sections_html .= Permalink_Manager_UI_Elements::get_alert_message( __( 'No Custom URIs or Custom Redirects were removed!', 'permalink-manager' ), 'error updated_slugs' );
167 }
168 }
169
170 /**
171 * Remove obsolete custom permalink & redirects for specific post or term
172 *
173 * @param string|int $element_id
174 * @param bool $count_removed
175 *
176 * @return array
177 */
178 public static function clear_single_element_uris_and_redirects( $element_id, $count_removed = false ) {
179 global $wpdb, $permalink_manager_redirects, $permalink_manager_options;
180
181 // Count removed URIs & redirects
182 $removed_uris = 0;
183 $removed_redirects = 0;
184
185 // Only admin users can remove the broken URIs for removed post types & taxonomies
186 $check_if_admin = is_admin();
187
188 // Check if the advanced mode is turned on
189 $advanced_mode = Permalink_Manager_Helper_Functions::is_advanced_mode_on();
190
191 // If "Disable URI Editor to disallow Permalink changes" is set globally, the pages that follow the global settings should also be removed
192 if ( $advanced_mode && ! empty( $permalink_manager_options["general"]["auto_update_uris"] ) && $permalink_manager_options["general"]["auto_update_uris"] == 2 ) {
193 $strict_mode = true;
194 } else {
195 $strict_mode = false;
196 }
197
198 // 1. Check if element exists
199 if ( strpos( $element_id, 'tax-' ) !== false ) {
200 $term_id = preg_replace( "/[^0-9]/", "", $element_id );
201 $term_info = $wpdb->get_row( $wpdb->prepare( "SELECT taxonomy, meta_value FROM {$wpdb->term_taxonomy} AS t LEFT JOIN {$wpdb->termmeta} AS tm ON tm.term_id = t.term_id AND tm.meta_key = 'auto_update_uri' WHERE t.term_id = %d", $term_id ) );
202
203 // Custom URIs for disabled taxonomies may only be deleted via the admin dashboard, although they will always be removed if the term no longer exists in the database
204 $remove = ( ! empty( $term_info->taxonomy ) ) ? Permalink_Manager_Helper_Functions::is_taxonomy_disabled( $term_info->taxonomy, $check_if_admin ) : true;
205
206 // Remove custom URIs for URIs disabled in URI Editor
207 if ( $strict_mode ) {
208 $remove = ( empty( $term_info->meta_value ) || $term_info->meta_value == 2 ) ? true : $remove;
209 } else {
210 $remove = ( ! empty( $term_info->meta_value ) && $term_info->meta_value == 2 ) ? true : $remove;
211 }
212 } else if ( is_numeric( $element_id ) ) {
213 $post_info = $wpdb->get_row( $wpdb->prepare( "SELECT post_type, meta_value FROM {$wpdb->posts} AS p LEFT JOIN {$wpdb->postmeta} AS pm ON pm.post_ID = p.ID AND pm.meta_key = 'auto_update_uri' WHERE ID = %d AND post_status NOT IN ('auto-draft', 'trash') AND post_type != 'nav_menu_item'", $element_id ) );
214
215 // Custom URIs for disabled post types may only be deleted via the admin dashboard, although they will always be removed if the post no longer exists in the database
216 $remove = ( ! empty( $post_info->post_type ) ) ? Permalink_Manager_Helper_Functions::is_post_type_disabled( $post_info->post_type, $check_if_admin ) : true;
217
218 // Remove custom URIs for URIs disabled in URI Editor
219 if ( $strict_mode ) {
220 $remove = ( empty( $post_info->meta_value ) || $post_info->meta_value == 2 ) ? true : $remove;
221 } else {
222 $remove = ( ! empty( $post_info->meta_value ) && $post_info->meta_value == 2 ) ? true : $remove;
223 }
224
225 // Remove custom URIs for attachments redirected with Yoast's SEO Premium
226 $yoast_permalink_options = ( class_exists( 'WPSEO_Premium' ) ) ? get_option( 'wpseo_permalinks' ) : array();
227
228 if ( ! empty( $yoast_permalink_options['redirectattachment'] ) && $post_info->post_type == 'attachment' ) {
229 $attachment_parent = $wpdb->get_var( "SELECT post_parent FROM {$wpdb->prefix}posts WHERE ID = {$element_id} AND post_type = 'attachment'" );
230 if ( ! empty( $attachment_parent ) ) {
231 $remove = true;
232 }
233 }
234 }
235
236 // 2A. Remove ALL unused custom permalinks & redirects
237 if ( ! empty( $remove ) ) {
238 $current_uri = Permalink_Manager_URI_Functions::get_single_uri( $element_id, false, true, null );
239
240 // Remove URI
241 if ( ! empty( $current_uri ) ) {
242 $removed_uris = 1;
243 Permalink_Manager_URI_Functions::remove_single_uri( $element_id, null, false );
244 }
245
246 // Remove all custom redirects
247 if ( ! empty( $permalink_manager_redirects[ $element_id ] ) && is_array( $permalink_manager_redirects[ $element_id ] ) ) {
248 $removed_redirects = count( $permalink_manager_redirects[ $element_id ] );
249 unset( $permalink_manager_redirects[ $element_id ] );
250 }
251 } // 2B. Check if the post/term uses the same URI for both permalink & custom redirects
252 else {
253 $removed_redirect = self::clear_single_element_duplicated_redirect( $element_id, false );
254 $removed_redirects = ( ! empty( $removed_redirect ) ) ? 1 : 0;
255 }
256
257 // Check if function should only return the counts or update
258 if ( $count_removed ) {
259 return array( $removed_uris, $removed_redirects );
260 } else if ( ! empty( $removed_uris ) || ! empty( $removed_redirects ) ) {
261 Permalink_Manager_URI_Functions::save_all_uris();
262 update_option( 'permalink-manager-redirects', array_filter( $permalink_manager_redirects ) );
263 }
264
265 return array();
266 }
267
268 /**
269 * Remove the duplicated custom redirect if the post/term has the same URI for both custom permalink and custom redirect
270 *
271 * @param string|int $element_id
272 * @param bool $save_redirects
273 * @param string $uri
274 *
275 * @return int
276 */
277 public static function clear_single_element_duplicated_redirect( $element_id, $save_redirects = true, $uri = null ) {
278 global $permalink_manager_redirects;
279
280 // If the custom permalink is not changed ($uri) use the one that is currently used
281 if( ! empty( $uri ) ) {
282 $current_uri = $uri;
283 } else {
284 $current_uri = Permalink_Manager_URI_Functions::get_single_uri( $element_id, false, true, null );
285 }
286
287 if ( ! empty( $current_uri ) && ! empty( $permalink_manager_redirects[ $element_id ] ) && in_array( $current_uri, $permalink_manager_redirects[ $element_id ] ) ) {
288 $duplicated_redirect_id = array_search( $current_uri, $permalink_manager_redirects[ $element_id ] );
289 unset( $permalink_manager_redirects[ $element_id ][ $duplicated_redirect_id ] );
290 }
291
292 // Update the redirects array in the database if the duplicated redirect was unset
293 if ( isset( $duplicated_redirect_id ) && $save_redirects ) {
294 update_option( 'permalink-manager-redirects', array_filter( $permalink_manager_redirects ) );
295 }
296
297 return ( isset( $duplicated_redirect_id ) ) ? 1 : 0;
298 }
299
300 /**
301 * Remove the duplicated if the same URI is used for multiple custom redirects and return the removed redirects count
302 *
303 * @param bool $save_redirects
304 *
305 * @return int
306 */
307 public static function clear_redirects_array( $save_redirects = false ) {
308 global $permalink_manager_redirects;
309
310 $removed_redirects = 0;
311
312 $all_redirect_duplicates = Permalink_Manager_Admin_Functions::get_all_duplicates();
313
314 foreach ( $all_redirect_duplicates as $single_redirect_duplicate ) {
315 $last_element = reset( $single_redirect_duplicate );
316
317 foreach ( $single_redirect_duplicate as $redirect_key ) {
318 // Keep a single redirect
319 if ( $last_element == $redirect_key ) {
320 continue;
321 }
322 preg_match( "/redirect-(\d+)_(tax-\d+|\d+)/", $redirect_key, $ids );
323
324 if ( ! empty( $ids[2] ) && ! empty( $permalink_manager_redirects[ $ids[2] ][ $ids[1] ] ) ) {
325 $removed_redirects ++;
326 unset( $permalink_manager_redirects[ $ids[2] ][ $ids[1] ] );
327 }
328 }
329 }
330
331 // Update the redirects array in the database if the duplicated redirect was unset
332 if ( isset( $duplicated_redirect_id ) && $save_redirects ) {
333 update_option( 'permalink-manager-redirects', array_filter( $permalink_manager_redirects ) );
334 }
335
336 return $removed_redirects;
337 }
338
339 /**
340 * Remove custom permalinks & custom redirects for requested post or term
341 *
342 * @param $uri_key
343 *
344 * @return bool
345 */
346 public static function force_clear_single_element_uris_and_redirects( $uri_key ) {
347 global $permalink_manager_redirects, $permalink_manager_before_sections_html;
348
349 $custom_uri = Permalink_Manager_URI_Functions::get_single_uri( $uri_key, false, true, null );
350
351 // Check if custom URI is set
352 if ( ! empty( $custom_uri ) ) {
353 Permalink_Manager_URI_Functions::remove_single_uri( $uri_key, null, true );
354 // translators: %s is the custom URI that was removed.
355 $updated = Permalink_Manager_UI_Elements::get_alert_message( sprintf( __( 'URI "%s" was removed successfully!', 'permalink-manager' ), $custom_uri ), 'updated' );
356 }
357
358 // Check if custom redirects are set
359 if ( isset( $permalink_manager_redirects[ $uri_key ] ) ) {
360 unset( $permalink_manager_redirects[ $uri_key ] );
361 update_option( 'permalink-manager-redirects', $permalink_manager_redirects );
362 }
363
364 if ( empty( $updated ) ) {
365 $permalink_manager_before_sections_html .= Permalink_Manager_UI_Elements::get_alert_message( __( 'URI and/or custom redirects does not exist or were already removed!', 'permalink-manager' ), 'error' );
366 } else {
367 // Display the alert in admin panel
368 if ( isset( $permalink_manager_before_sections_html ) && is_admin() ) {
369 $permalink_manager_before_sections_html .= $updated;
370 }
371 }
372
373 return true;
374 }
375
376 /**
377 * Remove only custom redirects for requested post or term
378 *
379 * @param string $redirect_key
380 */
381 public static function force_clear_single_redirect( $redirect_key ) {
382 global $permalink_manager_redirects, $permalink_manager_before_sections_html;
383
384 preg_match( "/redirect-(\d+)_(tax-\d+|\d+)/", $redirect_key, $ids );
385
386 if ( ! empty( $permalink_manager_redirects[ $ids[2] ][ $ids[1] ] ) ) {
387 unset( $permalink_manager_redirects[ $ids[2] ][ $ids[1] ] );
388
389 update_option( 'permalink-manager-redirects', array_filter( $permalink_manager_redirects ) );
390
391 $permalink_manager_before_sections_html = Permalink_Manager_UI_Elements::get_alert_message( __( 'The redirect was removed successfully!', 'permalink-manager' ), 'updated' );
392 }
393 }
394
395 /**
396 * Save "Screen Options"
397 */
398 public static function save_screen_options() {
399 check_admin_referer( 'screen-options-nonce', 'screenoptionnonce' );
400
401 // The values will be sanitized inside the function
402 self::save_settings( 'screen-options', $_POST['screen-options'] );
403 }
404
405 /**
406 * Save the plugin settings
407 *
408 * @param bool $field
409 * @param bool $value
410 * @param bool $display_alert
411 */
412 public static function save_settings( $field = false, $value = false, $display_alert = true ) {
413 global $permalink_manager_options, $permalink_manager_before_sections_html;
414
415 // Info: The settings array is used also by "Screen Options"
416 $new_options = $permalink_manager_options;
417 //$new_options = array();
418
419 // Save only selected field/sections
420 if ( $field && $value ) {
421 $new_options[ $field ] = $value;
422 } else {
423 $post_fields = $_POST;
424
425 foreach ( $post_fields as $option_name => $option_value ) {
426 $new_options[ $option_name ] = $option_value;
427 }
428 }
429
430 // Allow only white-listed option groups
431 foreach ( $new_options as $group => $group_options ) {
432 if ( ! in_array( $group, array( 'licence', 'screen-options', 'general', 'permastructure-settings', 'stop-words' ) ) ) {
433 unset( $new_options[ $group ] );
434 }
435 }
436
437 // Sanitize & override the global with new settings
438 $new_options = Permalink_Manager_Helper_Functions::sanitize_array( $new_options );
439 $permalink_manager_options = $new_options = array_filter( $new_options );
440
441 // Save the settings in database
442 update_option( 'permalink-manager', $new_options );
443
444 // Display the message
445 $permalink_manager_before_sections_html .= ( $display_alert ) ? Permalink_Manager_UI_Elements::get_alert_message( __( 'The settings are saved!', 'permalink-manager' ), 'updated' ) : "";
446 }
447
448 /**
449 * Save the permastructures
450 */
451 public static function save_permastructures() {
452 global $permalink_manager_permastructs;
453
454 $permastructure_options = $permastructures = array();
455 $permastructure_types = array( 'post_types', 'taxonomies' );
456
457 // Split permastructures & sanitize them
458 foreach ( $permastructure_types as $type ) {
459 if ( empty( $_POST[ $type ] ) || ! is_array( $_POST[ $type ] ) ) {
460 continue;
461 }
462
463 $permastructures[ $type ] = $_POST[ $type ];
464
465 foreach ( $permastructures[ $type ] as &$single_permastructure ) {
466 $single_permastructure = Permalink_Manager_Helper_Functions::sanitize_title( $single_permastructure, true, false, false );
467 $single_permastructure = trim( $single_permastructure, '\/ ' );
468 }
469 }
470
471 if ( ! empty( $_POST['permastructure-settings'] ) ) {
472 $permastructure_options = $_POST['permastructure-settings'];
473 }
474
475 // A. Permastructures
476 if ( ! empty( $permastructures['post_types'] ) || ! empty( $permastructures['taxonomies'] ) ) {
477 // Override the global with settings
478 $permalink_manager_permastructs = $permastructures;
479
480 // Save the settings in database
481 update_option( 'permalink-manager-permastructs', $permastructures );
482 }
483
484 // B. Permastructure settings
485 if ( ! empty( $permastructure_options ) ) {
486 self::save_settings( 'permastructure-settings', $permastructure_options );
487 }
488 }
489
490 /**
491 * Update all permalinks in "Bulk URI Editor"
492 */
493 function update_all_permalinks() {
494 // Check if posts or terms should be updated
495 if ( ! empty( $_POST['content_type'] ) && $_POST['content_type'] == 'taxonomies' ) {
496 return Permalink_Manager_URI_Functions_Tax::update_all_permalinks();
497 } else {
498 return Permalink_Manager_URI_Functions_Post::update_all_permalinks();
499 }
500 }
501
502 /**
503 * Remove a specific section of the plugin data stored in the database
504 *
505 * @param $field_name
506 */
507 public static function remove_plugin_data( $field_name ) {
508 global $permalink_manager, $permalink_manager_before_sections_html;
509
510 // Make sure that the user is allowed to remove the plugin data
511 if ( ! current_user_can( 'manage_options' ) ) {
512 $permalink_manager_before_sections_html .= Permalink_Manager_UI_Elements::get_alert_message( __( 'You are not allowed to remove Permalink Manager data!', 'permalink-manager' ), 'error updated_slugs' );
513 }
514
515 switch ( $field_name ) {
516 case 'uris' :
517 $option_name = 'permalink-manager-uris';
518 $alert = __( 'Custom permalinks', 'permalink-manager' );
519 break;
520 case 'redirects' :
521 $option_name = 'permalink-manager-redirects';
522 $alert = __( 'Custom redirects', 'permalink-manager' );
523 break;
524 case 'external-redirects' :
525 $option_name = 'permalink-manager-external-redirects';
526 $alert = __( 'External redirects', 'permalink-manager' );
527 break;
528 case 'permastructs' :
529 $option_name = 'permalink-manager-permastructs';
530 $alert = __( 'Permastructure settings', 'permalink-manager' );
531 break;
532 case 'settings' :
533 $option_name = 'permalink-manager';
534 $alert = __( 'Permastructure settings', 'permalink-manager' );
535 break;
536 default :
537 $alert = '';
538 }
539
540 if ( ! empty( $option_name ) ) {
541 // Remove the option from DB
542 delete_option( $option_name );
543
544 // Reload globals
545 $permalink_manager->get_options_and_globals();
546
547 // Translators: %s is the name of the data field that was removed
548 $alert_message = sprintf( __( '%s were removed!', 'permalink-manager' ), $alert );
549 $permalink_manager_before_sections_html .= Permalink_Manager_UI_Elements::get_alert_message( $alert_message, 'updated updated_slugs' );
550 }
551 }
552
553 /**
554 * Trigger bulk tools ("Regenerate & reset", "Find & replace") via AJAX
555 */
556 function ajax_bulk_tools() {
557 global $sitepress, $wpdb;
558
559 // Define variables
560 $return = array( 'alert' => Permalink_Manager_UI_Elements::get_alert_message( __( '<strong>No slugs</strong> were updated!', 'permalink-manager' ), 'error updated_slugs' ) );
561
562 // Get the name of the function
563 if ( isset( $_POST['regenerate'] ) && wp_verify_nonce( $_POST['regenerate'], 'permalink-manager' ) ) {
564 $operation = 'regenerate';
565 } else if ( isset( $_POST['find_and_replace'] ) && wp_verify_nonce( $_POST['find_and_replace'], 'permalink-manager' ) && ! empty( $_POST['old_string'] ) && ! empty( $_POST['new_string'] ) ) {
566 $operation = 'find_and_replace';
567 }
568
569 // Get the session ID
570 $uniq_id = ( ! empty( $_POST['pm_session_id'] ) ) ? $_POST['pm_session_id'] : '';
571
572 // Get content type & post statuses
573 if ( ! empty( $_POST['content_type'] ) && $_POST['content_type'] == 'taxonomies' ) {
574 $content_type = 'taxonomies';
575
576 if ( empty( $_POST['taxonomies'] ) ) {
577 $error = true;
578 $return = array( 'alert' => Permalink_Manager_UI_Elements::get_alert_message( __( '<strong>No taxonomy</strong> selected!', 'permalink-manager' ), 'error updated_slugs' ) );
579 }
580 } else {
581 $content_type = 'post_types';
582
583 // Check if any post type was selected
584 if ( empty( $_POST['post_types'] ) ) {
585 $error = true;
586 $return = array( 'alert' => Permalink_Manager_UI_Elements::get_alert_message( __( '<strong>No post type</strong> selected!', 'permalink-manager' ), 'error updated_slugs' ) );
587 }
588
589 // Check post status
590 if ( empty( $_POST['post_statuses'] ) ) {
591 $error = true;
592 $return = array( 'alert' => Permalink_Manager_UI_Elements::get_alert_message( __( '<strong>No post status</strong> selected!', 'permalink-manager' ), 'error updated_slugs' ) );
593 }
594 }
595
596 if ( ! empty( $operation ) && empty( $error ) ) {
597 // Hotfix for WPML (start)
598 if ( $sitepress ) {
599 remove_filter( 'get_terms_args', array( $sitepress, 'get_terms_args_filter' ), 10 );
600 remove_filter( 'get_term', array( $sitepress, 'get_term_adjust_id' ), 1 );
601 remove_filter( 'terms_clauses', array( $sitepress, 'terms_clauses' ), 10 );
602 remove_filter( 'get_pages', array( $sitepress, 'get_pages_adjust_ids' ), 1 );
603 }
604
605 // Get the mode
606 $mode = ( isset( $_POST['mode'] ) ) ? $_POST['mode'] : 'custom_uris';
607 $preview_mode = ( ! empty( $_POST['preview_mode'] ) ) ? true : false;
608
609 // Get items (try to get them from transient)
610 $items = get_transient( "pm_{$uniq_id}" );
611
612 // Get the iteration count and chunk size
613 $iteration = isset( $_POST['iteration'] ) ? intval( $_POST['iteration'] ) : 1;
614 $chunk_size = apply_filters( 'permalink_manager_chunk_size', 50 );
615
616 if ( empty( $items ) && ! empty ( $chunk_size ) ) {
617 if ( $content_type == 'taxonomies' ) {
618 $items = Permalink_Manager_URI_Functions_Tax::get_items();
619 } else {
620 $items = Permalink_Manager_URI_Functions_Post::get_items();
621 }
622
623 if ( ! empty( $items ) ) {
624 // Count how many items need to be processed
625 $total = count( $items );
626
627 // Split items array into chunks and save them to transient
628 $items = array_chunk( $items, $chunk_size );
629
630 set_transient( "pm_{$uniq_id}", $items, 600 );
631
632 // Check for MySQL errors
633 if ( ! empty( $wpdb->last_error ) ) {
634 printf( '%s (%sMB)', esc_html( $wpdb->last_error ), esc_html( number_format( strlen( serialize( $items ) ) / 1000000, 2 ) ) );
635 http_response_code( 500 );
636 die();
637 }
638 }
639 }
640
641 // Get homepage URL and ensure that it ends with slash
642 $home_url = Permalink_Manager_Helper_Functions::get_permalink_base() . "/";
643
644 // Process the variables from $_POST object
645 $old_string = ( ! empty( $_POST['old_string'] ) ) ? str_replace( $home_url, '', esc_sql( $_POST['old_string'] ) ) : '';
646 $new_string = ( ! empty( $_POST['new_string'] ) ) ? str_replace( $home_url, '', esc_sql( $_POST['new_string'] ) ) : '';
647
648 // Process only one subarray
649 if ( ! empty( $items[ $iteration - 1 ] ) ) {
650 $chunk = $items[ $iteration - 1 ];
651
652 // Check how many iterations are needed
653 $total_iterations = count( $items );
654
655 if ( $content_type == 'taxonomies' ) {
656 $output = Permalink_Manager_URI_Functions_Tax::bulk_process_items( $chunk, $mode, $operation, $old_string, $new_string, $preview_mode );
657 } else {
658 $output = Permalink_Manager_URI_Functions_Post::bulk_process_items( $chunk, $mode, $operation, $old_string, $new_string, $preview_mode );
659 }
660
661 if ( ! empty( $output['updated_count'] ) ) {
662 $return = array_merge( $return, (array) Permalink_Manager_UI_Elements::display_updated_slugs( $output['updated'], true, true, $preview_mode ) );
663 $return['updated_count'] = $output['updated_count'];
664 }
665
666 // Send total number of processed items with a first chunk
667 if ( ! empty( $total ) && ! empty( $total_iterations ) && $iteration == 1 ) {
668 $return['total'] = $total;
669 $return['items'] = $items;
670 }
671
672 $return['iteration'] = $iteration;
673 $return['total_iterations'] = $total_iterations;
674 $return['progress'] = $chunk_size * $iteration;
675 $return['chunk'] = $chunk;
676
677 // After all chunks are processed remove the transient
678 if ( $iteration == $total_iterations ) {
679 delete_transient( "pm_{$uniq_id}" );
680 }
681 }
682
683 // Hotfix for WPML (end)
684 if ( $sitepress ) {
685 add_filter( 'terms_clauses', array( $sitepress, 'terms_clauses' ), 10, 4 );
686 add_filter( 'get_term', array( $sitepress, 'get_term_adjust_id' ), 1, 1 );
687 add_filter( 'get_terms_args', array( $sitepress, 'get_terms_args_filter' ), 10, 2 );
688 add_filter( 'get_pages', array( $sitepress, 'get_pages_adjust_ids' ), 1, 2 );
689 }
690 }
691
692 wp_send_json( $return );
693 die();
694 }
695
696 /**
697 * Save permalink via AJAX
698 */
699 public function ajax_save_permalink() {
700 $element_id = ( ! empty( $_POST['permalink-manager-edit-uri-element-id'] ) ) ? sanitize_text_field( $_POST['permalink-manager-edit-uri-element-id'] ) : '';
701
702 if ( ! empty( $element_id ) && is_numeric( $element_id ) && current_user_can( 'edit_post', $element_id ) ) {
703 Permalink_Manager_URI_Functions_Post::update_post_hook( $element_id );
704
705 // Reload URI Editor & clean post cache
706 clean_post_cache( $element_id );
707 die();
708 }
709 }
710
711 /**
712 * Check if URI was used before
713 */
714 function ajax_detect_duplicates() {
715 $duplicate_alert = __( "Permalink is already in use, please select another one!", "permalink-manager" );
716 $duplicates_data = array();
717
718 if ( ! empty( $_REQUEST['custom_uris'] ) ) {
719 $custom_uris = Permalink_Manager_Helper_Functions::sanitize_array( $_REQUEST['custom_uris'] );
720
721 // Check each URI
722 foreach ( $custom_uris as $raw_element_id => $element_uri ) {
723 $element_id = sanitize_key( $raw_element_id );
724 $duplicates_data[ $element_id ] = Permalink_Manager_URI_Functions::is_uri_duplicated( $element_uri, $element_id ) ? $duplicate_alert : 0;
725 }
726 } else if ( ! empty( $_REQUEST['custom_uri'] ) && ! empty( $_REQUEST['element_id'] ) ) {
727 $duplicates_data = Permalink_Manager_URI_Functions::is_uri_duplicated( $_REQUEST['custom_uri'], sanitize_key( $_REQUEST['element_id'] ) );
728 }
729
730 wp_send_json( $duplicates_data );
731 }
732
733 /**
734 * Hide global notices (AJAX)
735 */
736 function ajax_hide_global_notice() {
737 global $permalink_manager_alerts;
738
739 // Get the ID of the alert
740 $alert_id = ( ! empty( $_REQUEST['alert_id'] ) ) ? sanitize_title( $_REQUEST['alert_id'] ) : "";
741 if ( ! empty( $permalink_manager_alerts[ $alert_id ] ) ) {
742 $dismissed_transient_name = sprintf( 'permalink-manager-notice_%s', $alert_id );
743 $dismissed_time = ( ! empty( $permalink_manager_alerts[ $alert_id ]['dismissed_time'] ) ) ? (int) $permalink_manager_alerts[ $alert_id ]['dismissed_time'] : DAY_IN_SECONDS;
744
745 set_transient( $dismissed_transient_name, 1, $dismissed_time );
746 }
747 }
748
749 /**
750 * Import old URIs from "Custom Permalinks" (Pro)
751 */
752 function import_custom_permalinks_uris() {
753 Permalink_Manager_Third_Parties::import_custom_permalinks_uris();
754 }
755
756 }
757