| 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 | } |