block-api
2 days ago
form
2 days ago
import
2 days ago
popup
2 days ago
templates
2 days ago
class-gutenberg-block-styles.php
2 days ago
class-gutenberg-cache-util.php
2 days ago
class-gutenberg-conditions-controller.php
2 days ago
class-gutenberg-controller.php
2 days ago
class-gutenberg-dynamic-content-controller.php
2 days ago
class-gutenberg-enhancements-controller.php
2 days ago
class-gutenberg-social-icons-controller.php
2 days ago
class-gutenberg-sticky-controller.php
2 days ago
class-gutenberg-z-index-controller.php
2 days ago
class-gutenberg-conditions-controller.php
165 lines
| 1 | <?php |
| 2 | |
| 3 | namespace SuperbAddons\Gutenberg\Controllers; |
| 4 | |
| 5 | defined('ABSPATH') || exit(); |
| 6 | |
| 7 | class GutenbergConditionsController |
| 8 | { |
| 9 | public static function Initialize() |
| 10 | { |
| 11 | add_filter('pre_render_block', [__CLASS__, 'MaybeHideBlock'], 10, 2); |
| 12 | } |
| 13 | |
| 14 | public static function MaybeHideBlock($pre_render, $parsed_block) |
| 15 | { |
| 16 | // Preview contexts should always show blocks regardless of conditions, |
| 17 | // so authors can see their own content when clicking "Preview". |
| 18 | if (is_preview() || is_customize_preview()) { |
| 19 | return $pre_render; |
| 20 | } |
| 21 | |
| 22 | if (!isset($parsed_block['attrs']['spbaddConditions']) || !is_array($parsed_block['attrs']['spbaddConditions'])) { |
| 23 | return $pre_render; |
| 24 | } |
| 25 | |
| 26 | $visibility = $parsed_block['attrs']['spbaddConditions']; |
| 27 | if (empty($visibility['ruleGroups']) || !is_array($visibility['ruleGroups'])) { |
| 28 | return $pre_render; |
| 29 | } |
| 30 | |
| 31 | $action = isset($visibility['action']) ? sanitize_text_field($visibility['action']) : 'show'; |
| 32 | $has_user_condition = false; |
| 33 | $has_any_evaluated = false; |
| 34 | $block_visible = false; |
| 35 | |
| 36 | foreach ($visibility['ruleGroups'] as $group) { |
| 37 | if (empty($group['conditions']) || !is_array($group['conditions'])) { |
| 38 | continue; |
| 39 | } |
| 40 | |
| 41 | $all_pass = true; |
| 42 | $has_evaluated = false; |
| 43 | foreach ($group['conditions'] as $condition) { |
| 44 | if (!is_array($condition) || empty($condition['type'])) { |
| 45 | continue; |
| 46 | } |
| 47 | |
| 48 | $has_evaluated = true; |
| 49 | $has_any_evaluated = true; |
| 50 | $type = sanitize_text_field($condition['type']); |
| 51 | if (in_array($type, array('userVisibility', 'userRoles'), true)) { |
| 52 | $has_user_condition = true; |
| 53 | } |
| 54 | |
| 55 | if (!self::EvaluateCondition($condition)) { |
| 56 | $all_pass = false; |
| 57 | break; |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | if ($all_pass && $has_evaluated) { |
| 62 | $block_visible = true; |
| 63 | break; // OR logic — any group passing is enough |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | // Nothing evaluable (malformed/migrated data) — fall through as if no |
| 68 | // conditions were configured rather than silently hiding the block. |
| 69 | if (!$has_any_evaluated) { |
| 70 | return $pre_render; |
| 71 | } |
| 72 | |
| 73 | // Invert result for "hide if" action |
| 74 | if ($action === 'hide') { |
| 75 | $block_visible = !$block_visible; |
| 76 | } |
| 77 | |
| 78 | // Output varies per visitor for user-based conditions — must not be cached. |
| 79 | if ($has_user_condition) { |
| 80 | GutenbergCacheUtil::MarkAsUncacheable(); |
| 81 | } |
| 82 | |
| 83 | if (!$block_visible) { |
| 84 | // Short-circuits the entire render pipeline: children, render_callback, |
| 85 | // and enqueues tied to this block never run. |
| 86 | return ''; |
| 87 | } |
| 88 | |
| 89 | return $pre_render; |
| 90 | } |
| 91 | |
| 92 | private static function EvaluateCondition($condition) |
| 93 | { |
| 94 | $type = isset($condition['type']) ? sanitize_text_field($condition['type']) : ''; |
| 95 | $operator = isset($condition['operator']) ? sanitize_text_field($condition['operator']) : 'is'; |
| 96 | if (!in_array($operator, array('is', 'isNot'), true)) { |
| 97 | $operator = 'is'; |
| 98 | } |
| 99 | |
| 100 | switch ($type) { |
| 101 | case 'userVisibility': |
| 102 | // No operator — values are already opposites |
| 103 | $val = isset($condition['value']) ? sanitize_text_field($condition['value']) : ''; |
| 104 | if ($val === 'logged-in') return is_user_logged_in(); |
| 105 | if ($val === 'logged-out') return !is_user_logged_in(); |
| 106 | return true; |
| 107 | |
| 108 | case 'userRoles': |
| 109 | $roles = isset($condition['value']) && is_array($condition['value']) ? $condition['value'] : array(); |
| 110 | $roles = array_map('sanitize_text_field', $roles); |
| 111 | if (empty($roles)) return true; |
| 112 | if (!is_user_logged_in()) { |
| 113 | $result = false; |
| 114 | } else { |
| 115 | $user = wp_get_current_user(); |
| 116 | $result = !empty(array_intersect($roles, $user->roles)); |
| 117 | } |
| 118 | return $operator === 'isNot' ? !$result : $result; |
| 119 | |
| 120 | case 'postType': |
| 121 | $types = isset($condition['value']) && is_array($condition['value']) ? $condition['value'] : array(); |
| 122 | $types = array_map('sanitize_text_field', $types); |
| 123 | if (empty($types)) return true; |
| 124 | $result = in_array(get_post_type(), $types, true); |
| 125 | return $operator === 'isNot' ? !$result : $result; |
| 126 | |
| 127 | case 'postAuthor': |
| 128 | $authors = isset($condition['value']) && is_array($condition['value']) ? $condition['value'] : array(); |
| 129 | if (empty($authors)) return true; |
| 130 | $result = in_array((int) get_post_field('post_author'), array_map('intval', $authors), true); |
| 131 | return $operator === 'isNot' ? !$result : $result; |
| 132 | |
| 133 | case 'postCategory': |
| 134 | $cats = isset($condition['value']) && is_array($condition['value']) ? $condition['value'] : array(); |
| 135 | if (empty($cats)) return true; |
| 136 | $result = has_category(array_map('intval', $cats)); |
| 137 | return $operator === 'isNot' ? !$result : $result; |
| 138 | |
| 139 | case 'postTag': |
| 140 | $tags = isset($condition['value']) && is_array($condition['value']) ? $condition['value'] : array(); |
| 141 | if (empty($tags)) return true; |
| 142 | $result = has_tag(array_map('intval', $tags)); |
| 143 | return $operator === 'isNot' ? !$result : $result; |
| 144 | |
| 145 | default: |
| 146 | // Delegate to premium/extensions (pass operator via condition array) |
| 147 | $result = apply_filters('superbaddons_evaluate_visibility_condition', null, $condition); |
| 148 | return $result === null ? true : (bool) $result; |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | public static function GetConditionsRoles() |
| 153 | { |
| 154 | $wp_roles = wp_roles(); |
| 155 | $roles = array(); |
| 156 | foreach ($wp_roles->roles as $role_key => $role) { |
| 157 | $roles[] = array( |
| 158 | 'value' => sanitize_text_field($role_key), |
| 159 | 'label' => translate_user_role($role['name']), |
| 160 | ); |
| 161 | } |
| 162 | return $roles; |
| 163 | } |
| 164 | } |
| 165 |