PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.9
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.9
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
fluentform / app / Services / Logger / Logger.php

Logger.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.9, at app/Services/Logger/Logger.php

427 lines 15.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentForm\App\Services\Logger;
4
5 use FluentForm\App\Models\Log;
6 use FluentForm\App\Models\Form;
7 use FluentForm\App\Helpers\Helper;
8 use FluentForm\App\Models\Scheduler;
9 use FluentForm\App\Services\Manager\FormManagerService;
10 use FluentForm\Framework\Support\Arr;
11 use FluentForm\Framework\Support\Collection;
12 use FluentForm\Framework\Validator\ValidationException;
13
14 class Logger
15 {
16 public function get($attributes = [])
17 {
18 $statuses = Arr::get($attributes, 'status');
19 $formIds = $this->normalizeFormScope(Arr::get($attributes, 'form_id'));
20 $formIds = $this->resolveVisibleFormScope($formIds);
21 $components = Arr::get($attributes, 'component');
22 $sortBy = \FluentForm\App\Helpers\Helper::sanitizeOrderValue(Arr::get($attributes, 'sort_by', 'DESC'));
23 $type = Arr::get($attributes, 'type', 'log');
24 $dateRange = Arr::get($attributes, 'date_range', []);
25 $startDate = Arr::get($dateRange, 0);
26 $endDate = Arr::get($dateRange, 1);
27 [$table, $model, $columns, $join, $componentColumn, $dateColumn] = $this->getBases($type);
28
29 $logsQuery = $model->select($columns)
30 ->leftJoin('fluentform_forms', 'fluentform_forms.id', '=', $join)
31 ->orderBy($table . '.id', $sortBy)
32 ->when(false !== $formIds && [] !== $formIds, function ($q) use ($formIds) {
33 return $q->whereIn('fluentform_forms.id', array_map('intval', $formIds));
34 })
35 ->when([] === $formIds, function ($q) {
36 return $q->whereIn('fluentform_forms.id', [0]);
37 })
38 ->when($statuses, function ($q) use ($statuses, $table) {
39 return $q->whereIn($table . '.status', array_map('sanitize_text_field', $statuses));
40 })
41 ->when($components, function ($q) use ($components, $componentColumn) {
42 return $q->whereIn($componentColumn, array_map('sanitize_text_field', $components));
43 })
44 ->when($startDate && $endDate, function ($q) use ($startDate, $endDate, $dateColumn) {
45 // Concatenate time if not time included on start/end date string
46 if ($startDate != date("Y-m-d H:i:s", strtotime($startDate))) {
47 $startDate .= ' 00:00:01';
48 }
49 if ($endDate != date("Y-m-d H:i:s", strtotime($endDate))) {
50 $endDate .= ' 23:59:59';
51 }
52 return $q->where($dateColumn, '>=', $startDate)
53 ->where($dateColumn, '<=', $endDate);
54 });
55
56 $logs = $logsQuery->paginate();
57
58 $logItems = $logs->items();
59
60 foreach ($logItems as $log) {
61 $hasUrl = ('api' === $type) || (
62 'submission_item' == $log->source_type && $log->submission_id
63 );
64
65 if ($hasUrl) {
66 $log->submission_url = admin_url(
67 'admin.php?page=fluent_forms&route=entries&form_id=' . $log->form_id . '#/entries/' . $log->submission_id
68 );
69 }
70
71 $log->component = Helper::getLogInitiator($log->component, $type);
72 $log->integration_enabled = false;
73
74 $notificationKeys = apply_filters('fluentform/global_notification_active_types', [], $log->form_id);
75
76 unset($notificationKeys['user_registration_feeds']);
77 unset($notificationKeys['notifications']);
78
79 $notificationKeys = array_flip($notificationKeys);
80
81 $actionName = $log->getOriginal('component');
82 if ($actionName) {
83 $actionName = str_replace(['fluentform_integration_notify_', 'fluentform/integration_notify_'], '', $actionName);
84
85 if (in_array($actionName, $notificationKeys)) {
86 $log->integration_enabled = true;
87 }
88 }
89 }
90
91 $logItems = apply_filters_deprecated(
92 'fluentform_all_logs',
93 [
94 $logItems
95 ],
96 FLUENTFORM_FRAMEWORK_UPGRADE,
97 'fluentform/get_logs',
98 'Use fluentform/get_logs instead of fluentform_all_logs'
99 );
100
101 $logs->setCollection(Collection::make($logItems));
102
103 return apply_filters('fluentform/get_logs', $logs);
104 }
105
106 protected function normalizeFormScope($formIds)
107 {
108 if (null === $formIds || false === $formIds || '' === $formIds || [] === $formIds) {
109 return false;
110 }
111
112 $normalized = array_values(array_filter(array_map('intval', (array) $formIds)));
113
114 return $normalized ?: [];
115 }
116
117 protected function resolveVisibleFormScope($requestedFormIds)
118 {
119 $allowedForms = FormManagerService::getUserAllowedFormsScope();
120
121 if (false === $allowedForms) {
122 return $requestedFormIds;
123 }
124
125 if (false === $requestedFormIds) {
126 return $allowedForms;
127 }
128
129 return array_values(array_intersect($requestedFormIds, $allowedForms));
130 }
131
132 protected function getBases($type)
133 {
134 if ('log' === $type) {
135 $table = 'fluentform_logs';
136 $model = Log::query();
137 $columns = [
138 'fluentform_logs.*',
139 'fluentform_forms.title as form_title',
140 'fluentform_logs.source_id as submission_id',
141 'fluentform_logs.parent_source_id as form_id',
142 ];
143 $join = 'fluentform_logs.parent_source_id';
144 $componentColumn = 'fluentform_logs.component';
145 $dateColumn = 'fluentform_logs.created_at';
146 } else {
147 $table = 'ff_scheduled_actions';
148 $model = Scheduler::query();
149 $columns = [
150 'ff_scheduled_actions.id',
151 'ff_scheduled_actions.action as component',
152 'ff_scheduled_actions.form_id',
153 'ff_scheduled_actions.origin_id as submission_id',
154 'ff_scheduled_actions.status',
155 'ff_scheduled_actions.note',
156 'ff_scheduled_actions.updated_at',
157 'ff_scheduled_actions.feed_id',
158 'fluentform_forms.title as form_title',
159 ];
160 $join = 'ff_scheduled_actions.form_id';
161 $componentColumn = 'ff_scheduled_actions.action';
162 $dateColumn = 'ff_scheduled_actions.updated_at';
163 }
164
165 return [$table, $model, $columns, $join, $componentColumn, $dateColumn];
166 }
167
168 public function getFilters($attributes = [])
169 {
170 $type = Arr::get($attributes, 'type', 'log');
171
172 if ('log' === $type) {
173 $statusRows = Log::select('status')->distinct()->get();
174 $componentRows = Log::select('component')->distinct()->get();
175 $formIdRows = Log::select('parent_source_id as form_id')->distinct()->get();
176 } else {
177 $statusRows = Scheduler::select('status')->distinct()->get();
178 $componentRows = Scheduler::select('action as component')->distinct()->get();
179 $formIdRows = Scheduler::select('form_id')->distinct()->get();
180 }
181
182 $statuses = $statusRows->pluck('status')->filter()->map(function ($item) {
183 return [
184 'label' => ucwords($item),
185 'value' => $item,
186 ];
187 })->values();
188
189 $components = $componentRows->pluck('component')->filter()->map(function ($item) use ($type) {
190 return [
191 'label' => Helper::getLogInitiator($item, $type),
192 'value' => $item,
193 ];
194 })->values();
195
196 $formIds = $formIdRows->pluck('form_id')->filter()->toArray();
197 if (false !== ($allowForms = FormManagerService::getUserAllowedFormsScope())) {
198 $formIds = array_filter($formIds, function($value) use ($allowForms) {
199 return in_array($value, $allowForms);
200 });
201 }
202
203 $forms = Form::select('id', 'title')->whereIn('id', $formIds ?: [0])->get();
204
205 return apply_filters('fluentform/get_log_filters', [
206 'statuses' => $statuses,
207 'components' => $components,
208 'forms' => $forms,
209 ]);
210 }
211
212 public function getSubmissionLogs($submissionId, $attributes = [])
213 {
214 $logType = Arr::get($attributes, 'log_type', 'logs');
215
216 $sourceType = Arr::get($attributes, 'source_type', 'submission_item');
217
218 if ('logs' === $logType) {
219 $logs = Log::where('source_id', $submissionId)
220 ->where('source_type', $sourceType)
221 ->orderBy('id', 'DESC')
222 ->get();
223
224 $logs = apply_filters_deprecated(
225 'fluentform_entry_logs',
226 [
227 $logs,
228 $submissionId
229 ],
230 FLUENTFORM_FRAMEWORK_UPGRADE,
231 'fluentform/submission_logs',
232 'Use fluentform/submission_logs instead of fluentform_entry_logs.'
233 );
234
235 $logs = apply_filters('fluentform/submission_logs', $logs, $submissionId);
236
237 $entryLogs = [];
238
239 foreach ($logs as $log) {
240 if (isset($log->component) && $log->component === 'slack') {
241 continue;
242 }
243 $entryLogs[] = [
244 'id' => $log->id,
245 'status' => $log->status,
246 'title' => $log->component . ' (' . $log->title . ')',
247 'description' => $log->description,
248 'created_at' => (string)$log->created_at,
249 ];
250 }
251 } else {
252 $columns = [
253 'id',
254 'action',
255 'status',
256 'note',
257 'created_at',
258 'form_id',
259 'feed_id',
260 'origin_id',
261 ];
262
263 $logs = Scheduler::select($columns)
264 ->where('origin_id', $submissionId)
265 ->orderBy('id', 'DESC')
266 ->get();
267
268 $logs = apply_filters_deprecated(
269 'fluentform_entry_api_logs',
270 [
271 $logs,
272 $submissionId
273 ],
274 FLUENTFORM_FRAMEWORK_UPGRADE,
275 'fluentform/submission_api_logs',
276 'Use fluentform/submission_api_logs instead of fluentform_entry_api_logs.'
277 );
278 $logs = apply_filters('fluentform/submission_api_logs', $logs, $submissionId);
279
280 $entryLogs = [];
281
282 foreach ($logs as $log) {
283 $entryLog = [
284 'id' => $log->id,
285 'status' => $log->status,
286 'title' => 'n/a',
287 'description' => $log->note,
288 'created_at' => (string)$log->created_at,
289 'form_id' => $log->form_id,
290 'feed_id' => $log->feed_id,
291 'submission_id' => $log->origin_id,
292 'integration_enabled' => false
293 ];
294
295 $notificationKeys = apply_filters('fluentform/global_notification_active_types', [], $log->form_id);
296
297 unset($notificationKeys['user_registration_feeds']);
298 unset($notificationKeys['notifications']);
299
300 $notificationKeys = array_flip($notificationKeys);
301
302 $actionName = Helper::getLogInitiator($log->action);
303 if ($actionName) {
304 $actionName = str_replace(['Fluentform_integration_notify_', 'Fluentform/integration_notify_'], '', $actionName);
305
306 if (in_array($actionName, $notificationKeys)) {
307 $entryLog['integration_enabled'] = true;
308 }
309 }
310
311 if ($log->action) {
312 $entryLog['title'] = Helper::getLogInitiator($log->action, $logType);
313 }
314
315 $entryLogs[] = $entryLog;
316 }
317 }
318
319 return apply_filters('fluentform/submission_logs', $entryLogs, $submissionId);
320 }
321
322 public function remove($attributes = [])
323 {
324 $ids = $this->normalizeLogIds($attributes);
325
326 if (!$ids) {
327 throw new ValidationException(
328 // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Exception message, not output
329 __('No selections found', 'fluentform')
330 );
331 }
332
333 $logType = Arr::get($attributes, 'type', Arr::get($attributes, 'log_type', 'logs'));
334 $entryId = intval(Arr::get($attributes, 'entry_id'));
335 $targetLogs = $this->getLogsForDeletion($ids, $logType);
336
337 if (!$targetLogs->count()) {
338 throw new ValidationException(
339 // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Exception message, not output
340 __('No selections found', 'fluentform')
341 );
342 }
343
344 $this->assertDeletePermission($targetLogs, $entryId);
345 $this->getDeleteQuery($logType)
346 ->whereIn('id', $targetLogs->pluck('id')->all())
347 ->delete();
348
349 return [
350 'message' => __('Selected log(s) successfully deleted', 'fluentform'),
351 ];
352 }
353
354 protected function normalizeLogIds($attributes)
355 {
356 $ids = Arr::get($attributes, 'log_ids', []);
357
358 if (!is_array($ids)) {
359 $ids = [];
360 }
361
362 $singleLogId = intval(Arr::get($attributes, 'log_id'));
363 if ($singleLogId) {
364 $ids[] = $singleLogId;
365 }
366
367 $ids = array_map('intval', $ids);
368 $ids = array_filter($ids);
369
370 return array_values(array_unique($ids));
371 }
372
373 protected function getLogsForDeletion($ids, $logType)
374 {
375 if ('logs' === $logType) {
376 return Log::select([
377 'id',
378 'parent_source_id as form_id',
379 'source_id as submission_id',
380 ])->whereIn('id', $ids)->get();
381 }
382
383 return Scheduler::select([
384 'id',
385 'form_id',
386 'origin_id as submission_id',
387 ])->whereIn('id', $ids)->get();
388 }
389
390 protected function getDeleteQuery($logType)
391 {
392 return 'logs' === $logType ? Log::query() : Scheduler::query();
393 }
394
395 protected function assertDeletePermission($targetLogs, $entryId = 0)
396 {
397 if ($entryId) {
398 foreach ($targetLogs as $targetLog) {
399 if (intval($targetLog->submission_id) !== $entryId) {
400 $this->throwDeletePermissionError();
401 }
402 }
403 }
404
405 $allowedForms = FormManagerService::getUserAllowedFormsScope();
406 if (false === $allowedForms) {
407 return;
408 }
409
410 foreach ($targetLogs as $targetLog) {
411 $formId = intval($targetLog->form_id);
412
413 if (!$formId || !in_array($formId, $allowedForms, true)) {
414 $this->throwDeletePermissionError();
415 }
416 }
417 }
418
419 protected function throwDeletePermissionError()
420 {
421 throw new ValidationException(
422 // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Exception message, not output
423 __('You do not have permission to delete the selected logs', 'fluentform')
424 );
425 }
426 }
427