PluginProbe
The Innovative Form Builder – IvyForms / 0.8
The Innovative Form Builder – IvyForms v0.8
1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 1.2 1.3
ivyforms / backend / src / Common / Helpers / EntryQueryHelper.php

EntryQueryHelper.php in The Innovative Form Builder – IvyForms 0.8, at backend/src/Common/Helpers/EntryQueryHelper.php

204 lines 7.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace IvyForms\Common\Helpers;
4
5 // phpcs:disable PSR1.Files.SideEffects
6 if (!defined('ABSPATH')) {
7 exit; // Exit if accessed directly
8 }
9
10 use IvyForms\Common\Exceptions\InvalidArgumentException;
11 use IvyForms\Services\InstallActions\DB\Entry\EntriesTable;
12 use IvyForms\Services\InstallActions\DB\EntryField\EntryFieldsTable;
13 use IvyForms\Services\InstallActions\DB\Form\FormsTable;
14
15 class EntryQueryHelper
16 {
17 /**
18 * Helper to return search conditions for entries (for complexity reduction)
19 *
20 * @param array<string, mixed>|null $params
21 * @return array<string>
22 */
23 public static function getEntrySearchConditions(?array $params = null): array
24 {
25 $conditions = [
26 'e.id LIKE %s',
27 'e.formId LIKE %s',
28 'f.name LIKE %s',
29 ];
30 // Only include fieldValue if searchFieldValue is true (default true for BC)
31 if (!isset($params['searchFieldValue']) || $params['searchFieldValue']) {
32 $conditions[] = 'eft.fieldValue LIKE %s';
33 }
34 return $conditions;
35 }
36
37 /**
38 * Get entry fields SQL and params for the given entries.
39 *
40 * @param array<int, array<string, mixed>> $entries
41 * @return array{sql: string, params: array<int, int>}
42 * @throws InvalidArgumentException
43 */
44 public static function getEntryFieldsQuery(array $entries): array
45 {
46 if (empty($entries)) {
47 return ['sql' => '', 'params' => []];
48 }
49 $entryIds = array_column($entries, 'id');
50 $placeholders = implode(',', array_fill(0, count($entryIds), '%d'));
51 $entryFieldsTable = EntryFieldsTable::getTableName();
52 $sql = "SELECT * FROM {$entryFieldsTable} WHERE entryId IN ($placeholders)";
53 return ['sql' => $sql, 'params' => $entryIds];
54 }
55
56 /**
57 * Get the count of entries for a specific form (SQL and params).
58 *
59 * @param string $table
60 * @param int $formId
61 * @return array{sql: string, params: array<int, int>}
62 */
63 public static function getCountByFormIdQuery(string $table, int $formId): array
64 {
65 $sql = "SELECT COUNT(*) FROM {$table} WHERE formId = %d";
66 return ['sql' => $sql, 'params' => [$formId]];
67 }
68
69 /**
70 * Get the count of entries for the filter dropdown (SQL and params).
71 *
72 * @param string $table
73 * @param array<string, mixed>|null $params
74 * @return array{sql: string, params: array<int, int>}
75 */
76 public static function getFilterCountQuery(string $table, ?array $params = null): array
77 {
78 $where = '';
79 $queryParams = [];
80 if (!empty($params['filters']['formId'])) {
81 $where = 'WHERE formId = %d';
82 $queryParams[] = (int)$params['filters']['formId'];
83 }
84 $sql = "SELECT
85 SUM(status = 'read') as readTrueCount,
86 SUM(status = 'unread') as readFalseCount,
87 SUM(starred = 1) as starredTrueCount,
88 SUM(starred = 0) as starredFalseCount
89 FROM {$table} $where";
90 return ['sql' => $sql, 'params' => $queryParams];
91 }
92
93 /**
94 * Get the count of entries for multiple form IDs (SQL and params).
95 *
96 * @param int[] $formIds
97 * @return array{sql: string, params: array<int, int>, formIds: array<int, int>}
98 * @throws InvalidArgumentException
99 */
100 public static function getEntryCountByFormIdsQuery(array $formIds): array
101 {
102 if (empty($formIds)) {
103 return ['sql' => '', 'params' => [], 'formIds' => []];
104 }
105 $formIds = array_map('intval', $formIds);
106 $placeholders = implode(',', array_fill(0, count($formIds), '%d'));
107 $tableName = EntriesTable::getTableName();
108 $sql = "SELECT formId, COUNT(*) as count FROM {$tableName} WHERE formId IN ($placeholders) GROUP BY formId";
109 return ['sql' => $sql, 'params' => $formIds, 'formIds' => $formIds];
110 }
111
112 /**
113 * Build the SELECT query and parameters for entries, with or without pagination.
114 * @param string $entriesTable
115 * @param string $join
116 * @param string $whereClauses
117 * @param string $sortColumn
118 * @param string $order
119 * @param array<int|string, mixed> $queryParams
120 * @param int|string $perPage
121 * @param int $page
122 * @return array{sql: string, params: array<int|string, mixed>}
123 */
124 public static function buildEntrySelectQuery(
125 string $entriesTable,
126 string $join,
127 string $whereClauses,
128 string $sortColumn,
129 string $order,
130 array $queryParams,
131 $perPage,
132 int $page
133 ): array {
134 $isAll = ($perPage === 'all' || $perPage === 0);
135 if ($isAll) {
136 $sql = "SELECT DISTINCT e.* FROM {$entriesTable} e $join
137 WHERE {$whereClauses} ORDER BY {$sortColumn} {$order}";
138 return ['sql' => $sql, 'params' => $queryParams];
139 }
140 $perPage = max((int)$perPage, 1);
141 $offset = ($page - 1) * $perPage;
142 $params = $queryParams;
143 $params[] = $perPage;
144 $params[] = $offset;
145 $sql = "SELECT DISTINCT e.* FROM {$entriesTable} e $join
146 WHERE {$whereClauses} ORDER BY {$sortColumn} {$order} LIMIT %d OFFSET %d";
147 return ['sql' => $sql, 'params' => $params];
148 }
149
150 /**
151 * Get the JOIN clause for entries, entry fields, and forms.
152 *
153 * @return string
154 * @throws InvalidArgumentException
155 */
156 public static function getEntryJoinClause(): string
157 {
158 $entryFieldsTable = EntryFieldsTable::getTableName();
159 $formsTable = FormsTable::getTableName();
160 $join = " LEFT JOIN {$entryFieldsTable} eft ON e.id = eft.entryId ";
161 $join .= " LEFT JOIN {$formsTable} f ON e.formId = f.id ";
162 return $join;
163 }
164
165 /**
166 * Build search WHERE clause and query parameters for entry search.
167 * @param array<string, mixed>|null $params
168 * @return array{where: string|null, params: array<int, string>}
169 */
170 public static function buildSearchWhereClause(?array $params): array
171 {
172 if (!empty($params['search'])) {
173 global $wpdb;
174 $searchEscaped = '%' . $wpdb->esc_like($params['search']) . '%';
175 $searchConditions = self::getEntrySearchConditions($params);
176 $where = '(' . implode(' OR ', $searchConditions) . ')';
177 $queryParams = array_fill(0, count($searchConditions), $searchEscaped);
178 return ['where' => $where, 'params' => $queryParams];
179 }
180 return ['where' => null, 'params' => []];
181 }
182
183 /**
184 * Build filter WHERE clause and query parameters for entry filter.
185 * @param array<string, mixed>|null $params
186 * @param array<int, string> $filterableColumns
187 * @return array{where: array<int, string>, params: array<int, string>}
188 */
189 public static function buildFilterWhereClause(?array $params, array $filterableColumns): array
190 {
191 $whereClauses = [];
192 $queryParams = [];
193 if (!empty($params['filters'])) {
194 foreach ($params['filters'] as $key => $value) {
195 if (in_array($key, $filterableColumns, true) && $value !== null && $value !== '') {
196 $whereClauses[] = "e.{$key} = %s";
197 $queryParams[] = sanitize_text_field($value);
198 }
199 }
200 }
201 return ['where' => $whereClauses, 'params' => $queryParams];
202 }
203 }
204