PluginProbe ʕ •ᴥ•ʔ
Auto Post Cleaner / 3.14.0
Auto Post Cleaner v3.14.0
3.14.0 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 3 months ago class-delete-old-posts-redirects.php 14 hours ago class-delete-old-posts.php 3 months ago class-enqueue-assets.php 3 months ago
class-delete-old-posts-redirects.php
602 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
243 // Verify nonce — must match 'bulk-' . plural used in table constructor
244 check_admin_referer( 'bulk-delop-redirects' );
245
246 if( empty($_REQUEST['redirect_id']) ) return; // bail early
247
248 $deletedPostsNames = get_option('deletedpostredirectsopt');
249
250 if( is_array($_REQUEST['redirect_id']) ) foreach( $_REQUEST['redirect_id'] as $redirect_id_to_delete ){
251 unset( $deletedPostsNames[absint($redirect_id_to_delete)] );
252 update_option('deletedpostredirectsopt', $deletedPostsNames, false);
253 }
254
255 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') ) );
256 break;
257 case 'edit':
258 if (isset($_GET['element']) && (isset($_GET['_wpnonce']) & wp_verify_nonce($_GET['_wpnonce'], 'edit_redirect'))){
259 /**
260 * Nonce verified - edit the redirect
261 * Create a new option and store the new link
262 * Check if the id of the redirect is in the new option, then redirect to edited link
263 */
264 $element = intval($_GET['element']);
265 $deletedPostsNames = get_option('deletedpostredirectsopt');
266 $old_redirect = $deletedPostsNames[$element];
267
268 /**
269 * Check if form was saved and don't show it
270 */
271 if( ! isset($_POST['new_redirect']) ){
272 // check if redirect was already edited
273 $redirectsOptEdited = get_option('deletedpostredirectsoptedited');
274 ?>
275 <form method="post" class="flex flex-col flex-wrap p-6">
276 <label class="" for="old_redirect">
277 <span class=""><?php esc_html_e('Deleted post slug:', 'delete-old-posts'); ?></span>
278 <input class="p-1" type="text" disabled name="old_redirect" value="<?php echo $old_redirect; ?>" />
279 </label>
280 <label class="" for="new_redirect">
281 <span class="block"><?php esc_html_e('New redirect to post (full URL starting with https:// or http://):', 'delete-old-posts'); ?></span>
282 <input class="w-3/4" type="text" name="new_redirect" value="<?php if( isset($redirectsOptEdited[absint($_GET['element'])]) ) echo $redirectsOptEdited[absint($_GET['element'])]; ?>" />
283 </label>
284 <input
285 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"
286 type="submit"
287 value="Save the new link"
288 />
289 </form>
290 <?php
291 }
292 /**
293 * Save the edted redirect in option and check when the redirection is made
294 */
295 if( isset($_POST['new_redirect']) && $_POST['new_redirect'] != '' ){
296 $new_redirect_url = sanitize_url( $_POST['new_redirect'] );
297 // check if valid URL was inserted
298 if ( ! wp_http_validate_url( $new_redirect_url ) ) {
299 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') ) );
300 break;
301 }
302 $redirectsOptEdited = get_option('deletedpostredirectsoptedited');
303 if( ! is_array($redirectsOptEdited) ) $redirectsOptEdited = array();
304 $redirectsOptEdited[absint($_GET['element'])] = $new_redirect_url;
305 update_option('deletedpostredirectsoptedited', $redirectsOptEdited, false);
306 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') ) );
307 }
308 }
309 break;
310 case 'delete':
311 if (isset($_GET['element']) && isset($_GET['_wpnonce']) && wp_verify_nonce($_GET['_wpnonce'], 'delete_redirect')){
312 /** Nonce verified - delete the redirect */
313 $element = absint($_GET['element']);
314 $deletedPostsNames = get_option('deletedpostredirectsopt');
315 if( isset($deletedPostsNames[$element]) ){
316 $redirect_text = $deletedPostsNames[$element];
317 unset($deletedPostsNames[$element]);
318 update_option('deletedpostredirectsopt', $deletedPostsNames, false);
319 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') ) );
320 }
321 }
322 break;
323 }
324 }
325
326 /**
327 * Add global redirect for deleted posts
328 */
329 function deloldp_redirectGlobal(){
330 if ( ! isset( $_POST['redirects_global_nonce_field'] ) || ! wp_verify_nonce( $_POST['redirects_global_nonce_field'], 'redirects_global' ) ) {
331 _e('Sorry, not allowed!', 'delete-old-posts');
332 return;
333 }
334
335 if( ! isset($_POST['global_redirect_url']) ) return;
336 $deloldp_post_days_option = get_option('deloldp-post-days-option');
337 if( is_object($deloldp_post_days_option->params) ) {
338 if( $_POST['global_redirect_url'] != '' ) {
339 $deloldp_post_days_option->params->global_redirect_url = strtolower(esc_url_raw($_POST['global_redirect_url']));
340 } else {
341 unset($deloldp_post_days_option->params->global_redirect_url);
342 }
343 // save the global URL for redirects
344 update_option('deloldp-post-days-option', $deloldp_post_days_option, false);
345 }
346
347 ( isset($_POST['_wp_http_referer']) ) ? wp_redirect( esc_url($_POST['_wp_http_referer']) ) : wp_redirect( home_url() );
348 }
349 }
350
351 /**
352 * MARK: WP_List_Table Ext.
353 * ================================================================================== WP_List_Table Class for Redirections
354 */
355 // WP_List_Table is not loaded automatically so we need to load it in our application
356 if( !class_exists('WP_List_Table') ){
357 require_once( ABSPATH . 'wp-admin/includes/screen.php' );
358 require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
359 }
360 /**
361 * Create the class that will list the redirects table and will extend the WP_List_Table
362 */
363 class Redirects_List_Table extends \WP_List_Table {
364
365 public function __construct() {
366 parent::__construct( array(
367 'singular' => 'delop-redirect', // singular label, used internally
368 'plural' => 'delop-redirects', // <-- check_admin_referer() must match this in bulk actions
369 'ajax' => false,
370 ) );
371 }
372
373 /**
374 * Edit table classes
375 */
376 protected function get_table_classes() {
377 // Get the default classes
378 $classes = parent::get_table_classes();
379
380 // Remove 'fixed'
381 $classes = array_diff( $classes, array( 'fixed' ) );
382
383 return $classes;
384 }
385 /**
386 * Prepare the items for the table to process
387 *
388 * @return Void
389 */
390 public function prepare_items()
391 {
392 $columns = $this->get_columns();
393 $hidden = $this->get_hidden_columns();
394 $sortable = $this->get_sortable_columns();
395
396 /**
397 * set the number of items displayed / page
398 */
399 $perPage = 10;
400 /** check if items per page was set in the screen options */
401 $redirects_per_page = intval(get_user_meta(get_current_user_id(), 'redirects_per_page', true));
402 if( is_int($redirects_per_page) && $redirects_per_page > 0 ) $perPage = $redirects_per_page;
403
404 /** check if it a search - then display all entries */
405 $search = ( isset( $_POST['s'] ) ) ? $_POST['s'] : '';
406 if( $search != '' ) {
407 /** get table data on search */
408 $data = $this->table_data($search);
409 $perPage = count($data);
410 } else {
411 $data = $this->table_data();
412 }
413
414 // sort data
415 usort( $data, array( &$this, 'sort_data' ) );
416
417 $currentPage = $this->get_pagenum();
418 $totalItems = count($data);
419
420 $this->set_pagination_args( array(
421 'total_items' => $totalItems,
422 'per_page' => $perPage
423 ) );
424
425 $data = array_slice($data,(($currentPage-1)*$perPage),$perPage);
426
427 $this->_column_headers = array($columns, $hidden, $sortable);
428 $this->items = $data;
429 }
430
431 /**
432 * Override the parent columns method. Defines the columns to use in your listing table
433 *
434 * @return array
435 */
436 public function get_columns()
437 {
438 $columns = array(
439 'cb' => '<input type="checkbox" />',
440 'id' => __('ID', 'delete-old-posts'),
441 'post_slug' => __('Deleted post slug', 'delete-old-posts'),
442 'check' => __('Redirection', 'delete-old-posts'),
443 );
444
445 return $columns;
446 }
447
448 /**
449 * Define which columns are hidden
450 *
451 * @return array
452 */
453 public function get_hidden_columns()
454 {
455 return array();
456 }
457
458 /**
459 * Define the sortable columns
460 *
461 * @return array
462 */
463 public function get_sortable_columns()
464 {
465 $sortable_columns = array(
466 'id' => array('id', false),
467 'post_slug' => array('post_slug', false)
468 );
469
470 return $sortable_columns;
471 }
472
473 /**
474 * Get the table data
475 *
476 * @return array
477 */
478 private function table_data( $search = '' )
479 {
480 $data = array();
481
482 // get deleted posts array and edited redirections array
483 $deletedPostsNames = get_option('deletedpostredirectsopt');
484 $redirectsOptEdited = get_option('deletedpostredirectsoptedited');
485
486 // get the permalink structure
487 $permalink_structure = get_option( 'permalink_structure' );
488 if( stristr( $permalink_structure, '%postname%' ) === false ) {
489 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') ) );
490 return $data; // return empty data
491 }
492
493 if( is_array($deletedPostsNames) ) foreach( $deletedPostsNames as $key => $deletedPostSlug) {
494 if ( ! empty($search) && ! stristr($deletedPostSlug, $search) ) continue;
495 $checkTxt = 'Check redirection';
496 $checkUrl = get_home_url() .'/'. $deletedPostSlug;
497 if( isset($redirectsOptEdited[$key]) && esc_url($redirectsOptEdited[$key]) != '' ) {
498 $checkTxt = esc_url($redirectsOptEdited[$key]);
499 }
500
501 $data[] = array(
502 'id' => $key,
503 'post_slug' => $deletedPostSlug,
504 'check' => '<a href="' . $checkUrl . '" target="_blank" class="text-sky-500">'.__($checkTxt, 'delete-old-posts').'</a>',
505 );
506 }
507
508 return $data;
509 }
510
511 /**
512 * Define what data to show on each column of the table
513 *
514 * @param array $item Data
515 * @param string $column_name - Current column name
516 *
517 * @return Mixed
518 */
519 public function column_default( $item, $column_name )
520 {
521 switch( $column_name ) {
522 case 'id':
523 case 'post_slug':
524 case 'check':
525 return $item[ $column_name ];
526
527 default:
528 return print_r( $item, true ) ;
529 }
530 }
531
532 /**
533 * Allows you to sort the data by the variables set in the $_GET
534 *
535 * @return mixed
536 */
537 private function sort_data( $a, $b ) {
538 // Set defaults
539 $orderby = 'post_slug';
540 $order = 'asc';
541 $result = strcmp( $a[$orderby], $b[$orderby] );
542
543 // If orderby is set, use this as the sort column
544 if(!empty($_GET['orderby']))
545 {
546 $orderby = $_GET['orderby'];
547 }
548
549 // If order is set use this as the order
550 if(!empty($_GET['order']))
551 {
552 $order = $_GET['order'];
553 }
554
555 if( isset($_GET['orderby']) ) switch( $_GET['orderby'] ){
556 case 'id':
557 $result = strnatcmp( $a[$orderby], $b[$orderby] );
558 break;
559 }
560
561 if($order === 'asc') {
562 return $result;
563 }
564
565 return -$result;
566 }
567
568 /**
569 * create checkboxes for table rows
570 * checkbox will come in handy when we need to create bulk actions to our table.
571 */
572 function column_cb($item)
573 {
574 return sprintf('<input type="checkbox" name="redirect_id[]" value="%s" />', $item['id']);
575 }
576
577 /**
578 * Adding action links to column
579 */
580 function column_post_slug( array $item){
581 if( !isset($_REQUEST['page']) || !isset($item['id']) || !isset($item['post_slug']) ) return false; //exit earlier
582
583 $actions = array(
584 '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>',
585 '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>',
586 );
587
588 return sprintf('%1$s %2$s', $item['post_slug'], $this->row_actions($actions));
589 }
590
591 /**
592 * show bulk action dropdown
593 */
594 function get_bulk_actions() {
595 $actions = array(
596 'delete_all' => __('Delete', 'delete-old-posts'),
597 );
598
599 return $actions;
600 }
601 }
602 ?>