← All changes
|
modules/widget-visibility/widget-conditions.php
+95
-19
13.5.2
→
16.3-a.1
View file →
| @@ -4,10 +4,15 @@ | ||
| 4 | 4 | * |
| 5 | 5 | * @package automattic/jetpack |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | +use Automattic\Block_Scanner; | |
| 8 | 9 | use Automattic\Jetpack\Assets; |
| 9 | 10 | |
| 11 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 12 | + exit( 0 ); | |
| 13 | +} | |
| 14 | + | |
| 10 | 15 | /** |
| 11 | 16 | * Hide or show legacy widgets conditionally. |
| 12 | 17 | * |
| 13 | 18 | * This class has two responsiblities - administrating the conditions in which legacy widgets may be hidden or shown |
| @@ -662,11 +667,11 @@ | ||
| 662 | 667 | * @return array Modified settings. |
| 663 | 668 | */ |
| 664 | 669 | public static function widget_update( $instance, $new_instance, $old_instance ) { |
| 665 | 670 | $conditions = array(); |
| 666 | - $conditions['action'] = isset( $new_instance['conditions']['action'] ) ? $new_instance['conditions']['action'] : null; | |
| 671 | + $conditions['action'] = $new_instance['conditions']['action'] ?? null; | |
| 667 | 672 | $conditions['match_all'] = ! empty( $new_instance['conditions']['match_all'] ) ? '1' : '0'; |
| 668 | - $conditions['rules'] = isset( $new_instance['conditions']['rules'] ) ? $new_instance['conditions']['rules'] : array(); | |
| 673 | + $conditions['rules'] = $new_instance['conditions']['rules'] ?? array(); | |
| 669 | 674 | |
| 670 | 675 | if ( isset( $new_instance['conditions']['rules_major'] ) ) { |
| 671 | 676 | foreach ( $new_instance['conditions']['rules_major'] as $index => $major_rule ) { |
| 672 | 677 | if ( ! $major_rule ) { |
| @@ -674,10 +679,10 @@ | ||
| 674 | 679 | } |
| 675 | 680 | |
| 676 | 681 | $conditions['rules'][] = array( |
| 677 | 682 | 'major' => $major_rule, |
| 678 | - 'minor' => isset( $new_instance['conditions']['rules_minor'][ $index ] ) ? $new_instance['conditions']['rules_minor'][ $index ] : '', | |
| 679 | - 'has_children' => isset( $new_instance['conditions']['page_children'][ $index ] ) ? true : false, | |
| 683 | + 'minor' => $new_instance['conditions']['rules_minor'][ $index ] ?? '', | |
| 684 | + 'has_children' => isset( $new_instance['conditions']['page_children'][ $index ] ), | |
| 680 | 685 | ); |
| 681 | 686 | } |
| 682 | 687 | } |
| 683 | 688 | |
| @@ -794,8 +799,42 @@ | ||
| 794 | 799 | return $rule['major'] . ':' . $rule['minor']; |
| 795 | 800 | } |
| 796 | 801 | |
| 797 | 802 | /** |
| 803 | + * Normalize widget `content` into a string suitable for block scanning. | |
| 804 | + * | |
| 805 | + * @since 15.1 | |
| 806 | + * | |
| 807 | + * @param mixed $content The widget instance 'content' value. | |
| 808 | + * @return string|false Normalized string content or false if none. | |
| 809 | + */ | |
| 810 | + private static function normalize_widget_content( $content ) { | |
| 811 | + if ( empty( $content ) ) { | |
| 812 | + return false; | |
| 813 | + } | |
| 814 | + | |
| 815 | + if ( is_string( $content ) ) { | |
| 816 | + return $content; | |
| 817 | + } | |
| 818 | + | |
| 819 | + if ( ! is_array( $content ) ) { | |
| 820 | + return false; | |
| 821 | + } | |
| 822 | + | |
| 823 | + if ( isset( $content['content'] ) && is_string( $content['content'] ) ) { | |
| 824 | + return $content['content']; | |
| 825 | + } | |
| 826 | + | |
| 827 | + if ( isset( $content[0] ) && is_array( $content[0] ) && isset( $content[0]['blockName'] ) ) { | |
| 828 | + // Looks like a parsed blocks array. | |
| 829 | + return serialize_blocks( $content ); | |
| 830 | + } | |
| 831 | + | |
| 832 | + // Unknown array shape: treat as no visibility rules. | |
| 833 | + return false; | |
| 834 | + } | |
| 835 | + | |
| 836 | + /** | |
| 798 | 837 | * Determine whether the widget should be displayed based on conditions set by the user. |
| 799 | 838 | * |
| 800 | 839 | * @param array $instance The widget settings. |
| 801 | 840 | * @return array Settings to display or bool false to hide. |
| @@ -820,23 +859,47 @@ | ||
| 820 | 859 | if ( self::filter_widget_check_conditions( $instance['conditions'] ) ) { |
| 821 | 860 | return $instance; |
| 822 | 861 | } |
| 823 | 862 | return false; |
| 824 | - } elseif ( ! empty( $instance['content'] ) && has_blocks( $instance['content'] ) ) { | |
| 825 | - // Block-Based widgets: We have gutenberg blocks that could have the 'conditions' attribute. | |
| 826 | - $blocks = parse_blocks( $instance['content'] ); | |
| 827 | - if ( empty( $blocks[0]['attrs']['conditions']['rules'] ) ) { | |
| 863 | + } | |
| 864 | + | |
| 865 | + if ( empty( $instance['content'] ) ) { | |
| 866 | + return $instance; | |
| 867 | + } | |
| 868 | + $content = self::normalize_widget_content( $instance['content'] ?? null ); | |
| 869 | + | |
| 870 | + if ( false === $content || ! has_blocks( $content ) ) { | |
| 871 | + // No visibility found. | |
| 872 | + return $instance; | |
| 873 | + } | |
| 874 | + | |
| 875 | + $scanner = Block_Scanner::create( $content ); | |
| 876 | + if ( ! $scanner ) { | |
| 877 | + // No Rules: Display widget. | |
| 878 | + return $instance; | |
| 879 | + } | |
| 880 | + | |
| 881 | + // Find the first block that opens | |
| 882 | + while ( $scanner->next_delimiter() ) { | |
| 883 | + if ( ! $scanner->opens_block() ) { | |
| 884 | + continue; | |
| 885 | + } | |
| 886 | + | |
| 887 | + $attributes = $scanner->allocate_and_return_parsed_attributes(); | |
| 888 | + | |
| 889 | + if ( ! is_array( $attributes ) || empty( $attributes['conditions']['rules'] ) ) { | |
| 828 | 890 | // No Rules: Display widget. |
| 829 | 891 | return $instance; |
| 830 | 892 | } |
| 831 | - if ( self::filter_widget_check_conditions( $blocks[0]['attrs']['conditions'] ) ) { | |
| 893 | + | |
| 894 | + if ( self::filter_widget_check_conditions( $attributes['conditions'] ) ) { | |
| 832 | 895 | // Rules passed checks: Display widget. |
| 833 | 896 | return $instance; |
| 834 | 897 | } |
| 898 | + | |
| 835 | 899 | // Rules failed checks: Hide widget. |
| 836 | 900 | return false; |
| 837 | 901 | } |
| 838 | - | |
| 839 | 902 | // No visibility found. |
| 840 | 903 | return $instance; |
| 841 | 904 | } |
| 842 | 905 | |
| @@ -975,15 +1038,17 @@ | ||
| 975 | 1038 | $condition_result = ! $condition_result; |
| 976 | 1039 | } |
| 977 | 1040 | break; |
| 978 | 1041 | case 'author': |
| 979 | - $post = get_post(); | |
| 980 | 1042 | if ( ! $rule['minor'] && is_author() ) { |
| 981 | 1043 | $condition_result = true; |
| 982 | 1044 | } elseif ( $rule['minor'] && is_author( $rule['minor'] ) ) { |
| 983 | 1045 | $condition_result = true; |
| 984 | - } elseif ( is_singular() && $rule['minor'] && $rule['minor'] === $post->post_author ) { | |
| 985 | - $condition_result = true; | |
| 1046 | + } elseif ( is_singular() && $rule['minor'] ) { | |
| 1047 | + $post = get_post(); | |
| 1048 | + if ( $post && $rule['minor'] === $post->post_author ) { | |
| 1049 | + $condition_result = true; | |
| 1050 | + } | |
| 986 | 1051 | } |
| 987 | 1052 | break; |
| 988 | 1053 | case 'role': |
| 989 | 1054 | if ( is_user_logged_in() ) { |
| @@ -1129,12 +1194,17 @@ | ||
| 1129 | 1194 | * |
| 1130 | 1195 | * @since 4.7.1 |
| 1131 | 1196 | */ |
| 1132 | 1197 | public static function migrate_post_type_rules() { |
| 1133 | - global $wp_registered_widgets; | |
| 1198 | + global $wp_widget_factory, $wp_registered_widgets; | |
| 1199 | + '@phan-var \WP_Widget_Factory $wp_widget_factory'; | |
| 1134 | 1200 | |
| 1135 | 1201 | $sidebars_widgets = get_option( 'sidebars_widgets' ); |
| 1136 | 1202 | |
| 1203 | + if ( ! is_array( $sidebars_widgets ) ) { | |
| 1204 | + return; | |
| 1205 | + } | |
| 1206 | + | |
| 1137 | 1207 | // Going through all sidebars and through inactive and orphaned widgets. |
| 1138 | 1208 | foreach ( $sidebars_widgets as $sidebar ) { |
| 1139 | 1209 | if ( ! is_array( $sidebar ) ) { |
| 1140 | 1210 | continue; |
| @@ -1145,11 +1215,17 @@ | ||
| 1145 | 1215 | if ( empty( $wp_registered_widgets[ $widget ] ) ) { |
| 1146 | 1216 | continue; |
| 1147 | 1217 | } |
| 1148 | 1218 | |
| 1149 | - $opts = $wp_registered_widgets[ $widget ]; | |
| 1150 | - $instances = get_option( $opts['callback'][0]->option_name ); | |
| 1219 | + $id_base = wp_parse_widget_id( $widget )['id_base']; | |
| 1220 | + $widget_object = $wp_widget_factory->get_widget_object( $id_base ); | |
| 1151 | 1221 | |
| 1222 | + if ( ! $widget_object ) { | |
| 1223 | + continue; | |
| 1224 | + } | |
| 1225 | + | |
| 1226 | + $instances = get_option( $widget_object->option_name ); | |
| 1227 | + | |
| 1152 | 1228 | if ( ! is_array( $instances ) || empty( $instances ) ) { |
| 1153 | 1229 | continue; |
| 1154 | 1230 | } |
| 1155 | 1231 | |
| @@ -1156,10 +1232,10 @@ | ||
| 1156 | 1232 | // Going through each instance of the widget. |
| 1157 | 1233 | foreach ( $instances as $number => $instance ) { |
| 1158 | 1234 | if ( |
| 1159 | 1235 | ! is_array( $instance ) || |
| 1160 | - empty( $instance['conditions'] ) || | |
| 1161 | - empty( $instance['conditions']['rules'] ) | |
| 1236 | + empty( $instance['conditions']['rules'] ) || | |
| 1237 | + ! is_array( $instance['conditions']['rules'] ) | |
| 1162 | 1238 | ) { |
| 1163 | 1239 | continue; |
| 1164 | 1240 | } |
| 1165 | 1241 | |
| @@ -1189,9 +1265,9 @@ | ||
| 1189 | 1265 | } |
| 1190 | 1266 | } |
| 1191 | 1267 | } |
| 1192 | 1268 | |
| 1193 | - update_option( $opts['callback'][0]->option_name, $instances ); | |
| 1269 | + update_option( $widget_object->option_name, $instances ); | |
| 1194 | 1270 | } |
| 1195 | 1271 | } |
| 1196 | 1272 | } |
| 1197 | 1273 | } |