Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
80.00% covered (success)
80.00%
16 / 20
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
SearchFactory
80.00% covered (success)
80.00%
16 / 20
33.33% covered (danger)
33.33%
1 / 3
13.15
0.00% covered (danger)
0.00%
0 / 1
 create
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 instantiate
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
3.33
 resolveDatabaseType
62.50% covered (warning)
62.50%
5 / 8
0.00% covered (danger)
0.00%
0 / 1
7.90
1<?php
2
3/**
4 * Factory class for phpMyFAQ search classes.
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 2010-2026 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     2010-07-06
16 */
17
18declare(strict_types=1);
19
20namespace phpMyFAQ\Search;
21
22use phpMyFAQ\Configuration;
23use phpMyFAQ\Database\DatabaseDriver;
24
25/**
26 * Class SearchFactory
27 *
28 * @package phpMyFAQ\Search
29 */
30class SearchFactory
31{
32    /**
33     * Factory for generating search instances.
34     *
35     * @param string[] $searchHandler Array with search handlers, e.g., array ('database' => 'mysqli')
36     */
37    public static function create(Configuration $configuration, array $searchHandler): SearchDatabase
38    {
39        $type = (string) current($searchHandler);
40        $connector = ucfirst((string) key($searchHandler));
41        if ($type === '') {
42            $type = self::resolveDatabaseType($configuration->getDb());
43        }
44
45        if (str_starts_with($type, 'pdo_')) {
46            $searchClass = sprintf('\phpMyFAQ\Search\%s\Pdo%s', $connector, ucfirst(substr(string: $type, offset: 4)));
47
48            return self::instantiate($searchClass, $configuration);
49        }
50
51        $searchClass = sprintf('\phpMyFAQ\Search\%s\%s', $connector, ucfirst($type));
52
53        return self::instantiate($searchClass, $configuration);
54    }
55
56    private static function instantiate(string $searchClass, Configuration $configuration): SearchDatabase
57    {
58        if (!class_exists($searchClass) || !is_subclass_of($searchClass, SearchDatabase::class)) {
59            throw new \RuntimeException('Unknown search backend: ' . $searchClass);
60        }
61
62        return new $searchClass($configuration);
63    }
64
65    private static function resolveDatabaseType(DatabaseDriver $databaseDriver): string
66    {
67        $classNameParts = explode('\\', $databaseDriver::class);
68        $driverClass = strtolower((string) end($classNameParts));
69
70        return match ($driverClass) {
71            'pdomysql' => 'pdo_mysql',
72            'pdopgsql' => 'pdo_pgsql',
73            'pdosqlite' => 'pdo_sqlite',
74            'pdosqlsrv' => 'pdo_sqlsrv',
75            default => $driverClass,
76        };
77    }
78}