PluginProbe ʕ •ᴥ•ʔ
Auto Post Cleaner / trunk
Auto Post Cleaner vtrunk
3.12.0 3.13.1 3.2.4 3.2.5 3.3.0 3.3.10 3.3.11 3.3.8 3.4.2 3.5.3 3.6.0 3.7.0 3.7.1 3.7.2 3.7.3 3.7.5 3.7.6 3.8.0 3.9.0 3.9.4 3.9.6 3.9.7 trunk 3.0.0 3.1.0 3.10.1 3.10.2 3.11.4
delete-old-posts-programmatically / inc / class-delete-old-posts-redirects.php
delete-old-posts-programmatically / inc Last commit date
class-delete-old-posts-filters.php 1 month ago class-delete-old-posts-redirects.php 1 month ago class-delete-old-posts.php 1 month ago class-enqueue-assets.php 1 month ago
class-delete-old-posts-redirects.php
573 lines
1 <?php
2 namespace DEL\OLD\Posts\Cls;
3
4 /**
5 * Make the plugin class.
6 */
7 class Delete_Old_Posts_Redirects extends Delete_Old_Posts {
8
9 /**
10 * Hooks init (nothing else) and calls things that need to run right away.
11 */
12 public function __construct(){
13 // add redirection for deleted posts
14 add_action('template_redirect', [ $this, 'deloldp_redirectDeletedPosts' ]);
15 // add global redirection
16 add_action( 'admin_post_redirects_global', [ $this, 'deloldp_redirectGlobal'] );
17 // add redirects menu
18 add_action( 'admin_menu', [ $this, 'deloldp_custom_menu_page' ] );
19 }
20
21 /**
22 * add a custom menu in admin menu
23 */
24 function deloldp_custom_menu_page() {
25
26 global $deloldp_redirects_submenu;
27
28 // Add submenu page with same slug as parent to ensure no duplicates
29 $deloldp_redirects_submenu = add_submenu_page(
30 'delete-old-posts',
31 'Redirects - Auto Post Cleaner',
32 esc_html__('Redirects', 'delete-old-posts'),
33 'manage_options',
34 'delete-old-posts-redirects',
35 [$this, 'deloldpRedirects']
36 );
37
38 /** Create the screen option for submenu */
39 add_action("load-$deloldp_redirects_submenu", [$this, "deloldp_redirects_screen_options"]);
40 }
41
42 /**
43 * Logic to redirect deleted posts to similar ones
44 */
45 function deloldp_redirectDeletedPosts(){
46
47 global $wp;
48
49 /**
50 * check if user enabled the redirects
51 */
52 $getOptionObject = get_option('deloldp-post-days-option');
53 if ( is_object($getOptionObject) && property_exists($getOptionObject, 'params') )
54 if ( isset($getOptionObject->params->deloldpRedirect) && $getOptionObject->params->deloldpRedirect == 0 ) return false;
55
56 // user have enabled the redirects - go on
57 if (is_404()){ // check if 404 page
58 $requestedUrl = home_url( $wp->request );
59 /**
60 * check the requested url into deleted posts opt
61 */
62 $deletedPostsNames = get_option('deletedpostredirectsopt');
63 if( is_array($deletedPostsNames) ) foreach( $deletedPostsNames as $deletedPostKey => $deletedPostN ){
64 if( stristr($requestedUrl, $deletedPostN) !== false ){
65 /**
66 * the requested url is one of deleted posts
67 * check if global redirect is defined or
68 * check if was manually edited by user or
69 * redirect it to a similar post
70 */
71 // cehck if global redirect is set
72 $global_redirect_url = (property_exists($getOptionObject->params, 'global_redirect_url')) ? $getOptionObject->params->global_redirect_url : '';
73 if( $global_redirect_url != '' && wp_http_validate_url( $global_redirect_url ) ) {
74 // URL is valid
75 wp_redirect( esc_url($global_redirect_url), 301 );
76 exit;
77 }
78 // check if redirect manually edited and redirect to the requested URL
79 $redirectsOptEdited = get_option('deletedpostredirectsoptedited');
80 if( is_array($redirectsOptEdited) && array_key_exists($deletedPostKey, $redirectsOptEdited) ) {
81 wp_redirect( esc_url($redirectsOptEdited[$deletedPostKey]), 301 );
82 exit;
83 }
84 // redirect was not manually edited - search for sumilar posts
85 $redirect_url = $this->deloldp_posts_results_filter($requestedUrl);
86 wp_redirect( esc_url($redirect_url), 301 );
87 exit;
88 }
89 }
90
91 /**
92 * URL was not found in the list
93 * Do Nothing!
94 */
95 return false;
96 }
97 }
98
99 /**
100 * search similar posts
101 *
102 * @param $requestedUrl (string)
103 */
104 function deloldp_posts_results_filter( $requestedUrl ){
105 $requestedUrl = (string) $requestedUrl;
106 $args = array(
107 'numberposts' => 50000,
108 // 'category' => 0,
109 'orderby' => 'date',
110 'order' => 'DESC',
111 'include' => array(),
112 'exclude' => array(),
113 'meta_key' => '',
114 'meta_value' => '',
115 'post_type' => 'any',
116 'suppress_filters' => true,
117 );
118 $posts = get_posts( $args );
119
120 $filtered_posts = array();
121 foreach ( $posts as $post ) {
122 similar_text($post->post_name, $requestedUrl, $similarPercentage);
123 $filtered_posts[$similarPercentage] = $post->ID;
124 }
125
126 // sort the post after similarity percentage
127 krsort($filtered_posts);
128 $bestPostMatch = reset($filtered_posts);
129 // error_log('Best similar match: ' . array_key_first($filtered_posts) . ' - ' . print_r(get_permalink($bestPostMatch), true));
130
131 return get_permalink($bestPostMatch);
132 }
133
134 /**
135 * Create the rediects page
136 */
137 function deloldpRedirects(){
138
139 /** Check and make the redirects table actions */
140 $this->tableActions();
141
142 /**
143 * Check if user changed the screen options
144 * Update the user_meta if changed -> used into Redirects_List_Table->prepare_items
145 */
146 if( isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options']) ){
147 if( isset($_POST['wp_screen_options']['option']) && isset($_POST['wp_screen_options']['value']) ){
148 $wp_screen_options = $_POST['wp_screen_options']['option'];
149 switch ($wp_screen_options){
150 case 'redirects_per_page':
151 update_user_meta( get_current_user_id(), 'redirects_per_page', $_POST['wp_screen_options']['value'] );
152 break;
153 }
154 }
155 }
156
157 /**
158 * Show redirects table
159 */
160 $redirects_list_table = new Redirects_List_Table();
161 ?>
162 <div class='mx-4 my-8'>
163 <div class="wrap"><h2><?php esc_html_e('Deleted posts list', 'delete-old-posts'); ?></h2></div>
164 <?php
165 $page = filter_input( INPUT_GET, 'page', FILTER_UNSAFE_RAW );
166 $paged = filter_input( INPUT_GET, 'paged', FILTER_SANITIZE_NUMBER_INT );
167 $deloldp_options = get_option('deloldp-post-days-option');
168 $global_redirect_url = (property_exists($deloldp_options->params, 'global_redirect_url')) ? $deloldp_options->params->global_redirect_url : '';
169
170 echo '
171 <hr /><br />
172 <section>
173 <div>
174 <form action="'. esc_url( admin_url('admin-post.php') ) .'" method="post">
175 <input type="hidden" name="action" value="redirects_global">';
176 wp_nonce_field( 'redirects_global', 'redirects_global_nonce_field' );
177 echo '
178 <div class="global-redirect-url-input-wrapper">
179 <label for="global_redirect_url">';
180 _e('Redirect all deleted items to: ', 'delete-old-posts');
181 echo '<input type="text" id="global_redirect_url" name="global_redirect_url" class="w-1/2" value="'.esc_url($global_redirect_url).'" />';
182 echo '<span class="after">x</span>';
183 echo '
184 </label>';
185 printf( '<input type="submit" class="button no-vertical-align !ml-2" value="%s" />', 'Save' );
186 echo '
187 </div>';
188 echo '<br />ex. <a href="#" id="global_redirects_home_link" data-href="'. home_url() .'">'. home_url() .'</a>
189 </form>
190 </div>
191 </section>
192 <section>
193 <div>
194 <form method="post" id="delete-old-posts-redirects">';
195 printf( '<input type="hidden" name="page" value="%s" />', $page );
196 printf( '<input type="hidden" name="paged" value="%d" />', $paged );
197 $redirects_list_table->prepare_items();
198 $redirects_list_table->search_box( __( 'Search redirects', 'delete-old-posts' ), 'search_id' );
199 $redirects_list_table->display();
200 echo '
201 </form>
202 </div>
203 </section>';
204 ?>
205 </div>
206 <?php
207 }
208
209 /**
210 * add screen options for the redirects page
211 */
212 function deloldp_redirects_screen_options() {
213
214 global $deloldp_redirects_submenu;
215
216 $screen = get_current_screen();
217
218 // get out of here if we are not on our settings page
219 if(!is_object($screen) || $screen->id != $deloldp_redirects_submenu)
220 return;
221
222 /** check if items per page was set in the screen options */
223 $redirects_per_page = get_user_meta(get_current_user_id(), 'redirects_per_page', false);
224 if( ! $redirects_per_page || $redirects_per_page == '' ) $redirects_per_page = 10;
225
226 $args = array(
227 'label' => __('Redirects per page', 'delete-old-posts'),
228 'default' => $redirects_per_page,
229 'option' => 'redirects_per_page'
230 );
231 add_screen_option( 'per_page', $args );
232 }
233
234 /**
235 * Make the redirects table actions
236 */
237 function tableActions(){
238 if( isset($_REQUEST['action']) )
239 switch( $_REQUEST['action'] ){
240 case 'delete_all':
241 /** delete redirects in bulk */
242 $deletedPostsNames = get_option('deletedpostredirectsopt');
243 if( isset($_REQUEST['redirect_id']) ) foreach( $_REQUEST['redirect_id'] as $redirect_id_to_delete ){
244 unset( $deletedPostsNames[absint($redirect_id_to_delete)] );
245 update_option('deletedpostredirectsopt', $deletedPostsNames);
246 }
247 printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( 'notice notice-success' ), esc_html( __('The redirects have been deleted.', 'delete-old-posts') ) );
248 break;
249 case 'edit':
250 if (isset($_GET['element']) && (isset($_GET['_wpnonce']) & wp_verify_nonce($_GET['_wpnonce'], 'edit_redirect'))){
251 /**
252 * Nonce verified - edit the redirect
253 * Create a new option and store the new link
254 * Check if the id of the redirect is in the new option, then redirect to edited link
255 */
256 $element = intval($_GET['element']);
257 $deletedPostsNames = get_option('deletedpostredirectsopt');
258 $old_redirect = $deletedPostsNames[$element];
259
260 /**
261 * Check if form was saved and don't show it
262 */
263 if( ! isset($_POST['new_redirect']) ){
264 // check if redirect was already edited
265 $redirectsOptEdited = get_option('deletedpostredirectsoptedited');
266 ?>
267 <form method="post" class="flex flex-col flex-wrap p-6">
268 <label class="" for="old_redirect">
269 <span class=""><?php esc_html_e('Deleted post slug:', 'delete-old-posts'); ?></span>
270 <input class="p-1" type="text" disabled name="old_redirect" value="<?php echo $old_redirect; ?>" />
271 </label>
272 <label class="" for="new_redirect">
273 <span class="block"><?php esc_html_e('New redirect to post (full URL starting with https:// or http://):', 'delete-old-posts'); ?></span>
274 <input class="w-3/4" type="text" name="new_redirect" value="<?php if( isset($redirectsOptEdited[absint($_GET['element'])]) ) echo $redirectsOptEdited[absint($_GET['element'])]; ?>" />
275 </label>
276 <input
277 class="mt-3 cursor-pointer p-2 text-center w-1/5 bg-gray-200 drop-shadow-sm hover:bg-gray-400 hover:text-white"
278 type="submit"
279 value="Save the new link"
280 />
281 </form>
282 <?php
283 }
284 /**
285 * Save the edted redirect in option and check when the redirection is made
286 */
287 if( isset($_POST['new_redirect']) && $_POST['new_redirect'] != '' ){
288 $new_redirect_url = sanitize_url( $_POST['new_redirect'] );
289 // check if valid URL was inserted
290 if ( ! wp_http_validate_url( $new_redirect_url ) ) {
291 printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( 'notice notice-error' ), esc_html( __('It\'s NOT valid URL.', 'delete-old-posts') ) );
292 break;
293 }
294 $redirectsOptEdited = get_option('deletedpostredirectsoptedited');
295 if( ! is_array($redirectsOptEdited) ) $redirectsOptEdited = array();
296 $redirectsOptEdited[absint($_GET['element'])] = $new_redirect_url;
297 update_option('deletedpostredirectsoptedited', $redirectsOptEdited);
298 printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( 'notice notice-success' ), esc_html( __('The new redirect have been saved.', 'delete-old-posts') ) );
299 }
300 }
301 break;
302 case 'delete':
303 if (isset($_GET['element']) && isset($_GET['_wpnonce']) && wp_verify_nonce($_GET['_wpnonce'], 'delete_redirect')){
304 /** Nonce verified - delete the redirect */
305 $element = absint($_GET['element']);
306 $deletedPostsNames = get_option('deletedpostredirectsopt');
307 if( isset($deletedPostsNames[$element]) ){
308 $redirect_text = $deletedPostsNames[$element];
309 unset($deletedPostsNames[$element]);
310 update_option('deletedpostredirectsopt', $deletedPostsNames);
311 printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( 'notice notice-success' ), esc_html( __('The redirect "'.$redirect_text.'" have been deleted.', 'delete-old-posts') ) );
312 }
313 }
314 break;
315 }
316 }
317
318 /**
319 * Add global redirect for deleted posts
320 */
321 function deloldp_redirectGlobal(){
322 if ( ! isset( $_POST['redirects_global_nonce_field'] ) || ! wp_verify_nonce( $_POST['redirects_global_nonce_field'], 'redirects_global' ) ) {
323 _e('Sorry, not allowed!', 'delete-old-posts');
324 return;
325 }
326
327 if( ! isset($_POST['global_redirect_url']) ) return;
328 $deloldp_post_days_option = get_option('deloldp-post-days-option');
329 if( is_object($deloldp_post_days_option->params) ) {
330 if( $_POST['global_redirect_url'] != '' ) {
331 $deloldp_post_days_option->params->global_redirect_url = strtolower(esc_url_raw($_POST['global_redirect_url']));
332 } else {
333 unset($deloldp_post_days_option->params->global_redirect_url);
334 }
335 // save the global URL for redirects
336 update_option('deloldp-post-days-option', $deloldp_post_days_option);
337 }
338
339 ( isset($_POST['_wp_http_referer']) ) ? wp_redirect( esc_url($_POST['_wp_http_referer']) ) : wp_redirect( home_url() );
340 }
341 }
342
343 /**
344 * MARK: WP_List_Table Ext.
345 * ================================================================================== WP_List_Table Class for Redirections
346 */
347 // WP_List_Table is not loaded automatically so we need to load it in our application
348 if( !class_exists('WP_List_Table') ){
349 require_once( ABSPATH . 'wp-admin/includes/screen.php' );
350 require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
351 }
352 /**
353 * Create the class that will list the redirects table and will extend the WP_List_Table
354 */
355 class Redirects_List_Table extends \WP_List_Table {
356 /**
357 * Prepare the items for the table to process
358 *
359 * @return Void
360 */
361 public function prepare_items()
362 {
363 $columns = $this->get_columns();
364 $hidden = $this->get_hidden_columns();
365 $sortable = $this->get_sortable_columns();
366
367 /**
368 * set the number of items displayed / page
369 */
370 $perPage = 10;
371 /** check if items per page was set in the screen options */
372 $redirects_per_page = intval(get_user_meta(get_current_user_id(), 'redirects_per_page', true));
373 if( is_int($redirects_per_page) && $redirects_per_page > 0 ) $perPage = $redirects_per_page;
374
375 /** check if it a search - then display all entries */
376 $search = ( isset( $_POST['s'] ) ) ? $_POST['s'] : '';
377 if( $search != '' ) {
378 /** get table data on search */
379 $data = $this->table_data($search);
380 $perPage = count($data);
381 } else {
382 $data = $this->table_data();
383 }
384
385 // sort data
386 usort( $data, array( &$this, 'sort_data' ) );
387
388 $currentPage = $this->get_pagenum();
389 $totalItems = count($data);
390
391 $this->set_pagination_args( array(
392 'total_items' => $totalItems,
393 'per_page' => $perPage
394 ) );
395
396 $data = array_slice($data,(($currentPage-1)*$perPage),$perPage);
397
398 $this->_column_headers = array($columns, $hidden, $sortable);
399 $this->items = $data;
400 }
401
402 /**
403 * Override the parent columns method. Defines the columns to use in your listing table
404 *
405 * @return Array
406 */
407 public function get_columns()
408 {
409 $columns = array(
410 'cb' => '<input type="checkbox" />',
411 'id' => __('ID', 'delete-old-posts'),
412 'post_slug' => __('Deleted post slug', 'delete-old-posts'),
413 'check' => __('Redirection', 'delete-old-posts'),
414 );
415
416 return $columns;
417 }
418
419 /**
420 * Define which columns are hidden
421 *
422 * @return Array
423 */
424 public function get_hidden_columns()
425 {
426 return array();
427 }
428
429 /**
430 * Define the sortable columns
431 *
432 * @return Array
433 */
434 public function get_sortable_columns()
435 {
436 $sortable_columns = array(
437 'id' => array('id', false),
438 'post_slug' => array('post_slug', false)
439 );
440
441 return $sortable_columns;
442 }
443
444 /**
445 * Get the table data
446 *
447 * @return Array
448 */
449 private function table_data( $search = '' )
450 {
451 $data = array();
452
453 // get deleted posts array and edited redirections array
454 $deletedPostsNames = get_option('deletedpostredirectsopt');
455 $redirectsOptEdited = get_option('deletedpostredirectsoptedited');
456
457 // get the permalink structure
458 $permalink_structure = get_option( 'permalink_structure' );
459 if( stristr( $permalink_structure, '%postname%' ) === false ) {
460 printf( '<div class="%1$s"><p>%2$s <a href="%3$s">%4$s</a>.</p></div>', esc_attr( 'notice notice-error' ), esc_html( __('Sorry. You can\'t use the redirection feature because your permalink structure is not using the postname. To use the redirect, change your permanent structure in ', 'delete-old-posts') ), admin_url('options-permalink.php'), esc_attr( __('settings', 'delete-old-posts') ) );
461 return $data; // return empty data
462 }
463
464 if( is_array($deletedPostsNames) ) foreach( $deletedPostsNames as $key => $deletedPostSlug) {
465 if ( ! empty($search) && ! stristr($deletedPostSlug, $search) ) continue;
466 $checkTxt = 'Check redirection';
467 $checkUrl = get_home_url() .'/'. $deletedPostSlug;
468 if( isset($redirectsOptEdited[$key]) && esc_url($redirectsOptEdited[$key]) != '' ) {
469 $checkTxt = esc_url($redirectsOptEdited[$key]);
470 }
471
472 $data[] = array(
473 'id' => $key,
474 'post_slug' => $deletedPostSlug,
475 'check' => '<a href="' . $checkUrl . '" target="_blank" class="text-sky-500">'.__($checkTxt, 'delete-old-posts').'</a>',
476 );
477 }
478
479 return $data;
480 }
481
482 /**
483 * Define what data to show on each column of the table
484 *
485 * @param Array $item Data
486 * @param String $column_name - Current column name
487 *
488 * @return Mixed
489 */
490 public function column_default( $item, $column_name )
491 {
492 switch( $column_name ) {
493 case 'id':
494 case 'post_slug':
495 case 'check':
496 return $item[ $column_name ];
497
498 default:
499 return print_r( $item, true ) ;
500 }
501 }
502
503 /**
504 * Allows you to sort the data by the variables set in the $_GET
505 *
506 * @return Mixed
507 */
508 private function sort_data( $a, $b ) {
509 // Set defaults
510 $orderby = 'post_slug';
511 $order = 'asc';
512 $result = strcmp( $a[$orderby], $b[$orderby] );
513
514 // If orderby is set, use this as the sort column
515 if(!empty($_GET['orderby']))
516 {
517 $orderby = $_GET['orderby'];
518 }
519
520 // If order is set use this as the order
521 if(!empty($_GET['order']))
522 {
523 $order = $_GET['order'];
524 }
525
526 if( isset($_GET['orderby']) ) switch( $_GET['orderby'] ){
527 case 'id':
528 $result = strnatcmp( $a[$orderby], $b[$orderby] );
529 break;
530 }
531
532 if($order === 'asc') {
533 return $result;
534 }
535
536 return -$result;
537 }
538
539 /**
540 * create checkboxes for table rows
541 * checkbox will come in handy when we need to create bulk actions to our table.
542 */
543 function column_cb($item)
544 {
545 return sprintf('<input type="checkbox" name="redirect_id[]" value="%s" />', $item['id']);
546 }
547
548 /**
549 * Adding action links to column
550 */
551 function column_post_slug($item){
552 if( !isset($_REQUEST['page']) || !isset($item['id']) || !isset($item['post_slug']) ) return false; //exit earlier
553
554 $actions = array(
555 'edit' => '<a href="' . esc_url( wp_nonce_url( admin_url('admin.php') . sprintf('?page=%s&action=%s&element=%s&paged=%s', esc_html($_REQUEST['page']), 'edit', $item['id'], esc_html($_REQUEST['paged'])), 'edit_redirect' ) ) . '">' . __('Edit', 'delete-old-posts') . '</a>',
556 'delete' => '<a href="' . esc_url( wp_nonce_url( admin_url('admin.php') . sprintf('?page=%s&action=%s&element=%s&paged=%s', esc_html($_REQUEST['page']), 'delete', $item['id'], esc_html($_REQUEST['paged'])), 'delete_redirect' ) ) . '">' . __('Delete', 'delete-old-posts') . '</a>',
557 );
558
559 return sprintf('%1$s %2$s', $item['post_slug'], $this->row_actions($actions));
560 }
561
562 /**
563 * show bulk action dropdown
564 */
565 function get_bulk_actions() {
566 $actions = array(
567 'delete_all' => __('Delete', 'delete-old-posts'),
568 );
569
570 return $actions;
571 }
572 }
573 ?>