PluginProbe
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder / 2.16.0
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder v2.16.0
2.16.0 2.15.0 2.14.0 2.13.0 2.13.1 2.12.0 2.11.1 2.11.0 2.10.0 2.9.0 2.7.4 2.7.5 2.7.6 2.7.7 2.8.0 2.8.1 2.9.1 trunk 1.0 1.0-beta1 1.0-beta2 1.0-beta3 1.0.1 1.0.2 1.0.3 All 83 releases
← All changes | includes/blocks/price-menu-item/block.php +180 -12 2.15.0 → 2.16.0 View file →
@@ -13,8 +13,9 @@
13 13 use ABlocks\Controls\TextShadow;
14 14 use ABlocks\Controls\TextStroke;
15 15 use ABlocks\Controls\Range;
16 16 use ABlocks\Controls\Color;
17 +use ABlocks\Helper;
17 18
18 19 class Block extends BlockBaseAbstract {
19 20 protected $parent_block_name = 'price-menu';
20 21 protected $block_name = 'price-menu-item';
@@ -41,8 +42,9 @@
41 42 '{{WRAPPER}} .ablocks-icon-wrap img.ablocks-image-icon',
42 43 Icon::get_element_image_css( $attributes ),
43 44 Icon::get_element_image_css( $attributes, 'Tablet' ),
44 45 Icon::get_element_image_css( $attributes, 'Mobile' ),
46 + $css_generator->custom_device_map( function ( $device ) use ( $attributes ) { return Icon::get_element_image_css( $attributes, $device ); } )
45 47 );
46 48 $css_generator->add_class_styles(
47 49 '{{WRAPPER}} .ablocks-icon-wrap img.ablocks-image-icon:hover',
48 50 Icon::get_element_image_hover_css( $attributes ),
@@ -47,8 +49,9 @@
47 49 '{{WRAPPER}} .ablocks-icon-wrap img.ablocks-image-icon:hover',
48 50 Icon::get_element_image_hover_css( $attributes ),
49 51 Icon::get_element_image_hover_css( $attributes, 'Tablet' ),
50 52 Icon::get_element_image_hover_css( $attributes, 'Mobile' ),
53 + $css_generator->custom_device_map( function ( $device ) use ( $attributes ) { return Icon::get_element_image_hover_css( $attributes, $device ); } )
51 54 );
52 55 $css_generator->add_class_styles(
53 56 '{{WRAPPER}} .ablocks-icon-wrap svg.ablocks-svg-icon',
54 57 Icon::get_element_css( $attributes ),
@@ -53,8 +56,9 @@
53 56 '{{WRAPPER}} .ablocks-icon-wrap svg.ablocks-svg-icon',
54 57 Icon::get_element_css( $attributes ),
55 58 Icon::get_element_css( $attributes, 'Tablet' ),
56 59 Icon::get_element_css( $attributes, 'Mobile' ),
60 + $css_generator->custom_device_map( function ( $device ) use ( $attributes ) { return Icon::get_element_css( $attributes, $device ); } )
57 61 );
58 62 $css_generator->add_class_styles(
59 63 '{{WRAPPER}} .ablocks-icon-wrap svg.ablocks-svg-icon:hover',
60 64 Icon::get_element_image_hover_css( $attributes ),
@@ -59,8 +63,9 @@
59 63 '{{WRAPPER}} .ablocks-icon-wrap svg.ablocks-svg-icon:hover',
60 64 Icon::get_element_image_hover_css( $attributes ),
61 65 Icon::get_element_image_hover_css( $attributes, 'Tablet' ),
62 66 Icon::get_element_image_hover_css( $attributes, 'Mobile' ),
67 + $css_generator->custom_device_map( function ( $device ) use ( $attributes ) { return Icon::get_element_image_hover_css( $attributes, $device ); } )
63 68 );
64 69 // TitleText CSS
65 70 $css_generator->add_class_styles(
66 71 '{{WRAPPER}} .ablocks-price-menu-item-details-title',
@@ -66,8 +71,9 @@
66 71 '{{WRAPPER}} .ablocks-price-menu-item-details-title',
67 72 $this->get_title_text_css( $attributes, '' ),
68 73 $this->get_title_text_css( $attributes, 'Tablet' ),
69 74 $this->get_title_text_css( $attributes, 'Mobile' ),
75 + $css_generator->custom_device_map( function ( $device ) use ( $attributes ) { return $this->get_title_text_css( $attributes, $device ); } )
70 76 );
71 77 // DescriptionText CSS
72 78 $css_generator->add_class_styles(
73 79 '{{WRAPPER}} .ablocks-price-menu-item-details-des',
@@ -73,8 +79,9 @@
73 79 '{{WRAPPER}} .ablocks-price-menu-item-details-des',
74 80 $this->get_description_text_css( $attributes, '' ),
75 81 $this->get_description_text_css( $attributes, 'Tablet' ),
76 82 $this->get_description_text_css( $attributes, 'Mobile' ),
83 + $css_generator->custom_device_map( function ( $device ) use ( $attributes ) { return $this->get_description_text_css( $attributes, $device ); } )
77 84 );
78 85 // SeparatorText CSS
79 86 $css_generator->add_class_styles(
80 87 '{{WRAPPER}} .ablocks-price-menu-divider__pattern-' . ( $attributes['dividerType'] === 'mask-style' ? 'mask' : 'css' ),
@@ -80,8 +87,9 @@
80 87 '{{WRAPPER}} .ablocks-price-menu-divider__pattern-' . ( $attributes['dividerType'] === 'mask-style' ? 'mask' : 'css' ),
81 88 $this->get_divider_css( $attributes, '' ),
82 89 $this->get_divider_css( $attributes, 'Tablet' ),
83 90 $this->get_divider_css( $attributes, 'Mobile' ),
91 + $css_generator->custom_device_map( function ( $device ) use ( $attributes ) { return $this->get_divider_css( $attributes, $device ); } )
84 92 );
85 93 // PriceText CSS
86 94 $css_generator->add_class_styles(
87 95 '{{WRAPPER}} .ablocks-price-menu-item-price',
@@ -87,13 +95,185 @@
87 95 '{{WRAPPER}} .ablocks-price-menu-item-price',
88 96 $this->get_price_text_css( $attributes, '' ),
89 97 $this->get_price_text_css( $attributes, 'Tablet' ),
90 98 $this->get_price_text_css( $attributes, 'Mobile' ),
99 + $css_generator->custom_device_map( function ( $device ) use ( $attributes ) { return $this->get_price_text_css( $attributes, $device ); } )
91 100 );
101 + // Divider width (item override of the parent's width)
102 + $css_generator->add_class_styles(
103 + '{{WRAPPER}} .ablocks-divider',
104 + self::get_divider_width_css( $attributes, '' ),
105 + self::get_divider_width_css( $attributes, 'Tablet' ),
106 + self::get_divider_width_css( $attributes, 'Mobile' ),
107 + $css_generator->custom_device_map( function ( $device ) use ( $attributes ) { return self::get_divider_width_css( $attributes, $device ); } )
108 + );
109 + $css_generator->add_class_styles(
110 + '{{WRAPPER}} .ablocks-price-menu-item',
111 + self::get_item_width_css( $attributes, '' ),
112 + self::get_item_width_css( $attributes, 'Tablet' ),
113 + self::get_item_width_css( $attributes, 'Mobile' ),
114 + $css_generator->custom_device_map( function ( $device ) use ( $attributes ) { return self::get_item_width_css( $attributes, $device ); } )
115 + );
116 + $css_generator->add_class_styles(
117 + '{{WRAPPER}} .ablocks-price-menu-item-details-brief > .ablocks-price-menu-item-price',
118 + self::get_price_row_css( $attributes )
119 + );
120 + // Responsive placements: hide the slots not used on each device.
121 + foreach ( [
122 + 'divider' => isset( $attributes['placeDivider'] ) ? $attributes['placeDivider'] : '',
123 + 'price' => isset( $attributes['placePrice'] ) ? $attributes['placePrice'] : '',
124 + ] as $kind => $placement ) {
125 + foreach ( self::get_used_placements( $placement ) as $slot ) {
126 + $css_generator->add_class_styles(
127 + '{{WRAPPER}} .' . self::get_slot_class_name( $kind, $slot ),
128 + self::get_slot_css( $placement, $slot, '' ),
129 + self::get_slot_css( $placement, $slot, 'Tablet' ),
130 + self::get_slot_css( $placement, $slot, 'Mobile' ),
131 + $css_generator->custom_device_map( function ( $device ) use ( $placement, $slot ) { return self::get_slot_css( $placement, $slot, $device ); } )
132 + );
133 + }
134 + }
92 135
93 136 return $css_generator->generate_css();
94 137 }
95 138
139 + /**
140 + * Divider width as a custom property; mirrors get_divider_width_css() in
141 + * src/blocks/price-menu-item/styling.js. The parent passes its own property
142 + * and default. A width without a stored unit keeps the legacy unit: % with a
143 + * description, px without.
144 + */
145 + public static function get_divider_width_css( $attributes, $device = '', $property = '--ablocks-pm-item-divider-width', $default_value = null ) {
146 + return Range::get_css([
147 + 'attributeValue' => isset( $attributes['width'] ) ? $attributes['width'] : [],
148 + 'attributeObjectKey' => 'value',
149 + 'isResponsive' => true,
150 + 'defaultValue' => $default_value,
151 + 'hasUnit' => true,
152 + 'unitDefaultValue' => ! empty( $attributes['allowDescription'] ) ? '%' : 'px',
153 + 'property' => $property,
154 + 'device' => $device,
155 + ]);
156 + }
157 +
158 + // A responsive member for the device, inherited from wider devices; '' when unset.
159 + private static function resolve_member( $value, $key, $device ) {
160 + $target = 'Desktop' === $device ? '' : (string) $device;
161 + foreach ( array_merge( [ $target ], Helper::get_responsive_ancestors( $target ) ) as $suffix ) {
162 + $member = is_array( $value ) && isset( $value[ $key . $suffix ] ) && ! is_array( $value[ $key . $suffix ] ) ? (string) $value[ $key . $suffix ] : '';
163 + if ( Helper::has_responsive_value( $member ) ) {
164 + return $member;
165 + }
166 + }
167 + return '';
168 + }
169 +
170 + // A % Title & price gap in effect on this device (unit default px).
171 + public static function is_percent_title_price_gap( $attributes, $device = '' ) {
172 + $gap = isset( $attributes['titlePriceGap'] ) ? $attributes['titlePriceGap'] : [];
173 + return '' !== self::resolve_member( $gap, 'value', $device ) && '%' === Range::get_unit( [
174 + 'attributeValue' => $gap,
175 + 'attributeObjectKey' => 'value',
176 + 'unitDefaultValue' => 'px',
177 + 'device' => $device,
178 + ] );
179 + }
180 +
181 + // A % on the title row; mirrors isPercentTitleRow() in styling.js. The legacy
182 + // implicit % (Allow description, no stored unit) is left alone.
183 + public static function is_percent_title_row( $attributes, $device = '' ) {
184 + return self::is_percent_title_price_gap( $attributes, $device ) || (
185 + ! empty( $attributes['allowDivider'] ) &&
186 + 'near title' === self::get_placement( isset( $attributes['placeDivider'] ) ? $attributes['placeDivider'] : '', $device ) &&
187 + '%' === self::resolve_member( isset( $attributes['width'] ) ? $attributes['width'] : [], 'valueUnit', $device )
188 + );
189 + }
190 +
191 + private static function has_percent_unit( $value ) {
192 + if ( ! is_array( $value ) ) {
193 + return false;
194 + }
195 + foreach ( $value as $key => $member ) {
196 + if ( 0 === strpos( $key, 'valueUnit' ) && '%' === $member ) {
197 + return true;
198 + }
199 + }
200 + return false;
201 + }
202 +
203 + public static function has_percent_title_price_gap( $attributes ) {
204 + return self::has_percent_unit( isset( $attributes['titlePriceGap'] ) ? $attributes['titlePriceGap'] : [] );
205 + }
206 +
207 + // Whether any device can use the % title row, so narrower devices that do
208 + // not must reset the item width they would otherwise inherit.
209 + public static function has_percent_title_row( $attributes ) {
210 + return self::has_percent_title_price_gap( $attributes ) || (
211 + ! empty( $attributes['allowDivider'] ) &&
212 + in_array( 'near title', self::get_used_placements( isset( $attributes['placeDivider'] ) ? $attributes['placeDivider'] : '' ), true ) &&
213 + self::has_percent_unit( isset( $attributes['width'] ) ? $attributes['width'] : [] )
214 + );
215 + }
216 +
217 + // Once Price alignment is chosen the item spans its row and the price fills
218 + // the space after the title/divider so text-align can position it. A % on
219 + // the title row needs the same; mirrors get_item_width_css() in styling.js.
220 + public static function get_item_width_css( $attributes, $device = '' ) {
221 + if ( ! empty( $attributes['priceAlignmentCustom'] ) ) {
222 + return $device ? [] : [ 'width' => '100%' ];
223 + }
224 + if ( self::is_percent_title_row( $attributes, $device ) ) {
225 + return [ 'width' => '100%' ];
226 + }
227 + return $device && self::has_percent_title_row( $attributes ) ? [ 'width' => 'fit-content' ] : [];
228 + }
229 +
230 + public static function get_price_row_css( $attributes ) {
231 + return ! empty( $attributes['priceAlignmentCustom'] ) ? [ 'flex-grow' => '1' ] : [];
232 + }
233 +
234 + /**
235 + * placeDivider / placePrice: a legacy string or a responsive array
236 + * ( value, valueTablet, valueMobile, … ). Mirrors placement.js.
237 + */
238 + public static function get_placement( $placement, $device = '' ) {
239 + $placement = is_array( $placement ) ? $placement : [ 'value' => (string) $placement ];
240 + $target = 'Desktop' === $device ? '' : (string) $device;
241 + foreach ( array_merge( [ $target ], Helper::get_responsive_ancestors( $target ) ) as $suffix ) {
242 + $value = isset( $placement[ 'value' . $suffix ] ) ? $placement[ 'value' . $suffix ] : '';
243 + if ( Helper::has_responsive_value( $value ) ) {
244 + return $value;
245 + }
246 + }
247 + return '';
248 + }
249 +
250 + public static function get_used_placements( $placement ) {
251 + if ( ! is_array( $placement ) ) {
252 + return Helper::has_responsive_value( $placement ) ? [ $placement ] : [];
253 + }
254 + $used = [];
255 + foreach ( $placement as $key => $value ) {
256 + if ( 0 === strpos( $key, 'value' ) && is_string( $value ) && Helper::has_responsive_value( $value ) ) {
257 + $used[] = $value;
258 + }
259 + }
260 + return array_values( array_unique( $used ) );
261 + }
262 +
263 + // The placement is a block attribute and this name lands in a selector of
264 + // an inline <style>, which esc_css_value() does not cover; keep it a class.
265 + public static function get_slot_class_name( $kind, $placement ) {
266 + return 'ablocks-price-menu-' . $kind . '-slot--' . sanitize_html_class( preg_replace( '/\s+/', '-', $placement ) );
267 + }
268 +
269 + public static function get_slot_css( $placement, $slot, $device = '' ) {
270 + if ( count( self::get_used_placements( $placement ) ) < 2 ) {
271 + return [];
272 + }
273 + return [ 'display' => self::get_placement( $placement, $device ) === $slot ? 'block' : 'none' ];
274 + }
275 +
96 276 public function get_title_text_css( $attributes, $device = '' ) {
97 277 $typographyValueGlobal = ! empty( $attributes['titleTypographyGlobal'] ) ? $attributes['titleTypographyGlobal'] : array();
98 278 return array_merge(
99 279 [ 'color' => Color::get_css( isset( $attributes['titleColor'] ) ? $attributes['titleColor'] : '' ) ],
@@ -115,10 +295,8 @@
115 295 );
116 296 }
117 297 public function get_divider_css( $attributes, $device = '' ) {
118 298 $css = [];
119 - $divider_width = isset( $attributes['width'][ 'value' . $device ] ) ? $attributes['width'][ 'value' . $device ] : 60;
120 - $default_Unit = $attributes['allowDescription'] === true ? '%' : 'px';
121 299
122 300 if ( ! empty( $attributes['color'] ) ) {
123 301 $css['--ablocks-divider-pattern-color'] = Color::get_css(
124 302 isset( $attributes['color'] ) ? $attributes['color'] : '#000000');
@@ -157,18 +335,8 @@
157 335 }
158 336
159 337 return array_merge(
160 338 $css,
161 - Range::get_css([
162 - 'attributeValue' => $attributes['width'],
163 - 'attribute_object_key' => 'value',
164 - 'isResponsive' => true,
165 - 'defaultValue' => null,
166 - 'hasUnit' => false,
167 - 'unitDefaultValue' => $attributes['allowDescription'] === true ? '%' : 'px',
168 - 'property' => 'width',
169 - 'device' => $device,
170 - ]),
171 339 $moreRangeCSS,
172 340 );
173 341 }
174 342 public function get_price_text_css( $attributes, $device = '' ) {