PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.1
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.1
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 / Services / Filter / LogFilter.php

LogFilter.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.6.1, at app/Services/Filter/LogFilter.php

117 lines 4.1 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\Services\Filter;
4
5 use FluentCart\App\Models\Activity;
6 use FluentCart\Framework\Support\Str;
7
8 class LogFilter extends BaseFilter
9 {
10
11 public function applySimpleFilter(?string $search = null): void
12 {
13 $this->query->when($search ?? $this->search, function ($query, $search) {
14 return $query
15 ->where(function ($query) use ($search) {
16 $searchOptions = [];
17 if (Str::of($search)->contains('#')) {
18 $searchableColumns = ['id'];
19 $search = Str::of($search)->remove('#')->toString();
20 } else {
21 $searchableColumns = ['id', 'title', 'content', 'module_name'];
22 }
23
24 foreach ($searchableColumns as $index => $column) {
25 $searchOptions[$column] = [
26 'column' => $column,
27 'operator' => $index === 0 ? 'like_all' : 'or_like_all',
28 'value' => $search
29 ];
30 }
31 $query->search($searchOptions);
32 });
33 });
34 }
35
36
37 public function tabsMap(): array
38 {
39 return [
40 'success' => 'status',
41 'warning' => 'status',
42 'error' => 'status',
43 'failed' => 'status',
44 'info' => 'status',
45 'api' => 'log_type',
46 ];
47 }
48
49 public function getModel(): string
50 {
51 return Activity::class;
52 }
53
54 public static function getFilterName(): string
55 {
56 return 'logs';
57 }
58
59 /**
60 * No screen key, because there is no screen: the admin table (LogTable.js)
61 * does not override `Table::with()`, so nothing in the admin sends a `with`
62 * to the activity feed at all. Inventing a context key for a context that
63 * does not exist would be an entry with no reader.
64 *
65 * PUBLIC key — `user` is the relation name a consumer asks an activity
66 * endpoint for, and it is the name the repo's own remaining consumer sends:
67 * the Phase 16 throughput guard (`tests/integration/throughput-guards.php`,
68 * `throughput-activity-feed`) materializes `$activity->user` for every row
69 * inside its query-count boundary and asserts the count does not grow from
70 * 5 rows to 25. Without an eager-load path that guard cannot pass at all —
71 * the actor would be lazily fetched per row — so the only way to drop this
72 * key is to delete the N+1 assertion, which is the gate itself.
73 *
74 * No further permission bar: the feed mounts under `AdminPolicy`, so a
75 * caller here is already a super admin. The grant is narrow anyway —
76 * `Activity::user()` selects exactly ID, display_name and user_email on the
77 * relation itself.
78 *
79 * `Activity::activity()` is a `morphTo()` and MUST NEVER be allowlisted at
80 * any depth. Its target is chosen by the `module_type` column of each row,
81 * so a single `with=activity` would hydrate whatever model the log happens
82 * to point at — orders, subscriptions, licenses — bypassing every
83 * per-model permission check this map exists to enforce.
84 *
85 * @return array<string, callable>
86 */
87 protected function allowedWiths(): array
88 {
89 return [
90 'user' => [$this, 'publicUser'],
91 ];
92 }
93
94 /**
95 * The actor behind a log row. No select here: `Activity::user()` already
96 * narrows itself to ID, display_name and user_email.
97 *
98 * @param \FluentCart\Framework\Database\Orm\Builder $query
99 * @return \FluentCart\Framework\Database\Orm\Builder
100 */
101 protected function publicUser($query)
102 {
103 return $query->with(['user']);
104 }
105
106
107 public function applyActiveViewFilter(?string $activeView = null): void
108 {
109 $activeView = $activeView ?? $this->activeView;
110 $tabsMap = $this->tabsMap();
111
112 $this->query->when($activeView, function ($query, $activeView) use ($tabsMap) {
113 $query->where($tabsMap[$activeView], $activeView);
114 });
115 }
116 }
117