variables = $variables; $this->types = $types; $this->rules = $rules; $this->locales = $locales; } public function register() { add_action( 'glovario_admin_after_variable_form', array( $this, 'rules_panel' ) ); add_action( 'admin_post_glovario_save_rule', array( $this, 'save_rule' ) ); add_action( 'admin_post_glovario_delete_rule', array( $this, 'delete_rule' ) ); } public function rules_panel( $variable ) { if ( empty( $variable['id'] ) ) { echo '

' . esc_html__( 'Save the variable before adding conditional values.', 'glovario' ) . '

'; return; } $rules = $this->rules->for_variable( $variable['id'] ); $add_modal_id = 'glovario-rule-modal-new-' . absint( $variable['id'] ); ?>

rule_summary( $variable, $rule ); ?>

rule_dialog( $variable, null, $add_modal_id ); ?>

rule_condition_chips( $rule['conditions'] ); ?>
rule_dialog( $variable, $rule, $modal_id ); ?> array(), 'auth' => 'everyone', 'roles' => array(), 'post_types' => array(), 'post_ids' => array(), 'locales' => array(), ) ); $specific = false; foreach ( (array) $conditions['locales'] as $locale ) { $specific = true; ?> '', 'until' => '', ) ); if ( $date['from'] ) { $specific = true; /* translators: %s: rule start date and time. */ $this->rule_chip( sprintf( __( 'From %s', 'glovario' ), str_replace( 'T', ' ', $date['from'] ) ) ); } if ( $date['until'] ) { $specific = true; /* translators: %s: rule end date and time. */ $this->rule_chip( sprintf( __( 'Until %s', 'glovario' ), str_replace( 'T', ' ', $date['until'] ) ) ); } $auth_labels = array( 'logged_in' => __( 'Logged-in visitors', 'glovario' ), 'logged_out' => __( 'Logged-out visitors', 'glovario' ), ); if ( isset( $auth_labels[ $conditions['auth'] ] ) ) { $specific = true; $this->rule_chip( $auth_labels[ $conditions['auth'] ] ); } if ( $conditions['roles'] ) { $specific = true; $role_names = wp_roles()->get_names(); $labels = array_map( static function ( $role ) use ( $role_names ) { return isset( $role_names[ $role ] ) ? translate_user_role( $role_names[ $role ] ) : $role; }, (array) $conditions['roles'] ); /* translators: %s: comma-separated user role names. */ $this->rule_chip( sprintf( __( 'Roles: %s', 'glovario' ), implode( ', ', $labels ) ) ); } if ( $conditions['post_types'] ) { $specific = true; $labels = array_map( static function ( $post_type ) { $object = get_post_type_object( $post_type ); return $object ? $object->labels->singular_name : $post_type; }, (array) $conditions['post_types'] ); /* translators: %s: comma-separated post type names. */ $this->rule_chip( sprintf( __( 'Content: %s', 'glovario' ), implode( ', ', $labels ) ) ); } if ( $conditions['post_ids'] ) { $specific = true; /* translators: %s: comma-separated post IDs. */ $this->rule_chip( sprintf( __( 'IDs: %s', 'glovario' ), implode( ', ', array_map( 'absint', (array) $conditions['post_ids'] ) ) ) ); } /** * Filters extra labels shown on a rule in the alternative values list. * * @param string[] $chips Labels. * @param array $conditions Rule conditions. */ foreach ( (array) apply_filters( 'glovario_rule_summary_chips', array(), $conditions ) as $chip ) { $specific = true; $this->rule_chip( (string) $chip ); } if ( RuleEngine::has_audience_conditions( $conditions ) && ! apply_filters( 'glovario_rule_audience_conditions_supported', false ) ) { $this->rule_chip( __( 'Uses conditions that are not applied', 'glovario' ) ); } if ( ! $specific ) { $this->rule_chip( __( 'All visitors, content, dates, and locales', 'glovario' ) ); } } private function rule_chip( $label ) { ?>

rule_form( $variable, $rule ); ?>
0, 'name' => '', 'alternative_value' => '', 'enabled' => 1, 'priority' => 10, 'conditions' => array( 'date' => array( 'from' => '', 'until' => '', ), 'auth' => 'everyone', 'roles' => array(), 'post_types' => array(), 'post_ids' => array(), 'locales' => array(), ), ); $rule = wp_parse_args( $rule ? $rule : array(), $defaults ); $c = wp_parse_args( $rule['conditions'], $defaults['conditions'] ); $roles = wp_roles()->get_names(); $post_types = get_post_types( array( 'show_ui' => true ), 'objects' ); ?>

locale_field( $rule, $c ); ?>
locales->settings(); $current = 1 === count( $selected ) ? reset( $selected ) : ''; $stored = count( $selected ) > 1 || ( '' !== $current && $current !== $settings['default_locale'] && $current !== $settings['second_locale'] ); ?>



guard(); $variable_id = isset( $_POST['variable_id'] ) ? absint( $_POST['variable_id'] ) : 0; check_admin_referer( 'glovario_save_rule_' . $variable_id ); $variable = $this->variables->find( $variable_id ); if ( ! $variable ) { $this->redirect( __( 'Variable not found.', 'glovario' ), 'error' ); } $rule_id = isset( $_POST['rule_id'] ) ? absint( $_POST['rule_id'] ) : 0; if ( $rule_id ) { $existing_rule = $this->rules->find( $rule_id ); if ( ! $existing_rule || (int) $existing_rule['variable_id'] !== $variable_id ) { $this->redirect( __( 'Rule not found.', 'glovario' ), 'error' ); } } $raw_value = isset( $_POST['alternative_value'] ) ? wp_unslash( $_POST['alternative_value'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Type-specific sanitization follows validation. $valid = $this->types->validate( $raw_value, $variable['type'] ); if ( is_wp_error( $valid ) ) { $this->redirect( $valid->get_error_message(), 'error', array( 'action' => 'edit', 'id' => $variable_id, ) ); } $value = $this->types->sanitize( $raw_value, $variable['type'] ); $conditions = $this->conditions_from_request( $rule_id ? $existing_rule['conditions'] : array() ); if ( is_wp_error( $conditions ) ) { $this->redirect( $conditions->get_error_message(), 'error', array( 'action' => 'edit', 'id' => $variable_id, ) ); } do_action( 'glovario_before_rule_change', $variable ); $result = $this->rules->save( array( 'variable_id' => $variable_id, 'name' => isset( $_POST['rule_name'] ) ? sanitize_text_field( wp_unslash( $_POST['rule_name'] ) ) : '', 'alternative_value' => $value, 'enabled' => isset( $_POST['enabled'] ), 'priority' => isset( $_POST['priority'] ) ? (int) $_POST['priority'] : 10, 'conditions' => $conditions, ), $rule_id ); if ( is_wp_error( $result ) ) { $this->redirect( $result->get_error_message(), 'error', array( 'action' => 'edit', 'id' => $variable_id, ) ); } do_action( 'glovario_after_rule_change', $variable_id, $rule_id ? 'rule_updated' : 'rule_created' ); $this->redirect( $rule_id ? __( 'Rule updated.', 'glovario' ) : __( 'Rule created.', 'glovario' ), 'success', array( 'action' => 'edit', 'id' => $variable_id, ) ); } public function delete_rule() { $this->guard(); $id = isset( $_POST['rule_id'] ) ? absint( $_POST['rule_id'] ) : 0; check_admin_referer( 'glovario_delete_rule_' . $id ); $rule = $this->rules->find( $id ); if ( ! $rule ) { $this->redirect( __( 'Rule not found.', 'glovario' ), 'error' ); } $variable = $this->variables->find( $rule['variable_id'] ); do_action( 'glovario_before_rule_change', $variable ); $this->rules->delete( $id ); do_action( 'glovario_after_rule_change', $variable['id'], 'rule_deleted' ); $this->redirect( __( 'Rule deleted.', 'glovario' ), 'success', array( 'action' => 'edit', 'id' => $variable['id'], ) ); } private function conditions_from_request( $existing = array() ) { $from = isset( $_POST['date_from'] ) ? sanitize_text_field( wp_unslash( $_POST['date_from'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Called only by save_rule() after check_admin_referer(). $until = isset( $_POST['date_until'] ) ? sanitize_text_field( wp_unslash( $_POST['date_until'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Called only by save_rule() after check_admin_referer(). foreach ( array_filter( array( $from, $until ) ) as $date ) { if ( ! preg_match( '/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/', $date ) ) { return new \WP_Error( 'invalid_date', __( 'Enter valid condition dates.', 'glovario' ) ); } } // Start from the stored conditions so saving never drops conditions this edition does not edit. $conditions = is_array( $existing ) ? $existing : array(); $conditions['version'] = 1; $conditions['date'] = array( 'from' => $from, 'until' => $until, ); // One language, or none for every language; a rule saved with other languages keeps them. $choice = isset( $_POST['locale'] ) ? sanitize_text_field( wp_unslash( $_POST['locale'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Called only by save_rule() after check_admin_referer(). $conditions['locales'] = self::KEEP_LOCALES === $choice ? array_values( (array) ( $conditions['locales'] ?? array() ) ) : array_filter( array( sanitize_locale_name( $choice ) ) ); /** * Filters rule conditions parsed from the rule editor. * * @param array $conditions Conditions to store. */ return apply_filters( 'glovario_rule_conditions_from_request', $conditions ); } private function guard() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission to use this feature.', 'glovario' ), 403 ); } } private function redirect( $message, $type = 'success', $args = array(), $page = 'glovario' ) { set_transient( 'glovario_notice_' . get_current_user_id(), array( 'message' => $message, 'type' => $type, ), 60 ); wp_safe_redirect( add_query_arg( $args, admin_url( 'admin.php?page=' . $page ) ) ); exit; } }