PluginProbe
ElasticPress / 4.7.2
ElasticPress v4.7.2
5.3.5 5.3.4 3.6.5 3.6.6 4.0.0 4.0.1 4.1.0 4.2.0 4.2.1 4.2.2 4.3.0 4.3.1 4.4.0 4.4.1 4.5.0 4.5.1 4.5.2 4.6.0 4.6.1 4.7.0 4.7.1 4.7.2 5.0.0 5.0.1 5.0.2 All 108 releases
elasticpress / includes / classes / SyncManager.php

SyncManager.php in ElasticPress 4.7.2, at includes/classes/SyncManager.php

297 lines 7.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * SyncManager common functionality
4 *
5 * @package elasticpress
6 * @since 3.0
7 */
8
9 namespace ElasticPress;
10
11 use ElasticPress\Utils;
12
13 /**
14 * Abstract sync manager class to be extended for each indexable
15 */
16 abstract class SyncManager {
17
18 /**
19 * Save objects for indexing later
20 *
21 * @since 3.0
22 * @var array
23 */
24 public $sync_queue = [];
25
26 /**
27 * Indexable slug
28 *
29 * @var string
30 * @since 3.0
31 */
32 public $indexable_slug;
33
34 /**
35 * Create new SyncManager
36 *
37 * @param string $indexable_slug Indexable slug.
38 * @since 3.0
39 */
40 public function __construct( $indexable_slug ) {
41 $this->indexable_slug = $indexable_slug;
42
43 if ( defined( 'EP_SYNC_CHUNK_LIMIT' ) && is_numeric( EP_SYNC_CHUNK_LIMIT ) ) {
44 /**
45 * We also sync when we exceed Chunk limit set.
46 * This is sometimes useful when posts are generated programatically.
47 */
48 add_action( 'ep_after_add_to_queue', [ $this, 'index_sync_on_chunk_limit' ] );
49 }
50 /**
51 * We do all syncing on shutdown or redirect
52 */
53 add_action( 'shutdown', [ $this, 'index_sync_queue' ] );
54 add_filter( 'wp_redirect', [ $this, 'index_sync_queue_on_redirect' ], 10, 1 );
55
56 /**
57 * Actions for multisite
58 */
59 add_action( 'delete_blog', array( $this, 'action_delete_blog_from_index' ) );
60 add_action( 'make_delete_blog', array( $this, 'action_delete_blog_from_index' ) );
61 add_action( 'make_spam_blog', array( $this, 'action_delete_blog_from_index' ) );
62 add_action( 'archive_blog', array( $this, 'action_delete_blog_from_index' ) );
63 add_action( 'deactivate_blog', array( $this, 'action_delete_blog_from_index' ) );
64
65 // Implemented by children.
66 $this->setup();
67 }
68
69 /**
70 * Add an object to the sync queue.
71 *
72 * @since 3.1.2
73 *
74 * @param int $object_id Object ID to sync.
75 * @return boolean
76 */
77 public function add_to_queue( $object_id ) {
78 if ( ! is_numeric( $object_id ) ) {
79 return false;
80 }
81 $this->sync_queue[ $object_id ] = true;
82
83 /**
84 * Fires after item is added to sync queue
85 *
86 * @hook ep_after_add_to_queue
87 * @param {int} $object_id ID of object
88 * @param {array} $sync_queue Current sync queue
89 * @since 3.1.2
90 */
91 do_action( 'ep_after_add_to_queue', $object_id, $this->sync_queue );
92
93 return true;
94 }
95
96 /**
97 * Remove an object from the sync queue.
98 *
99 * @since 3.5
100 *
101 * @param int $object_id Object ID to remove from the queue.
102 * @return boolean
103 */
104 public function remove_from_queue( $object_id ) {
105 if ( ! is_numeric( $object_id ) ) {
106 return false;
107 }
108
109 unset( $this->sync_queue[ $object_id ] );
110
111 /**
112 * Fires after item is removed from sync queue
113 *
114 * @hook ep_after_remove_from_queue
115 * @param {int} $object_id ID of object
116 * @param {array} $sync_queue Current sync queue
117 * @since 3.5
118 */
119 do_action( 'ep_after_remove_from_queue', $object_id, $this->sync_queue );
120
121 return true;
122 }
123
124 /**
125 * Sync queued objects if the EP_SYNC_CHUNK_LIMIT is reached.
126 *
127 * @since 3.1.2
128 * @return boolean
129 */
130 public function index_sync_on_chunk_limit() {
131 if ( defined( 'EP_SYNC_CHUNK_LIMIT' ) && is_numeric( EP_SYNC_CHUNK_LIMIT ) &&
132 is_array( $this->sync_queue ) && count( $this->sync_queue ) > EP_SYNC_CHUNK_LIMIT ) {
133 $this->index_sync_queue();
134 }
135 return true;
136 }
137
138 /**
139 * Sync queued objects before a redirect occurs. Hackish but very important since
140 * shutdown won't be firing
141 *
142 * @param string $location Redirect location.
143 * @since 3.0
144 * @return string
145 */
146 public function index_sync_queue_on_redirect( $location ) {
147 $this->index_sync_queue();
148
149 return $location;
150 }
151
152 /**
153 * Sync objects in queue.
154 *
155 * @since 3.0
156 */
157 public function index_sync_queue() {
158 if ( empty( $this->sync_queue ) ) {
159 return;
160 }
161
162 /**
163 * Allow other code to intercept the sync process
164 *
165 * @hook pre_ep_index_sync_queue
166 * @param {boolean} $bail True to skip the rest of index_sync_queue(), false to continue normally
167 * @param {SyncManager} $sync_manager SyncManager instance for the indexable
168 * @param {string} $indexable_slug Slug of the indexable being synced
169 * @since 3.5
170 */
171 if ( apply_filters( 'pre_ep_index_sync_queue', false, $this, $this->indexable_slug ) ) {
172 return;
173 }
174
175 /**
176 * Backwards compat for pre-3.0
177 */
178 foreach ( $this->sync_queue as $object_id => $value ) {
179 /**
180 * Fires when object in queue are synced
181 *
182 * @hook ep_sync_on_meta_update_queue
183 * @param {int} $object_id ID of object
184 */
185 do_action( 'ep_sync_on_meta_update', $object_id );
186 }
187
188 // Bulk sync them all.
189 Indexables::factory()->get( $this->indexable_slug )->bulk_index_dynamically( array_keys( $this->sync_queue ) );
190
191 /**
192 * Make sure to reset sync queue in case an shutdown happens before a redirect
193 * when a redirect has already been triggered.
194 */
195 $this->sync_queue = [];
196 }
197
198 /**
199 * Check if we can index content in the current blog
200 *
201 * @since 3.5
202 * @return boolean
203 */
204 public function can_index_site() {
205 if ( ( defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK ) && ! Utils\is_site_indexable() ) {
206 $this->tear_down();
207 return false;
208 }
209
210 return true;
211 }
212
213 /**
214 * Determine whether syncing an indexable should take place.
215 *
216 * Returns true or false depending on the value of the WP_IMPORTING global.
217 * Contains the 'ep_sync_indexable_kill' filter that enables overriding the default behavior.
218 *
219 * @since 3.4.2
220 * @return bool
221 */
222 public function kill_sync() {
223
224 $is_importing = defined( 'WP_IMPORTING' ) && true === WP_IMPORTING;
225
226 /**
227 * Filter whether to bypass sync.
228 *
229 * @since 3.4.2
230 * @hook ep_sync_indexable_kill
231 * @param {boolean} $kill True if WP_IMPORTING is defined and true, else false.
232 * @param {array} $indexable_slug Indexable slug.
233 */
234 return apply_filters( 'ep_sync_indexable_kill', $is_importing, $this->indexable_slug );
235 }
236
237 /**
238 * Remove blog from index when a site is deleted, archived, or deactivated
239 *
240 * @param int $blog_id WP Blog ID.
241 */
242 public function action_delete_blog_from_index( $blog_id ) {
243 if ( $this->kill_sync() ) {
244 return;
245 }
246
247 $indexable = Indexables::factory()->get( $this->indexable_slug );
248
249 // Don't delete global indexes
250 if ( $indexable->global ) {
251 return;
252 }
253
254 /**
255 * Filter to whether to keep index on site deletion
256 *
257 * @hook ep_keep_index
258 * @since 3.0
259 * @since 3.6.2 Moved from Post\SyncManager to the main SyncManager class
260 * @since 3.6.5 Added `$blog_id` and `$indexable_slug`
261 * @param {bool} $keep True means don't delete index
262 * @param {int} $blog_id WP Blog ID
263 * @param {string} $indexable_slug Indexable slug
264 * @return {bool} New value
265 */
266 if ( $indexable->index_exists( $blog_id ) && ! apply_filters( 'ep_keep_index', false, $blog_id, $this->indexable_slug ) ) {
267 $indexable->delete_index( $blog_id );
268 }
269 }
270
271 /**
272 * Clear the cache of the total fields limit
273 *
274 * @since 4.7.0
275 */
276 public function clear_index_settings_cache() {
277 $indexable = Indexables::factory()->get( $this->indexable_slug );
278 $cache_key = 'ep_index_settings_' . $indexable->get_index_name();
279
280 Utils\delete_transient( $cache_key );
281 }
282
283 /**
284 * Implementation should setup hooks/filters
285 *
286 * @since 3.0
287 */
288 abstract public function setup();
289
290 /**
291 * Implementation (for multisite) should un-setup hooks/filters if applicable.
292 *
293 * @since 4.0
294 */
295 abstract public function tear_down();
296 }
297