PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.5.1
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.5.1
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 / EmailNotificationController.php

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

312 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\App\App;
6 use FluentCart\Api\StoreSettings;
7 use FluentCart\App\Helpers\EditorShortCodeHelper;
8 use FluentCart\App\Http\Requests\EmailNotificationRequest;
9 use FluentCart\App\Http\Requests\EmailSettingsRequest;
10 use FluentCart\App\Http\Requests\SchedulingSettingsRequest;
11 use FluentCart\App\Services\Email\EmailNotificationMailer;
12 use FluentCart\App\Services\Email\EmailNotifications;
13 use FluentCart\App\Services\Email\StoreDigestService;
14 use FluentCart\App\Services\PDF\ReceiptPdfTemplateService;
15 use FluentCart\App\Services\Reminders\ReminderService;
16 use FluentCart\App\Services\ShortCodeParser\ShortcodeTemplateBuilder;
17 use FluentCart\App\Services\Email\EmailPreviewService;
18 use FluentCart\App\Services\TemplateService;
19 use FluentCart\Framework\Http\Request\Request;
20 use FluentCart\Framework\Support\Arr;
21 use FluentCart\Framework\Support\Str;
22
23 class EmailNotificationController extends Controller
24 {
25 public function index(Request $request): \WP_REST_Response
26 {
27
28 $getNotifications = EmailNotifications::getNotifications();
29
30 if ($getNotifications) {
31 return $this->sendSuccess([
32 'data' => $getNotifications
33 ]);
34 }
35 return $this->sendError([
36 'data' => []
37 ]);
38 }
39
40 public function find($notification): \WP_REST_Response
41 {
42 $name = sanitize_text_field($notification);
43 $notification = EmailNotifications::getNotification($name);
44
45
46 if ($notification) {
47 $hasFluentPdf = defined('FLUENT_PDF');
48 $fontsReady = false;
49 $setupUrl = '';
50
51 if ($hasFluentPdf && class_exists('FluentPdf\Classes\Controller\FontDownloader')) {
52 $fontDownloader = new \FluentPdf\Classes\Controller\FontDownloader();
53 $fontsReady = empty($fontDownloader->getDownloadableFonts());
54 $setupUrl = admin_url('admin.php?page=fluent_pdf.php');
55 }
56
57 $pdfTemplates = $hasFluentPdf ? (new ReceiptPdfTemplateService())->getTemplateList() : [];
58
59 return $this->sendSuccess([
60 'data' => $notification,
61 'shortcodes' => EditorShortCodeHelper::getEmailNotificationShortcodes(),
62 'has_fluent_pdf' => $hasFluentPdf,
63 'fonts_ready' => $fontsReady,
64 'setup_url' => $setupUrl,
65 'pdf_templates' => $pdfTemplates,
66 ]);
67 }
68
69 return $this->sendError([
70 'message' => __('Notification Details not found', 'fluent-cart')
71 ]);
72 }
73
74 public function update(EmailNotificationRequest $request, $notification): \WP_REST_Response
75 {
76 $data = $request->getSafe($request->sanitize());
77
78 $settings = Arr::get($data, 'settings', []);
79
80 // Strip custom template data in free; pro filter restores it
81 $settingsWithoutTemplate = $settings;
82 unset($settingsWithoutTemplate['email_body']);
83 $settingsWithoutTemplate['is_default_body'] = 'yes';
84
85 $settings = apply_filters('fluent_cart/prepare_email_template_data', $settingsWithoutTemplate, $settings);
86
87 $updated = EmailNotifications::updateNotification($notification, $settings);
88 if ($updated) {
89 return $this->sendSuccess([
90 'message' => __('Notification updated successfully', 'fluent-cart')
91 ]);
92 } else {
93 return $this->sendError([
94 'message' => __('Failed to update notification', 'fluent-cart')
95 ]);
96 }
97
98 }
99
100 public function enableNotification(Request $request, $name): \WP_REST_Response
101 {
102 $enabledValue = sanitize_text_field(Arr::get($request->all(), 'active'));
103
104 $notification = EmailNotifications::updateNotification(
105 $name,
106 ['active' => $enabledValue]
107 );
108
109 if ($notification) {
110 return $this->sendSuccess([
111 'message' => __('Notification updated successfully', 'fluent-cart')
112 ]);
113 }
114 return $this->sendError([
115 'message' => __('Failed to update notification', 'fluent-cart')
116 ]);
117
118 }
119
120 public function getShortCodes(Request $request): \WP_REST_Response
121 {
122 return $this->sendSuccess([
123 'data' => [
124 'email_templates' => $this->getTemplateFiles(),
125 'shortcodes' => EditorShortCodeHelper::getEmailNotificationShortcodes(),
126 'buttons' => EditorShortCodeHelper::getButtons()
127 ],
128 ]);
129 }
130
131 public function previewDefaultTemplate(Request $request)
132 {
133 $template = sanitize_text_field($request->get('template'));
134 $previewService = new EmailPreviewService();
135 $data = $previewService->getPreviewData($template);
136
137 $body = TemplateService::getTemplateByPathName($template, $data);
138
139 // Wrap in the same outer email template used by actual emails
140 $header = (string) App::make('view')->make('emails.parts.order_header', $data);
141 $mailer = new EmailNotificationMailer();
142 $view = (string) App::make('view')->make('emails.general_template', [
143 'emailBody' => $body,
144 'preheader' => '',
145 'header' => $header,
146 'emailFooter' => $mailer->getEmailFooter(),
147 ]);
148
149 // Resolve shortcodes (e.g., {{ settings.store_brand }}, {{order.created_at}})
150 $view = ShortcodeTemplateBuilder::make($view, $data);
151
152 // Disable all links/buttons in the preview so they are not clickable
153 $view .= '<style>a, button, [role="button"] { pointer-events: none !important; cursor: default !important; }</style>';
154
155 return $this->sendSuccess([
156 'data' => [
157 'content' => $view
158 ],
159 ]);
160 }
161
162 public function getTemplateFiles()
163 {
164 $defaultFilePath = FLUENTCART_PLUGIN_PATH . '/app/Views/emails';
165 $filesArray = [];
166 $files = scandir($defaultFilePath);
167 foreach ($files as $file) {
168 $filePath = $defaultFilePath . '/' . $file;
169 if (is_file($filePath)) {
170 $file = Str::of($file)->replace('.php', '');
171 $filesArray[] = [
172 'path' => $file,
173 'label' => Str::of($file)->replace('fluent_cart', '')->headline()
174 ];
175 }
176 }
177 return $filesArray;
178 }
179
180 public function getSettings(): \WP_REST_Response
181 {
182 return $this->sendSuccess([
183 'data' => EmailNotifications::getSettings(),
184 'shortcodes' => EditorShortCodeHelper::getEmailSettingsShortcodes(),
185 ]);
186 }
187
188 public function saveSettings(EmailSettingsRequest $request): \WP_REST_Response
189 {
190 $data = $request->getSafe($request->sanitize());
191
192 if (!App::isProActive()) {
193 $data['show_email_footer'] = 'yes';
194 }
195
196 $updated = EmailNotifications::updateSettings($data);
197
198 if ($updated) {
199 return $this->sendSuccess([
200 'message' => __('Email settings saved successfully', 'fluent-cart')
201 ]);
202 } else {
203 return $this->sendError([
204 'message' => __('Failed to save email settings', 'fluent-cart')
205 ]);
206 }
207 }
208
209 public function getDigestSettings(): \WP_REST_Response
210 {
211 return $this->sendSuccess([
212 'data' => StoreDigestService::getSettings(),
213 ]);
214 }
215
216 public function saveDigestSettings(Request $request): \WP_REST_Response
217 {
218 $saved = StoreDigestService::saveSettings($request->all());
219
220 return $this->sendSuccess([
221 'data' => $saved,
222 'message' => __('Store digest settings saved successfully', 'fluent-cart'),
223 ]);
224 }
225
226 public function sendDigestTest(Request $request): \WP_REST_Response
227 {
228 $frequency = sanitize_text_field(Arr::get($request->all(), 'frequency', 'daily'));
229 if (!in_array($frequency, StoreDigestService::CADENCES, true)) {
230 $frequency = 'daily';
231 }
232
233 // Send the test to the configured recipients, falling back to the WP admin email.
234 $recipients = StoreDigestService::getSettings('recipients');
235 if (empty($recipients)) {
236 $recipients = get_bloginfo('admin_email');
237 }
238
239 $sent = StoreDigestService::sendDigest($frequency, (string) $recipients);
240
241 if ($sent) {
242 return $this->sendSuccess([
243 'message' => __('Test digest email sent.', 'fluent-cart'),
244 ]);
245 }
246
247 return $this->sendError([
248 'message' => __('Could not send the test email. Please check your mailing settings and recipients.', 'fluent-cart'),
249 ]);
250 }
251
252 public function getSchedulingSettings(StoreSettings $storeSettings): array
253 {
254 $tab = 'reminders';
255 $currentTabFields = Arr::get($storeSettings->fields(), 'setting_tabs.schema.' . $tab);
256
257 return [
258 'settings' => $storeSettings->get(),
259 'fields' => [
260 $tab => $currentTabFields
261 ]
262 ];
263 }
264
265 public function saveSchedulingSettings(SchedulingSettingsRequest $request, StoreSettings $storeSettings): \WP_REST_Response
266 {
267 try {
268 $sanitizedData = $request->getSafe($request->sanitize());
269
270 $data = array_merge(
271 $storeSettings->get(),
272 $sanitizedData
273 );
274
275 $updated = $storeSettings->save($data);
276
277 return $this->sendSuccess([
278 'data' => $updated,
279 'message' => __('Scheduling settings saved successfully', 'fluent-cart')
280 ]);
281 } catch (\Throwable $e) {
282 return $this->sendError([
283 'message' => __('Failed to save scheduling settings', 'fluent-cart')
284 ], 423);
285 }
286 }
287
288 public function sendManualReminder(Request $request): \WP_REST_Response
289 {
290 $event = sanitize_text_field(Arr::get($request->all(), 'event', ''));
291 $entityId = absint(Arr::get($request->all(), 'entity_id', 0));
292
293 if (empty($event) || empty($entityId)) {
294 return $this->sendError([
295 'message' => __('Event type and entity ID are required', 'fluent-cart')
296 ]);
297 }
298
299 $result = (new ReminderService())->sendManualReminder($event, $entityId);
300
301 if ($result['success']) {
302 return $this->sendSuccess([
303 'message' => $result['message']
304 ]);
305 }
306
307 return $this->sendError([
308 'message' => $result['message']
309 ]);
310 }
311 }
312