slug ] ) ) ? (array) $all_settings[ $this->slug ] : []; $feature_settings = wp_parse_args( $feature_settings, $this->default_settings ); return $feature_settings; } /** * Return a specific setting of the feature * * @since 4.5.0 * @param string $setting_name The setting name * @return mixed */ public function get_setting( string $setting_name ) { $settings = $this->get_settings(); return isset( $settings[ $setting_name ] ) ? $settings[ $setting_name ] : null; } /** * Returns true if feature is active * * @since 2.2 * @return boolean */ public function is_active() { $feature_settings = Utils\get_option( 'ep_feature_settings', [] ); $active = false; if ( ! empty( $feature_settings[ $this->slug ] ) && $feature_settings[ $this->slug ]['active'] ) { $active = ! in_array( $this->requirements_status()->get_code(), [ FeatureRequirementsStatus::FORCE_DISABLED, FeatureRequirementsStatus::TEMPORARILY_DISABLED ], true ); } /** * Filter whether a feature is active or not * * @hook ep_feature_active * @param {bool} $active Whether feature is active or not * @param {array} $feature_settings Current feature settings * @param {Feature} $feature Current feature * @since 2.2 * @return {bool} New active value */ return apply_filters( 'ep_feature_active', $active, $feature_settings, $this ); } /** * Get the value of the setting that requires a reindex, if it exists. * * @since 4.5.0 * @return mixed */ public function get_reindex_setting() { $settings = $this->get_settings(); $setting = $this->setting_requires_install_reindex; return $settings && $setting && ! empty( $settings[ $setting ] ) ? $settings[ $setting ] : ''; } /** * To be run after initial feature activation * * @since 2.1 */ public function post_activation() { /** * Fires after feature is activated * * @hook ep_feature_post_activation * @param {string} $slug Feature slug * @param {Feature} $feature Current feature * @since 2.1 */ do_action( 'ep_feature_post_activation', $this->slug, $this ); } /** * To be run after feature deactivation * * @since 5.3.2 */ public function post_deactivation() { /** * Fires after feature is deactivated * * @hook ep_feature_post_deactivation * @param {string} $slug Feature slug * @param {Feature} $feature Current feature * @since 5.3.2 */ do_action( 'ep_feature_post_deactivation', $this->slug, $this ); } /** * Returns the feature title. * * @since 4.4.1 * @return string */ public function get_title(): string { return $this->title; } /** * Returns the feature short title. * * @since 4.4.1 * @return string */ public function get_short_title(): string { if ( ! empty( $this->short_title ) ) { return $this->short_title; } return $this->get_title(); } /** * Returns whether the feature is visible in the dashboard or not. * * By default, all active features are visible. * * @since 4.5.0 * @return boolean */ public function is_visible() { /** * Filter whether a feature is visible or not in the dashboard. * * Example: * ``` * add_filter( * 'ep_feature_is_visible', * function ( $is_visible, $feature_slug ) { * return 'terms' === $feature_slug ? true : $is_visible; * }, * 10, * 2 * ); * ``` * * @hook ep_feature_is_visible * @param {bool} $is_visible True to display the feature * @param {string} $feature_slug Feature slug * @param {Feature} $feature Feature object * @since 4.5.0 * @return {bool} New $is_visible value */ return apply_filters( 'ep_feature_is_visible', $this->is_visible || $this->is_active(), $this->slug, $this ); } /** * Returns whether the feature is available or not. * * @since 4.5.0 * @return boolean */ public function is_available(): bool { $requirements_status = $this->requirements_status(); /** * Filter whether a feature is available or not. * * Example: * ``` * add_filter( * 'ep_feature_is_available', * function ( $is_available, $feature_slug ) { * return 'terms' === $feature_slug ? true : $is_available; * }, * 10, * 2 * ); * ``` * * @hook ep_feature_is_available * @param {bool} $is_available True if the feature is available * @param {string} $feature_slug Feature slug * @param {Feature} $feature Feature object * @since 4.5.0 * @return {bool} New $is_available value */ return apply_filters( 'ep_feature_is_available', $this->is_visible() && ! in_array( $requirements_status->get_code(), [ FeatureRequirementsStatus::FORCE_DISABLED, FeatureRequirementsStatus::TEMPORARILY_DISABLED ], true ), $this->slug, $this ); } /** * Get a JSON representation of the feature * * @since 5.0.0 * @return string */ public function get_json() { $requirements_status = $this->requirements_status(); $feature_desc = [ 'slug' => $this->slug, 'title' => $this->get_title(), 'shortTitle' => $this->get_short_title(), 'summary' => $this->summary, 'docsUrl' => $this->docs_url, 'defaultSettings' => $this->default_settings, 'order' => $this->order, 'isAvailable' => $this->is_available(), 'isPoweredByEpio' => $this->is_powered_by_epio, 'isVisible' => $this->is_visible(), 'reqStatusCode' => $requirements_status->get_code(), 'reqStatusMessages' => (array) $requirements_status->get_message(), 'settingsSchema' => $this->get_settings_schema(), 'group' => $this->group, 'requiredFeature' => $this->get_required_feature(), 'fieldGroups' => $this->get_field_group_map(), ]; return $feature_desc; } /** * Return the feature settings schema * * @since 5.0.0 * @return array */ public function get_settings_schema() { // Settings were not set yet. if ( [] === $this->settings_schema ) { $this->set_settings_schema(); } $active = [ 'default' => false, 'key' => 'active', 'label' => __( 'Enable', 'elasticpress' ), 'requires_feature' => $this->get_required_feature(), 'requires_sync' => $this->requires_install_reindex, 'type' => 'toggle', ]; $settings_schema = [ $active, ...$this->settings_schema, ]; /** * Filter the settings schema of a feature * * @hook ep_feature_is_available * @since 5.0.0 * @param {array} $settings_schema True if the feature is available * @param {string} $feature_slug Feature slug * @param {Feature} $feature Feature object * @return {array} New $settings_schema value */ return apply_filters( 'ep_feature_settings_schema', $settings_schema, $this->slug, $this ); } /** * Reset the cached settings schema so it is rebuilt on next access. * * @since 5.3.3 */ public function reset_settings_schema() { $this->settings_schema = []; } /** * Default implementation of `set_settings_schema` based on the `default_settings` attribute * * @since 5.0.0 */ protected function set_settings_schema() { if ( [] === $this->default_settings ) { return; } foreach ( $this->default_settings as $key => $default_value ) { $type = 'text'; if ( in_array( $default_value, [ '0', '1' ], true ) ) { $type = 'checkbox'; } if ( is_bool( $default_value ) ) { $type = 'toggle'; } $this->settings_schema[] = [ 'default' => $default_value, 'key' => $key, 'label' => $key, 'type' => $type, ]; } } /** * Sets the i18n strings for the feature. * * @return void * @since 5.2.0 */ public function set_i18n_strings(): void { } /** * Get all features required by this feature * * @since 5.3.0 * @return array List of required feature slugs */ public function get_required_feature() { return $this->requires_feature ? array_unique( (array) $this->requires_feature ) : []; } /** * Get the field group map for the feature. * * @since 5.3.0 * @return array */ public function get_field_group_map(): array { /** * Filter available field groups. * * @hook ep_feature_field_groups * @since 5.3.0 * @param {array} $field_groups Current field groups * @return {array} New field groups */ return apply_filters( 'ep_feature_field_groups', $this->field_group_map ); } /** * Get the feature slug. * * @since 5.3.0 * @return string Feature slug. */ public function get_feature_slug(): string { return $this->slug; } /** * Pre-handle feature activation * * This method is called before features are setup and is intended to be used * to modify features requirements status. * * @since 5.3.3 * @return void */ public function pre_handle_feature_activation() { } }