PluginProbe
ElasticPress / 4.4.0
ElasticPress v4.4.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.4.0, at includes/classes/Upgrades.php

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