/home/preegmxb/bricks.theoriginalsstudios.com/wp-content/themes/bricks/includes/conditions.php
<?php
namespace Bricks;
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
class Conditions {
public static $groups = [];
public static $options = [];
public function __construct() {
// Init conditions after WP is loaded (@since 1.8.5)
add_action( 'wp_loaded', [ $this, 'init' ] );
}
public function init() {
$this->set_groups();
$this->set_options();
}
/**
* Set condition groups
*
* @return void
*
* @since 1.8.4
*/
public function set_groups() {
$groups = [];
$groups[] = [
'name' => 'post',
'label' => esc_html__( 'Post', 'bricks' ),
];
$groups[] = [
'name' => 'user',
'label' => esc_html__( 'User', 'bricks' ),
];
$groups[] = [
'name' => 'date',
'label' => esc_html__( 'Date & time', 'bricks' ),
];
$groups[] = [
'name' => 'other',
'label' => esc_html__( 'Other', 'bricks' ),
];
// Filter: Add groups
$groups = apply_filters( 'bricks/conditions/groups', $groups );
self::$groups = $groups;
}
/**
* Set condition options
*
* @return void
*
* @since 1.8.4
*/
public function set_options() {
// OPTIONS
$math_options = [
'==' => '==',
'!=' => '!=',
'>=' => '>=',
'<=' => '<=',
'>' => '>',
'<' => '<',
];
$is_not_options = [
'==' => esc_html__( 'is', 'bricks' ),
'!=' => esc_html__( 'is not', 'bricks' ),
];
// post_author: 'id' => 'display_name' of all users with 'edit_posts' capability
$authors = get_users(
[
'fields' => [ 'ID', 'display_name' ],
'orderby' => 'display_name',
'capabilities' => [ 'edit_posts' ],
]
);
$author_options = [];
foreach ( $authors as $author ) {
$author_options[ $author->ID ] = $author->display_name;
}
$options = [];
// POST
$options[] = [
'key' => 'post_id',
'group' => 'post',
'label' => esc_html__( 'Post ID', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => $math_options,
'placeholder' => '==',
],
'value' => [
'type' => 'text',
],
];
$options[] = [
'key' => 'post_title',
'group' => 'post',
'label' => esc_html__( 'Post title', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => [
'==' => esc_html__( 'is', 'bricks' ),
'!=' => esc_html__( 'is not', 'bricks' ),
'contains' => esc_html__( 'contains', 'bricks' ),
'contains_not' => esc_html__( 'does not contain', 'bricks' ),
],
'placeholder' => esc_html__( 'is', 'bricks' ),
],
'value' => [
'type' => 'text',
],
];
$options[] = [
'key' => 'post_parent',
'group' => 'post',
'label' => esc_html__( 'Post parent', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => $math_options,
'placeholder' => '==',
],
'value' => [
'type' => 'text',
'placeholder' => 0,
],
];
$options[] = [
'key' => 'post_status',
'group' => 'post',
'label' => esc_html__( 'Post status', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => $is_not_options,
'placeholder' => esc_html__( 'is', 'bricks' ),
],
'value' => [
'type' => 'select',
'options' => get_post_statuses(),
'multiple' => true,
'placeholder' => esc_html__( 'Select', 'bricks' ),
],
];
$options[] = [
'key' => 'post_author',
'group' => 'post',
'label' => esc_html__( 'Post author', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => $is_not_options,
],
'value' => [
'type' => 'select',
'options' => $author_options,
],
];
$options[] = [
'key' => 'post_date',
'group' => 'post',
'label' => esc_html__( 'Post date', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => $math_options,
'placeholder' => '==',
],
'value' => [
'type' => 'datepicker',
'enableTime' => false,
],
];
// set OR not set
$options[] = [
'key' => 'featured_image',
'group' => 'post',
'label' => esc_html__( 'Featured image', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => $is_not_options,
'placeholder' => esc_html__( 'Select', 'bricks' ),
// 'required' => ['key', '!=', 'featured_image'],
],
'value' => [
'type' => 'select',
'options' => [
'1' => esc_html__( 'set', 'bricks' ),
'0' => esc_html__( 'not set', 'bricks' ),
],
'placeholder' => esc_html__( 'Select', 'bricks' ),
],
];
// USER
$options[] = [
'key' => 'user_logged_in',
'group' => 'user',
'label' => esc_html__( 'User login', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => $is_not_options,
'placeholder' => esc_html__( 'is', 'bricks' ),
],
'value' => [
'type' => 'select',
'options' => [
1 => esc_html__( 'Logged in', 'bricks' ),
0 => esc_html__( 'Logged out', 'bricks' ),
],
'placeholder' => esc_html__( 'Select', 'bricks' ),
],
];
$options[] = [
'key' => 'user_id',
'group' => 'user',
'label' => esc_html__( 'User ID', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => $math_options,
'placeholder' => '==',
],
'value' => [
'type' => 'text',
'placeholder' => '',
],
];
$options[] = [
'key' => 'user_registered',
'group' => 'user',
'label' => esc_html__( 'User registered', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => [
'<' => esc_html__( 'after', 'bricks' ),
'>' => esc_html__( 'before', 'bricks' ),
],
'placeholder' => esc_html__( 'Select', 'bricks' ),
],
'value' => [
'type' => 'datepicker',
'enableTime' => false,
'placeholder' => date( 'Y-m-d' ),
],
];
$options[] = [
'key' => 'user_role',
'group' => 'user',
'label' => esc_html__( 'User role', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => $is_not_options,
],
'value' => [
'type' => 'select',
'options' => wp_roles()->get_names(),
'multiple' => true,
'placeholder' => esc_html__( 'Select', 'bricks' ),
],
];
// DATE
$options[] = [
'key' => 'weekday',
'group' => 'date',
'label' => esc_html__( 'Weekday', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => $math_options,
'placeholder' => '==',
],
'value' => [
'type' => 'select',
'options' => [
1 => esc_html__( 'Monday', 'bricks' ),
2 => esc_html__( 'Tuesday', 'bricks' ),
3 => esc_html__( 'Wednesday', 'bricks' ),
4 => esc_html__( 'Thursday', 'bricks' ),
5 => esc_html__( 'Friday', 'bricks' ),
6 => esc_html__( 'Saturday', 'bricks' ),
7 => esc_html__( 'Sunday', 'bricks' ),
],
'placeholder' => esc_html__( 'Select', 'bricks' ),
],
];
/**
* Note about WP time zone being used
*
* Example: Timezone: UTC+2:00
*
* @since 1.9.3
*/
$timezone_description = esc_html__( 'Timezone', 'bricks' ) . ': UTC' . wp_timezone_string() . ' (<a href="' . admin_url( 'options-general.php' ) . '" target="_blank">' . esc_html__( 'Edit', 'bricks' ) . '</a>)';
$options[] = [
'key' => 'date',
'group' => 'date',
'label' => esc_html__( 'Date', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => $math_options,
'placeholder' => '==',
],
'value' => [
'type' => 'datepicker',
'enableTime' => false,
'placeholder' => date( 'Y-m-d', current_time( 'timestamp' ) ),
'description' => $timezone_description,
],
];
$options[] = [
'key' => 'time',
'group' => 'date',
'label' => esc_html__( 'Time', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => $math_options,
'placeholder' => '==',
],
'value' => [
'type' => 'text',
'placeholder' => date( 'H:i a', current_time( 'timestamp' ) ),
'description' => $timezone_description,
],
];
// @since 1.8
$options[] = [
'key' => 'datetime',
'group' => 'date',
'label' => esc_html__( 'Datetime', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => $math_options,
'placeholder' => '==',
],
'value' => [
'type' => 'datepicker',
'enableTime' => true,
'placeholder' => date( 'Y-m-d h:i a', current_time( 'timestamp' ) ),
'description' => $timezone_description,
],
];
// OTHER
$options[] = [
'key' => 'dynamic_data',
'group' => 'other',
'label' => esc_html__( 'Dynamic data', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => array_merge(
[
'contains' => esc_html__( 'contains', 'bricks' ),
'contains_not' => esc_html__( 'does not contain', 'bricks' ),
],
$math_options
),
'placeholder' => '==',
],
'value' => [
'type' => 'text',
],
];
$options[] = [
'key' => 'browser',
'group' => 'other',
'label' => esc_html__( 'Browser', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => $is_not_options,
'placeholder' => esc_html__( 'is', 'bricks' ),
],
'value' => [
'type' => 'select',
'options' => [
'chrome' => 'Chrome',
'firefox' => 'Firefox',
'safari' => 'Safari',
'edge' => 'Edge',
'opera' => 'Opera',
'msie' => 'Internet Explorer'
],
'placeholder' => esc_html__( 'Select', 'bricks' ),
],
];
$options[] = [
'key' => 'operating_system',
'group' => 'other',
'label' => esc_html__( 'Operating system', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => $is_not_options,
'placeholder' => esc_html__( 'is', 'bricks' ),
],
'value' => [
'type' => 'select',
'options' => [
'windows' => 'Windows',
'mac' => 'macOS',
'linux' => 'Linux',
'ubuntu' => 'Ubuntu',
'iphone' => 'iPhone',
'ipad' => 'iPad',
'ipod' => 'iPod',
'android' => 'Android',
'blackberry' => 'Blackberry',
'webos' => 'Mobile (webOS)',
],
'placeholder' => esc_html__( 'Select', 'bricks' ),
],
];
// Current URL incl. params (@since 1.9.3)
$options[] = [
'key' => 'current_url',
'group' => 'other',
'label' => esc_html__( 'Current URL', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => [
'==' => esc_html__( 'is', 'bricks' ),
'!=' => esc_html__( 'is not', 'bricks' ),
'contains' => esc_html__( 'contains', 'bricks' ),
'contains_not' => esc_html__( 'does not contain', 'bricks' ),
],
'placeholder' => esc_html__( 'is', 'bricks' ),
],
'value' => [
'type' => 'text',
],
];
$options[] = [
'key' => 'referer',
'group' => 'other',
'label' => esc_html__( 'Referrer URL', 'bricks' ),
'compare' => [
'type' => 'select',
'options' => [
'==' => esc_html__( 'is', 'bricks' ),
'!=' => esc_html__( 'is not', 'bricks' ),
'contains' => esc_html__( 'contains', 'bricks' ),
'contains_not' => esc_html__( 'does not contain', 'bricks' ),
],
'placeholder' => esc_html__( 'is', 'bricks' ),
],
'value' => [
'type' => 'text',
],
];
// Filter: Add options
$options = apply_filters( 'bricks/conditions/options', $options );
self::$options = $options;
}
/**
* Return all controls (builder)
*
* @return array
*/
public static function get_controls_data() {
// Return: Prevent querying database outside of builder for condition controls (@since 1.5.7)
if ( ! bricks_is_builder() ) {
return;
}
// STEP: Populate controls for builder
$controls = [];
// Loop over groups
foreach ( self::$groups as $group ) {
// Skip if $group has no name or label
if ( ! isset( $group['name'] ) || empty( $group['name'] ) || ! isset( $group['label'] ) || empty( $group['label'] ) ) {
continue;
}
// Add group title - backwards compatibility. e.g. $controls['postGroupTitle']
$controls[ $group['name'] . 'GroupTitle' ] = [
'label' => $group['label'],
];
// Use array_filter to get controls for current group and must have a key
$group_controls = array_filter(
self::$options,
function( $option ) use ( $group ) {
return $option['group'] === $group['name'] && ! empty( $option['key'] );
}
);
// Add controls for current group
foreach ( $group_controls as $control ) {
$controls[ $control['key'] ] = $control;
}
}
return $controls;
}
/**
* Transform dynamic data tag
*
* Add ':value' to ACF true_false tag to get unlocalized value.
*
* @since 1.9.9
*/
public static function maybe_transform_dynamic_tag( $dynamic_tag ) {
// Return: Not a string
if ( ! is_string( $dynamic_tag ) ) {
return $dynamic_tag;
}
// Add ':value' filter to ACF true_false tag to avoid localisation (in element conditions)
if (
strpos( $dynamic_tag, '{acf_' ) === 0 &&
strpos( $dynamic_tag, ':value}' ) === false &&
$dynamic_tag !== '{acf_get_row_layout}'
) {
// ACF: Get field type from dynamic data tag
$acf_provider = Integrations\Dynamic_Data\Providers::get_registered_provider( 'acf' );
if ( $acf_provider ) {
$tags = $acf_provider->get_tags();
$my_key = str_replace( [ '{','}' ], '', $dynamic_tag );
$field_type = $tags[ $my_key ]['field']['type'] ?? false;
// Add ':value' to true_false DD tag to get unlocalized value
if ( $field_type === 'true_false' ) {
$dynamic_tag = str_replace( '}', ':value}', $dynamic_tag );
}
}
}
return $dynamic_tag;
}
/**
* Check element conditions
*
* At least one condition set must be fulfilled for the element to be rendered.
*
* Inside a condition all items must evaluate to true.
*
* @return boolean true = render element | false = don't render element
*
* @since 1.5.4
*/
public static function check( $conditions, $instance ) {
// Return: Always render element in builder
if ( bricks_is_builder() || bricks_is_builder_call() ) {
return true;
}
$user_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : null;
$post_id = $instance->post_id;
$post = get_post( $post_id );
$user = wp_get_current_user();
$render_element = false;
// Loop over condition sets (logic between sets: OR)
foreach ( $conditions as $condition_set ) {
$render_set = true;
// Loop over conditions inside a set (logic inside a set: AND)
foreach ( $condition_set as $condition ) {
// Skip further checks in condition set if we already have a false condition inside this set
if ( $render_set === false ) {
continue;
}
$key = isset( $condition['key'] ) ? $condition['key'] : false;
$compare = isset( $condition['compare'] ) ? $condition['compare'] : '==';
// NOTE: Might need to use maybe_transform_dynamic_tag() here (@since 1.9.9)
$required = isset( $condition['value'] ) ? $instance->render_dynamic_data( $condition['value'] ) : false;
$value = false;
// STEP: Get current value
switch ( $key ) {
// POST
case 'post_id':
$value = $post_id;
break;
case 'post_title':
$value = $post->post_title ?? '';
break;
case 'post_parent':
$value = $post->post_parent ?? 0;
break;
case 'post_status':
$value = $post->post_status ?? '';
break;
case 'post_author':
$value = $post->post_author ?? 0;
break;
case 'post_date':
$value = isset( $post->post_date ) ? date( 'Y-m-d', strtotime( $post->post_date ) ) : false; // 2022-12-31
break;
case 'featured_image':
$value = has_post_thumbnail( $post_id );
break;
// USER
case 'user_logged_in':
$value = is_user_logged_in();
break;
case 'user_id':
$value = is_a( $user, 'WP_User' ) ? $user->ID : 0;
break;
case 'user_registered':
$value = date( 'Y-m-d', strtotime( $user->user_registered ) );
if ( ! $required ) {
$required = date( 'Y-m-d' );
}
break;
case 'user_role':
$value = is_a( $user, 'WP_User' ) ? $user->roles : [];
break;
// DATE
case 'weekday':
$value = date( 'N' ); // 1 = monday, 2 = tuesday, etc.
break;
// DATE, TIME, DATETIME
case 'date':
case 'time':
case 'datetime':
// Use website current time (@since 1.9.3)
$value = current_time( 'timestamp' );
if ( $required ) {
// Convert user input to timestamp for comparison (@since 1.9.3)
$required = strtotime( $required );
} else {
// No user input, use current time
$required = $value;
}
if ( $key === 'date' ) {
// Just get the date part and compare
$value = date( 'Y-m-d', $value );
$required = date( 'Y-m-d', $required );
}
elseif ( $key === 'time' ) {
// Just get the time part and compare
$value = date( 'H:i', $value );
$required = date( 'H:i', $required );
}
break;
// OTHER
case 'dynamic_data':
$dynamic_data_tag = $condition['dynamic_data'] ?? false;
if ( $dynamic_data_tag ) {
// Transform dynamic data tag - Add ':value' to ACF true_false tag to get unlocalized value
$dynamic_data_tag = self::maybe_transform_dynamic_tag( $dynamic_data_tag );
// Render dynamic data and assign to value
$value = $instance->render_dynamic_data( $dynamic_data_tag );
}
// Re-evaluate value field again because user might use the condition in value field (@since 1.9.9)
$condition_value = $condition['value'] ?? false;
if ( $condition_value ) {
// Transform dynamic data tag: Add ':value' filter to ACF true_false tag to get unlocalized value
$condition_value = self::maybe_transform_dynamic_tag( $condition_value );
// Render dynamic data and assign to required
$required = $instance->render_dynamic_data( $condition_value );
}
break;
case 'browser':
// Logic moved to Helpers::user_agent_to_browser()
$value = Helpers::user_agent_to_browser( $user_agent );
break;
case 'operating_system':
// Logic moved to Helpers::user_agent_to_os()
$value = Helpers::user_agent_to_os( $user_agent );
break;
case 'referer':
$value = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : '';
break;
// @since 1.9.3
case 'current_url':
global $wp;
// Retrieve all GET query parameters and sanitize them
$get_query_params = isset( $_GET ) ? wp_unslash( $_GET ) : [];
$value = home_url( add_query_arg( $get_query_params, $wp->request ? trailingslashit( $wp->request ) : '' ) );
$value = esc_url_raw( $value );
break;
}
/**
* Convert boolean-like strings to actual booleans for proper true/false comparisions
*
* @since 1.7
*/
$possible_boolean = [ 'True', 'False', 'true', 'false', true, false, '1', '0', '' ];
if ( in_array( $required, $possible_boolean, true ) && in_array( $value, $possible_boolean, true ) ) {
$required = filter_var( $required, FILTER_VALIDATE_BOOLEAN );
$value = filter_var( $value, FILTER_VALIDATE_BOOLEAN );
}
// COMPARISON OPERANDS
switch ( $compare ) {
case '==':
// user_role (one of the user roles must be in requested roles array)
if ( is_array( $value ) && is_array( $required ) ) {
$render_set = count( array_intersect( $value, $required ) ) > 0;
}
// Handle array (e.g. post_status) and string value
elseif ( is_array( $required ) ) {
$render_set = in_array( $value, $required );
} else {
$render_set = $value == $required;
}
break;
case '!=':
// @since 1.7.2 - User role (one of the user roles must be in requested roles array) (#862jj0afz)
if ( is_array( $value ) && is_array( $required ) ) {
$render_set = count( array_intersect( $value, $required ) ) == 0;
}
// Handle array (e.g. post_status) and string value
elseif ( is_array( $required ) ) {
$render_set = ! in_array( $value, $required );
} else {
$render_set = $value != $required;
}
break;
case '>=':
$render_set = $value >= $required;
break;
case '<=':
$render_set = $value <= $required;
break;
case '>':
$render_set = $value > $required;
break;
case '<':
$render_set = $value < $required;
break;
// post_title
case 'contains':
// Check if string contains keyword
if ( $value && gettype( $value ) === 'string' && gettype( $required ) === 'string' ) {
$render_set = strpos( $value, $required ) !== false;
} else {
$render_set = false;
}
break;
// post_title
case 'contains_not':
// Check if string does not contain keyword
if ( $value && gettype( $value ) === 'string' && gettype( $required ) === 'string' ) {
$render_set = strpos( $value, $required ) === false;
} else {
$render_set = false;
}
break;
}
/**
* Allow third party plugins to modify the boolean value of a condition
*
* @since 1.8.4
*/
$render_set = apply_filters( 'bricks/conditions/result', $render_set, $key, $condition );
}
// All items inside condition are fulfilled: Render element
if ( $render_set ) {
$render_element = true;
}
}
return $render_element;
}
}