Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
Relation
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
2 / 2
2
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAllRelatedByQuestion
100.00% covered (success)
100.00%
25 / 25
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3/**
4 * The Relation class for dynamic-related record linking.
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    Marco Enders <marco@minimarco.de>
12 * @author    Thorsten Rinne <thorsten@phpmyfaq.de>
13 * @copyright 2006-2026 phpMyFAQ Team
14 * @license   https://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
15 * @link      https://www.phpmyfaq.de
16 * @since     2006-06-18
17 */
18
19declare(strict_types=1);
20
21namespace phpMyFAQ;
22
23use phpMyFAQ\Search\SearchFactory;
24
25/**
26 * Class Relation
27 * @package phpMyFAQ
28 */
29readonly class Relation
30{
31    /**
32     * Relation constructor.
33     */
34    public function __construct(
35        private Configuration $configuration,
36    ) {
37    }
38
39    /**
40     * Returns all relevant articles for a FAQ record with the same language.
41     * Prefer exact matches to avoid unrelated results from fuzzy searches.
42     *
43     * @param string $question FAQ title
44     * @param string $keywords FAQ keywords
45     * @return \stdClass[]
46     */
47    public function getAllRelatedByQuestion(string $question, string $keywords): array
48    {
49        $terms = str_replace(search: '-', replace: ' ', subject: $question) . ' ' . $keywords;
50        $searchDatabase = SearchFactory::create($this->configuration, ['database' => Database::getType()]);
51
52        $searchDatabase
53            ->setTable(Database::getTablePrefix() . 'faqdata AS fd')
54            ->setResultColumns([
55                'fd.id AS id',
56                'fd.lang AS lang',
57                'fcr.category_id AS category_id',
58                'fd.thema AS question',
59                'fd.content AS answer',
60                'fd.keywords AS keywords',
61            ])
62            ->setJoinedTable(Database::getTablePrefix() . 'faqcategoryrelations AS fcr')
63            ->setJoinedColumns([
64                'fd.id = fcr.record_id',
65                'fd.lang = fcr.record_lang',
66            ])
67            ->setConditions([
68                'fd.active' => 'yes',
69                'fd.lang' => $this->configuration->getLanguage()->getLanguage(),
70            ])
71            ->setMatchingColumns(['fd.keywords', 'fd.thema', 'fd.content'])
72            ->disableRelevance();
73
74        $result = $searchDatabase->search($terms);
75
76        return $this->configuration->getDb()->fetchAll($result) ?? [];
77    }
78}