PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.5
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.5
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/Http/Controllers/ShopController.php +35 -4 1.5.5 → 1.6.5 View file →
@@ -41,9 +41,17 @@
41 41 $status = ["post_status" => ["column" => "post_status", "operator" => "in", "value" => ["publish"]]];
42 42 $allowOutOfStock = $request->get('allow_out_of_stock', false) == true;
43 43 $cursor = $request->get('cursor', null);
44 44 $orderType = $request->get('order_type', 'DESC');
45 - $with = $request->get('with', []);
45 + // The storefront never chooses its own eager loads. This route is public
46 + // (frontend_routes.php, PublicPolicy), and forwarding the request's `with`
47 + // let an anonymous caller walk arbitrary relation chains — e.g.
48 + // `?with[]=orderItems.order.customer.wpUser` reached the WordPress users
49 + // table. The two relations below are the ones the appends applied after
50 + // this call already touch (`thumbnail` reads `detail`, `has_subscription`
51 + // reads `variants`), so the response shape is unchanged and they are now
52 + // eager loaded instead of lazily fetched per row.
53 + $with = ['detail', 'variants'];
46 54
47 55 // Shortcode filter params from AJAX
48 56 $includeIds = array_slice(array_values(array_filter(array_map('intval', (array) $request->get('include_ids', [])), function ($id) { return $id > 0; })), 0, 100);
49 57 $excludeIds = array_slice(array_values(array_filter(array_map('intval', (array) $request->get('exclude_ids', [])), function ($id) { return $id > 0; })), 0, 100);
@@ -70,15 +78,37 @@
70 78 ];
71 79
72 80 $products = ShopResource::get($params);
73 81
82 + $collection = $products['products']->getCollection();
83 +
84 + // The appended has_subscription accessor reads $product->variants during
85 + // serialization, so variants reach the response even without with[]=variants.
86 + // Eager-load them once for the whole page (single query) so the sensitive
87 + // fields can be hidden before serialization.
88 + $collection->loadMissing('variants');
89 +
74 90 $products['products']->setCollection(
75 - $products['products']->getCollection()->transform(function ($product) {
91 + $collection->transform(function ($product) {
76 92 $product->setAppends(['view_url', 'has_subscription', 'thumbnail']);
77 93 $product->makeHidden(['post_content']);
78 94 if ($product->detail !== null) {
79 95 $product->detail->makeHidden(['item_cost', 'editing_stage', 'stock', 'manage_stock', 'manage_cost', 'settings']);
80 96 }
97 + $product->variants->each(function ($variant) {
98 + $variant->makeHidden(['item_cost', 'manage_cost', 'manage_stock', 'total_stock', 'available', 'committed', 'on_hold']);
99 +
100 + // other_info is a JSON blob that makeHidden cannot reach into; strip its
101 + // admin-only keys while keeping the storefront display fields (payment_type,
102 + // repeat_interval, trial_days, billing_summary, weight/dimensions).
103 + $info = $variant->other_info;
104 + if (is_array($info)) {
105 + foreach (['tax_class', 'tax_exempt', 'package_slug', 'bundle_child_ids', 'variation_type', 'is_bundle_product'] as $internalKey) {
106 + unset($info[$internalKey]);
107 + }
108 + $variant->other_info = $info;
109 + }
110 + });
81 111 return $product;
82 112 })
83 113 );
84 114
@@ -195,11 +225,12 @@
195 225
196 226 $perPage = $request->get('per_page', 10);
197 227 $products['total'] = $total;
198 228 $products['last_page'] = max((int)ceil($total / $perPage), 1);
229 + $hideExcerpt = filter_var($request->get('hide_excerpt', false), FILTER_VALIDATE_BOOLEAN);
199 230 ob_start();
200 231 if (($products['total'])) {
201 - (new ProductListRenderer(Arr::get($products, 'products.products')))->renderProductList();
232 + (new ProductListRenderer(Arr::get($products, 'products.products'), null, null, ['hide_excerpt' => $hideExcerpt]))->renderProductList();
202 233 } else {
203 234 ProductRenderer::renderNoProductFound();
204 235 }
205 236
@@ -319,9 +350,9 @@
319 350 'show_thumbnail' => $showThumbnail,
320 351 ]))->renderResultItems($products);
321 352
322 353 $view = ob_get_clean();
323 - return $this->response->json([
354 + return $this->response->sendSuccess([
324 355 'htmlView' => $view
325 356 ]);
326 357 }
327 358 }