PluginProbe
ElasticPress / 4.3.0
ElasticPress v4.3.0
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 / Upgrades.php

Upgrades.php in ElasticPress 4.3.0, at includes/classes/Upgrades.php

322 lines 8.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Handle upgrades.
4 *
5 * @since 3.x
6 * @package elasticpress
7 */
8
9 namespace ElasticPress;
10
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit; // Exit if accessed directly.
13 }
14
15 /**
16 * Class Upgrades
17 *
18 * @package ElasticPress
19 */
20 class Upgrades {
21
22 /**
23 * Store the version number before performing upgrades.
24 * Set in the `setup()` method.
25 *
26 * @var null|string
27 */
28 protected $old_version;
29
30 /**
31 * Initialize class
32 */
33 public function setup() {
34 if ( defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK ) {
35 $this->old_version = get_site_option( 'ep_version', false );
36 } else {
37 $this->old_version = get_option( 'ep_version', false );
38 }
39
40 /**
41 * An array with the upgrades routines.
42 * Indexes are the ElasticPress version and values
43 * are an array with the method name and, if needed,
44 * the action name where it should be hooked.
45 */
46 $routines = [
47 '3.5.2' => [ 'upgrade_3_5_2', 'init' ],
48 '3.5.3' => [ 'upgrade_3_5_3', 'init' ],
49 '3.6.6' => [ 'upgrade_3_6_6', 'init' ],
50 '4.2.2' => [ 'upgrade_4_2_2', 'init' ],
51 ];
52
53 array_walk( $routines, [ $this, 'run_upgrade_routine' ] );
54
55 /**
56 * Check if a reindex is needed.
57 */
58 add_action( 'plugins_loaded', [ $this, 'check_reindex_needed' ], 5 );
59
60 /**
61 * Update the version number.
62 * Note: if a upgrade routine method is hooked to some action,
63 * this code will be executed *earlier* than the routine method.
64 */
65 if ( defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK ) {
66 update_site_option( 'ep_version', sanitize_text_field( EP_VERSION ) );
67 } else {
68 update_option( 'ep_version', sanitize_text_field( EP_VERSION ) );
69 }
70
71 add_filter( 'ep_admin_notices', [ $this, 'resync_notice_4_0_0_instant_results' ] );
72 }
73
74 /**
75 * Run the upgrade routine, if needed.
76 *
77 * @param array $routine Array with the info about the method to call.
78 * If needed to be run in an action, it'll contain the action name.
79 * @param string $version The version number to be tested.
80 */
81 protected function run_upgrade_routine( $routine, $version ) {
82 if ( version_compare( $this->old_version, $version, '<' ) ) {
83 $function_name = $routine[0];
84 $action_tag = $routine[1];
85 $priority = ( ! empty( $routine[2] ) ) ? $routine[2] : 10;
86 if ( $action_tag ) {
87 add_action( $action_tag, [ $this, $function_name ], $priority );
88 } else {
89 $this->$function_name();
90 }
91 }
92 }
93
94 /**
95 * Upgrade routine of v3.5.2.
96 *
97 * If weighting options exist and the WooCommerce feature is enabled,
98 * this method will enable the SKU field.
99 */
100 public function upgrade_3_5_2() {
101 $weighting_options = get_option( 'elasticpress_weighting', [] );
102 if ( empty( $weighting_options ) ) {
103 return;
104 }
105
106 $woocommerce = Features::factory()->get_registered_feature( 'woocommerce' );
107 if ( ! $woocommerce->is_active() ) {
108 return;
109 }
110
111 if ( empty( $weighting_options['product'] ) ) {
112 return;
113 }
114
115 if ( ! empty( $weighting_options['product']['author_name'] ) ) {
116 unset( $weighting_options['product']['author_name'] );
117 }
118
119 $weighting_options['product']['meta._sku.value'] = array(
120 'enabled' => true,
121 'weight' => 1,
122 );
123
124 update_option( 'elasticpress_weighting', $weighting_options );
125 }
126
127 /**
128 * Upgrade routine of v3.5.3.
129 *
130 * Check if synonyms post has the correct post type, otherwise,
131 * change it to the correct one.
132 */
133 public function upgrade_3_5_3() {
134 delete_option( 'elasticpress_synonyms_post_id' );
135 delete_site_option( 'elasticpress_synonyms_post_id' );
136 }
137
138 /**
139 * Upgrade routine of v3.6.6.
140 *
141 * Delete all synonyms that have the post content identical to the example we set.
142 * In previous versions we had a bug that created several posts with it.
143 *
144 * @see https://github.com/10up/ElasticPress/issues/2516
145 */
146 public function upgrade_3_6_6() {
147 global $wpdb;
148
149 $synonyms = \ElasticPress\Features::factory()->get_registered_feature( 'search' )->synonyms;
150
151 if ( ! $synonyms ) {
152 return;
153 }
154
155 $synonyms_example_ids = $wpdb->get_col(
156 $wpdb->prepare(
157 "SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_content = %s LIMIT 100",
158 $synonyms::POST_TYPE_NAME,
159 $synonyms->example_synonym_list()
160 )
161 );
162
163 if ( ! $synonyms_example_ids ) {
164 return;
165 }
166
167 foreach ( $synonyms_example_ids as $synonym_post_id ) {
168 wp_delete_post( $synonym_post_id, true );
169 }
170 }
171
172 /**
173 * Upgrade routine of v4.2.2.
174 *
175 * Delete the transient with ES info, so EP is forced to fetch it again,
176 * determining the correct software type (elasticsearch or opensearch, for example)
177 *
178 * @see https://github.com/10up/ElasticPress/issues/2882
179 */
180 public function upgrade_4_2_2() {
181 if ( defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK ) {
182 delete_site_transient( 'ep_es_info' );
183 } else {
184 delete_transient( 'ep_es_info' );
185 }
186 }
187
188 /**
189 * Adjust the upgrade sync notice to warn users about Instant Results.
190 *
191 * As 4.0.0 introduces this new feature and it requires a resync, admin users
192 * might want to enable the feature before the resync (and then resync only once.)
193 *
194 * @since 4.0.0
195 * @param array $notices All admin notices
196 * @return array
197 */
198 public function resync_notice_4_0_0_instant_results( $notices ) {
199 if ( ! isset( $notices['upgrade_sync'] ) ) {
200 return $notices;
201 }
202
203 $instant_results = \ElasticPress\Features::factory()->get_registered_feature( 'instant-results' );
204 if ( $instant_results->is_active() ) {
205 return $notices;
206 }
207
208 $feature_status = $instant_results->requirements_status();
209 $appended_message = '';
210 if ( 1 >= $feature_status->code ) {
211 if ( defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK ) {
212 $features_url = admin_url( 'network/admin.php?page=elasticpress' );
213 } else {
214 $features_url = admin_url( 'admin.php?page=elasticpress' );
215 }
216
217 $appended_message = wp_kses_post(
218 sprintf(
219 /* translators: 1: <a> tag (Zendesk article); 2. </a>; 3: <a> tag (link to Features screen); 4. </a>; */
220 __( '%1$sInstant Results%2$s is now available in ElasticPress, but requires a re-sync before activation. If you would like to use Instant Results, click %3$shere%4$s to activate the feature and start your sync.', 'elasticpress' ),
221 '<a href="https://elasticpress.zendesk.com/hc/en-us/articles/360050447492#instant-results">',
222 '</a>',
223 '<a href="' . $features_url . '">',
224 '</a>'
225 )
226 );
227 } else {
228 $appended_message = wp_kses_post(
229 sprintf(
230 /* translators: 1: <a> tag (Zendesk article about Instant Results); 2. </a>; 3: <a> tag (Zendesk article about self hosted Elasticsearch setups); 4. </a>; */
231 __( '%1$sInstant Results%2$s is now available in ElasticPress, but requires a re-sync before activation. If you would like to use Instant Results, since you are not using ElasticPress.io, you will also need to %3$sinstall and configure a PHP proxy%4$s.', 'elasticpress' ),
232 '<a href="https://elasticpress.zendesk.com/hc/en-us/articles/360050447492#instant-results">',
233 '</a>',
234 '<a href="https://elasticpress.zendesk.com/hc/en-us/articles/4413938931853-Considerations-for-self-hosted-Elasticsearch-setups">',
235 '</a>'
236 )
237 );
238 }
239
240 $notices['upgrade_sync']['html'] .= '<br><br>' . $appended_message;
241
242 return $notices;
243 }
244
245 /**
246 * Check if a reindex is needed based on the version number.
247 */
248 public function check_reindex_needed() {
249 if ( ! is_admin() || defined( 'DOING_AJAX' ) ) {
250 return;
251 }
252
253 if ( defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK ) {
254 $last_sync = get_site_option( 'ep_last_sync', 'never' );
255 } else {
256 $last_sync = get_option( 'ep_last_sync', 'never' );
257 }
258
259 // No need to upgrade since we've never synced.
260 if ( empty( $last_sync ) || 'never' === $last_sync ) {
261 return;
262 }
263
264 /**
265 * Reindex if we cross a reindex version in the upgrade
266 */
267 $reindex_versions = apply_filters(
268 'ep_reindex_versions',
269 array(
270 '2.2',
271 '2.3.1',
272 '2.4',
273 '2.5.1',
274 '2.6',
275 '2.7',
276 '3.0',
277 '3.1',
278 '3.3',
279 '3.4',
280 '3.6.0',
281 '3.6.1',
282 '4.0.0-beta.1',
283 '4.0.0',
284 )
285 );
286
287 $need_upgrade_sync = false;
288
289 if ( false !== $this->old_version ) {
290 $last_reindex_version = $reindex_versions[ count( $reindex_versions ) - 1 ];
291
292 if ( -1 === version_compare( $this->old_version, $last_reindex_version ) && 0 <= version_compare( EP_VERSION, $last_reindex_version ) ) {
293 $need_upgrade_sync = true;
294 }
295 }
296
297 if ( $need_upgrade_sync ) {
298 if ( defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK ) {
299 update_site_option( 'ep_need_upgrade_sync', true );
300 } else {
301 update_option( 'ep_need_upgrade_sync', true );
302 }
303 }
304 }
305
306 /**
307 * Return singleton instance of class
308 *
309 * @return self
310 */
311 public static function factory() {
312 static $instance = false;
313
314 if ( ! $instance ) {
315 $instance = new self();
316 $instance->setup();
317 }
318
319 return $instance;
320 }
321 }
322