Skip to:
Content

BuddyPress.org

Ticket #7534: 7534.01.patch

File 7534.01.patch, 6.9 KB (added by r-a-y, 6 years ago)

Changed deletion limit to 1000; add cron job on root blog only

  • src/bp-notifications/bp-notifications-functions.php

     
    462462add_action( 'wpmu_delete_user', 'bp_notifications_delete_notifications_on_user_delete' );
    463463add_action( 'delete_user', 'bp_notifications_delete_notifications_on_user_delete' );
    464464
     465/**
     466 * Removes stale notifications from the database.
     467 *
     468 * @since 3.0.0
     469 */
     470function bp_notifications_delete_stale() {
     471        // Helper function to return stale notification IDs.
     472        $get_stale_ids = function( $date, $per_page ) {
     473                // @todo ::get() should support 'fields' parameter to limit DB columns return.
     474                $q = BP_Notifications_Notification::get( array(
     475                        'is_new'            => 0,
     476                        'component_name'    => false,
     477                        'update_meta_cache' => false,
     478                        'order_by'          => 'ID',
     479                        'sort_order'        => 'ASC',
     480                        'date_query'        => array( array(
     481                                'before' => $date
     482                        ) ),
     483                        'per_page'          => $per_page,
     484                        'page'              => 1
     485                ) );
     486
     487                if ( ! empty( $q ) ) {
     488                        $q = wp_list_pluck( $q, 'id' );
     489                        return $q;
     490                } else {
     491                        return array();
     492                }
     493        };
     494
     495        /**
     496         * Date limit to delete stale notifications for.
     497         *
     498         * @since 3.0.0
     499         *
     500         * @param string $date_limit Default: 30 days ago.
     501         */
     502        $date_limit = apply_filters( 'bp_notifications_delete_date_limit', '30 days ago' );
     503
     504        /**
     505         * Number of stale notifications to delete at a time.
     506         *
     507         * @since 3.0.0
     508         *
     509         * @param int $limit 1000 by default.
     510         */
     511        $limit = (int) apply_filters( 'bp_notifications_delete_stale_limit', 1000 );
     512
     513        // Purge time!
     514        $ids = $get_stale_ids( $date_limit, $limit );
     515        if ( ! empty( $ids ) ) {
     516                // Remove notification user cache purge as this only affects unread items.
     517                remove_action( 'bp_notification_before_delete', 'bp_notifications_clear_all_for_user_cache_before_delete' );
     518
     519                BP_Notifications_Notification::delete_by_ids( $ids );
     520
     521                add_action( 'bp_notification_before_delete', 'bp_notifications_clear_all_for_user_cache_before_delete' );
     522
     523                // Recurse if necessary.
     524                $ids = $get_stale_ids( $date_limit, $limit );
     525                if ( ! empty( $ids ) ) {
     526                        // Sleep for half a second before doing this again.
     527                        usleep( 500000 );
     528                        bp_notifications_delete_stale();
     529                }
     530        }
     531}
     532
    465533/** Mark **********************************************************************/
    466534
    467535/**
     
    790858
    791859        return $retval;
    792860}
     861
     862/** Cron **********************************************************************/
     863
     864/**
     865 * Schedule cronjobs for notifications component.
     866 *
     867 * @since 3.0.0
     868 */
     869function bp_notifications_cron() {
     870        if ( bp_is_root_blog() && ! wp_next_scheduled( 'bp_notifications_delete_stale' ) ) {
     871                wp_schedule_event( time(), 'weekly', 'bp_notifications_delete_stale' );
     872        }
     873}
     874add_action( 'bp_init', 'bp_notifications_cron' );
     875
     876/**
     877 * Remove notification cronjobs on deactivation.
     878 *
     879 * @since 3.0.0
     880 */
     881function bp_notifications_deactivation_cron() {
     882        $switched = false;
     883        if ( ! bp_is_root_blog() ) {
     884                $switched = true;
     885                switch_to_blog( bp_get_root_blog_id() );
     886        }
     887
     888        $timestamp = wp_next_scheduled( 'bp_notifications_delete_stale' );
     889        wp_unschedule_event( $timestamp, 'bp_notifications_delete_stale' );
     890
     891        if ( $switched ) {
     892                restore_current_blog();
     893        }
     894}
     895add_action( 'bp_deactivation', 'bp_notifications_deactivation' );
  • src/bp-notifications/classes/class-bp-notifications-notification.php

     
    816816                }
    817817
    818818                // Date query.
    819                 $date_query = new BP_Date_Query( $date_query, 'date_recorded' );
     819                $date_query = new BP_Date_Query( $date_query, 'date_notified' );
    820820
    821821                // Strip the leading AND - it's handled in get().
    822822                return preg_replace( '/^\sAND/', '', $date_query->get_sql() );
     
    890890                return self::_delete( $where['data'], $where['format'] );
    891891        }
    892892
     893        /**
     894         * Delete multiple notifications by IDs.
     895         *
     896         * Unlike the delete() method, this method can handle bulk deletions.
     897         *
     898         * @since 3.0.0
     899         *
     900         * @param  array $ids Array of notification IDs.
     901         * @return int|false Number of rows affected/selected or false on error
     902         */
     903        public static function delete_by_ids( $ids = array() ) {
     904                $bp = buddypress();
     905
     906                $ids = array_map( 'absint', $ids );
     907                foreach ( $ids as $id ) {
     908                        /** This hook is documented in /bp-notifications/classes/class-bp-notifications-notification.php */
     909                        do_action( 'bp_notification_before_delete', array( 'id' => $id ) );
     910                }
     911
     912                $ids = implode( ',', $ids );
     913
     914                // Delete in bulk.
     915                return $GLOBALS['wpdb']->query( "DELETE FROM {$bp->notifications->table_name} WHERE ID IN ($ids)" );
     916        }
     917
    893918        /** Convenience methods ***************************************************/
    894919
    895920        /**
  • tests/phpunit/testcases/notifications/functions.php

     
    393393                unset( $this->n_args );
    394394        }
    395395
     396        /**
     397         * @ticket BP7534
     398         */
     399        public function test_bp_notifications_delete_stale() {
     400                $u   = self::factory()->user->create();
     401                $now = time();
     402
     403                $n1 = self::factory()->notification->create( array(
     404                        'component_name'    => 'messages',
     405                        'component_action'  => 'new_message',
     406                        'item_id'           => 99,
     407                        'user_id'           => $u,
     408                        'is_new'            => 0
     409                ) );
     410
     411                $n2 = self::factory()->notification->create( array(
     412                        'component_name'    => 'activity',
     413                        'component_action'  => 'new_at_mention',
     414                        'item_id'           => 99,
     415                        'user_id'           => $u,
     416                        'is_new'            => 0,
     417                        'date_notified'     => date( 'Y-m-d H:i:s', $now - DAY_IN_SECONDS * 35 )
     418                ) );
     419
     420                $n3 = self::factory()->notification->create( array(
     421                        'component_name' => 'groups',
     422                        'user_id'        => $u,
     423                        'is_new'         => 0,
     424                        'date_notified'  => date( 'Y-m-d H:i:s', $now - DAY_IN_SECONDS * 40 )
     425                ) );
     426
     427                $n4 = self::factory()->notification->create( array(
     428                        'component_name'   => 'friends',
     429                        'component_action' => 'friendship_request',
     430                        'user_id'          => $u,
     431                        'is_new'           => 0
     432                ) );
     433
     434                // Remove stale notifications.
     435                bp_notifications_delete_stale();
     436
     437                // Assert notifications are deleted.
     438                $this->assertNull( bp_notifications_get_notification( $n2 )->component_name );
     439                $this->assertNull( bp_notifications_get_notification( $n3 )->component_name );
     440
     441                // Check user's read notifications and ensure stale notifications are removed.
     442                $n = BP_Notifications_Notification::get( array(
     443                        'user_id' => $u,
     444                        'is_new'  => 0
     445                ) );
     446                $this->assertEqualSets( array( $n1, $n4 ), wp_list_pluck( $n, 'id' ) );
     447        }
     448
    396449        /**
    397450         * Used in test_notification_callback_parameter_integrity() test.
    398451         */