PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.3.23
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.3.23
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.3.23, at app/Http/Controllers/ShopController.php

326 lines 10.6 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 = $products['products']['total'];
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 ob_start();
200 if (($products['total'])) {
201 (new ProductListRenderer(Arr::get($products, 'products.products')))->renderProductList();
202 } else {
203 ProductRenderer::renderNoProductFound();
204 }
205
206 $view = ob_get_clean();
207
208 $products['views'] = $view;
209 $products['per_page'] = $perPage;
210 $from = ($page - 1) * $perPage + 1;
211 $to = min($total, $page * $perPage);
212
213 if ($from <= 0) {
214 $from = 1;
215 }
216
217 $products['from'] = $from;
218
219 if ($to == 0) {
220 $to = 1;
221 }
222
223 if ($page == 0) {
224 $page = 1;
225 }
226
227 $products['to'] = $to;
228 $products['page'] = $page;
229 $products['current_page'] = $page;
230
231 unset($products['data']);
232 unset($products['products']);
233
234 return [
235 'products' => $products
236 ];
237 }
238
239 public function getTermIdsFromDefaultFilter($defaultFilters): array
240 {
241 $ids = [];
242 $taxonomies = Taxonomy::getTaxonomies();
243 foreach ($taxonomies as $key => $taxonomy) {
244 $defaultTerms = array_filter(explode(',', Arr::get($defaultFilters, $key, '')));
245 $ids = array_merge(
246 $ids,
247 $defaultTerms
248 );
249 }
250
251 return Collection::make($ids)->map(function ($termId) {
252 return sanitize_text_field((string)$termId);
253 })->toArray();
254 }
255
256 public function getTermIdsFromFilter($filters): array
257 {
258 $taxonomies = Taxonomy::getTaxonomies();
259 if (is_string($filters)) {
260 $filters = json_decode($filters, true);
261 }
262 $formattedFilters = [];
263
264 foreach ($taxonomies as $key => $taxonomy) {
265 $terms = Arr::get($filters, $key, []);
266 if (!is_array($terms)) {
267 $terms = [$terms];
268 }
269
270 if (!empty($terms)) {
271 $terms = array_map(function ($term) {
272 return sanitize_text_field((string)$term);
273 }, $terms);
274
275 $formattedFilters[$key] = $terms;
276 }
277
278
279 }
280
281 return $formattedFilters;
282 }
283
284 public function searchProduct(Request $request)
285 {
286
287 $searchValue = $request->getSafe('post_title', 'sanitize_text_field');
288 $urlMode = $request->getSafe('url_mode', 'sanitize_text_field');
289 $termId = $request->getSafe('termId', 'intval');
290
291 $defaultFilters =
292 [
293 "wildcard" => $searchValue,
294 ];
295
296 $status = ["post_status" => ["column" => "post_status", "operator" => "in", "value" => ["publish"]]];
297
298 $params = [
299 "select" => ['guid', 'post_title'],
300 "with" => ['wpTerms'],
301 "selected_status" => true,
302 "status" => $status,
303 "default_filters" => $defaultFilters,
304 ];
305
306 if (!empty($termId)) {
307 $params["taxonomy_filters"] = [
308 'product-categories' => Arr::wrap($termId)
309 ];
310 }
311
312 $results = ShopResource::get($params);
313 $products = $results['products'];
314 ob_start();
315
316 (new SearchBarRenderer([
317 'url_mode' => $urlMode
318 ]))->renderResultItems($products);
319
320 $view = ob_get_clean();
321 return $this->response->json([
322 'htmlView' => $view
323 ]);
324 }
325 }
326