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