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 / Feature.php

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

507 lines 12.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Feature class to be initiated for all features.
4 *
5 * All features extend this class.
6 *
7 * @since 2.1
8 * @package elasticpress
9 */
10
11 namespace ElasticPress;
12
13 use ElasticPress\FeatureRequirementsStatus;
14 use ElasticPress\Utils;
15
16 if ( ! defined( 'ABSPATH' ) ) {
17 exit; // Exit if accessed directly.
18 }
19
20 /**
21 * Feature abstract class
22 */
23 abstract class Feature {
24 /**
25 * Feature slug
26 *
27 * @var string
28 * @since 2.1
29 */
30 public $slug;
31
32 /**
33 * Feature pretty title
34 *
35 * @var string
36 * @since 2.1
37 */
38 public $title;
39
40 /**
41 * Short title
42 *
43 * @var string
44 * @since 4.4.1
45 */
46 public $short_title;
47
48 /**
49 * Feature summary
50 *
51 * @var string
52 * @since 4.0.0
53 */
54 public $summary;
55
56 /**
57 * URL to feature documentation.
58 *
59 * @var string
60 * @since 4.0.0
61 */
62 public $docs_url;
63
64 /**
65 * Optional feature default settings
66 *
67 * @since 2.2
68 * @var array
69 */
70 public $default_settings = [];
71
72 /**
73 * True if the feature requires content reindexing after activating
74 *
75 * @since 2.1
76 * @var bool
77 */
78 public $requires_install_reindex = false;
79
80 /**
81 * The slug of a setting that requires content reindexing after activating.
82 *
83 * @since 4.5.0
84 * @var string
85 */
86 public $setting_requires_install_reindex = '';
87
88 /**
89 * The order in the features screen
90 *
91 * @var int
92 * @since 3.6.0
93 */
94 public $order;
95
96 /**
97 * Set if a feature should be on the left or right side
98 *
99 * @var string
100 * @since 3.6.0
101 */
102 public $group_order;
103
104 /**
105 * True if activation of this feature should be available during
106 * installation.
107 *
108 * @since 4.0.0
109 * @var boolean
110 */
111 public $available_during_installation = false;
112
113 /**
114 * Whether the feature should be always visible in the dashboard
115 *
116 * @since 4.5.0
117 * @var boolean
118 */
119 protected $is_visible = true;
120
121 /**
122 * Run on every page load for feature to set itself up
123 *
124 * @since 2.1
125 */
126 abstract public function setup();
127
128 /**
129 * Output feature box summary
130 *
131 * @since 2.1
132 */
133 public function output_feature_box_summary() {
134 if ( $this->summary ) {
135 echo '<p>' . esc_html( $this->summary ) . '</p>';
136 }
137 }
138
139 /**
140 * Implement to output feature box long text
141 *
142 * @since 3.0
143 */
144 abstract public function output_feature_box_long();
145
146 /**
147 * Create feature
148 *
149 * @since 3.0
150 */
151 public function __construct() {
152 /**
153 * Fires when Feature object is created
154 *
155 * @hook ep_feature_create
156 * @param {Feature} $feature Current feature
157 * @since 3.0
158 */
159 do_action( 'ep_feature_create', $this );
160 }
161
162 /**
163 * Returns requirements status of feature
164 *
165 * @since 2.2
166 * @return FeatureRequirementsStatus
167 */
168 public function requirements_status() {
169 $status = new FeatureRequirementsStatus( 0 );
170
171 /**
172 * Filter feature requirement status
173 *
174 * @hook ep_{indexable_slug}_index_kill
175 * @param {FeatureRequirementStatus} $status Current feature requirement status
176 * @param {Feature} $feature Current feature
177 * @since 2.2
178 * @return {FeatureRequirementStatus} New status
179 */
180 return apply_filters( 'ep_feature_requirements_status', $status, $this );
181 }
182
183 /**
184 * Return feature settings
185 *
186 * @since 2.2.1, 4.5.0 started using default settings
187 * @return array
188 */
189 public function get_settings() {
190 $all_settings = Utils\get_option( 'ep_feature_settings', [] );
191
192 $feature_settings = ( ! empty( $all_settings[ $this->slug ] ) ) ? (array) $all_settings[ $this->slug ] : [];
193
194 $feature_settings = wp_parse_args( $feature_settings, $this->default_settings );
195
196 return $feature_settings;
197 }
198
199 /**
200 * Return a specific setting of the feature
201 *
202 * @since 4.5.0
203 * @param string $setting_name The setting name
204 * @return mixed
205 */
206 public function get_setting( string $setting_name ) {
207 $settings = $this->get_settings();
208
209 return isset( $settings[ $setting_name ] ) ? $settings[ $setting_name ] : null;
210 }
211
212 /**
213 * Returns true if feature is active
214 *
215 * @since 2.2
216 * @return boolean
217 */
218 public function is_active() {
219 $feature_settings = Utils\get_option( 'ep_feature_settings', [] );
220
221 $active = false;
222
223 if ( ! empty( $feature_settings[ $this->slug ] ) && $feature_settings[ $this->slug ]['active'] ) {
224 $active = true;
225 }
226
227 /**
228 * Filter whether a feature is active or not
229 *
230 * @hook ep_feature_active
231 * @param {bool} $active Whether feature is active or not
232 * @param {array} $feature_settings Current feature settings
233 * @param {Feature} $feature Current feature
234 * @since 2.2
235 * @return {bool} New active value
236 */
237 return apply_filters( 'ep_feature_active', $active, $feature_settings, $this );
238 }
239
240 /**
241 * Get the value of the setting that requires a reindex, if it exists.
242 *
243 * @since 4.5.0
244 * @return mixed
245 */
246 public function get_reindex_setting() {
247 $settings = $this->get_settings();
248 $setting = $this->setting_requires_install_reindex;
249
250 return $settings && $setting && ! empty( $settings[ $setting ] )
251 ? $settings[ $setting ]
252 : '';
253 }
254
255 /**
256 * To be run after initial feature activation
257 *
258 * @since 2.1
259 */
260 public function post_activation() {
261 /**
262 * Fires after feature is activated
263 *
264 * @hook ep_feature_post_activation
265 * @param {string} $slug Feature slug
266 * @param {Feature} $feature Current feature
267 * @since 2.1
268 */
269 do_action( 'ep_feature_post_activation', $this->slug, $this );
270 }
271
272 /**
273 * Outputs feature box
274 *
275 * @since 2.1
276 */
277 public function output_feature_box() {
278 $this->output_feature_box_summary();
279
280 /**
281 * Fires before feature box summary is shown
282 *
283 * @hook ep_feature_box_summary
284 * @param {string} $slug Feature slug
285 * @param {Feature} $feature Current feature
286 * @since 2.1
287 */
288 do_action( 'ep_feature_box_summary', $this->slug, $this );
289 ?>
290
291 <button aria-expanded="false" class="learn-more button button-secondary button-small" type="button"><?php esc_html_e( 'Learn more', 'elasticpress' ); ?></button>
292
293 <div class="long">
294 <?php $this->output_feature_box_long(); ?>
295
296 <p><button aria-expanded="true" class="collapse button button-secondary button-small" type="button"><?php esc_html_e( 'Collapse', 'elasticpress' ); ?></button></p>
297
298 <?php
299 /**
300 * Fires after feature long description
301 *
302 * @hook ep_feature_box_long
303 * @param {string} $slug Feature slug
304 * @param {Feature} $feature Current feature
305 * @since 2.1
306 */
307 do_action( 'ep_feature_box_long', $this->slug, $this );
308 ?>
309
310 </div>
311 <?php
312 }
313
314 /**
315 * Output extra feature box settings.
316 *
317 * By default this does nothing. Override to add additional settings.
318 *
319 * @since 3.0
320 */
321 public function output_feature_box_settings() {
322 /**
323 * Optionally override
324 */
325 }
326
327 /**
328 * Output feature settings
329 *
330 * @since 3.0
331 */
332 public function output_settings_box() {
333 $requirements_status = $this->requirements_status();
334 $sync_url = ( defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK )
335 ? network_admin_url( 'admin.php?page=elasticpress-sync' )
336 : admin_url( 'admin.php?page=elasticpress-sync' );
337 ?>
338
339 <form>
340 <?php
341 if ( ! empty( $requirements_status->message ) ) :
342 $messages = (array) $requirements_status->message;
343 ?>
344 <?php foreach ( $messages as $message ) : ?>
345 <div class="requirements-status-notice">
346 <?php echo wp_kses_post( $message ); ?>
347 </div>
348 <?php endforeach; ?>
349 <?php endif; ?>
350
351 <?php if ( $this->requires_install_reindex || $this->setting_requires_install_reindex ) : ?>
352 <div class="requirements-status-notice requirements-status-notice--reindex" role="status">
353 <?php esc_html_e( 'Enabling this feature will require re-syncing your content.', 'elasticpress' ); ?>
354 </div>
355 <?php endif; ?>
356
357 <div class="requirements-status-notice requirements-status-notice--syncing" role="alert">
358 <?php
359 printf(
360 '%1$s <a href="%2$s">%3$s</a>',
361 esc_html__( 'Settings not saved. Cannot save settings while a sync is in progress.', 'elasticpress' ),
362 esc_url( $sync_url ),
363 esc_html__( 'View sync status.', 'elasticpress' )
364 );
365 ?>
366 </div>
367
368 <h3><?php esc_html_e( 'Settings', 'elasticpress' ); ?></h3>
369
370 <div class="feature-fields">
371 <div class="field js-toggle-feature">
372 <div class="field-name status"><?php esc_html_e( 'Status', 'elasticpress' ); ?></div>
373 <div class="input-wrap <?php if ( 2 === $requirements_status->code ) : ?>disabled<?php endif; ?>">
374 <label><input name="settings[active]" <?php disabled( 2 === $requirements_status->code ); ?> type="radio" <?php checked( $this->is_active() ); ?> value="1"><?php esc_html_e( 'Enabled', 'elasticpress' ); ?></label><br>
375 <label><input name="settings[active]" <?php disabled( 2 === $requirements_status->code ); ?> type="radio" <?php checked( ! $this->is_active() ); ?> value="0"><?php esc_html_e( 'Disabled', 'elasticpress' ); ?></label>
376 </div>
377 </div>
378
379 <?php
380 $this->output_feature_box_settings();
381 ?>
382 </div>
383
384 <div class="action-wrap">
385 <span class="no-dash-sync">
386 <?php esc_html_e( 'Setting adjustments to this feature require a re-sync. Use WP-CLI.', 'elasticpress' ); ?>
387 </span>
388
389 <input type="hidden" name="action" value="ep_save_feature">
390 <input type="hidden" name="feature" value="<?php echo esc_attr( $this->slug ); ?>">
391 <input type="hidden" name="requires_reindex" value="<?php echo $this->requires_install_reindex ? '1' : '0'; ?>">
392 <input type="hidden" name="was_active" value="<?php echo $this->is_active() ? '1' : '0'; ?>">
393 <input type="hidden" name="setting_requires_reindex" value="<?php echo esc_attr( $this->setting_requires_install_reindex ); ?>">
394 <input type="hidden" name="setting_requires_reindex_was" value="<?php echo esc_attr( $this->get_reindex_setting() ); ?>">
395 <?php wp_nonce_field( 'ep_dashboard_nonce', 'nonce' ); ?>
396
397 <button name="submit" <?php disabled( 2 === $requirements_status->code || ( $this->requires_install_reindex && defined( 'EP_DASHBOARD_SYNC' ) && ! EP_DASHBOARD_SYNC ) ); ?> class="button button-primary" type="submit">
398 <?php esc_html_e( 'Save', 'elasticpress' ); ?>
399 </button>
400 </div>
401 </form>
402
403 <?php
404 }
405
406 /**
407 * Returns the ElasticPress.io logo.
408 *
409 * @since 4.4.1
410 * @return string
411 */
412 public function get_epio_logo() : string {
413 return sprintf( '<img class="feature-epio-logo" alt="ElasticPresss.io logo" src="%s" width="110" height="20">', esc_url( plugins_url( '/images/logo-elasticpress-io.svg', EP_FILE ) ) );
414 }
415
416 /**
417 * Returns the feature title.
418 *
419 * @since 4.4.1
420 * @return string
421 */
422 public function get_title() : string {
423 return $this->title;
424 }
425
426 /**
427 * Returns the feature short title.
428 *
429 * @since 4.4.1
430 * @return string
431 */
432 public function get_short_title() : string {
433 if ( ! empty( $this->short_title ) ) {
434 return $this->short_title;
435 }
436
437 return $this->get_title();
438 }
439
440 /**
441 * Returns whether the feature is visible in the dashboard or not.
442 *
443 * By default, all active features are visible.
444 *
445 * @since 4.5.0
446 * @return boolean
447 */
448 public function is_visible() {
449 /**
450 * Filter whether a feature is visible or not in the dashboard.
451 *
452 * Example:
453 * ```
454 * add_filter(
455 * 'ep_feature_is_visible',
456 * function ( $is_visible, $feature_slug ) {
457 * return 'terms' === $feature_slug ? true : $is_visible;
458 * },
459 * 10,
460 * 2
461 * );
462 * ```
463 *
464 * @hook ep_feature_is_visible
465 * @param {bool} $is_visible True to display the feature
466 * @param {string} $feature_slug Feature slug
467 * @param {Feature} $feature Feature object
468 * @since 4.5.0
469 * @return {bool} New $is_visible value
470 */
471 return apply_filters( 'ep_feature_is_visible', $this->is_visible || $this->is_active(), $this->slug, $this );
472 }
473
474 /**
475 * Returns whether the feature is available or not.
476 *
477 * @since 4.5.0
478 * @return boolean
479 */
480 public function is_available() : bool {
481 $requirements_status = $this->requirements_status();
482 /**
483 * Filter whether a feature is available or not.
484 *
485 * Example:
486 * ```
487 * add_filter(
488 * 'ep_feature_is_available',
489 * function ( $is_available, $feature_slug ) {
490 * return 'terms' === $feature_slug ? true : $is_available;
491 * },
492 * 10,
493 * 2
494 * );
495 * ```
496 *
497 * @hook ep_feature_is_available
498 * @param {bool} $is_available True if the feature is available
499 * @param {string} $feature_slug Feature slug
500 * @param {Feature} $feature Feature object
501 * @since 4.5.0
502 * @return {bool} New $is_available value
503 */
504 return apply_filters( 'ep_feature_is_available', $this->is_visible && 2 !== $requirements_status->code, $this->slug, $this );
505 }
506 }
507