/wp-content/plugins/the-events-calendar/src/Tribe/Amalgamator.php
https://github.com/livinglab/openlab · PHP · 305 lines · 190 code · 34 blank · 81 comment · 21 complexity · afca76f2acdd4b393f6d9d62738a9ba8 MD5 · raw file
- <?php
- /**
- * Merge pre-3.0 duplicate venues and organizers
- */
- class Tribe__Events__Amalgamator {
- private $default_venue = 0;
- private $default_community_venue = 0;
- private $default_organizer = 0;
- private $default_community_organizer = 0;
- /**
- * constructor
- */
- public function __construct() {
- $this->default_venue = (int) tribe_get_option( 'eventsDefaultVenueID', 0 );
- $this->default_organizer = (int) tribe_get_option( 'eventsDefaultOrganizerID', 0 );
- if ( class_exists( 'Tribe__Events__Community__Main' ) ) {
- $community = Tribe__Events__Community__Main::instance();
- $this->default_community_venue = (int) $community->getOption( 'defaultCommunityVenueID', 0 );
- $this->default_community_organizer = (int) $community->getOption( 'defaultCommunityOrganizerID', 0 );
- }
- }
- /**
- * Merge all duplicate event-related posts
- *
- */
- public function merge_duplicates() {
- $this->merge_identical_organizers();
- $this->merge_identical_venues();
- $events = Tribe__Events__Main::instance();
- wp_cache_flush();
- }
- /**
- * Merge identical organizers
- *
- */
- public function merge_identical_organizers() {
- $titles = $this->get_redundant_titles( Tribe__Events__Main::ORGANIZER_POST_TYPE );
- $buckets = [];
- foreach ( $titles as $t ) {
- $organizer_ids = $this->get_posts_with_title( $t, Tribe__Events__Main::ORGANIZER_POST_TYPE );
- foreach ( $organizer_ids as $id ) {
- $post = get_post( $id );
- $data = [
- 'title' => $post->post_title,
- 'status' => $post->post_status,
- 'content' => $post->post_content,
- '_OrganizerPhone' => get_post_meta( $id, '_OrganizerPhone', true ),
- '_OrganizerWebsite' => get_post_meta( $id, '_OrganizerWebsite', true ),
- '_OrganizerEmail' => get_post_meta( $id, '_OrganizerEmail', true ),
- ];
- $hash = md5( serialize( $data ) );
- if ( ! isset( $buckets[ $hash ] ) ) {
- $buckets[ $hash ] = [];
- }
- // prioritize organizers with an eventbrite id
- $eventbrite = get_post_meta( $id, '_OrganizerEventBriteID', true );
- if ( empty( $eventbrite ) ) {
- array_push( $buckets[ $hash ], $id );
- } else {
- array_unshift( $buckets[ $hash ], $id );
- }
- }
- }
- foreach ( $buckets as $organizer_ids ) {
- $this->amalgamate_organizers( $organizer_ids );
- }
- }
- /**
- * Merge identical venues
- *
- */
- public function merge_identical_venues() {
- $titles = $this->get_redundant_titles( Tribe__Events__Main::VENUE_POST_TYPE );
- $buckets = [];
- foreach ( $titles as $t ) {
- $venue_ids = $this->get_posts_with_title( $t, Tribe__Events__Main::VENUE_POST_TYPE );
- foreach ( $venue_ids as $id ) {
- $post = get_post( $id );
- $data = [
- 'title' => $post->post_title,
- 'status' => $post->post_status,
- 'content' => $post->post_content,
- '_VenueAddress' => get_post_meta( $id, '_VenueAddress', true ),
- '_VenueCity' => get_post_meta( $id, '_VenueCity', true ),
- '_VenueProvince' => get_post_meta( $id, '_VenueProvince', true ),
- '_VenueState' => get_post_meta( $id, '_VenueState', true ),
- '_VenueCountry' => get_post_meta( $id, '_VenueCountry', true ),
- '_VenueZip' => get_post_meta( $id, '_VenueZip', true ),
- '_VenuePhone' => get_post_meta( $id, '_VenuePhone', true ),
- '_VenueURL' => get_post_meta( $id, '_VenueURL', true ),
- ];
- $hash = md5( serialize( $data ) );
- if ( ! isset( $buckets[ $hash ] ) ) {
- $buckets[ $hash ] = [];
- }
- // prioritize venues with an eventbrite id
- $eventbrite = get_post_meta( $id, '_VenueEventBriteID', true );
- if ( empty( $eventbrite ) ) {
- array_push( $buckets[ $hash ], $id );
- } else {
- array_unshift( $buckets[ $hash ], $id );
- }
- }
- }
- foreach ( $buckets as $venue_ids ) {
- $this->amalgamate_venues( $venue_ids );
- }
- }
- /**
- * Get all post titles of the given post type that have duplicates
- *
- * @param string $type The post type to query
- *
- * @return array
- */
- private function get_redundant_titles( $type ) {
- global $wpdb;
- $sql = "SELECT post_title FROM {$wpdb->posts} WHERE post_type=%s GROUP BY post_title HAVING COUNT(*) > 1";
- $sql = $wpdb->prepare( $sql, $type );
- $titles = $wpdb->get_col( $sql );
- return $titles;
- }
- /**
- * Find all posts of the given type with the given title
- *
- * @param string $title
- * @param string $type
- *
- * @return array
- */
- private function get_posts_with_title( $title, $type ) {
- global $wpdb;
- $sql = "SELECT ID FROM {$wpdb->posts} WHERE post_type=%s AND post_title=%s ORDER BY ID ASC";
- $sql = $wpdb->prepare( $sql, $type, $title );
- $posts = $wpdb->get_col( $sql );
- return $posts;
- }
- /**
- * Merge all venues in the given list into one post (keeping the first)
- *
- * @param array $venue_ids
- *
- */
- private function amalgamate_venues( $venue_ids ) {
- if ( empty( $venue_ids ) || count( $venue_ids ) < 2 ) {
- return;
- }
- global $wpdb;
- array_map( 'intval', $venue_ids );
- $keep = array_shift( $venue_ids );
- $old_ids = implode( ',', $venue_ids );
- $sql = "UPDATE {$wpdb->postmeta} SET meta_value=%d WHERE meta_key=%s AND meta_value IN($old_ids)";
- $sql = $wpdb->prepare( $sql, $keep, '_EventVenueID' );
- $wpdb->query( $sql );
- $this->update_default_venues( $keep, $venue_ids );
- $this->delete_posts( $venue_ids );
- }
- /**
- * Merge all organizers in the given list into one post (keeping the first)
- *
- * @param array $organizer_ids
- *
- */
- public function amalgamate_organizers( $organizer_ids ) {
- if ( empty( $organizer_ids ) || count( $organizer_ids ) < 2 ) {
- return;
- }
- global $wpdb;
- array_map( 'intval', $organizer_ids );
- $keep = array_shift( $organizer_ids );
- $old_ids = implode( ',', $organizer_ids );
- $sql = "UPDATE {$wpdb->postmeta} SET meta_value=%d WHERE meta_key=%s AND meta_value IN($old_ids)";
- $sql = $wpdb->prepare( $sql, $keep, '_EventOrganizerID' );
- $wpdb->query( $sql );
- $this->update_default_organizers( $keep, $organizer_ids );
- $this->delete_posts( $organizer_ids );
- }
- /**
- * If a removed venue is being used as a default, change the default to
- * its replacement.
- *
- * @param int $keep
- * @param array $replace
- *
- */
- private function update_default_venues( $keep, array $replace ) {
- if ( $this->default_venue && in_array( $this->default_venue, $replace ) ) {
- $events = Tribe__Events__Main::instance();
- $events->setOption( 'eventsDefaultVenueID', $keep );
- }
- if ( $this->default_community_venue && in_array( $this->default_community_venue, $replace ) ) {
- $community = Tribe__Events__Community__Main::instance();
- $community->setOption( 'defaultCommunityVenueID', $keep );
- }
- }
- /**
- * If a removed organizer is being used as a default, change the default to
- * its replacement.
- *
- * @param int $keep
- * @param array $replace
- *
- */
- private function update_default_organizers( $keep, array $replace ) {
- if ( $this->default_organizer && in_array( $this->default_organizer, $replace ) ) {
- $events = Tribe__Events__Main::instance();
- $events->setOption( 'eventsDefaultOrganizerID', $keep );
- }
- if ( $this->default_community_organizer && in_array( $this->default_community_organizer, $replace ) ) {
- $community = Tribe__Events__Community__Main::instance();
- $community->setOption( 'defaultCommunityOrganizerID', $keep );
- }
- }
- /**
- * Delete all the posts given
- *
- * @param array $post_ids
- */
- private function delete_posts( $post_ids ) {
- foreach ( $post_ids as $id ) {
- $force = apply_filters( 'tribe_force_delete_duplicates', true );
- wp_delete_post( $id, $force );
- }
- }
- /**
- * Make a button to trigger the amalgamation process
- *
- * @param string $text
- *
- * @return string
- */
- public static function migration_button( $text = '' ) {
- $text = $text ? $text : __( 'Merge Duplicates', 'the-events-calendar' );
- $settings = Tribe__Settings::instance();
- // get the base settings page url
- $url = apply_filters(
- 'tribe_settings_url', add_query_arg(
- [
- 'post_type' => Tribe__Events__Main::POSTTYPE,
- 'page' => $settings->adminSlug,
- ], admin_url( 'edit.php' )
- )
- );
- $url = add_query_arg( [ 'amalgamate' => '1' ], $url );
- $url = wp_nonce_url( $url, 'amalgamate_duplicates' );
- return sprintf( '<a href="%s" class="button">%s</a>', $url, $text );
- }
- /**
- * If the migration button is clicked, start working
- *
- */
- public static function listen_for_migration_button() {
- if ( empty( $_REQUEST['amalgamate'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'amalgamate_duplicates' ) ) {
- return;
- }
- $amalgamator = new self();
- $amalgamator->merge_duplicates();
- // redirect to base settings page
- $settings = Tribe__Settings::instance();
- $url = apply_filters(
- 'tribe_settings_url', add_query_arg(
- [
- 'post_type' => Tribe__Events__Main::POSTTYPE,
- 'page' => $settings->adminSlug,
- ], admin_url( 'edit.php' )
- )
- );
- wp_redirect( esc_url_raw( $url ) );
- exit();
- }
- }