PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.6
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.6
1.6.6 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 All 49 releases
← All changes | app/Services/Renderer/ShopAppRenderer.php +44 -6 1.3.21 → 1.6.6 View file →
@@ -7,8 +7,9 @@
7 7 use FluentCart\App\Helpers\Helper;
8 8 use FluentCart\App\Http\Routes\WebRoutes;
9 9 use FluentCart\App\Modules\Templating\AssetLoader;
10 10 use FluentCart\Framework\Pagination\CursorPaginator;
11 +use FluentCart\Framework\Pagination\LengthAwarePaginator;
11 12 use FluentCart\Framework\Support\Arr;
12 13
13 14 class ShopAppRenderer
14 15 {
@@ -40,10 +41,15 @@
40 41 protected $customFilters = [];
41 42
42 43 protected $total = 0;
43 44
45 + protected $isWildcardFilterEnabled = false;
46 +
47 + protected $enableSortBy = true;
48 +
44 49 public function __construct($products = [], $config = [])
45 50 {
51 +
46 52 $defaultFilters = Arr::get($config, 'default_filters', []);
47 53 $customFilters = Arr::get($config, 'custom_filters', []);
48 54 $this->customFilters = $customFilters;
49 55 $enableFilter = false;
@@ -72,10 +78,11 @@
72 78 } else if ($this->paginator === 'cursor') {
73 79 $this->paginator = 'scroll';
74 80 }
75 81 $this->productBoxGridSize = $config['product_box_grid_size'] ?? 4;
82 + $this->isWildcardFilterEnabled = Arr::get($config, 'enable_wildcard_filter', false);
83 + $this->enableSortBy = Arr::get($config, 'enable_sort_by', true);
76 84
77 -
78 85 if (Arr::get($products, 'products', [])) {
79 86 $this->products = Arr::get($products, 'products', []);
80 87 } else {
81 88 $this->products = $products;
@@ -84,8 +91,15 @@
84 91 if($this->products instanceof CursorPaginator){
85 92 $this->total = 0;
86 93 }else{
87 94 $this->total = Arr::get($products, 'total', 0);
95 + if (!$this->total && $this->products instanceof LengthAwarePaginator) {
96 + // A raw LengthAwarePaginator's ArrayAccess proxies to its item
97 + // collection, not its own properties, so Arr::get($products, 'total')
98 + // above always misses when the caller passes the paginator directly
99 + // instead of the normalized ['products' => ..., 'total' => ...] shape.
100 + $this->total = $this->products->total();
101 + }
88 102 }
89 103 //$this->total = $products['total'];
90 104
91 105
@@ -116,8 +130,17 @@
116 130 if (Arr::get($config, 'allow_out_of_stock')) {
117 131 $this->defaultFilters['allow_out_of_stock'] = true;
118 132 }
119 133
134 + // Merge wildcard search preset into defaultFilters so it persists in AJAX re-fetches
135 + $wildcard = Arr::get($defaultFilters, 'wildcard', '');
136 + if ($wildcard !== '') {
137 + $this->defaultFilters['wildcard'] = $wildcard;
138 + if (empty($this->defaultFilters['enabled'])) {
139 + $this->defaultFilters['enabled'] = true;
140 + }
141 + }
142 +
120 143 // Merge sort_by from config filters into defaultFilters for AJAX persistence
121 144 $configFilters = Arr::get($config, 'filters', []);
122 145 if (is_string($configFilters)) {
123 146 $configFilters = json_decode($configFilters, true) ?: [];
@@ -129,13 +152,19 @@
129 152 $this->defaultFilters['enabled'] = true;
130 153 }
131 154 }
132 155
133 - if (Arr::get($this->customFilters, 'price_range', false)) {
156 + $priceRange = Arr::get($this->customFilters, 'price_range', false);
157 + if ($priceRange) {
158 + // Accepts true (default "Price" label) or ['label' => '...'] so
159 + // integrations can name the price filter the same way the
160 + // taxonomies config names taxonomy filters.
134 161 $this->filters['price_range'] = [
135 162 "filter_type" => "range",
136 163 "is_meta" => false,
137 - "label" => "Price",
164 + "label" => is_array($priceRange) && !empty($priceRange['label'])
165 + ? $priceRange['label']
166 + : "Price",
138 167 "enabled" => true,
139 168 ];
140 169 }
141 170
@@ -234,8 +263,13 @@
234 263 }
235 264 if ($onSale) {
236 265 $wrapperAttributes['data-on-sale'] = '1';
237 266 }
267 + // Persist hide_excerpt so AJAX pagination/filtering renders cards the
268 + // same way as the initial response (Paginator.js round-trips it).
269 + if (Arr::get($this->config, 'hide_excerpt', false)) {
270 + $wrapperAttributes['data-hide-excerpt'] = '1';
271 + }
238 272 ?>
239 273 <div class="fct-products-wrapper" data-fluent-cart-shop-app data-fluent-cart-product-wrapper role="main" aria-label="<?php esc_attr_e('Products', 'fluent-cart'); ?>">
240 274 <?php $this->renderViewSwitcher(); ?>
241 275 <div <?php RenderHelper::renderAtts($wrapperAttributes); ?>>
@@ -272,9 +306,9 @@
272 306 ?>
273 307 <div class="fct-shop-view-switcher-wrap">
274 308 <?php $this->renderViewSwitcherButton(); ?>
275 309 <?php
276 - if ($this->isFilterEnabled) {
310 + if ($this->isFilterEnabled && $this->enableSortBy) {
277 311 $this->renderSortByFilter();
278 312 }
279 313 ?>
280 314 </div>
@@ -471,9 +505,13 @@
471 505 <div class="fluent-cart-shop-app-filter-wrapper-inner">
472 506
473 507 <form class="fct-shop-filter-form" data-fluent-cart-product-filter-form role="search"
474 508 aria-label="<?php esc_attr_e('Product filter form', 'fluent-cart'); ?>">
475 - <?php $renderer->renderSearch(); ?>
509 + <?php
510 + if($this->isWildcardFilterEnabled){
511 + $renderer->renderSearch();
512 + }
513 + ?>
476 514 <?php $renderer->renderOptions(); ?>
477 515 <?php if (!$this->liveFilter) : ?>
478 516 <div class="fct-shop-filter-item">
479 517 <div class="fct-shop-button-group">
@@ -513,9 +551,9 @@
513 551 if ($index === 0) {
514 552 $cursorAttr = Arr::get($cursor, 'cursor', '');
515 553 }
516 554
517 - (new \FluentCart\App\Services\Renderer\ProductCardRender($product, ['cursor' => $cursorAttr]))->render();
555 + (new \FluentCart\App\Services\Renderer\ProductCardRender($product, ['cursor' => $cursorAttr, 'hide_excerpt' => Arr::get($this->config, 'hide_excerpt', false)]))->render();
518 556 ?>
519 557 <?php } ?>
520 558 <?php
521 559 }