File Editor
Directories:
.. (Back)
Admin
Aggregator
Ajax
Collections
Customizer
Dates
Editor
Event_Status
Event_Tickets
Featured_Events
Google
Importer
Integrations
JSON_LD
Linked_Posts
Meta
Models
REST
Repositories
Revisions
Service_Providers
Shortcode
Taxonomy
Template
Utils
Validator
Views
Files:
API.php
Adjacent_Events.php
Admin_List.php
Aggregator.php
Amalgamator.php
Assets.php
Capabilities.php
Constants.php
Cost_Utils.php
Deactivation.php
Default_Values.php
Editor.php
Embedded_Maps.php
Event_Cleaner.php
Event_Cleaner_Scheduler.php
Featured_Events.php
Front_Page_View.php
Gutenberg.php
I18n.php
Ignored_Events.php
Linked_Posts.php
Main.php
Options_Exception.php
Organizer.php
Plugin_Register.php
Post_Exception.php
Privacy.php
Query.php
Rewrite.php
Template_Factory.php
Templates.php
Timezones.php
Updater.php
Venue.php
iCal.php
Create New File
Create
Edit File: Ignored_Events.php
<?php // Don't load directly if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } if ( ! class_exists( 'Tribe__Events__Ignored_Events' ) ) { /** * Ignored Events are fully powered by this class */ class Tribe__Events__Ignored_Events { public static $ignored_status = 'tribe-ignored'; public static $legacy_deleted_post = 'deleted_event'; public static $legacy_origin = 'ical-importer'; /** * Where we save the previous Status when ignoring an Event * * @since 4.5.13 * @var string */ public static $key_previous_status = '_tribe_ignored_event_previous_status'; /** * Static Singleton Factory Method * * @return self */ public static function instance() { return tribe( 'tec.ignored-events' ); } public function action_assets() { $plugin = Tribe__Events__Main::instance(); $localize = []; if ( ! empty( $_GET['post'] ) && $this->can_ignore( $_GET['post'] ) ) { $post = get_post( $_GET['post'] ); if ( self::$ignored_status === $post->post_status ) { $localize['single'] = [ 'link_text' => esc_html__( 'Delete Permanently', 'the-events-calendar' ), 'link_title' => esc_attr__( 'Ignored events that are deleted will be removed permanently. They can be recreated via import.', 'the-events-calendar' ), 'link_nonce' => wp_create_nonce( 'delete-post_' . $post->ID ), 'link_post' => $post->ID, 'link_status' => esc_html__( 'Ignored', 'the-events-calendar' ), ]; } else { $localize['single'] = [ 'link_text' => esc_html__( 'Hide & Ignore', 'the-events-calendar' ), 'link_title' => esc_attr__( 'Ignored events do not show on the calendar but can be updated with future imports', 'the-events-calendar' ), ]; } } if ( isset( $_GET['post_status'] ) && self::$ignored_status === $_GET['post_status'] ) { $localize['archive'] = [ 'delete_label' => esc_html__( 'Delete Permanently', 'the-events-calendar' ), ]; } $args = [ 'localize' => [ 'name' => 'tribe_ignore_events', 'data' => $localize, ], 'conditionals' => static function() { /** @var Tribe__Admin__Helpers $admin_helpers */ $admin_helpers = tribe( 'admin.helpers' ); return $admin_helpers->is_screen() || $admin_helpers->is_post_type_screen(); } ]; tribe_asset( $plugin, 'tribe-ignored-events', 'admin-ignored-events.js', [ 'jquery' ], 'admin_enqueue_scripts', $args ); } /** * Filter the displayed bulk actions on the Ignored Events status * * @param array $actions List of bulk actions * * @return array */ public function filter_bulk_actions( $actions ) { if ( ! isset( $_GET['post_status'] ) || self::$ignored_status !== $_GET['post_status'] ) { return $actions; } $post_type_obj = get_post_type_object( Tribe__Events__Main::POSTTYPE ); if ( isset( $actions['trash'] ) ) { unset( $actions['trash'] ); } return $actions; } /** * Makes sure that we have the Required Messages displaying correctly for the Legacy Events Warning * * @param array $messages Array of arrays, with the CPT messages for each status * @param array $counts Array with the Counts of each one of the messages * * @return array */ public function filter_updated_messages( $messages, $counts ) { if ( ! Tribe__Admin__Helpers::instance()->is_post_type_screen( Tribe__Events__Main::POSTTYPE ) ) { return $messages; } if ( ! isset( $_GET['ids'] ) ) { return $messages; } $check_counts = array_filter( $counts ); if ( empty( $check_counts ) ) { return $messages; } if ( ! isset( $counts['trashed'] ) || 0 === $counts['trashed'] ) { return $messages; } $ids = (array) explode( ',', $_GET['ids'] ); $ignored = array_filter( $ids, [ $this, 'can_ignore' ] ); $count_ignored = count( $ignored ); if ( 0 >= $count_ignored ) { return $messages; } $counts['trashed'] -= $count_ignored; $messages[ Tribe__Events__Main::POSTTYPE ] = $messages['post']; // we are going to continue to use the language "posts" as that's what WordPress uses for custom post types in this messaging. if ( 0 === $counts['trashed'] ) { $messages[ Tribe__Events__Main::POSTTYPE ]['trashed'] = '%s ' . _n( 'post moved to Ignored.', 'posts moved to Ignored.', $count_ignored, 'the-events-calendar' ); } else { $GLOBALS['bulk_counts'] = $counts; $messages[ Tribe__Events__Main::POSTTYPE ]['trashed'] = _n( '%s post moved to the Trash', '%s posts moved to the Trash', $counts['trashed'], 'the-events-calendar' ) . ' '; $messages[ Tribe__Events__Main::POSTTYPE ]['trashed'] .= sprintf( _n( 'and %s post moved to Ignored.', 'and %s posts moved to Ignored.', $count_ignored, 'the-events-calendar' ), $count_ignored ); } $args = [ 'ids' => preg_replace( '/[^0-9,]/', '', $_REQUEST['ids'] ), 'tribe-action' => 'tribe-restore', 'post_type' => Tribe__Events__Main::POSTTYPE, ]; $url = wp_nonce_url( add_query_arg( $args, 'edit.php' ), 'tribe-restore' ); // Cant `esc_url` this URL because it will make sprintf throw a warning on WP code $messages[ Tribe__Events__Main::POSTTYPE ]['trashed'] .= ' <a href="' . urldecode( $url ) . '" class="tribe-restore-link">' . esc_html__( 'Undo', 'the-events-calendar' ) . '</a>'; return $messages; } /** * Returns the HTML for a notice depending on the if we have Legacy Items to be Migrated * * @return string */ public function render_notice_legacy() { if ( ! Tribe__Admin__Helpers::instance()->is_post_type_screen( Tribe__Events__Main::POSTTYPE ) ) { return false; } if ( empty( $_GET['post_status'] ) || $_GET['post_status'] !== self::$ignored_status ) { return false; } if ( ! $this->has_legacy_deleted_posts() ) { return false; } $html = '<p>' . esc_html__( 'Event Aggregator includes a new, better system for removing unwanted imported events from your calendar. Click the button below to transition previously deleted events. This process will remove unwanted records from your database and include recent or upcoming trashed events in your Ignored archive.', 'the-events-calendar' ); $html .= ' <a href="https://theeventscalendar.com/knowledgebase/ignored-events/" target="_blank">' . esc_html_x( 'Read more about Ignored Events.', 'link to knowlegebase article', 'the-events-calendar' ) . '</a></p>'; $html .= '<p style="display:inline-block;">' . get_submit_button( esc_html__( 'Migrate Legacy Ignored Events' ), 'secondary', 'tribe-migrate-legacy-events', false ) . '<span class="spinner"></span></p>'; return Tribe__Admin__Notices::instance()->render( 'legacy-ignored-events', $html ); } /** * Action to Restore Events on the Single Page * * @param WP_Screen $screen Which WP Screen we are currently in * * @return void|Redirect */ public function action_restore_events() { if ( ! wp_verify_nonce( tribe_get_request_var( '_wpnonce', '' ), 'restore-post_' . tribe_get_request_var( 'post', '' ) ) ) { return; } if ( ! isset( $_GET['action'] ) || 'tribe-restore' !== $_GET['action'] ) { return; } $event = get_post( absint( $_GET['post'] ) ); if ( ! $event instanceof WP_Post ) { return; } if ( Tribe__Events__Main::POSTTYPE !== $event->post_type ) { return; } if ( self::$ignored_status !== $event->post_status ) { return; } if ( ! function_exists( 'wp_get_referer' ) ) { if ( ! empty( $_SERVER['REQUEST_URI'] ) ) { $sendback = $_SERVER['REQUEST_URI']; } elseif ( ! empty( $_REQUEST['_wp_http_referer'] ) ) { $sendback = $_REQUEST['_wp_http_referer']; } elseif ( ! empty( $_SERVER['HTTP_REFERER'] ) ) { $sendback = $_SERVER['HTTP_REFERER']; } } else { $sendback = wp_get_referer(); } $sendback = remove_query_arg( [ 'trashed', 'untrashed', 'deleted', 'locked', 'ids' ], $sendback ); if ( isset( $_REQUEST['ids'] ) ) { $post_ids = explode( ',', $_REQUEST['ids'] ); } elseif ( ! empty( $_REQUEST['post'] ) ) { $post_ids = array_map( 'intval', (array) $_REQUEST['post'] ); } $restored = 0; foreach ( (array) $post_ids as $post_id ) { if ( ! current_user_can( 'delete_post', $post_id ) ) { wp_die( esc_html__( 'You do not have permission to restore this post.', 'the-events-calendar' ) ); } if ( ! $this->restore_event( $post_id ) ) { wp_die( esc_html__( 'Error restoring from Ignored Events.', 'the-events-calendar' ) ); } $restored++; } $sendback = add_query_arg( 'restored', $restored, $sendback ); wp_redirect( $sendback ); exit; } /** * Allows Bulk Actions to Work it's magic (more Complex than it needs to be) * * @return void|false */ public function action_restore_ignored() { if ( ! Tribe__Admin__Helpers::instance()->is_post_type_screen( Tribe__Events__Main::POSTTYPE ) ) { return false; } if ( ! isset( $_GET['ids'] ) ) { return false; } if ( ! isset( $_GET['tribe-action'] ) || 'tribe-restore' !== $_GET['tribe-action'] ) { return false; } if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'tribe-restore' ) ) { return false; } $ids = (array) explode( ',', $_GET['ids'] ); $restored = []; foreach ( $ids as $id ) { if ( ! current_user_can( 'delete_post', $id ) ) { wp_die( esc_html__( 'You do not have permission to restore this post.', 'the-events-calendar' ) ); } $restore = $this->restore_event( $id ); if ( ! $restore ) { wp_die( esc_html__( 'Error restoring from Ignored Events.', 'the-events-calendar' ) ); } $restored[] = $restore; } $count_restored = count( $restored ); $message = '<p>' . sprintf( _n( '%s post restored.', '%s posts restored.', $count_restored, 'the-events-calendar' ), $count_restored ) . '</p>'; if ( ! empty( $_SERVER['REQUEST_URI'] ) ) { $_SERVER['REQUEST_URI'] = remove_query_arg( [ 'tribe-action', '_wpnonce' ], $_SERVER['REQUEST_URI'] ); } elseif ( ! empty( $_REQUEST['_wp_http_referer'] ) ) { $_REQUEST['_wp_http_referer'] = remove_query_arg( [ 'tribe-action', '_wpnonce', ], $_REQUEST['_wp_http_referer'] ); } elseif ( ! empty( $_SERVER['HTTP_REFERER'] ) ) { $_SERVER['HTTP_REFERER'] = remove_query_arg( [ 'tribe-action', '_wpnonce' ], $_SERVER['HTTP_REFERER'] ); } return tribe_notice( 'restored-events', $message, 'dismiss=1&type=success' ); } /** * Which Columns are Available on Ignored Events view * * @param array $columns Columns and it's labels * * @return array */ public function filter_columns( $columns ) { if ( empty( $_GET['post_status'] ) || $_GET['post_status'] !== self::$ignored_status ) { return $columns; } // Remove unwanted Columns unset( $columns['author'], $columns['events-cats'], $columns['tags'], $columns['comments'], $columns['recurring'] ); // Add New Columns backwards $columns = Tribe__Main::array_insert_after_key( 'title', $columns, [ 'source' => esc_html__( 'Source', 'the-events-calendar' ) ] ); $info = ' <span class="dashicons dashicons-editor-help" title="' . esc_attr__( 'The last time this event was imported and/or updated via import.', 'the-events-calendar' ) . '"></span>'; $columns = Tribe__Main::array_insert_after_key( 'title', $columns, [ 'last-import' => esc_html__( 'Last Import', 'the-events-calendar' ) . $info ] ); return $columns; } /** * Filters the Contents of the Columns for the Ignored Events View * * @param string $column Which column we are dealing with * @param int|WP_Post $post WP Post ID or Object * * @return string|null|false */ public function action_column_contents( $column, $post ) { $record = Tribe__Events__Aggregator__Records::instance()->get_by_event_id( $post ); if ( tribe_is_error( $record ) ) { return false; } $html = []; if ( 'source' === $column ) { $html[] = '<p>' . esc_html_x( 'via ', 'record via origin', 'the-events-calendar' ) . '<strong>' . $record->get_label() . '</strong></p>'; if ( 'ea/ics' === $record->post->post_mime_type || 'ea/csv' === $record->post->post_mime_type ) { $file_path = get_attached_file( absint( $record->meta['file'] ) ); $filename = basename( $file_path ); $html[] = '<p>' . esc_html__( 'Source:', 'the-events-calendar' ) . ' <code>' . esc_html( $filename ) . '</code></p>'; } else { $html[] = '<p>' . esc_html__( 'Source:', 'the-events-calendar' ) . ' <code>' . esc_html( $record->meta['source'] ) . '</code></p>'; } } elseif ( 'last-import' === $column ) { $last_import = null; $original = $record->post->post_modified; $time = strtotime( $original ); $now = current_time( 'timestamp' ); $html[] = '<span title="' . esc_attr( $original ) . '">'; if ( ( $now - $time ) <= DAY_IN_SECONDS ) { $diff = human_time_diff( $time, $now ); if ( ( $now - $time ) > 0 ) { $html[] = sprintf( esc_html_x( 'about %s ago', 'human readable time ago', 'the-events-calendar' ), $diff ); } else { $html[] = sprintf( esc_html_x( 'in about %s', 'in human readable time', 'the-events-calendar' ), $diff ); } } else { $html[] = date( Tribe__Date_Utils::DATEONLYFORMAT, $time ) . '<br>' . date( Tribe__Date_Utils::TIMEFORMAT, $time ); } $html[] = '</span>'; } echo implode( "\r\n", (array) $html ); } /** * Add the required Row Actions for the Ignored Events View * * @param array $actions List of the current actions * @param int|WP_Post $post WP Post ID or Object * * @return array */ public function filter_actions( $actions, $post ) { $event = get_post( $post ); if ( ! $event instanceof WP_Post ) { return $actions; } if ( Tribe__Events__Main::POSTTYPE !== $event->post_type ) { return $actions; } $title = _draft_or_post_title(); if ( self::$ignored_status !== $event->post_status ) { // Modify when it can be ignored if ( $this->can_ignore( $event ) ) { $actions['trash'] = sprintf( '<a href="%1$s" class="submitdelete" aria-label="%2$s" title="%3$s">%4$s</a>', get_delete_post_link( $event->ID ), /* translators: %s: post title */ esc_attr( sprintf( __( 'Hide and Ignore “%s”', 'the-events-calendar' ), $title ) ), esc_attr__( 'Ignored events do not show on the calendar but can be updated with future imports', 'the-events-calendar' ), __( 'Hide & Ignore', 'the-events-calendar' ) ); } return $actions; } $origin = get_post_meta( $event->ID, '_EventOrigin', true ); foreach ( $actions as $key => $html ) { /** * @todo Add logic to prevent removal of edit on EA origin */ if ( 'edit' === $key && true === false ) { continue; } // Remove all Actions on unset( $actions[ $key ] ); } $post_type_object = get_post_type_object( $event->post_type ); if ( current_user_can( 'delete_post', $event->ID ) ) { $actions['restore'] = sprintf( '<a href="%s" aria-label="%s">%s</a>', wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&action=tribe-restore', $event->ID ) ), 'restore-post_' . $event->ID ), /* translators: %s: post title */ esc_attr( sprintf( __( 'Restore “%s” from the Ignored', 'the-events-calendar' ), $title ) ), __( 'Restore', 'the-events-calendar' ) ); $actions['delete'] = sprintf( '<a href="%s" class="submitdelete" aria-label="%s">%s</a>', get_delete_post_link( $event->ID, '', true ), /* translators: %s: post title */ esc_attr( sprintf( __( 'Delete “%s” permanently', 'the-events-calendar' ), $title ) ), __( 'Delete Permanently', 'the-events-calendar' ) ); } return $actions; } /** * Add the new Link to the Ignored events on the Events Page * * @param array $views Array of all the previous Views/Links * * @return array $views After adding the new Link */ public function filter_views( $views = [] ) { // This will prevent having the Ignored link twice on the Edit Page if ( $this->has_ignored_posts( false ) ) { return $views; } // Are there any legacy deleted posts? $counter = $this->count_legacy_deleted_posts(); if ( 0 >= $counter ) { return $views; } $args = [ 'post_type' => Tribe__Events__Main::POSTTYPE, 'post_status' => self::$ignored_status, ]; $url = add_query_arg( $args, 'edit.php' ); $views['import-deleted'] = '<a class="' . ( isset( $_GET['ignored_events'] ) ? 'current' : '' ) . '" href="' . esc_url( $url ) . '">' . esc_html__( 'Ignored', 'the-events-calendar' ) . sprintf( ' <span class="count">(%d)</span></a>', $counter ); return $views; } /** * Count legacy "ignored" posts * * @return int */ public function count_legacy_deleted_posts() { // Fetch any posts on the `deleted_event` CPT $counter = wp_count_posts( self::$legacy_deleted_post ); // Check if we have trash status set if ( ! isset( $counter->trash ) ) { return 0; } // Return it been a Int return absint( $counter->trash ); } /** * Check if there are any legacy posts * * @return boolean */ public function has_legacy_deleted_posts() { return $this->count_legacy_deleted_posts() > 0; } /** * Check if there are any ignored posts * * @param boolean $check_legacy If the method should also check legacy CPTs * @return boolean */ public function has_ignored_posts( $check_legacy = true ) { $has_legacy = $this->has_legacy_deleted_posts(); if ( true === $check_legacy && true === $has_legacy ) { return true; } $query = $this->get_query( [ 'fields' => 'ids' ] ); return $query->have_posts(); } /** * Gets all ids for events that have been ignored * * @param null|array $data Array of event IDs/objects/data to check * * @return array */ public function get( $args = [] ) { $query = $this->get_query( $args ); return $query->posts; } /** * Gets all ids for events that have been ignored * * @param null|array $data Array of event IDs/objects/data to check * * @return WP_Query */ public function get_query( $args = [] ) { $defaults = [ 'post_type' => Tribe__Events__Main::POSTTYPE, 'post_status' => self::$ignored_status, ]; $args = wp_parse_args( $args, $defaults ); return new WP_Query( $args ); } /** * Gets all ids for events that have been ignored * * @param null|array $data Array of event IDs/objects/data to check * @param array $args WP_Query args * * @return array */ public function get_by_id( $data = [], $args = [] ) { // if there isn't any data, there won't be any results. Bail if ( empty( $data ) ) { return []; } // fields we'll look for in objects/arrays $search = [ 'ID', 'id', 'post_id', ]; $ids = []; // if the passed in data is not an array, turn it into one if ( ! is_array( $data ) ) { $data = [ $data ]; } $first = reset( $data ); if ( is_scalar( $first ) ) { $ids = $data; } else { $id_field = null; $first = (object) $first; // look through the object for one of the possible ID fields and bail when/if we find it foreach ( $search as $field ) { if ( empty( $first->$field ) ) { continue; } $id_field = $field; break; } // if we've found an ID field, let's generate an array of those IDs if ( $id_field ) { $ids = wp_list_pluck( $data, $id_field ); } } // if there aren't any IDs, let's make sure we don't get any results if ( empty( $ids ) ) { return []; } if ( isset( $args['post__in'] ) ) { $args['post__in'] = array_merge( $args['post__in'], $ids ); } else { $args['post__in'] = $ids; } return $this->get( $args ); } /** * Changes the event to the correct Post Status * * @param int|WP_Post $event Which event try to convert * @return bool|int|WP_Error */ public function ignore_event( $event, $force = false ) { $event = get_post( $event ); if ( ! $force && ! $this->can_ignore( $event ) ) { return false; } // Update only what we need $arguments = [ 'ID' => $event->ID, 'post_type' => Tribe__Events__Main::POSTTYPE, 'post_status' => self::$ignored_status, ]; // Set the Required Meta to flag it to the Legacy Posts if ( self::$legacy_deleted_post === $event->post_type ) { update_post_meta( $event->ID, '_tribe_legacy_ignored_event', 1 ); } // Try to update back to the Event CPT $updated = wp_update_post( $arguments ); // Saves on a meta the previous Status if ( $updated && 'trash' !== $event->post_status ) { update_post_meta( $event->ID, self::$key_previous_status, $event->post_status ); } return $updated; } /** * Verify if we can Ignore an Event depending on all the Required rules * * @param int|WP_Post $post ID of the Event or it's Object * * @return bool */ public function can_ignore( $post ) { $event = get_post( $post ); // If we don't have a post (weird) we also leave if ( ! $event instanceof WP_Post ) { return false; } // Verify if it's a Legacy Ignore or Tribe Event if ( ! in_array( $event->post_type, [ Tribe__Events__Main::POSTTYPE, self::$legacy_deleted_post ] ) ) { return false; } $ignored_origins = [ Tribe__Events__Aggregator__Event::$event_origin, 'facebook-importer', 'ical-importer', ]; $origin = get_post_meta( $event->ID, '_EventOrigin', true ); // Verify the Origin if ( ! in_array( $origin, $ignored_origins ) ) { return false; } if ( Tribe__Events__Aggregator__Event::$event_origin === $origin ) { $aggregator_origin = get_post_meta( $event->ID, Tribe__Events__Aggregator__Event::$origin_key, true ); } return true; } /** * Restore Event * * @param int|WP_Post $event Which event try to convert * @return bool|int|WP_Error */ public function restore_event( $event ) { $event = get_post( $event ); if ( ! $event instanceof WP_Post ) { return false; } // If we are not in the Event CPT we don't care either if ( Tribe__Events__Main::POSTTYPE !== $event->post_type ) { return null; } $restore_status = get_post_meta( $event->ID, self::$key_previous_status, true ); if ( empty( $restore_status ) ) { /** * Which is the default Post status to Restore Ignored Events * * @param string $post_status * @param WP_Post $event */ $restore_status = apply_filters( 'tribe_events_ignored_events_default_restore_status', 'publish', $event ); } // Update only what we need $arguments = [ 'ID' => $event->ID, 'post_status' => $restore_status, ]; // Try to update back to the Event CPT $updated = wp_update_post( $arguments ); // Delete the Previous status stored if ( $updated ) { delete_post_meta( $event->ID, self::$key_previous_status ); } return $updated; } /** * Register the Ignored Post Status * * @return void */ public function register_ignored_post_status() { $arguments = [ 'label' => esc_html__( 'Ignored', 'the-events-calendar' ), 'label_count' => _n_noop( 'Ignored <span class="count">(%s)</span>', 'Ignored <span class="count">(%s)</span>', 'the-events-calendar' ), 'show_in_admin_all_list' => false, 'show_in_admin_status_list' => true, 'public' => false, 'internal' => false, ]; register_post_status( self::$ignored_status, $arguments ); // We need to register this to have the legacy work register_post_type( self::$legacy_deleted_post, [ 'public' => false, ] ); } /** * Making sure that we have the previous Status saved * * @since 4.5.13 * * @param int|WP_Post $event Which event to track the Previous status * * @return bool */ public function action_track_previous_status( $event ) { $event = get_post( $event ); if ( ! $event instanceof WP_Post ) { return false; } // If we are not in the Event CPT we don't care either if ( Tribe__Events__Main::POSTTYPE !== $event->post_type ) { return false; } if ( self::$ignored_status === $event->post_type ) { return false; } if ( 'trash' === $event->post_type ) { return false; } return update_post_meta( $event->ID, self::$key_previous_status, $event->post_status ); } /** * On version 4.4 of WP we get a new Filter to prevent an event from been trashed and/or deleted * * @param null|bool $check Boolean or Null depending if we need to delete or not * @param int $post WP Post ID * @param bool $force_delete Force the Event delete * * @return null|bool */ public function action_pre_delete_event( $unused_check, $post, $force_delete ) { // If someone is trying to delete it for-reals we actually delete it. if ( true === $force_delete ) { return null; } $post = get_post( $post ); if ( self::$ignored_status === $post->post_status ) { return wp_delete_post( $post->ID, true ); } // Important to note that this needs to return null for any invalid ignoring if ( ! $this->can_ignore( $post ) ) { return null; } $status = $this->ignore_event( $post ); // If we couldn't convert we actually trash it return ! is_wp_error( $status ) ? $status : null; } /** * Used to get an Trashed event and move it to the `post_status` of Ignored * * @param int $post ID of the Post * * @return bool|null */ public function action_from_trash_to_ignored( $post ) { $post = get_post( $post ); if ( self::$ignored_status === $post->post_status ) { return wp_delete_post( $post->ID, true ); } // Important to note that this needs to return null for any invalid ignoring if ( ! $this->can_ignore( $post ) ) { return null; } $status = $this->ignore_event( $post ); // If we couldn't convert we actually trash it return ! is_wp_error( $status ) ? $status : null; } /** * Method that Handles the AJAX converting of Legacy Ignored Events to the new `post_status` * AJAX methods will not return anything, only print a JSON string * * @return void */ public function ajax_convert_legacy_ignored_events() { $response = (object) [ 'status' => false, 'text' => esc_html__( 'Error, a unknown bug happened and it was impossible to migrate the Legacy Ignored Events, try again later.', 'the-events-calendar' ), ]; $post_type = get_post_type_object( Tribe__Events__Main::POSTTYPE ); if ( empty( $post_type->cap->edit_posts ) || ! current_user_can( $post_type->cap->edit_posts ) ) { $response->status = false; $response->text = esc_html__( 'You do not have permission to migrate Legacy Ignored Events', 'the-events-calendar' ); wp_send_json( $response ); } if ( ! $this->has_legacy_deleted_posts() ) { $response->status = true; $response->text = esc_html__( 'There were no Legacy Events to be Migrated, you are ready to rock!', 'the-events-calendar' ); wp_send_json( $response ); } $args = [ 'post_type' => self::$legacy_deleted_post, 'post_status' => 'trash', ]; $query = new WP_Query( $args ); foreach ( $query->posts as $event ) { $status = $this->ignore_event( $event, true ); if ( is_wp_error( $status ) ) { $response->error[ $event->ID ] = $status->get_error_message(); } else { $response->migrated[ $event->ID ] = true; } } if ( ! empty( $response->error ) ) { if ( ! empty( $response->migrated ) ) { $response->status = false; $response->text = sprintf( _n( 'Migration: %d Legacy Ignored Post was migrated but %d failed. To see the migrated event you will first need to refresh this screen.', 'Migration: %d Legacy Ignored Posts were migrated but %d failed. To see the migrated events you will first need to refresh this screen.', count( $response->migrated ), 'the-events-calendar' ), count( $response->migrated ), count( $response->error ) ); } else { $response->status = false; $response->text = sprintf( _n( 'Migration: %d Legacy Ignored Post failed to be migrated.', 'Migration: %d Legacy Ignored Posts failed to be migrated.', count( $response->error ), 'the-events-calendar' ), count( $response->error ) ); } $response->text .= '<ul>'; foreach ( $response->error as $ID => $message ) { $response->text .= '<li>' . sprintf( __( 'Event %d: %s', 'the-events-calendar' ), $ID, $message ) . '</li>'; } $response->text .= '</ul>'; } elseif ( ! empty( $response->migrated ) ) { $response->status = true; $response->text = sprintf( _n( 'Migration: %d Legacy Ignored Post was migrated successfully. To see the migrated event you will first need to refresh this screen.', 'Migration: %d Legacy Ignored Posts were migrated successfully. To see the migrated events you will first need to refresh this screen.', count( $response->migrated ), 'the-events-calendar' ), count( $response->migrated ) ); } wp_send_json( $response ); } /** * Hooks the filters and actions needed for the class to work. * * @return bool Whether the filters and actions were hooked or not. */ public function hook() { add_action( 'init', [ $this, 'register_ignored_post_status' ] ); add_action( 'current_screen', [ $this, 'action_restore_events' ] ); add_action( 'current_screen', [ $this, 'action_restore_ignored' ] ); /** * `pre_delete_post` only exists after WP 4.4 * * @see https://core.trac.wordpress.org/ticket/12706 */ add_filter( 'pre_delete_post', [ $this, 'action_pre_delete_event' ], 10, 3 ); add_action( 'trashed_post', [ $this, 'action_from_trash_to_ignored' ] ); add_action( 'wp_trash_post', [ $this, 'action_track_previous_status' ] ); add_filter( 'views_edit-' . Tribe__Events__Main::POSTTYPE, [ $this, 'filter_views' ] ); add_filter( 'bulk_actions-edit-' . Tribe__Events__Main::POSTTYPE, [ $this, 'filter_bulk_actions' ], 15 ); add_filter( 'post_row_actions', [ $this, 'filter_actions' ], 10, 2 ); add_filter( 'manage_' . Tribe__Events__Main::POSTTYPE . '_posts_columns', [ $this, 'filter_columns' ], 100 ); add_action( 'manage_' . Tribe__Events__Main::POSTTYPE . '_posts_custom_column', [ $this, 'action_column_contents' ], 100, 2 ); add_action( 'wp_ajax_tribe_convert_legacy_ignored_events', [ $this, 'ajax_convert_legacy_ignored_events' ] ); // Modify Success messages add_filter( 'bulk_post_updated_messages', [ $this, 'filter_updated_messages' ], 10, 2 ); // Register assets add_action( 'init', [ $this, 'action_assets' ] ); /** * Register Notices */ tribe_notice( 'legacy-ignored-events', [ $this, 'render_notice_legacy' ], 'dismiss=1&type=warning' ); add_filter( 'wp_count_posts', [ $this, 'patch_count_posts' ] ); return true; } /** * Patch post-list-table queries to include ignored status, * as WP just accesses the stati without checking if they exist. * * @see wp-admin/includes/class-wp-posts-list-table.php->get_views() * * @since 5.1.5 * * @param object $counts An object containing the current post_type's post * counts by status. * * @return object $counts The modified object containing the current post_type's post * counts by status. */ public function patch_count_posts( $counts ) { $status = $this::$ignored_status; if ( ! isset( $counts->$status ) ) { $counts->$status = 0; } return $counts; } } }
Save Changes
Rename File
Rename