PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.0
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.0
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 trunk All 48 releases
fluent-cart / app / Http / Controllers / ShopController.php

ShopController.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.6.0, at app/Http/Controllers/ShopController.php

329 lines 10.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\App\Http\Controllers;
4
5 use FluentCart\Api\Resource\ShopResource;
6 use FluentCart\Api\Sanitizer\Sanitizer;
7 use FluentCart\Api\StoreSettings;
8 use FluentCart\App\Helpers\Helper;
9 use FluentCart\App\Models\Product;
10 use FluentCart\App\Services\Renderer\ProductListRenderer;
11 use FluentCart\App\Services\Renderer\ProductModalRenderer;
12 use FluentCart\App\Services\Renderer\ProductRenderer;
13 use FluentCart\App\Vite;
14 use FluentCart\Framework\Http\Request\Request;
15 use FluentCart\Framework\Pagination\CursorPaginator;
16 use FluentCart\Framework\Support\Arr;
17 use FluentCart\Framework\Support\Collection;
18 use FluentCart\Api\Taxonomy;
19 use FluentCart\App\Services\Renderer\SearchBarRenderer;
20
21 class ShopController extends Controller
22 {
23 public function getProducts(Request $request): array
24 {
25 $defaultFilters = $request->get('default_filters', []);
26 $filters = $request->get('filters', []);
27
28 // Merge sort_by from default_filters (shortcode) if not set by interactive filters
29 $defaultSortBy = Arr::get($defaultFilters, 'sort_by', '');
30 if ($defaultSortBy && empty(Arr::get($filters, 'sort_by'))) {
31 if (!is_array($filters)) {
32 $filters = [];
33 }
34 $filters['sort_by'] = sanitize_text_field($defaultSortBy);
35 }
36
37 $defaultTermIds = Helper::parseTermIdsForFilter($defaultFilters);
38 $filterTermIds = Helper::parseTermIdsForFilter($filters);
39 $mergedTermIds = Helper::mergeTermIdsForFilter($defaultTermIds, $filterTermIds);
40
41 $status = ["post_status" => ["column" => "post_status", "operator" => "in", "value" => ["publish"]]];
42 $allowOutOfStock = $request->get('allow_out_of_stock', false) == true;
43 $cursor = $request->get('cursor', null);
44 $orderType = $request->get('order_type', 'DESC');
45 $with = $request->get('with', []);
46
47 // Shortcode filter params from AJAX
48 $includeIds = array_slice(array_values(array_filter(array_map('intval', (array) $request->get('include_ids', [])), function ($id) { return $id > 0; })), 0, 100);
49 $excludeIds = array_slice(array_values(array_filter(array_map('intval', (array) $request->get('exclude_ids', [])), function ($id) { return $id > 0; })), 0, 100);
50 $productType = sanitize_text_field($request->get('product_type', ''));
51 $onSale = !empty($request->get('on_sale'));
52
53 $params = [
54 'cursor' => $cursor,
55 "order_type" => $orderType,
56 "select" => '*',
57 "with" => $with,
58 "selected_status" => true,
59 "status" => $status,
60 "default_filters" => $defaultFilters,
61 "filters" => $filters,
62 'taxonomy_filters' => $mergedTermIds,
63 'allow_out_of_stock' => $allowOutOfStock,
64 "per_page" => $request->getSafe('per_page', Sanitizer::SANITIZE_TEXT_FIELD) ?: 10,
65 'paginate_using' => $request->getSafe('paginate_using', Sanitizer::SANITIZE_TEXT_FIELD),
66 'include_ids' => $includeIds,
67 'exclude_ids' => $excludeIds,
68 'product_type' => $productType,
69 'on_sale' => $onSale,
70 ];
71
72 $products = ShopResource::get($params);
73
74 $products['products']->setCollection(
75 $products['products']->getCollection()->transform(function ($product) {
76 $product->setAppends(['view_url', 'has_subscription', 'thumbnail']);
77 $product->makeHidden(['post_content']);
78 if ($product->detail !== null) {
79 $product->detail->makeHidden(['item_cost', 'editing_stage', 'stock', 'manage_stock', 'manage_cost', 'settings']);
80 }
81 return $product;
82 })
83 );
84
85 return [
86 'products' => $products,
87 ];
88
89 }
90
91 public function getProductViews(Request $request): array
92 {
93 // $products = $this->getProducts($request)['products'];
94 // $products = $products->toArray();
95 $page = Arr::get($request->all(), 'current_page', 1);
96 $perPage = Arr::get($request->all(), 'per_page', 10);
97
98 $products = $this->getProducts($request);
99 $total = Arr::get($products, 'products.total', 0);
100 $templateProvider = $request->get('template_provider', '');
101 $clientId = $request->get('client_id', '');
102 if ($templateProvider) {
103 $preLoadedView = apply_filters('fluent_cart/products_views/preload_collection_' . $templateProvider, '', [
104 'client_id' => $clientId,
105 'products' => Arr::get($products, 'products.products', []),
106 'total' => $total,
107 'requestData' => $request->all()
108 ]);
109
110 if ($preLoadedView) {
111
112 $from = $total > 0 ? (($page - 1) * $perPage) + 1 : 0;
113 $to = $total > 0 ? min($total, $page * $perPage) : 0;
114
115 if ($from <= 0) {
116 $from = 1;
117 }
118
119
120 if ($to == 0) {
121 $to = 1;
122 }
123
124 if ($page == 0) {
125 $page = 1;
126 }
127
128 return [
129 'products' => [
130 'views' => $preLoadedView,
131 'current_page' => $page,
132 'last_page' => max((int)ceil($total / $request->get('per_page', 10)), 1),
133 'total' => $total,
134 'per_page' => $perPage,
135 'from' => $from,
136 'to' => $to,
137 ]
138 ];
139
140 }
141 }
142
143 $clientId = 'fct_product_loop_client_' . $clientId;
144
145 $variable = null;
146
147 if ($clientId) {
148 $variable = get_transient($clientId);
149 $variable = $variable['markup'] ?? null;
150 }
151
152 if ($variable) {
153 $view = do_blocks($variable);
154
155 $from = $total > 0 ? (($page - 1) * $perPage) + 1 : 0;
156 $to = $total > 0 ? min($total, $page * $perPage) : 0;
157
158 if ($from <= 0) {
159 $from = 1;
160 }
161
162
163 if ($to == 0) {
164 $to = 1;
165 }
166
167 if ($page == 0) {
168 $page = 1;
169 }
170
171 return [
172 'products' => [
173 'views' => $view,
174 'current_page' => $page,
175 'last_page' => max((int)ceil($total / $request->get('per_page', 10)), 1),
176 'total' => $total,
177 'per_page' => $perPage,
178 'from' => $from,
179 'to' => $to,
180 ]
181 ];
182
183 }
184
185 $products = $this->getProducts($request);
186
187 $originalProducts = $products['products'];
188
189 if ($originalProducts instanceof CursorPaginator) {
190 $cursor = wp_parse_args(wp_parse_url($originalProducts->nextPageUrl(), PHP_URL_QUERY));
191 }
192
193
194 $total = $products['products']['total'];
195
196 $perPage = $request->get('per_page', 10);
197 $products['total'] = $total;
198 $products['last_page'] = max((int)ceil($total / $perPage), 1);
199 $hideExcerpt = filter_var($request->get('hide_excerpt', false), FILTER_VALIDATE_BOOLEAN);
200 ob_start();
201 if (($products['total'])) {
202 (new ProductListRenderer(Arr::get($products, 'products.products'), null, null, ['hide_excerpt' => $hideExcerpt]))->renderProductList();
203 } else {
204 ProductRenderer::renderNoProductFound();
205 }
206
207 $view = ob_get_clean();
208
209 $products['views'] = $view;
210 $products['per_page'] = $perPage;
211 $from = ($page - 1) * $perPage + 1;
212 $to = min($total, $page * $perPage);
213
214 if ($from <= 0) {
215 $from = 1;
216 }
217
218 $products['from'] = $from;
219
220 if ($to == 0) {
221 $to = 1;
222 }
223
224 if ($page == 0) {
225 $page = 1;
226 }
227
228 $products['to'] = $to;
229 $products['page'] = $page;
230 $products['current_page'] = $page;
231
232 unset($products['data']);
233 unset($products['products']);
234
235 return [
236 'products' => $products
237 ];
238 }
239
240 public function getTermIdsFromDefaultFilter($defaultFilters): array
241 {
242 $ids = [];
243 $taxonomies = Taxonomy::getTaxonomies();
244 foreach ($taxonomies as $key => $taxonomy) {
245 $defaultTerms = array_filter(explode(',', Arr::get($defaultFilters, $key, '')));
246 $ids = array_merge(
247 $ids,
248 $defaultTerms
249 );
250 }
251
252 return Collection::make($ids)->map(function ($termId) {
253 return sanitize_text_field((string)$termId);
254 })->toArray();
255 }
256
257 public function getTermIdsFromFilter($filters): array
258 {
259 $taxonomies = Taxonomy::getTaxonomies();
260 if (is_string($filters)) {
261 $filters = json_decode($filters, true);
262 }
263 $formattedFilters = [];
264
265 foreach ($taxonomies as $key => $taxonomy) {
266 $terms = Arr::get($filters, $key, []);
267 if (!is_array($terms)) {
268 $terms = [$terms];
269 }
270
271 if (!empty($terms)) {
272 $terms = array_map(function ($term) {
273 return sanitize_text_field((string)$term);
274 }, $terms);
275
276 $formattedFilters[$key] = $terms;
277 }
278
279
280 }
281
282 return $formattedFilters;
283 }
284
285 public function searchProduct(Request $request)
286 {
287
288 $searchValue = $request->getSafe('post_title', 'sanitize_text_field');
289 $urlMode = $request->getSafe('url_mode', 'sanitize_text_field');
290 $termId = $request->getSafe('termId', 'intval');
291 $showThumbnail = filter_var($request->get('show_thumbnail', true), FILTER_VALIDATE_BOOLEAN);
292
293 $defaultFilters =
294 [
295 "wildcard" => $searchValue,
296 ];
297
298 $status = ["post_status" => ["column" => "post_status", "operator" => "in", "value" => ["publish"]]];
299
300 $params = [
301 "select" => ['ID', 'guid', 'post_title'],
302 "with" => ['wpTerms', 'detail.galleryImage'],
303 "selected_status" => true,
304 "status" => $status,
305 "default_filters" => $defaultFilters,
306 ];
307
308 if (!empty($termId)) {
309 $params["taxonomy_filters"] = [
310 'product-categories' => Arr::wrap($termId)
311 ];
312 }
313
314 $results = ShopResource::get($params);
315 $products = $results['products'];
316 ob_start();
317
318 (new SearchBarRenderer([
319 'url_mode' => $urlMode,
320 'show_thumbnail' => $showThumbnail,
321 ]))->renderResultItems($products);
322
323 $view = ob_get_clean();
324 return $this->response->json([
325 'htmlView' => $view
326 ]);
327 }
328 }
329