← All changes
|
includes/features/bbpc_attachments/code/public.php
+13
-144
trunk
→
2.5.0
View file →
| @@ -10,124 +10,23 @@ | ||
| 10 | 10 | * |
| 11 | 11 | * @return array list of attachments objects |
| 12 | 12 | */ |
| 13 | 13 | function forumax_get_post_attachments( $post_id ) { |
| 14 | - $post_id = (int) $post_id; | |
| 15 | - $store = &forumax_post_attachments_store(); | |
| 14 | + $args = [ | |
| 15 | + 'post_type' => 'attachment', | |
| 16 | + 'numberposts' => -1, | |
| 17 | + 'post_status' => null, | |
| 18 | + 'post_parent' => $post_id, | |
| 19 | + 'orderby' => 'ID', | |
| 20 | + 'order' => 'ASC', | |
| 21 | + ]; | |
| 16 | 22 | |
| 17 | - if ( ! isset( $store[ $post_id ] ) ) { | |
| 18 | - // Prime the whole topic/reply loop in one query instead of one per post. | |
| 19 | - forumax_prime_post_attachments( array_merge( [ $post_id ], forumax_current_loop_post_ids() ) ); | |
| 20 | - } | |
| 21 | - | |
| 22 | - return $store[ $post_id ] ?? []; | |
| 23 | + return get_posts( $args ); | |
| 23 | 24 | } |
| 24 | 25 | |
| 25 | 26 | /** |
| 26 | - * Per-request attachment store, keyed by parent post ID. | |
| 27 | - * | |
| 28 | - * @return array | |
| 29 | - */ | |
| 30 | -function &forumax_post_attachments_store() { | |
| 31 | - static $store = []; | |
| 32 | - return $store; | |
| 33 | -} | |
| 34 | - | |
| 35 | -/** | |
| 36 | - * IDs of the topics/replies in the active bbPress loops. | |
| 37 | - * | |
| 38 | - * @return int[] | |
| 39 | - */ | |
| 40 | -function forumax_current_loop_post_ids() { | |
| 41 | - $ids = []; | |
| 42 | - | |
| 43 | - if ( ! function_exists( 'bbpress' ) ) { | |
| 44 | - return $ids; | |
| 45 | - } | |
| 46 | - | |
| 47 | - foreach ( [ 'reply_query', 'topic_query' ] as $prop ) { | |
| 48 | - $query = bbpress()->{$prop} ?? null; | |
| 49 | - if ( $query instanceof WP_Query && ! empty( $query->posts ) ) { | |
| 50 | - $ids = array_merge( $ids, forumax_query_post_ids( $query ) ); | |
| 51 | - } | |
| 52 | - } | |
| 53 | - | |
| 54 | - return $ids; | |
| 55 | -} | |
| 56 | - | |
| 57 | -/** | |
| 58 | - * Post IDs of a query, whether it fetched objects or IDs. | |
| 59 | - * | |
| 60 | - * @param WP_Query $query Query. | |
| 61 | - * @return int[] | |
| 62 | - */ | |
| 63 | -function forumax_query_post_ids( $query ) { | |
| 64 | - return array_map( | |
| 65 | - static function ( $post ) { | |
| 66 | - return is_object( $post ) ? (int) $post->ID : (int) $post; | |
| 67 | - }, | |
| 68 | - (array) $query->posts | |
| 69 | - ); | |
| 70 | -} | |
| 71 | - | |
| 72 | -/** | |
| 73 | - * Fetch attachments for many parent posts in a single query. | |
| 74 | - * | |
| 75 | - * @param int[] $post_ids Topic or reply IDs. | |
| 76 | - * @return void | |
| 77 | - */ | |
| 78 | -function forumax_prime_post_attachments( array $post_ids ) { | |
| 79 | - $store = &forumax_post_attachments_store(); | |
| 80 | - $post_ids = array_values( array_diff( array_unique( array_filter( array_map( 'intval', $post_ids ) ) ), array_keys( $store ) ) ); | |
| 81 | - | |
| 82 | - if ( empty( $post_ids ) ) { | |
| 83 | - return; | |
| 84 | - } | |
| 85 | - | |
| 86 | - foreach ( $post_ids as $id ) { | |
| 87 | - $store[ $id ] = []; | |
| 88 | - } | |
| 89 | - | |
| 90 | - // No row cap: the parent set is already bounded by the current loop, and a | |
| 91 | - // cap would silently drop attachments of the posts past it (each of them | |
| 92 | - // is marked as loaded above). | |
| 93 | - $attachments = get_posts( | |
| 94 | - [ | |
| 95 | - 'post_type' => 'attachment', | |
| 96 | - 'numberposts' => -1, | |
| 97 | - 'post_status' => 'inherit', | |
| 98 | - 'post_parent__in' => $post_ids, | |
| 99 | - 'orderby' => 'ID', | |
| 100 | - 'order' => 'ASC', | |
| 101 | - 'update_post_term_cache' => false, | |
| 102 | - ] | |
| 103 | - ); | |
| 104 | - | |
| 105 | - foreach ( $attachments as $attachment ) { | |
| 106 | - $store[ (int) $attachment->post_parent ][] = $attachment; | |
| 107 | - } | |
| 108 | -} | |
| 109 | - | |
| 110 | -/** | |
| 111 | - * Forget a parent's cached attachments when one is added or removed. | |
| 112 | - * | |
| 113 | - * @param int $attachment_id Attachment ID. | |
| 114 | - * @return void | |
| 115 | - */ | |
| 116 | -function forumax_flush_post_attachments_store( $attachment_id ) { | |
| 117 | - $store = &forumax_post_attachments_store(); | |
| 118 | - $parent = (int) wp_get_post_parent_id( $attachment_id ); | |
| 119 | - unset( $store[ $parent ] ); | |
| 120 | -} | |
| 121 | -add_action( 'add_attachment', 'forumax_flush_post_attachments_store' ); | |
| 122 | -add_action( 'delete_attachment', 'forumax_flush_post_attachments_store' ); | |
| 123 | - | |
| 124 | -/** | |
| 125 | 27 | * Count attachments for the forum topic. It can include topic replies in the count. |
| 126 | 28 | * |
| 127 | - * Counts for every topic in the current loop are fetched together, so the | |
| 128 | - * topic list costs two queries instead of one per topic. | |
| 129 | - * | |
| 130 | 29 | * @param int $topic_id id of the topic to count attachments for |
| 131 | 30 | * @param bool $include_replies true, to include reply attachments |
| 132 | 31 | * |
| 133 | 32 | * @return int number of attachments |
| @@ -133,47 +32,17 @@ | ||
| 133 | 32 | * @return int number of attachments |
| 134 | 33 | */ |
| 135 | 34 | function forumax_topic_attachments_count( $topic_id, $include_replies = false ) { |
| 136 | 35 | global $wpdb; |
| 137 | - static $counts = []; | |
| 138 | 36 | |
| 139 | - $topic_id = (int) $topic_id; | |
| 140 | - $key = $include_replies ? 'all' : 'own'; | |
| 37 | + $sql = 'select ID from ' . $wpdb->posts . ' where post_parent = ' . $topic_id . " and post_type = 'attachment'"; | |
| 141 | 38 | |
| 142 | - if ( $topic_id <= 0 ) { | |
| 143 | - return 0; | |
| 144 | - } | |
| 145 | - | |
| 146 | - if ( isset( $counts[ $key ][ $topic_id ] ) ) { | |
| 147 | - return $counts[ $key ][ $topic_id ]; | |
| 148 | - } | |
| 149 | - | |
| 150 | - $topic_ids = [ $topic_id ]; | |
| 151 | - if ( function_exists( 'bbpress' ) && bbpress()->topic_query instanceof WP_Query ) { | |
| 152 | - $topic_ids = array_merge( $topic_ids, forumax_query_post_ids( bbpress()->topic_query ) ); | |
| 153 | - } | |
| 154 | - $topic_ids = array_values( array_unique( array_filter( $topic_ids ) ) ); | |
| 155 | - | |
| 156 | - foreach ( $topic_ids as $id ) { | |
| 157 | - $counts[ $key ][ $id ] = 0; | |
| 158 | - } | |
| 159 | - | |
| 160 | - $placeholders = implode( ',', array_fill( 0, count( $topic_ids ), '%d' ) ); | |
| 161 | - | |
| 162 | - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared | |
| 163 | - $rows = $wpdb->get_results( $wpdb->prepare( "SELECT post_parent AS topic_id, COUNT(*) AS total FROM {$wpdb->posts} WHERE post_type = 'attachment' AND post_parent IN ($placeholders) GROUP BY post_parent", $topic_ids ) ); | |
| 164 | - | |
| 165 | 39 | if ( $include_replies ) { |
| 166 | - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared | |
| 167 | - $reply_rows = $wpdb->get_results( $wpdb->prepare( "SELECT r.post_parent AS topic_id, COUNT(*) AS total FROM {$wpdb->posts} r INNER JOIN {$wpdb->posts} a ON a.post_parent = r.ID AND a.post_type = 'attachment' WHERE r.post_type = 'reply' AND r.post_parent IN ($placeholders) GROUP BY r.post_parent", $topic_ids ) ); | |
| 168 | - $rows = array_merge( $rows, $reply_rows ); | |
| 40 | + $sql = '(' . $sql . ') union (select ID from ' . $wpdb->posts . ' where post_parent in (select ID from ' . $wpdb->posts . ' where post_parent = ' . $topic_id . " and post_type = 'reply') and post_type = 'attachment')"; | |
| 169 | 41 | } |
| 170 | 42 | |
| 171 | - foreach ( $rows as $row ) { | |
| 172 | - $counts[ $key ][ (int) $row->topic_id ] += (int) $row->total; | |
| 173 | - } | |
| 174 | - | |
| 175 | - return $counts[ $key ][ $topic_id ]; | |
| 43 | + $attachments = $wpdb->get_results( $sql ); | |
| 44 | + return count( $attachments ); | |
| 176 | 45 | } |
| 177 | 46 | |
| 178 | 47 | /** |
| 179 | 48 | * Handle upload file error. |