Advertisement
BakerMan

Modified cleanup script

Apr 17th, 2014
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 7.28 KB | None | 0 0
  1. <?php
  2. /*
  3. Plugin Name: The Events Calendar - Cleanup Recurrence Duplicates
  4. Description: Some users upgrading from an earlier version of Events Calendar PRO may, in rare circumstances, end up with duplicates of recurring events.
  5. Version: 3.5
  6. Author: Modern Tribe, Inc.
  7. Author URI: http://tri.be?ref=tec-plugin
  8. Text Domain: tribe-events-calendar-recurrence-cleanup
  9. License: GPLv2 or later
  10. */
  11.  
  12. if ( !class_exists('TribeEventsPro_DuplicateRecurringEventCleanup') ) {
  13.     class TribeEventsPro_DuplicateRecurringEventCleanup {
  14.         /** @var TribeEventsPro_DuplicateRecurringEventCleanup */
  15.         private static $instance = NULL;
  16.  
  17.         public static function instance() {
  18.             if ( empty(self::$instance) ) {
  19.                 self::$instance = new self();
  20.             }
  21.             return self::$instance;
  22.         }
  23.         public static function init() {
  24.             $self = self::instance();
  25.             if ( $self->is_valid_install() ) {
  26.                 $self->add_hooks();
  27.             }
  28.         }
  29.  
  30.         private function is_valid_install() {
  31.             if ( class_exists('TribeEventsPro') && defined('TribeEventsPro::VERSION') ) {
  32.                 if ( version_compare(TribeEventsPro::VERSION, '3.5') && class_exists( 'TribeEventsPro_RecurrenceInstance' ) ) {
  33.                     return TRUE;
  34.                 }
  35.             }
  36.             return FALSE;
  37.         }
  38.  
  39.         private function add_hooks() {
  40.             add_filter( 'tribe_settings_tab_fields', array( $this, 'add_seetings_tab_fields' ), 10, 2 );
  41.             add_action( 'load-tribe_events_page_tribe-events-calendar', array( $this, 'listen_for_cleanup_button' ), 10, 0 );
  42.         }
  43.  
  44.         public function add_seetings_tab_fields( $fields, $tab ) {
  45.             switch ( $tab ) {
  46.                 case 'general':
  47.                     $fields = TribeEvents::array_insert_after_key( 'amalgamateDuplicates', $fields, array(
  48.                         'amalgamateRecurrenceDuplicates' => array(
  49.                             'type' => 'html',
  50.                             'html' => '<fieldset class="tribe-field tribe-field-html"><legend>'.__('Duplicate Recurring Events', 'tribe-events-calendar-recurrence-cleanup').'</legend><div class="tribe-field-wrap">'.$this->cleanup_button(__('Merge Duplicate Recurring Events', 'tribe-events-calendar-recurrence-cleanup')).'<p class="tribe-field-indent description">'.__('Some users upgrading from an earlier version of Events Calendar PRO may, in rare circumstances, end up with duplicates of recurring events. Press this button to clean up those duplicate events.', 'tribe-events-calendar-recurrence-cleanup').'</p></div></fieldset><div class="clear"></div>',
  51.                         ),
  52.                     ) );
  53.                     break;
  54.             }
  55.             return $fields;
  56.         }
  57.  
  58.         private function cleanup_button( $text = '' ) {
  59.             $text = $text?$text:__('Merge Duplicate Recurring Events', 'tribe-events-calendar-recurrence-cleanup');
  60.             $html = '<a href="%s" class="button">%s</a>';
  61.             $settings = TribeSettings::instance();
  62. // get the base settings page url
  63.             $url = apply_filters( 'tribe_settings_url', add_query_arg( array( 'post_type' => TribeEvents::POSTTYPE, 'page' => $settings->adminSlug ), admin_url( 'edit.php' ) ) );
  64.             $url = add_query_arg(array('recurrenceCleanup' => '1'), $url);
  65.             $url = wp_nonce_url($url, 'recurrenceCleanup');
  66.             $html = sprintf($html, $url, $text);
  67.             return $html;
  68.         }
  69.  
  70.         public function listen_for_cleanup_button() {
  71.             if ( empty($_REQUEST['recurrenceCleanup']) || !wp_verify_nonce($_REQUEST['_wpnonce'], 'recurrenceCleanup') ) {
  72.                 return;
  73.             }
  74.  
  75.             $more = $this->do_cleanup();
  76.  
  77.             if ( $more ) {
  78.                 $this->trigger_reload();
  79.             } else {
  80.                 $this->redirect_to_settings_page();
  81.             }
  82.         }
  83.  
  84.         protected function trigger_reload() {
  85.             $url = $_SERVER['REQUEST_URI'];
  86.             $redirect = '<script type="text/javascript">';
  87.             $redirect .= 'window.location.href="'.$url.'";';
  88.             $redirect .= '</script>';
  89.             $redirect .= '<noscript>';
  90.             $redirect .= '<meta http-equiv="refresh" content="0;url='.$url.'" />';
  91.             $redirect .= '</noscript>';
  92.  
  93.             wp_die(__('Cleaning up events. This may take a while. Please do not close your browser window while cleanup is in progress.', 'tribe-events-calendar-recurrence-cleanup').$redirect, __('Cleaning up events', 'tribe-events-calendar-recurrence-cleanup'), array('response' => 200) );
  94.             exit();
  95.         }
  96.  
  97.         protected function redirect_to_settings_page() {
  98. // redirect to base settings page
  99.             $settings = TribeSettings::instance();
  100.             $url = apply_filters( 'tribe_settings_url', add_query_arg( array( 'post_type' => TribeEvents::POSTTYPE, 'page' => $settings->adminSlug ), admin_url( 'edit.php' ) ) );
  101.             wp_redirect($url);
  102.             exit();
  103.         }
  104.  
  105.         protected function do_cleanup() {
  106.             TribeEventsRecurrenceMeta::get_scheduler()->remove_hooks();
  107.             $third_level_event_ids = $this->get_third_level_event_ids();
  108.             if ( !empty($third_level_event_ids) ) {
  109.                 foreach ( $third_level_event_ids as $eid ) {
  110.                     $this->remove_third_level_event($eid);
  111.                 }
  112.                 return TRUE;
  113.             }
  114.  
  115.             $duplicate_meta_ids = $this->get_duplicate_meta_ids();
  116.             if ( !empty($duplicate_meta_ids) ) {
  117.                 foreach ( $duplicate_meta_ids as $eid ) {
  118.                     $this->remove_duplicate_meta($eid);
  119.                 }
  120.             }
  121.  
  122.             $duplicate_event_ids = $this->get_duplicate_event_ids();
  123.             if ( !empty($duplicate_event_ids) ) {
  124.                 foreach ( $duplicate_event_ids as $eid ) {
  125.                     $this->cleanup_event($eid);
  126.                 }
  127.                 return TRUE;
  128.             }
  129.  
  130.             return FALSE;
  131.         }
  132.  
  133.         private function get_duplicate_event_ids() {
  134.             global $wpdb;
  135.             $sql = "SELECT p.ID FROM {$wpdb->posts} p INNER JOIN {$wpdb->postmeta} m ON p.ID=m.post_id AND m.meta_key='_EventStartDate' WHERE p.post_parent <> 0 AND p.post_status <> 'trash' GROUP BY p.post_parent, m.meta_value HAVING COUNT(*) > 1";
  136.             $duplicate_instance_ids = $wpdb->get_col($sql);
  137.  
  138.             if ( empty($duplicate_instance_ids) ) {
  139.                 return array();
  140.             }
  141.             $duplicate_string = implode(',', $duplicate_instance_ids);
  142.             $parent_sql = "SELECT DISTINCT post_parent FROM {$wpdb->posts} p WHERE p.ID IN ($duplicate_string) LIMIT 10";
  143.             $result = $wpdb->get_col($parent_sql);
  144.             return $result;
  145.         }
  146.  
  147.         public function cleanup_event( $event_id ) {
  148.             TribeEventsRecurrenceMeta::saveEvents($event_id);
  149.         }
  150.  
  151.         private function get_third_level_event_ids() {
  152.             global $wpdb;
  153.  
  154.             $sql = "SELECT p.ID FROM {$wpdb->posts} p INNER JOIN {$wpdb->posts} p2 ON p.post_parent=p2.ID "
  155.                 . "WHERE p.post_parent <> 0 AND p2.post_parent <> 0 AND p.post_type=%s AND p2.post_type=%s LIMIT 10";
  156.  
  157.             return $wpdb->get_col( $wpdb->prepare( $sql, TribeEvents::POSTTYPE, TribeEvents::POSTTYPE ) );
  158.         }
  159.  
  160.         public function remove_third_level_event( $event_id ) {
  161.             global $wpdb;
  162.  
  163.             $children = $wpdb->get_col( $wpdb->prepare(
  164.                 "SELECT ID FROM {$wpdb->posts} WHERE post_parent=%d AND post_type=%s", $event_id, TribeEvents::POSTTYPE
  165.             ) );
  166.  
  167.             foreach ( $children as $child ) {
  168.                 $this->remove_third_level_event( $child );
  169.             }
  170.  
  171.             if ( TribeEvents::POSTTYPE === get_post_type( $event_id ) ) wp_delete_post( $event_id, TRUE );
  172.         }
  173.  
  174.         private function get_duplicate_meta_ids() {
  175.             global $wpdb;
  176.             $sql = "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key='_EventStartDate' GROUP BY post_id HAVING COUNT(*) > 1 LIMIT 100";
  177.             return $wpdb->get_col($sql);
  178.         }
  179.  
  180.         public function remove_duplicate_meta( $event_id ) {
  181.             $meta = get_post_meta( $event_id, '_EventStartDate', FALSE );
  182.             if ( count($meta) > 1 ) {
  183.                 delete_post_meta( $event_id, '_EventStartDate' );
  184.                 add_post_meta( $event_id, '_EventStartDate', $meta[0] );
  185.             }
  186.         }
  187.     }
  188.  
  189.     add_action('admin_init', array('TribeEventsPro_DuplicateRecurringEventCleanup', 'init'));
  190. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement