| @@ -2,11 +2,13 @@ | ||
| 2 | 2 | |
| 3 | 3 | namespace IvyForms\Common\Helpers; |
| 4 | 4 | |
| 5 | 5 | use IvyForms\Common\Exceptions\InvalidArgumentException; |
| 6 | +use IvyForms\Common\Exceptions\QueryExecutionException; | |
| 6 | 7 | use IvyForms\Services\InstallActions\DB\Entry\EntriesTable; |
| 7 | 8 | use IvyForms\Services\InstallActions\DB\EntryField\EntryFieldsTable; |
| 8 | 9 | use IvyForms\Services\InstallActions\DB\Form\FormsTable; |
| 10 | +use IvyForms\Services\Translations\BackendStrings; | |
| 9 | 11 | |
| 10 | 12 | class EntryQueryHelper |
| 11 | 13 | { |
| 12 | 14 | /** |
| @@ -193,6 +195,129 @@ | ||
| 193 | 195 | } |
| 194 | 196 | } |
| 195 | 197 | } |
| 196 | 198 | return ['where' => $whereClauses, 'params' => $queryParams]; |
| 199 | + } | |
| 200 | + | |
| 201 | + /** | |
| 202 | + * Build form name lookup SQL and params for the given entry rows. | |
| 203 | + * | |
| 204 | + * @param array<int, array<string, mixed>> $results | |
| 205 | + * @return array{sql: string, params: array<int, int>} | |
| 206 | + */ | |
| 207 | + public static function getFormNamesByIdsQuery(array $results, string $formsTable): array | |
| 208 | + { | |
| 209 | + if ($results === []) { | |
| 210 | + return ['sql' => '', 'params' => []]; | |
| 211 | + } | |
| 212 | + | |
| 213 | + $formIds = array_values(array_unique(array_map('intval', array_column($results, 'formId')))); | |
| 214 | + $formIds = array_values(array_filter($formIds)); | |
| 215 | + if ($formIds === []) { | |
| 216 | + return ['sql' => '', 'params' => []]; | |
| 217 | + } | |
| 218 | + | |
| 219 | + $placeholders = implode(',', array_fill(0, count($formIds), '%d')); | |
| 220 | + $sql = "SELECT id, name FROM {$formsTable} WHERE id IN ($placeholders)"; | |
| 221 | + | |
| 222 | + return ['sql' => $sql, 'params' => $formIds]; | |
| 223 | + } | |
| 224 | + | |
| 225 | + /** | |
| 226 | + * @param list<int|string> $ids | |
| 227 | + * @return list<int> | |
| 228 | + */ | |
| 229 | + public static function normalizePositiveIds(array $ids): array | |
| 230 | + { | |
| 231 | + return array_values(array_unique(array_filter( | |
| 232 | + array_map('intval', $ids), | |
| 233 | + static function (int $id): bool { | |
| 234 | + return $id > 0; | |
| 235 | + } | |
| 236 | + ))); | |
| 237 | + } | |
| 238 | + | |
| 239 | + /** | |
| 240 | + * @param int[] $entryIds | |
| 241 | + * @return array{sql: string, params: list<int>} | |
| 242 | + */ | |
| 243 | + public static function getFormIdsByEntryIdsQuery(array $entryIds): array | |
| 244 | + { | |
| 245 | + $entryIds = self::normalizePositiveIds($entryIds); | |
| 246 | + $table = EntriesTable::getTableName(); | |
| 247 | + | |
| 248 | + if ($entryIds === []) { | |
| 249 | + return [ | |
| 250 | + 'sql' => "SELECT id, formId FROM {$table} WHERE 0 = 1", | |
| 251 | + 'params' => [], | |
| 252 | + ]; | |
| 253 | + } | |
| 254 | + | |
| 255 | + $placeholders = implode(',', array_fill(0, count($entryIds), '%d')); | |
| 256 | + | |
| 257 | + return [ | |
| 258 | + 'sql' => "SELECT id, formId FROM {$table} WHERE id IN ({$placeholders})", | |
| 259 | + 'params' => $entryIds, | |
| 260 | + ]; | |
| 261 | + } | |
| 262 | + | |
| 263 | + /** | |
| 264 | + * @param array<int, array<string, mixed>> $rows | |
| 265 | + * @return array<int, int> entryId => formId | |
| 266 | + */ | |
| 267 | + public static function mapEntryIdToFormIdRows(array $rows): array | |
| 268 | + { | |
| 269 | + $map = []; | |
| 270 | + foreach ($rows as $row) { | |
| 271 | + $formId = (int) ($row['formId'] ?? 0); | |
| 272 | + if ($formId <= 0) { | |
| 273 | + continue; | |
| 274 | + } | |
| 275 | + $map[(int) $row['id']] = $formId; | |
| 276 | + } | |
| 277 | + | |
| 278 | + return $map; | |
| 279 | + } | |
| 280 | + | |
| 281 | + /** | |
| 282 | + * Multi-row inserts generate IDs spaced by auto_increment_increment, | |
| 283 | + * which is > 1 on replication-style setups. | |
| 284 | + * | |
| 285 | + * @param \wpdb $wpdb | |
| 286 | + */ | |
| 287 | + public static function getAutoIncrementStep($wpdb): int | |
| 288 | + { | |
| 289 | + $step = (int) $wpdb->get_var('SELECT @@auto_increment_increment'); | |
| 290 | + | |
| 291 | + return $step > 0 ? $step : 1; | |
| 292 | + } | |
| 293 | + | |
| 294 | + /** | |
| 295 | + * @param \wpdb $wpdb | |
| 296 | + * @param int[] $entryIds | |
| 297 | + * @return array<int, int> entryId => formId | |
| 298 | + * @throws QueryExecutionException | |
| 299 | + */ | |
| 300 | + public static function fetchFormIdsByEntryIds($wpdb, array $entryIds): array | |
| 301 | + { | |
| 302 | + $entryIds = self::normalizePositiveIds($entryIds); | |
| 303 | + if ($entryIds === []) { | |
| 304 | + return []; | |
| 305 | + } | |
| 306 | + | |
| 307 | + $queryParts = self::getFormIdsByEntryIdsQuery($entryIds); | |
| 308 | + if ($queryParts['params'] === []) { | |
| 309 | + return []; | |
| 310 | + } | |
| 311 | + | |
| 312 | + $query = $wpdb->prepare($queryParts['sql'], ...$queryParts['params']); | |
| 313 | + $rows = $wpdb->get_results($query, ARRAY_A); | |
| 314 | + | |
| 315 | + if (!is_array($rows)) { | |
| 316 | + throw new QueryExecutionException( | |
| 317 | + BackendStrings::getExceptionStrings()['unable_find_by_id'] . __CLASS__ | |
| 318 | + ); | |
| 319 | + } | |
| 320 | + | |
| 321 | + return self::mapEntryIdToFormIdRows($rows); | |
| 197 | 322 | } |
| 198 | 323 | } |