187 lines
5.2 KiB
PHP
187 lines
5.2 KiB
PHP
<?php
|
|
/**
|
|
* Handle logic for the conditional loading of snippets.
|
|
* You'll find here the available logic options and how they apply to snippets.
|
|
*
|
|
* @package WPCode
|
|
*/
|
|
|
|
/**
|
|
* The main conditional logic class that loads all the types.
|
|
*/
|
|
class WPCode_Conditional_Logic {
|
|
|
|
/**
|
|
* Types of conditional logic.
|
|
*
|
|
* @var WPCode_Conditional_Type[]
|
|
*/
|
|
private $types = array();
|
|
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
public function __construct() {
|
|
add_action( 'plugins_loaded', array( $this, 'load_types' ), 0 );
|
|
}
|
|
|
|
/**
|
|
* Load the different conditional logic types.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function load_types() {
|
|
require_once WPCODE_PLUGIN_PATH . 'includes/conditional-logic/class-wpcode-conditional-type.php';
|
|
require_once WPCODE_PLUGIN_PATH . 'includes/conditional-logic/class-wpcode-conditional-user.php';
|
|
require_once WPCODE_PLUGIN_PATH . 'includes/conditional-logic/class-wpcode-conditional-page.php';
|
|
}
|
|
|
|
/**
|
|
* Register an auto-insert type.
|
|
*
|
|
* @param WPCode_Conditional_Type $type The type to add to the available types.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function register_type( $type ) {
|
|
$this->types[ $type->name ] = $type;
|
|
}
|
|
|
|
/**
|
|
* Get all the admin options for the conditional logic form.
|
|
*
|
|
* @param bool $for_js Whether to return the options for JS or not.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_all_admin_options( $for_js = false ) {
|
|
$options = array();
|
|
foreach ( $this->types as $type ) {
|
|
$type->load_type_options(); // Reload the options in case a global snippet made them get loaded before some post types were registered, for example.
|
|
$options[ $type->get_name() ] = array(
|
|
'label' => $type->get_label(),
|
|
'name' => $type->get_name(),
|
|
'category' => $type->get_category(),
|
|
'options' => $type->get_type_options(),
|
|
);
|
|
}
|
|
|
|
// Sort options so the unavailable ones are at the end.
|
|
$available_options = array();
|
|
$unavailable_options = array();
|
|
foreach ( $options as $key => $option ) {
|
|
if ( empty( $option['options'] ) ) {
|
|
continue;
|
|
}
|
|
$first_option = reset( $option['options'] );
|
|
if ( ! empty( $first_option['upgrade'] ) ) {
|
|
$unavailable_options[ $key ] = $option;
|
|
} else {
|
|
$available_options[ $key ] = $option;
|
|
}
|
|
}
|
|
|
|
// For the user logged_in option let's run esc_attr on the option values to save the values correctly.
|
|
if ( $for_js && isset( $available_options['user']['options']['logged_in']['options'] ) ) {
|
|
foreach ( $available_options['user']['options']['logged_in']['options'] as $key => $option ) {
|
|
$available_options['user']['options']['logged_in']['options'][ $key ]['value'] = esc_attr( $option['value'] );
|
|
}
|
|
}
|
|
|
|
return apply_filters( 'wpcode_conditional_logic_admin_options', array_merge( $available_options, $unavailable_options ) );
|
|
}
|
|
|
|
/**
|
|
* Goes through a list of snippets and filters out the ones
|
|
* that don't match the conditional logic rules.
|
|
*
|
|
* @param WPCode_Snippet[] $snippets An array of snippets.
|
|
*
|
|
* @return WPCode_Snippet[]
|
|
*/
|
|
public function check_snippets_conditions( $snippets ) {
|
|
// If there's nothing to evaluate just return an empty array.
|
|
if ( empty( $snippets ) ) {
|
|
return array();
|
|
}
|
|
|
|
$filtered_snippets = array();
|
|
foreach ( $snippets as $snippet ) {
|
|
if ( ! $snippet->conditional_rules_enabled() ) {
|
|
// If rules are disabled, ignore.
|
|
$filtered_snippets[] = $snippet;
|
|
continue;
|
|
}
|
|
$rules = $snippet->get_conditional_rules();
|
|
if ( ! isset( $rules['show'] ) ) {
|
|
continue;
|
|
}
|
|
$show = 'show' === $rules['show'];
|
|
$rules_are_met = $this->are_snippet_rules_met( $snippet );
|
|
if ( $show && ! $rules_are_met ) {
|
|
// If we should show based on conditions, and conditions
|
|
// are not met, skip.
|
|
continue;
|
|
}
|
|
if ( ! $show && $rules_are_met ) {
|
|
// If we should hide based on conditions, and conditions
|
|
// are met, skip.
|
|
continue;
|
|
}
|
|
|
|
$filtered_snippets[] = $snippet;
|
|
}
|
|
|
|
return $filtered_snippets;
|
|
}
|
|
|
|
/**
|
|
* Takes a snippet and evaluates if conditional logic rules
|
|
* are met.
|
|
*
|
|
* @param WPCode_Snippet $snippet The snippet instance.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function are_snippet_rules_met( $snippet ) {
|
|
$rules = $snippet->get_conditional_rules();
|
|
if ( empty( $rules ) || ! is_array( $rules ) || empty( $rules['groups'] ) ) {
|
|
return true;
|
|
}
|
|
|
|
// Go through all rule groups.
|
|
foreach ( $rules['groups'] as $rule_group ) {
|
|
// If any of the groups are met return true.
|
|
if ( $this->are_group_rules_met( $rule_group, $snippet ) ) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// If no group rules satisfy the conditions, return false.
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Evaluate all the rows of rules in a group.
|
|
*
|
|
* @param array $rule_group An array of rows.
|
|
* @param WPCode_Snippet $snippet The snippet we are evaluating the rules for.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function are_group_rules_met( $rule_group, $snippet ) {
|
|
foreach ( $rule_group as $rule_row ) {
|
|
if ( ! isset( $rule_row['type'] ) || ! isset( $this->types[ $rule_row['type'] ] ) ) {
|
|
continue;
|
|
}
|
|
$rule_type = $this->types[ $rule_row['type'] ];
|
|
if ( ! $rule_type->evaluate_rule_row( $rule_row, $snippet ) ) {
|
|
// If this row doesn't match, the whole group fails.
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// If none of the rows failed the group matches.
|
|
return true;
|
|
}
|
|
}
|