Skip to:
Content

bbPress.org

Ticket #3395: 3395.2.diff

File 3395.2.diff, 8.6 KB (added by johnjamesjacoby, 6 weeks ago)
  • akismet.php

     
    6868                // Update post meta
    6969                add_action( 'wp_insert_post', array( $this, 'update_post_meta' ), 10, 2 );
    7070
     71                // Cleanup
     72                add_action( 'akismet_scheduled_delete', array( $this, 'delete_old_spam' ) );
     73                add_action( 'akismet_scheduled_delete', array( $this, 'delete_old_spam_meta' ) );
     74                add_action( 'akismet_scheduled_delete', array( $this, 'delete_orphaned_spam_meta' ) );
     75
    7176                // Admin
    7277                if ( is_admin() ) {
    7378                        add_action( 'add_meta_boxes', array( $this, 'add_metaboxes' ) );
     
    954959
    955960                <?php
    956961        }
     962
     963        /**
     964         * Delete old spam topics & replies from the queue after a few days
     965         * (determined by `_bbp_akismet_delete_spam_interval` filter).
     966         *
     967         * @since 2.7.0 bbPress (r7203)
     968         *
     969         * @global wpdb $wpdb
     970         */
     971        public function delete_old_spam() {
     972                global $wpdb;
     973
     974                /**
     975                 * Determines how many posts will be deleted in each batch.
     976                 *
     977                 * @param int The default as defined by AKISMET_DELETE_LIMIT (also used
     978                 *            in Akismet WordPress plugin).
     979                 */
     980                $delete_limit = (int) apply_filters( '_bbp_akismet_delete_spam_limit',
     981                        defined( 'AKISMET_DELETE_LIMIT' )
     982                                ? AKISMET_DELETE_LIMIT
     983                                : 10000
     984                );
     985
     986                // Validate the deletion limit
     987                $delete_limit = max( 1, intval( $delete_limit ) );
     988
     989                /**
     990                 * Determines how many days a piece of spam will be left in the Spam
     991                 * queue before being deleted.
     992                 *
     993                 * @param int The default number of days.
     994                 */
     995                $delete_interval = (int) apply_filters( '_bbp_akismet_delete_spam_interval', 15 );
     996
     997                // Validate the deletion interval
     998                $delete_interval = max( 1, intval( $delete_interval ) );
     999
     1000                // Setup the query
     1001                $sql = "SELECT id FROM {$wpdb->posts} WHERE post_type IN ('topic', 'reply') AND post_status = 'spam' AND DATE_SUB(NOW(), INTERVAL %d DAY) > post_date_gmt LIMIT %d";
     1002
     1003                // Query loop of topic & reply IDs
     1004                while ( $spam_ids = $wpdb->get_col( $wpdb->prepare( $sql, $delete_interval, $delete_limit ) ) ) {
     1005
     1006                        // Exit loop if no spam IDs
     1007                        if ( empty( $spam_ids ) ) {
     1008                                break;
     1009                        }
     1010
     1011                        // Reset queries
     1012                        $wpdb->queries = array();
     1013
     1014                        // Loop through each of the topic/reply IDs
     1015                        foreach ( $spam_ids as $spam_id ) {
     1016
     1017                                /**
     1018                                 * Perform a single action on the single topic/reply ID for
     1019                                 * simpler batch processing.
     1020                                 *
     1021                                 * Maybe we should run the bbp_delete_topic or bbp_delete_reply
     1022                                 * actions here, too?
     1023                                 *
     1024                                 * @param string The current function.
     1025                                 * @param int    The current topic/reply ID.
     1026                                 */
     1027                                do_action( '_bbp_akismet_batch_delete', __FUNCTION__, $spam_id );
     1028                        }
     1029
     1030                        // Prepared as strings since id is an unsigned BIGINT, and using %
     1031                        // will constrain the value to the maximum signed BIGINT.
     1032                        $format_string = implode( ", ", array_fill( 0, count( $spam_ids ), '%s' ) );
     1033
     1034                        // Run the delete queries
     1035                        $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->posts} WHERE post_id IN ( " . $format_string . " )", $spam_ids ) );
     1036                        $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->postmeta} WHERE post_id IN ( " . $format_string . " )", $spam_ids ) );
     1037
     1038                        // Clean the post cache for these topics & replies
     1039                        clean_post_cache( $spam_ids );
     1040
     1041                        /**
     1042                         * Single action that encompasses all topic/reply IDs after the
     1043                         * delete queries have been run.
     1044                         *
     1045                         * @param int   Count of topic/reply IDs
     1046                         * @param array Array of topic/reply IDs
     1047                         */
     1048                        do_action( '_bbp_akismet_delete_spam_count', count( $spam_ids ), $spam_ids );
     1049                }
     1050
     1051                /**
     1052                 * Determines whether tables should be optimized.
     1053                 *
     1054                 * @param int Random number between 1 and 5000.
     1055                 */
     1056                $optimize = (int) apply_filters( '_bbp_akismet_optimize_tables', mt_rand( 1, 5000 ), array( $wpdb->posts, $wpdb->postmeta ) );
     1057
     1058                // Lucky number 11
     1059                if ( 11 === $optimize ) {
     1060                        $wpdb->query( "OPTIMIZE TABLE {$wpdb->posts}" );
     1061                        $wpdb->query( "OPTIMIZE TABLE {$wpdb->postmeta}" );
     1062                }
     1063        }
     1064
     1065        /**
     1066         * Delete the `_bbp_akismet_as_submitted` meta keys after a while, since
     1067         * they are large and not useful in the long term.
     1068         *
     1069         * @since 2.7.0 bbPress (r7203)
     1070         *
     1071         * @global wpdb $wpdb
     1072         */
     1073        public function delete_old_spam_meta() {
     1074                global $wpdb;
     1075
     1076                /**
     1077                 * Determines how many days a piece of spam will be left in the Spam
     1078                 * queue before being deleted.
     1079                 *
     1080                 * @param int The default number of days.
     1081                 */
     1082                $interval = (int) apply_filters( '_bbp_akismet_delete_spam_meta_interval', 15 );
     1083
     1084                // Validate the deletion interval
     1085                $interval = max( 1, intval( $interval ) );
     1086
     1087                // Setup the query
     1088                $sql = "SELECT m.post_id FROM {$wpdb->postmeta} as m INNER JOIN {$wpdb->posts} as p ON m.post_id = p.id WHERE m.meta_key = '_bbp_akismet_as_submitted' AND DATE_SUB(NOW(), INTERVAL %d DAY) > p.post_date_gmt LIMIT 10000";
     1089
     1090                // Query loop of topic & reply IDs
     1091                while ( $spam_ids = $wpdb->get_col( $wpdb->prepare( $sql, $interval ) ) ) {
     1092
     1093                        // Exit loop if no spam IDs
     1094                        if ( empty( $spam_ids ) ) {
     1095                                break;
     1096                        }
     1097
     1098                        // Reset queries
     1099                        $wpdb->queries = array();
     1100
     1101                        // Loop through each of the topic/reply IDs
     1102                        foreach ( $spam_ids as $spam_id ) {
     1103
     1104                                // Delete the as_submitted meta data
     1105                                delete_post_meta( $spam_id, '_bbp_akismet_as_submitted' );
     1106
     1107                                /**
     1108                                 * Perform a single action on the single topic/reply ID for
     1109                                 * simpler batch processing.
     1110                                 *
     1111                                 * @param string The current function.
     1112                                 * @param int    The current topic/reply ID.
     1113                                 */
     1114                                do_action( '_bbp_akismet_batch_delete', __FUNCTION__, $spam_id );
     1115                        }
     1116
     1117                        /**
     1118                         * Single action that encompasses all topic/reply IDs after the
     1119                         * delete queries have been run.
     1120                         *
     1121                         * @param int   Count of topic/reply IDs
     1122                         * @param array Array of topic/reply IDs
     1123                         */
     1124                        do_action( '_bbp_akismet_delete_spam_meta_count', count( $spam_ids ), $spam_ids );
     1125                }
     1126
     1127                // Maybe optimize
     1128                $this->maybe_optimize_postmeta();
     1129        }
     1130
     1131        /**
     1132         * Clear out posts meta that no longer have corresponding posts in the database
     1133         *
     1134         * @since 2.7.0 bbPress (r7203)
     1135         *
     1136         * @global wpdb $wpdb
     1137         */
     1138        public function delete_orphaned_spam_meta() {
     1139                global $wpdb;
     1140
     1141                $last_meta_id = 0;
     1142
     1143                // Start time (float)
     1144                $start_time = isset( $_SERVER['REQUEST_TIME_FLOAT'] )
     1145                        ? (float) $_SERVER['REQUEST_TIME_FLOAT']
     1146                        : microtime( true );
     1147
     1148                // Maximum time
     1149                $max_exec_time = (float) max( ini_get( 'max_execution_time' ) - 5, 3 );
     1150
     1151                // Setup the query
     1152                $sql = "SELECT m.meta_id, m.post_id, m.meta_key FROM {$wpdb->postmeta} as m LEFT JOIN {$wpdb->posts} as p ON m.post_id = p.id WHERE p.id IS NULL AND m.meta_id > %d ORDER BY m.meta_id LIMIT 1000";
     1153
     1154                // Query loop of topic & reply IDs
     1155                while ( $spam_meta_results = $wpdb->get_results( $wpdb->prepare( $sql, $last_meta_id ) ) ) {
     1156
     1157                        // Exit loop if no spam IDs
     1158                        if ( empty( $spam_meta_results ) ) {
     1159                                break;
     1160                        }
     1161
     1162                        // Reset queries
     1163                        $wpdb->queries = array();
     1164
     1165                        // Reset deleted meta count
     1166                        $spam_meta_deleted = array();
     1167
     1168                        // Loop through each of the metas
     1169                        foreach ( $spam_meta_results as $spam_meta ) {
     1170
     1171                                // Skip if not an Akismet key
     1172                                if ( 'akismet_' !== substr( $spam_meta->meta_key, 0, 8 ) ) {
     1173                                        continue;
     1174                                }
     1175
     1176                                // Delete the meta
     1177                                delete_post_meta( $spam_meta->post_id, $spam_meta->meta_key );
     1178
     1179                                /**
     1180                                 * Perform a single action on the single topic/reply ID for
     1181                                 * simpler batch processing.
     1182                                 *
     1183                                 * @param string The current function.
     1184                                 * @param int    The current topic/reply ID.
     1185                                 */
     1186                                do_action( '_bbp_akismet_batch_delete', __FUNCTION__, $spam_meta );
     1187
     1188                                // Stash the meta ID being deleted
     1189                                $spam_meta_deleted[] = $last_meta_id = $spam_meta->meta_id;
     1190                        }
     1191
     1192                        /**
     1193                         * Single action that encompasses all topic/reply IDs after the
     1194                         * delete queries have been run.
     1195                         *
     1196                         * @param int   Count of spam meta IDs
     1197                         * @param array Array of spam meta IDs
     1198                         */
     1199                        do_action( '_bbp_akismet_delete_spam_meta_count', count( $spam_meta_deleted ), $spam_meta_deleted );
     1200
     1201                        // Break if getting close to max_execution_time.
     1202                        if ( ( microtime( true ) - $start_time ) > $max_exec_time ) {
     1203                                break;
     1204                        }
     1205                }
     1206
     1207                // Maybe optimize
     1208                $this->maybe_optimize_postmeta();
     1209        }
     1210
     1211        /**
     1212         * Maybe OPTIMIZE the _postmeta database table.
     1213         *
     1214         * @since 2.7.0 bbPress (r7203)
     1215         *
     1216         * @global wpdb $wpdb
     1217         */
     1218        private function maybe_optimize_postmeta() {
     1219                global $wpdb;
     1220
     1221                /**
     1222                 * Determines whether tables should be optimized.
     1223                 *
     1224                 * @param int Random number between 1 and 5000.
     1225                 */
     1226                $optimize = (int) apply_filters( '_bbp_akismet_optimize_table', mt_rand( 1, 5000 ), $wpdb->postmeta );
     1227
     1228                // Lucky number 11
     1229                if ( 11 === $optimize ) {
     1230                        $wpdb->query( "OPTIMIZE TABLE {$wpdb->postmeta}" );
     1231                }
     1232        }
    9571233}
    9581234endif;