PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 4.5.0
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v4.5.0
4.5.1 4.5.0 4.4.2 4.4.1 4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.3 4.2.2 4.2.1 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.11.1 1.11.2 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.9.0 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 2.0.0 2.0.1 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.10.0 2.10.1 2.11.0 2.11.1 2.11.2 2.11.3 2.11.4 2.12.0 2.13.0 2.14.0 2.14.1 2.15.0 2.15.1 2.16.0 2.16.1 2.16.2 2.16.3 2.17.0 2.17.1 2.17.2 2.18.0 2.19.0 2.19.2 2.19.3 2.19.4 2.2.0 2.2.1 2.20.0 2.20.1 2.20.2 2.20.3 2.20.4 2.20.5 2.20.6 2.21.0 2.22.0 2.22.1 2.23.0 2.24.0 2.25.0 2.25.1 2.25.2 2.26.0 2.27.0 2.27.1 2.28.0 2.29.0 2.29.1 2.29.2 2.29.3 2.29.4 2.3.0 2.3.1 2.30.0 2.31.0 2.31.1 2.31.2 2.31.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.40.0 2.40.1 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.9.0 3.0.0 3.0.0-RC1 3.0.0-RC2 3.0.0-beta1 3.0.0-beta2 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.10.0 3.10.1 3.11.0 3.12.0 3.13.0 3.13.1 3.13.2 3.13.3 3.13.4 3.14.0 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.16.6 3.16.7 3.16.8 3.17.0 3.17.1 3.17.2 3.17.3 3.17.4 3.17.5 3.17.6 3.18.0 3.19.0 3.19.1 3.19.2 3.2.0 3.2.1 3.2.2 3.20.0 3.20.1 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 4.0.0 4.0.1 4.0.2 4.0.3 trunk 4.1.0 0.2.19.1 4.1.1 1.0.0 4.2.0 1.0.1 1.0.2
surecart / app / src / Integrations / Bricks / Elements / ProductReviewBreakdown.php
surecart / app / src / Integrations / Bricks / Elements Last commit date
BuyButton.php 3 months ago CartMenuIcon.php 5 months ago CollectionTag.php 1 year ago CollectionTags.php 1 year ago Media.php 1 year ago PriceChoiceTemplate.php 1 year ago PriceChooser.php 4 months ago PriceData.php 1 year ago Product.php 4 months ago ProductCard.php 10 months ago ProductContent.php 10 months ago ProductData.php 1 year ago ProductLineItemNote.php 10 months ago ProductQuickAddButton.php 10 months ago ProductReviewAverageRatingStars.php 4 months ago ProductReviewAverageRatingValue.php 4 months ago ProductReviewBreakdown.php 4 months ago ProductReviewContent.php 4 months ago ProductReviewList.php 2 months ago ProductReviewRating.php 4 months ago ProductReviewTotalRating.php 4 months ago ProductReviews.php 4 months ago Quantity.php 10 months ago SaleBadge.php 1 year ago SelectedPriceAdHocAmount.php 1 year ago VariantPill.php 6 months ago VariantPills.php 1 year ago
ProductReviewBreakdown.php
313 lines
1 <?php
2
3 namespace SureCart\Integrations\Bricks\Elements;
4
5 use SureCart\Integrations\Bricks\Concerns\ConvertsBlocks;
6
7 if ( ! defined( 'ABSPATH' ) ) {
8 exit; // Exit if accessed directly.
9 }
10
11 /**
12 * Product Review Breakdown element.
13 */
14 class ProductReviewBreakdown extends \Bricks\Element {
15 use ConvertsBlocks;
16
17 /**
18 * Element category.
19 *
20 * @var string
21 */
22 public $category = 'SureCart Elements';
23
24 /**
25 * Element name.
26 *
27 * @var string
28 */
29 public $name = 'surecart-product-review-breakdown';
30
31 /**
32 * Element block name.
33 *
34 * @var string
35 */
36 public $block_name = 'surecart/product-review-breakdown';
37
38 /**
39 * Element icon.
40 *
41 * @var string
42 */
43 public $icon = 'ti-bar-chart';
44
45 /**
46 * Get element label.
47 *
48 * @return string
49 */
50 public function get_label() {
51 return esc_html__( 'Review Breakdown', 'surecart' );
52 }
53
54 /**
55 * Set control groups.
56 *
57 * @return void
58 */
59 public function set_control_groups() {
60 $this->control_groups['column_spacing'] = [
61 'title' => esc_html__( 'Column & Spacing', 'surecart' ),
62 'tab' => 'content',
63 ];
64
65 $this->control_groups['star_bar_colors'] = [
66 'title' => esc_html__( 'Star & Bar Colors', 'surecart' ),
67 'tab' => 'content',
68 ];
69 }
70
71 /**
72 * Set controls.
73 *
74 * @return void
75 */
76 public function set_controls() {
77 $this->controls['columns'] = [
78 'tab' => 'content',
79 'group' => 'column_spacing',
80 'label' => esc_html__( 'Columns', 'surecart' ),
81 'type' => 'select',
82 'options' => [
83 '1' => esc_html__( '1 Column', 'surecart' ),
84 '2' => esc_html__( '2 Columns', 'surecart' ),
85 '3' => esc_html__( '3 Columns', 'surecart' ),
86 ],
87 'default' => '1',
88 'placeholder' => esc_html__( '1 Column', 'surecart' ),
89 'description' => esc_html__( 'Choose the number of columns to display the review breakdown. Keep in mind the number of columns may shrink if the width is too narrow.', 'surecart' ),
90 ];
91
92 $this->controls['star_size'] = [
93 'tab' => 'content',
94 'group' => 'column_spacing',
95 'label' => esc_html__( 'Star Size', 'surecart' ),
96 'type' => 'number',
97 'units' => true,
98 'min' => 8,
99 'max' => 64,
100 'default' => '20px',
101 'placeholder' => '20px',
102 ];
103
104 $this->controls['row_gap'] = [
105 'tab' => 'content',
106 'group' => 'column_spacing',
107 'label' => esc_html__( 'Row Gap', 'surecart' ),
108 'type' => 'number',
109 'units' => true,
110 'min' => 0,
111 'max' => 50,
112 'default' => '2px',
113 'placeholder' => '2px',
114 'css' => [
115 [
116 'property' => 'row-gap',
117 'selector' => '.sc-star-bars',
118 ],
119 ],
120 ];
121
122 $this->controls['column_gap'] = [
123 'tab' => 'content',
124 'group' => 'column_spacing',
125 'label' => esc_html__( 'Column Gap', 'surecart' ),
126 'type' => 'number',
127 'units' => true,
128 'min' => 0,
129 'max' => 100,
130 'default' => '20px',
131 'placeholder' => '20px',
132 'css' => [
133 [
134 'property' => 'column-gap',
135 'selector' => '.sc-star-bars',
136 ],
137 ],
138 'required' => [ 'columns', '!=', '1' ],
139 ];
140
141 $this->controls['fill_color'] = [
142 'group' => 'star_bar_colors',
143 'label' => esc_html__( 'Star Color', 'surecart' ),
144 'type' => 'color',
145 'rerender' => true,
146 'default' => [
147 'hex' => 'var(--bricks-color-primary)',
148 ],
149 'css' => [
150 [
151 'property' => 'color',
152 'selector' => '.sc-star-row__label svg',
153 ],
154 [
155 'property' => 'fill',
156 'selector' => '.sc-star-row__label svg',
157 ],
158 [
159 'property' => 'stroke',
160 'selector' => '.sc-star-row__label svg',
161 ],
162 ],
163 ];
164
165 $this->controls['bar_fill_color'] = [
166 'group' => 'star_bar_colors',
167 'label' => esc_html__( 'Bar Active Color', 'surecart' ),
168 'type' => 'color',
169 'default' => [
170 'hex' => 'var(--bricks-color-primary)',
171 ],
172 'css' => [
173 [
174 'property' => 'background-color',
175 'selector' => '.sc-star-bars .sc-star-row__bar .sc-star-row__bar-fill',
176 ],
177 ],
178 ];
179
180 $this->controls['bar_background_color'] = [
181 'group' => 'star_bar_colors',
182 'label' => esc_html__( 'Bar Background Color', 'surecart' ),
183 'type' => 'color',
184 'default' => [
185 'hex' => '#e0e0e0',
186 ],
187 'css' => [
188 [
189 'property' => 'background-color',
190 'selector' => '.sc-star-bars .sc-star-row__bar',
191 ],
192 ],
193 ];
194 }
195
196 /**
197 * Render element.
198 *
199 * @return void
200 */
201 public function render() {
202 $star_size = ! empty( $this->settings['star_size'] ) ? $this->settings['star_size'] : '20px';
203 $columns = ! empty( $this->settings['columns'] ) ? (int) $this->settings['columns'] : 1;
204 $row_gap = ! empty( $this->settings['row_gap'] ) ? $this->settings['row_gap'] : '2px';
205 $column_gap = ! empty( $this->settings['column_gap'] ) ? $this->settings['column_gap'] : '40px';
206 $fill_color = $this->get_raw_color( 'fill_color' );
207 if ( empty( $fill_color ) ) {
208 $fill_color = 'var(--bricks-color-primary)';
209 }
210
211 // Ensure star_size has a unit for CSS.
212 if ( is_numeric( $star_size ) ) {
213 $star_size = $star_size . 'px';
214 }
215
216 if ( $this->is_admin_editor() ) {
217 $this->render_preview( $star_size, $fill_color, $columns, $column_gap, $row_gap );
218 return;
219 }
220
221 $rendered_attributes = $this->get_block_rendered_attributes();
222
223 $attributes = [
224 'size' => $star_size,
225 'columns' => $columns,
226 'row_gap' => $row_gap,
227 'column_gap' => $column_gap,
228 'fill_color' => esc_attr( $fill_color ),
229 'className' => $rendered_attributes['class'],
230 'anchor' => $rendered_attributes['id'],
231 ];
232
233 // Render the breakdown block directly without the summary wrapper.
234 // The summary wrapper causes width issues in flex containers.
235 $block_content = '<!-- wp:surecart/product-review-breakdown ' . wp_json_encode( $attributes ) . ' /-->';
236
237 // Use sc_pre_render_blocks to handle interactivity API debug notices.
238 echo sc_pre_render_blocks( $block_content ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
239 }
240
241 /**
242 * Render preview in editor.
243 *
244 * @param string $star_size Star size with unit.
245 * @param string $fill_color Fill color.
246 * @param int $columns Number of columns.
247 * @param string $column_gap Column gap with unit.
248 * @param string $row_gap Row gap with unit.
249 *
250 * @return void
251 */
252 private function render_preview( $star_size = '20px', $fill_color = '', $columns = 1, $column_gap = '20px', $row_gap = '2px' ) {
253 $breakdown_data = [
254 5 => 45,
255 4 => 25,
256 3 => 10,
257 2 => 5,
258 1 => 3,
259 ];
260 $total = array_sum( $breakdown_data );
261
262 if ( empty( $fill_color ) ) {
263 $fill_color = 'var(--bricks-color-primary)';
264 }
265
266 // Use CSS Grid for proper column layout (matching the actual block).
267 $grid_style = 'display: grid; width: 100%; min-width: 0; column-gap: ' . esc_attr( $column_gap ) . ';';
268 if ( 2 === $columns ) {
269 $grid_style .= ' grid-template-columns: repeat(2, 1fr); grid-auto-flow: column; grid-template-rows: repeat(3, minmax(auto, 1fr));';
270 } elseif ( 3 === $columns ) {
271 $grid_style .= ' grid-template-columns: repeat(3, 1fr); grid-auto-flow: column; grid-template-rows: repeat(2, minmax(auto, 1fr));';
272 } else {
273 $grid_style .= ' grid-template-columns: 1fr;';
274 }
275
276 $content = '<div style="width: 100%; min-width: 0; overflow: hidden;"><div class="sc-star-bars sc-star-bars__columns-' . esc_attr( $columns ) . '" style="' . esc_attr( $grid_style ) . '">';
277 for ( $star = 5; $star >= 1; $star-- ) {
278 $count = $breakdown_data[ $star ];
279 $percentage = $total > 0 ? ( $count / $total ) * 100 : 0;
280
281 $content .= '<a href="#" class="sc-star-row" onclick="event.preventDefault();" style="display: flex; align-items: center; gap: 8px; text-decoration: none; color: inherit; cursor: pointer; transition: opacity 0.2s ease;">';
282 $content .= '<div class="sc-star-row__label" style="display: flex; align-items: center; justify-content: center; min-width: 35px; gap: 4px;">';
283 $content .= esc_html( $star );
284 $content .= wp_kses(
285 \SureCart::svg()->get(
286 'star',
287 [
288 'height' => esc_attr( $star_size ),
289 'width' => esc_attr( $star_size ),
290 'fill' => esc_attr( $fill_color ),
291 'stroke' => esc_attr( $fill_color ),
292 'stroke-width' => 2,
293 ]
294 ),
295 sc_allowed_svg_html()
296 );
297 $content .= '</div>';
298 $content .= '<div class="sc-star-row__bar" style="flex: 1; height: 8px; border-radius: 4px; overflow: hidden; position: relative; min-width: 50px;">';
299 $content .= '<div class="sc-star-row__bar-fill" style="height: 100%; border-radius: 4px; width: ' . esc_attr( $percentage ) . '%; transition: width 0.3s ease;"></div>';
300 $content .= '</div>';
301 $content .= '<div class="sc-star-row__count" style="text-align: right;min-width: 20px;">' . esc_html( $count ) . '</div>';
302 $content .= '</a>';
303 }
304 $content .= '</div></div>'; // Close both the grid and overflow wrapper.
305
306 echo $this->preview( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
307 $content,
308 'wp-block-surecart-product-review-breakdown',
309 'div'
310 );
311 }
312 }
313