Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
85.71% covered (success)
85.71%
12 / 14
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
CategoryValidator
85.71% covered (success)
85.71%
12 / 14
33.33% covered (danger)
33.33%
1 / 3
10.29
0.00% covered (danger)
0.00%
0 / 1
 isValidCategory
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
3.33
 isDirectChild
80.00% covered (success)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
4.13
 collectDirectChildren
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3/**
4 * Validates category data structures.
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public License,
7 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
8 * obtain one at https://mozilla.org/MPL/2.0/.
9 *
10 * @package   phpMyFAQ
11 * @author    Thorsten Rinne <thorsten@phpmyfaq.de>
12 * @copyright 2025 phpMyFAQ Team
13 * @license   https://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
14 * @link      https://www.phpmyfaq.de
15 * @since     2025-10-19
16 */
17
18declare(strict_types=1);
19
20namespace phpMyFAQ\Category\Tree;
21
22final class CategoryValidator
23{
24    /**
25     * Validates if a category array has required fields.
26     */
27    public function isValidCategory(mixed $category): bool
28    {
29        if (!is_array($category)) {
30            return false;
31        }
32
33        return array_key_exists(key: 'parent_id', array: $category) && array_key_exists(key: 'id', array: $category);
34    }
35
36    /**
37     * Checks if a category is a direct child of a parent.
38     *
39     * @param array<string, mixed> $category
40     */
41    public function isDirectChild(array $category, mixed $categoryId, int $parentId): bool
42    {
43        if (!array_key_exists('parent_id', $category)) {
44            return false;
45        }
46
47        if ((int) $category['parent_id'] !== $parentId) {
48            return false;
49        }
50
51        return is_int($categoryId) && $categoryId > 0;
52    }
53
54    /**
55     * Collects direct children IDs for a parent.
56     *
57     * @param array<int, array<string, mixed>> $categories
58     * @return array<int>
59     */
60    public function collectDirectChildren(array $categories, int $parentId): array
61    {
62        $children = [];
63        foreach ($categories as $categoryId => $category) {
64            if (!$this->isDirectChild($category, $categoryId, $parentId)) {
65                continue;
66            }
67
68            $children[] = $categoryId;
69        }
70
71        return $children;
72    }
73}