PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 4.6.3
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v4.6.3
4.7.0 4.6.6 4.6.5 4.6.4 4.6.3 4.6.2 4.6.1 4.6.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 / packages / blocks / Blocks / ProductItemList / Block.php
surecart / packages / blocks / Blocks / ProductItemList Last commit date
Block.php 2 weeks ago block.json 1 month ago
Block.php
333 lines
1 <?php
2
3 namespace SureCartBlocks\Blocks\ProductItemList;
4
5 use SureCart\Support\PublicCatalogData;
6 use SureCartBlocks\Blocks\BaseBlock;
7 /**
8 * ProductItemList block
9 */
10 class Block extends BaseBlock {
11 /**
12 * Keeps track of instances of this block.
13 *
14 * @var integer
15 */
16 public static $instance;
17
18 /**
19 * Default block template.
20 *
21 * @var array
22 */
23 protected $default_block_template = [
24 [
25 'blockName' => 'surecart/product-item-image',
26 'attrs' => [
27 'sizing' => 'cover',
28 'ratio' => '1/1.33',
29 'style' => [
30 'border' => [
31 'radius' => '6px',
32 ],
33 'spacing' => [
34 'margin' => [
35 'bottom' => '16px',
36 ],
37 ],
38 ],
39 ],
40 ],
41 [
42 'blockName' => 'surecart/product-item-title',
43 'attrs' => [
44 'level' => 3,
45 'style' => [
46 'typography' => [
47 'fontSize' => '18px',
48 ],
49 'color' => [
50 'text' => '#000000',
51 ],
52 'spacing' => [
53 'margin' => [
54 'bottom' => '8px',
55 ],
56 ],
57 ],
58 ],
59 ],
60 [
61 'blockName' => 'surecart/product-item-price',
62 'attrs' => [
63 'style' => [
64 'typography' => [
65 'fontSize' => '16px',
66 ],
67 'color' => [
68 'text' => '#000000',
69 ],
70 'spacing' => [
71 'margin' => [
72 'bottom' => '8px',
73 ],
74 ],
75 ],
76 ],
77 ],
78 ];
79
80 /**
81 * Get the style for the block.
82 *
83 * @param array $attr Product List attributes.
84 * @return string
85 */
86 public function getProductListStyle( $attr ) {
87 $style = '--sc-product-item-list-column: ' . ( $attr['columns'] ?? 3 ) . ';';
88 $style .= '--sc-product-item-list-gap: ' . $this->getSpacingPresetCssVar( $attr['style']['spacing']['blockGap'] ?? '40px' ) . ';';
89 $style .= '--sc-pagination-font-size: ' . ( $attr['paginationSize'] ?? '14px' ) . ';';
90 return $style;
91 }
92
93 /**
94 * Get the style for the block
95 *
96 * @param array $attr Style variables.
97 * @param string $prefix Prefix for the css variable.
98 * @return string
99 */
100 public function getVars( $attr, $prefix ) {
101 $style = '';
102 // padding.
103 if ( ! empty( $attr['style']['spacing']['padding'] ) ) {
104 $padding = $attr['style']['spacing']['padding'];
105 $style .= '--sc-product-' . $prefix . '-padding-top: ' . $this->getSpacingPresetCssVar( array_key_exists( 'top', $padding ) ? $padding['top'] : '0' ) . ';';
106 $style .= '--sc-product-' . $prefix . '-padding-bottom: ' . $this->getSpacingPresetCssVar( array_key_exists( 'bottom', $padding ) ? $padding['bottom'] : '0' ) . ';';
107 $style .= '--sc-product-' . $prefix . '-padding-left: ' . $this->getSpacingPresetCssVar( array_key_exists( 'left', $padding ) ? $padding['left'] : '0' ) . ';';
108 $style .= '--sc-product-' . $prefix . '-padding-right: ' . $this->getSpacingPresetCssVar( array_key_exists( 'right', $padding ) ? $padding['right'] : '0' ) . ';';
109 }
110 // margin.
111 if ( ! empty( $attr['style']['spacing']['margin'] ) ) {
112 $margin = $attr['style']['spacing']['margin'];
113 $style .= '--sc-product-' . $prefix . '-margin-top: ' . $this->getSpacingPresetCssVar( array_key_exists( 'top', $margin ) ? $margin['top'] : '0' ) . ';';
114 $style .= '--sc-product-' . $prefix . '-margin-bottom: ' . $this->getSpacingPresetCssVar( array_key_exists( 'bottom', $margin ) ? $margin['bottom'] : '0' ) . ';';
115 $style .= '--sc-product-' . $prefix . '-margin-left: ' . $this->getSpacingPresetCssVar( array_key_exists( 'left', $margin ) ? $margin['left'] : '0' ) . ';';
116 $style .= '--sc-product-' . $prefix . '-margin-right: ' . $this->getSpacingPresetCssVar( array_key_exists( 'right', $margin ) ? $margin['right'] : '0' ) . ';';
117 }
118 // aspect ratio.
119 if ( ! empty( $attr['ratio'] ) ) {
120 $style .= '--sc-product-' . $prefix . '-aspect-ratio: ' . $attr['ratio'] . ';';
121 }
122 // border width.
123 if ( ! empty( $attr['style']['border']['width'] ) ) {
124 $style .= '--sc-product-' . $prefix . '-border-width: ' . $attr['style']['border']['width'] . ';';
125 }
126 // border radius.
127 if ( ! empty( $attr['style']['border']['radius'] ) ) {
128 $style .= '--sc-product-' . $prefix . '-border-radius: ' . $attr['style']['border']['radius'] . ';';
129 }
130 // font weight.
131 if ( ! empty( $attr['style']['typography']['fontWeight'] ) ) {
132 $style .= '--sc-product-' . $prefix . '-font-weight: ' . $attr['style']['typography']['fontWeight'] . ';';
133 }
134 // font size.
135 if ( ! empty( $attr['fontSize'] ) || ! empty( $attr['style']['typography']['fontSize'] ) ) {
136 $font_size = ! empty( $attr['fontSize'] ) ? $this->getFontSizePresetCssVar( $attr['fontSize'] ) : $attr['style']['typography']['fontSize'];
137 $style .= '--sc-product-' . $prefix . '-font-size: ' . $font_size . ';';
138 }
139 // border color.
140 if ( ! empty( $attr['borderColor'] ) || ! empty( $attr['style']['border']['color'] ) ) {
141 $border_color = ! empty( $attr['borderColor'] ) ? $this->getColorPresetCssVar( $attr['borderColor'] ) : $attr['style']['border']['color'];
142 $style .= '--sc-product-' . $prefix . '-border-color: ' . $border_color . ';';
143 }
144 // text color.
145 if ( ! empty( $attr['textColor'] ) || ! empty( $attr['style']['color']['text'] ) ) {
146 $text_color = ! empty( $attr['textColor'] ) ? $this->getColorPresetCssVar( $attr['textColor'] ) : $attr['style']['color']['text'];
147 $style .= '--sc-product-' . $prefix . '-text-color: ' . $text_color . ';';
148 }
149 if ( ! empty( $attr['backgroundColor'] ) || ! empty( $attr['style']['color']['background'] ) ) {
150 $background_color = ! empty( $attr['backgroundColor'] ) ? $this->getColorPresetCssVar( $attr['backgroundColor'] ) : $attr['style']['color']['background'];
151 $style .= '--sc-product-' . $prefix . '-background-color: ' . $background_color . ';';
152 }
153 // text align.
154 if ( ! empty( $attr['align'] ) ) {
155 $style .= '--sc-product-' . $prefix . '-align: ' . $attr['align'] . ';';
156 }
157
158 return $style;
159 }
160
161 /**
162 * Get the style for the block
163 *
164 * @param array $attr Product List attributes.
165 * @param array $item_attributes Product item attributes.
166 * @return string
167 */
168 public function getStyle( $attr, $item_attributes ) {
169 $style = 'border-style: none !important;';
170 $style .= $this->getProductListStyle( $attr );
171 $style .= $this->getVars( $item_attributes, 'item' );
172 return $style;
173 }
174
175 /**
176 * Get the dummy products array.
177 *
178 * @param int $limit Limit per page.
179 * @return array Dummy Products.
180 */
181 public function getDummyProducts( $limit = 15 ) {
182 $dummy_products = array();
183
184 for ( $i = 1; $i <= $limit; $i++ ) {
185 $product = array(
186 'permalink' => '#',
187 'name' => __( 'Example Product Title', 'surecart' ),
188 'created_at' => wp_rand( 1, 40 ),
189 'prices' => array(
190 'data' => array(
191 array(
192 'amount' => 1900,
193 'currency' => 'USD',
194 ),
195 ),
196 ),
197 );
198
199 $dummy_products[] = $product;
200 }
201
202 return $dummy_products;
203 }
204 /**
205 * Render the block
206 *
207 * @param array $attributes Block attributes.
208 * @param string $content Post content.
209 *
210 * @return string
211 */
212 public function render( $attributes, $content ) {
213 if ( isset( $attributes['sort_enabled'] ) ) { // This way we know it's the old block.
214 return \SureCart::block()->productListMigration( $attributes, $this->block )->render();
215 }
216
217 self::$instance = wp_unique_id( 'sc-product-item-list-' );
218
219 // check for inner blocks.
220 $product_inner_blocks = $this->block->parsed_block['innerBlocks'] ?? [];
221
222 $product_item_inner_blocks = $product_inner_blocks[0]['innerBlocks'] ?? $this->default_block_template;
223 $product_item_attributes = $product_inner_blocks[0]['attrs'] ?? $attributes;
224
225 $layout_config = array_map(
226 function ( $inner_block ) {
227 return (object) [
228 'blockName' => $inner_block['blockName'],
229 'attributes' => $inner_block['attrs'],
230 ];
231 },
232 $product_item_inner_blocks
233 );
234
235 $style = '';
236 $style .= $this->getStyle( $attributes, $product_item_attributes );
237
238 foreach ( $product_item_inner_blocks as $inner_blocks ) {
239 switch ( $inner_blocks['blockName'] ) {
240 case 'surecart/product-item-image':
241 $style .= $this->getVars( $inner_blocks['attrs'], 'image' );
242 break;
243 case 'surecart/product-item-title':
244 $style .= $this->getVars( $inner_blocks['attrs'], 'title' );
245 break;
246 case 'surecart/product-item-price':
247 $style .= $this->getVars( $inner_blocks['attrs'], 'price' );
248 break;
249 default:
250 break;
251 }
252 }
253
254 // backwards compat.
255 if ( empty( $attributes['type'] ) && ! empty( $attributes['ids'] ) ) {
256 $attributes['type'] = 'custom';
257 }
258 if ( empty( $attributes['type'] ) ) {
259 $attributes['type'] = '';
260 }
261
262 // query posts.
263 $product_query = new \WP_Query(
264 array(
265 'post_type' => 'sc_product',
266 'posts_per_page' => 10,
267 )
268 );
269
270 // get the product for each post, stripped for public serialization.
271 $products = array_map(
272 function ( $post ) {
273 return PublicCatalogData::product( sc_get_product( $post ) );
274 },
275 $product_query->posts ?? []
276 );
277
278 \SureCart::assets()->addComponentData(
279 'sc-product-item-list',
280 '#' . self::$instance,
281 [
282 'layoutConfig' => $layout_config,
283 'paginationAlignment' => $attributes['pagination_alignment'],
284 'limit' => $attributes['limit'],
285 'style' => $style,
286 'pagination' => [
287 'total' => $product_query->found_posts,
288 'total_pages' => $product_query->max_num_pages,
289 ],
290 'page' => (int) ( $_GET['product-page'] ?? 1 ),
291 'ids' => 'custom' === $attributes['type'] ? array_values( array_filter( $attributes['ids'] ) ) : [],
292 'paginationEnabled' => \SureCart::account()->isConnected() ? wp_validate_boolean( $attributes['pagination_enabled'] ) : false,
293 'ajaxPagination' => wp_validate_boolean( $attributes['ajax_pagination'] ),
294 'paginationAutoScroll' => $attributes['pagination_auto_scroll'],
295 'searchEnabled' => \SureCart::account()->isConnected() ? wp_validate_boolean( $attributes['search_enabled'] ) : false,
296 'sortEnabled' => \SureCart::account()->isConnected() ? wp_validate_boolean( $attributes['sort_enabled'] ) : false,
297 'featured' => 'featured' === $attributes['type'],
298 'products' => ! \SureCart::account()->isConnected() ? $this->getDummyProducts( $attributes['limit'] ) : $products,
299 'collectionEnabled' => \SureCart::account()->isConnected() ? wp_validate_boolean( $attributes['collection_enabled'] ) : false,
300 'pageTitle' => get_the_title(),
301 ]
302 );
303
304 return '<sc-product-item-list id="' . esc_attr( self::$instance ) . '"></sc-product-item-list>';
305 }
306
307 /**
308 * Get the query for the products.
309 *
310 * @param array $attributes Block attributes.
311 *
312 * @return array
313 */
314 public function getQuery( $attributes ) {
315 $query = [
316 'expand' => [ 'prices', 'featured_product_media', 'product_medias', 'product_media.media', 'variants' ],
317 'archived' => false,
318 'status' => [ 'published' ],
319 'sort' => 'cataloged_at:desc',
320 ];
321
322 if ( 'featured' === ( $attributes['type'] ?? '' ) ) {
323 $query['featured'] = true;
324 }
325
326 if ( 'custom' === ( $attributes['type'] ?? '' ) ) {
327 $query['ids'] = array_values( array_filter( $attributes['ids'] ?? [] ) );
328 }
329
330 return $query;
331 }
332 }
333