← All changes
|
modules/global-classes/global-classes-post-ids.php
+107
-14
4.3.0-beta3
→
4.1.4
View file →
| @@ -1,11 +1,13 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | namespace Elementor\Modules\GlobalClasses; |
| 4 | 4 | |
| 5 | +use Elementor\Core\Base\Document; | |
| 5 | 6 | use Elementor\Core\Kits\Documents\Kit; |
| 6 | -use Elementor\Core\Kits\Concerns\Has_Kit_Dependency; | |
| 7 | -use Elementor\Modules\GlobalClasses\Utils\Kit_Utils; | |
| 7 | +use Elementor\Modules\GlobalClasses\Concerns\Has_Kit_Dependency; | |
| 8 | +use Elementor\Plugin; | |
| 9 | +use Elementor\TemplateLibrary\Source_Local; | |
| 8 | 10 | use WP_Post; |
| 9 | 11 | |
| 10 | 12 | if ( ! defined( 'ABSPATH' ) ) { |
| 11 | 13 | exit; |
| @@ -15,8 +17,10 @@ | ||
| 15 | 17 | use Has_Kit_Dependency; |
| 16 | 18 | |
| 17 | 19 | const META_KEY = '_elementor_global_classes_post_ids'; |
| 18 | 20 | |
| 21 | + const BACKFILL_BATCH_SIZE = 100; | |
| 22 | + | |
| 19 | 23 | private ?array $cache = null; |
| 20 | 24 | |
| 21 | 25 | public static function make( ?Kit $kit = null ): self { |
| 22 | 26 | $instance = new self(); |
| @@ -36,10 +40,29 @@ | ||
| 36 | 40 | if ( Global_Class_Post_Type::CPT !== $post->post_type ) { |
| 37 | 41 | return; |
| 38 | 42 | } |
| 39 | 43 | |
| 40 | - foreach ( Kit_Utils::get_all_kit_documents() as $kit ) { | |
| 41 | - self::make( $kit )->remove_post_id( $post_id ); | |
| 44 | + $kit_ids = get_posts( [ | |
| 45 | + 'post_type' => Source_Local::CPT, | |
| 46 | + 'post_status' => 'any', | |
| 47 | + 'fields' => 'ids', | |
| 48 | + 'posts_per_page' => -1, | |
| 49 | + 'no_found_rows' => true, | |
| 50 | + 'update_post_meta_cache' => false, | |
| 51 | + 'meta_query' => [ | |
| 52 | + [ | |
| 53 | + 'key' => Document::TYPE_META_KEY, | |
| 54 | + 'value' => 'kit', | |
| 55 | + ], | |
| 56 | + ], | |
| 57 | + ] ); | |
| 58 | + | |
| 59 | + foreach ( $kit_ids as $kit_id ) { | |
| 60 | + $kit = Plugin::$instance->kits_manager->get_kit( $kit_id ); | |
| 61 | + | |
| 62 | + if ( $kit ) { | |
| 63 | + self::make( $kit )->remove_post_id( $post_id ); | |
| 64 | + } | |
| 42 | 65 | } |
| 43 | 66 | } |
| 44 | 67 | |
| 45 | 68 | public function get_post_id( string $class_id ): ?int { |
| @@ -44,21 +67,21 @@ | ||
| 44 | 67 | |
| 45 | 68 | public function get_post_id( string $class_id ): ?int { |
| 46 | 69 | $map = $this->read_map(); |
| 47 | 70 | |
| 48 | - if ( ! isset( $map[ $class_id ] ) ) { | |
| 49 | - return null; | |
| 50 | - } | |
| 71 | + if ( isset( $map[ $class_id ] ) ) { | |
| 72 | + $post_id = (int) $map[ $class_id ]; | |
| 51 | 73 | |
| 52 | - $post_id = (int) $map[ $class_id ]; | |
| 74 | + if ( get_post( $post_id ) ) { | |
| 75 | + return $post_id; | |
| 76 | + } | |
| 53 | 77 | |
| 54 | - if ( get_post( $post_id ) ) { | |
| 55 | - return $post_id; | |
| 78 | + $this->remove_post_id( $post_id ); | |
| 56 | 79 | } |
| 57 | 80 | |
| 58 | - $this->remove_post_id( $post_id ); | |
| 81 | + $resolved = $this->backfill( [ $class_id ] ); | |
| 59 | 82 | |
| 60 | - return null; | |
| 83 | + return $resolved[ $class_id ] ?? null; | |
| 61 | 84 | } |
| 62 | 85 | |
| 63 | 86 | public function get_post_ids( array $class_ids ): array { |
| 64 | 87 | if ( empty( $class_ids ) ) { |
| @@ -64,13 +87,15 @@ | ||
| 64 | 87 | if ( empty( $class_ids ) ) { |
| 65 | 88 | return []; |
| 66 | 89 | } |
| 67 | 90 | |
| 68 | - $map = $this->read_map(); | |
| 91 | + $map = $this->read_map(); | |
| 69 | 92 | $resolved = []; |
| 93 | + $missing = []; | |
| 70 | 94 | |
| 71 | 95 | foreach ( $class_ids as $class_id ) { |
| 72 | 96 | if ( ! isset( $map[ $class_id ] ) ) { |
| 97 | + $missing[] = $class_id; | |
| 73 | 98 | continue; |
| 74 | 99 | } |
| 75 | 100 | |
| 76 | 101 | $post_id = (int) $map[ $class_id ]; |
| @@ -77,12 +102,16 @@ | ||
| 77 | 102 | |
| 78 | 103 | if ( get_post( $post_id ) ) { |
| 79 | 104 | $resolved[ $class_id ] = $post_id; |
| 80 | 105 | } else { |
| 81 | - $this->remove_post_id( $post_id ); | |
| 106 | + $missing[] = $class_id; | |
| 82 | 107 | } |
| 83 | 108 | } |
| 84 | 109 | |
| 110 | + if ( ! empty( $missing ) ) { | |
| 111 | + $resolved += $this->backfill( $missing ); | |
| 112 | + } | |
| 113 | + | |
| 85 | 114 | return $resolved; |
| 86 | 115 | } |
| 87 | 116 | |
| 88 | 117 | public function set( string $class_id, int $post_id ): void { |
| @@ -134,8 +163,72 @@ | ||
| 134 | 163 | return; |
| 135 | 164 | } |
| 136 | 165 | |
| 137 | 166 | $this->write_map( $filtered ); |
| 167 | + } | |
| 168 | + | |
| 169 | + private function backfill( array $class_ids ): array { | |
| 170 | + $resolved = []; | |
| 171 | + | |
| 172 | + foreach ( array_chunk( array_values( array_unique( $class_ids ) ), self::BACKFILL_BATCH_SIZE ) as $chunk ) { | |
| 173 | + $resolved += $this->resolve_via_query( $chunk ); | |
| 174 | + } | |
| 175 | + | |
| 176 | + if ( ! empty( $resolved ) ) { | |
| 177 | + $this->set_many( $resolved ); | |
| 178 | + } | |
| 179 | + | |
| 180 | + return $resolved; | |
| 181 | + } | |
| 182 | + | |
| 183 | + private function resolve_via_query( array $class_ids ): array { | |
| 184 | + if ( empty( $class_ids ) ) { | |
| 185 | + return []; | |
| 186 | + } | |
| 187 | + | |
| 188 | + global $wpdb; | |
| 189 | + | |
| 190 | + $placeholders = implode( ',', array_fill( 0, count( $class_ids ), '%s' ) ); | |
| 191 | + | |
| 192 | + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared | |
| 193 | + $sql = $wpdb->prepare( | |
| 194 | + "SELECT pm.post_id, pm.meta_value | |
| 195 | + FROM {$wpdb->postmeta} pm | |
| 196 | + INNER JOIN {$wpdb->posts} p ON p.ID = pm.post_id | |
| 197 | + WHERE pm.meta_key = %s | |
| 198 | + AND pm.meta_value IN ($placeholders) | |
| 199 | + AND p.post_type = %s | |
| 200 | + AND p.post_status = %s", | |
| 201 | + array_merge( | |
| 202 | + [ Global_Class_Post::META_KEY_ID ], | |
| 203 | + $class_ids, | |
| 204 | + [ Global_Class_Post_Type::CPT, 'publish' ] | |
| 205 | + ) | |
| 206 | + ); | |
| 207 | + // phpcs:enable | |
| 208 | + | |
| 209 | + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- $sql is already prepared via $wpdb->prepare() above. | |
| 210 | + $rows = $wpdb->get_results( $sql ); | |
| 211 | + | |
| 212 | + $candidates = []; | |
| 213 | + | |
| 214 | + foreach ( $rows as $row ) { | |
| 215 | + $candidates[ (string) $row->meta_value ][] = (int) $row->post_id; | |
| 216 | + } | |
| 217 | + | |
| 218 | + $resolved = []; | |
| 219 | + | |
| 220 | + foreach ( $candidates as $class_id => $post_ids ) { | |
| 221 | + sort( $post_ids ); | |
| 222 | + $resolved[ $class_id ] = $post_ids[0]; | |
| 223 | + $duplicates = array_slice( $post_ids, 1 ); | |
| 224 | + | |
| 225 | + foreach ( $duplicates as $duplicate_id ) { | |
| 226 | + wp_delete_post( $duplicate_id, true ); | |
| 227 | + } | |
| 228 | + } | |
| 229 | + | |
| 230 | + return $resolved; | |
| 138 | 231 | } |
| 139 | 232 | |
| 140 | 233 | private function read_map(): array { |
| 141 | 234 | if ( null !== $this->cache ) { |