PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.3
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.3
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
fluent-cart / app / Http / Controllers / ProductDownloadablesController.php

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

216 lines 8.0 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\ProductDownloadResource;
6 use FluentCart\App\Helpers\Helper;
7 use FluentCart\App\Http\Requests\ProductDownloadable\ProductDownloadableBulkFileRequest;
8 use FluentCart\App\Http\Requests\ProductDownloadable\ProductDownloadableFileRequest;
9 use FluentCart\App\Models\Product;
10 use FluentCart\App\Models\ProductDetail;
11 use FluentCart\App\Models\ProductDownload;
12 use FluentCart\App\Services\FileSystem\StoragePath;
13 use FluentCart\App\Services\URL;
14 use FluentCart\Framework\Http\Request\Request;
15 use FluentCart\Framework\Http\URL as BaseUrl;
16 use FluentCart\Framework\Support\Arr;
17 use FluentCart\Framework\Support\Str;
18 use FluentCart\Framework\Validator\Validator;
19
20 class ProductDownloadablesController extends Controller
21 {
22 public function syncDownloadableFiles(Request $request): \WP_REST_Response
23 {
24 $productDownloadableBulkFileRequest = new ProductDownloadableBulkFileRequest();
25 $validator = Validator::make($request->all(), $productDownloadableBulkFileRequest->rules());
26 $validationErrors = [];
27
28
29 if ($validator->fails()) {
30 $validationErrors = $validator->errors();
31 }
32
33
34 if (count($validationErrors) !== 0) {
35 return $this->sendError($validationErrors);
36 }
37
38 $data = $request->get('downloadable_files');
39 $sanitizedData = [];
40
41 foreach ($data as $downloadableFile) {
42
43 $variationIds = Arr::get($downloadableFile, 'product_variation_id');
44 if (is_array($variationIds)) {
45 $variationIds = array_map('intval', $variationIds);
46 } else {
47 $variationIds = [];
48 }
49
50 $sanitizedData[] = [
51 'id' => intval(Arr::get($downloadableFile, 'id')),
52 'post_id' => intval(Arr::get($downloadableFile, 'post_id')),
53 'product_variation_id' => $variationIds,
54 'title' => sanitize_text_field(Arr::get($downloadableFile, 'title')),
55 'type' => sanitize_text_field(Arr::get($downloadableFile, 'type')),
56 'driver' => sanitize_text_field(Arr::get($downloadableFile, 'driver')),
57 'bucket' => sanitize_text_field(Arr::get($downloadableFile, 'bucket')),
58 'file_name' => sanitize_text_field(Arr::get($downloadableFile, 'file_name')),
59 'file_path' => sanitize_text_field(Arr::get($downloadableFile, 'file_path')),
60 'file_url' => sanitize_text_field(Arr::get($downloadableFile, 'file_url')),
61 'settings' => Arr::get($downloadableFile, 'settings'),
62 'serial' => sanitize_text_field(Arr::get($downloadableFile, 'serial')),
63 'file_size' => sanitize_text_field(Arr::get($downloadableFile, 'file_size')),
64 ];
65 }
66
67
68 $fileData['downloadable_files'] = $sanitizedData;
69
70
71 unset($fileData['downloadable_files']['*']);
72
73 $productId = $request->getSafe('postId', 'intval');
74
75 foreach ($fileData['downloadable_files'] as &$file) {
76
77 $file['download_identifier'] = Str::uuid();
78 $file['post_id'] = $productId;
79 $file['file_path'] = !empty($file['file_path']) ? $file['file_path'] : $file['file_name'];
80 $file['file_url'] = !empty($file['file_url']) ? $file['file_url'] : $file['file_name'];
81
82 // file_path is later composed onto the storage directory to read the
83 // file back, so a relative segment stored here would read outside it.
84 // Checked after the file_name fallback, which feeds the same column.
85 if (!StoragePath::isSafe($file['file_path'])) {
86 return $this->sendError([
87 'message' => __('Invalid file path', 'fluent-cart')
88 ], 422);
89 }
90
91 $file['product_variation_id'] = json_encode(
92 Arr::get($file, 'product_variation_id', [])
93 );
94
95 $fileName = $file['file_name'];
96 $fileName = explode('_____fluent-cart_____', $fileName)[0];
97 $fileName = explode('__fluent-cart__', $fileName)[0];
98 $file['file_name'] = $fileName;
99
100 $file['settings'] = json_encode(
101 Arr::get($file, 'settings', [])
102 );
103
104 unset($file['id']);
105 unset($file['bucket']);
106 }
107
108
109 ProductDetail::query()->where('post_id', $productId)->update([
110 'manage_downloadable' => 1
111 ]);
112
113
114 $isCreated = ProductDownload::query()->insert($fileData['downloadable_files']);
115 if ($isCreated) {
116 return $this->sendSuccess([
117 'downloadable_files' => ProductDownloadResource::search(['post_id' => $productId])
118 ]);
119 } else {
120 return $this->sendError([
121 'message' => __('Failed to attach downloadable files', 'fluent-cart')
122 ]);
123 }
124 }
125
126 public function getDownloadableUrl($downloadableId)
127 {
128 $productDownload = ProductDownload::query()->findOrFail($downloadableId);
129
130
131 if (empty($productDownload)) {
132 return $this->sendError([
133 'message' => __('Failed to generate downloadable link', 'fluent-cart')
134 ]);
135 }
136
137
138 return $this->sendSuccess([
139 'url' => Helper::generateDownloadFileLink($productDownload, null, 60 * 60 * 24 * 7, true)
140 ]);
141
142
143 }
144
145 public function update(ProductDownloadableFileRequest $request, $downloadId)
146 {
147 $productDownload = ProductDownload::query()->findOrFail($downloadId);
148 $data = $request->getSafe($request->sanitize());
149
150
151 $fileName = Arr::get($data, 'file_name');
152
153 $filePath = Arr::get($data, 'file_path') ?: $fileName;
154 $fileUrl = Arr::get($data, 'file_url') ?: $fileName;
155
156 // Same containment as the sync path: file_path is composed onto the
157 // storage directory when the file is read back.
158 if (!StoragePath::isSafe($filePath)) {
159 return $this->sendError([
160 'message' => __('Invalid file path', 'fluent-cart')
161 ], 422);
162 }
163
164 $productVariationId = Arr::get($data, 'product_variation_id', []);
165 $fileName = explode('_____fluent-cart_____', $fileName)[0];
166 $fileName = explode('__fluent-cart__', $fileName)[0];
167
168
169
170 if (is_array($productVariationId)) {
171 $productVariationId = array_values(array_filter(array_map('intval', $productVariationId)));
172 } else {
173 $productVariationId = [];
174 }
175
176 $productDownload->product_variation_id = $productVariationId;
177 $productDownload->title = Arr::get($data, 'title');
178 $productDownload->type = Arr::get($data, 'type');
179 $productDownload->driver = Arr::get($data, 'driver');
180 $productDownload->file_name = $fileName;
181 $productDownload->file_path = $filePath;
182 $productDownload->file_url = $fileUrl;
183 $productDownload->settings = Arr::get($data, 'settings');
184 $productDownload->serial = Arr::get($data, 'serial');
185
186 if ($productDownload->save()) {
187 return $this->sendSuccess([
188 'message' => __('Product downloadable files updated successfully', 'fluent-cart')
189 ]);
190 } else {
191 return $this->sendError([
192 'message' => __('Failed to update product downloadable files', 'fluent-cart')
193 ]);
194 }
195
196 }
197
198 public function delete($downloadableFileId)
199 {
200 $response = ProductDownloadResource::delete($downloadableFileId);
201 if (is_wp_error($response)) {
202 return $this->sendError([
203 'message' => $response->get_error_message()
204 ]);
205 }
206 return $this->sendSuccess([
207 'message' => $response['message']
208 ]);
209 }
210
211 public function updateDownloadableFile(Request $request, Product $product, ProductDownload $productDownload)
212 {
213
214 }
215 }
216