xref: /webtrees/app/Module/FrequentlyAskedQuestionsModule.php (revision 1d1f373cc23093682b1736881f66a527f62ccc46)
18c2e8227SGreg Roach<?php
23976b470SGreg Roach
38c2e8227SGreg Roach/**
48c2e8227SGreg Roach * webtrees: online genealogy
58fcd0d32SGreg Roach * Copyright (C) 2019 webtrees development team
68c2e8227SGreg Roach * This program is free software: you can redistribute it and/or modify
78c2e8227SGreg Roach * it under the terms of the GNU General Public License as published by
88c2e8227SGreg Roach * the Free Software Foundation, either version 3 of the License, or
98c2e8227SGreg Roach * (at your option) any later version.
108c2e8227SGreg Roach * This program is distributed in the hope that it will be useful,
118c2e8227SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
128c2e8227SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
138c2e8227SGreg Roach * GNU General Public License for more details.
148c2e8227SGreg Roach * You should have received a copy of the GNU General Public License
158c2e8227SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
168c2e8227SGreg Roach */
17fcfa147eSGreg Roach
18e7f56f2aSGreg Roachdeclare(strict_types=1);
19e7f56f2aSGreg Roach
2076692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module;
2176692c8bSGreg Roach
22*1d1f373cSGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\ControlPanel;
230e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N;
240e62c4b8SGreg Roachuse Fisharebest\Webtrees\Menu;
2550d6f48cSGreg Roachuse Fisharebest\Webtrees\Services\HtmlService;
26*1d1f373cSGreg Roachuse Fisharebest\Webtrees\Services\TreeService;
270e62c4b8SGreg Roachuse Fisharebest\Webtrees\Tree;
2877654037SGreg Roachuse Illuminate\Database\Capsule\Manager as DB;
2977654037SGreg Roachuse Illuminate\Database\Query\Builder;
3077654037SGreg Roachuse Illuminate\Support\Collection;
315229eadeSGreg Roachuse InvalidArgumentException;
326ccdf4f0SGreg Roachuse Psr\Http\Message\ResponseInterface;
336ccdf4f0SGreg Roachuse Psr\Http\Message\ServerRequestInterface;
348de50a4eSGreg Roachuse stdClass;
35f3874e19SGreg Roach
365229eadeSGreg Roachuse function assert;
37*1d1f373cSGreg Roachuse function redirect;
38*1d1f373cSGreg Roachuse function route;
398c2e8227SGreg Roach
408c2e8227SGreg Roach/**
418c2e8227SGreg Roach * Class FrequentlyAskedQuestionsModule
428c2e8227SGreg Roach */
4337eb8894SGreg Roachclass FrequentlyAskedQuestionsModule extends AbstractModule implements ModuleConfigInterface, ModuleMenuInterface
44c1010edaSGreg Roach{
4549a243cbSGreg Roach    use ModuleConfigTrait;
4649a243cbSGreg Roach    use ModuleMenuTrait;
4749a243cbSGreg Roach
4850d6f48cSGreg Roach    /** @var HtmlService */
4950d6f48cSGreg Roach    private $html_service;
5050d6f48cSGreg Roach
51*1d1f373cSGreg Roach    /** @var TreeService */
52*1d1f373cSGreg Roach    private $tree_service;
53*1d1f373cSGreg Roach
5450d6f48cSGreg Roach    /**
55*1d1f373cSGreg Roach     * BatchUpdateModule constructor.
5650d6f48cSGreg Roach     *
5750d6f48cSGreg Roach     * @param HtmlService $html_service
58*1d1f373cSGreg Roach     * @param TreeService $tree_service
5950d6f48cSGreg Roach     */
60*1d1f373cSGreg Roach    public function __construct(HtmlService $html_service, TreeService $tree_service)
6150d6f48cSGreg Roach    {
6250d6f48cSGreg Roach        $this->html_service = $html_service;
63*1d1f373cSGreg Roach        $this->tree_service = $tree_service;
6450d6f48cSGreg Roach    }
6550d6f48cSGreg Roach
66961ec755SGreg Roach    /**
670cfd6963SGreg Roach     * How should this module be identified in the control panel, etc.?
68961ec755SGreg Roach     *
69961ec755SGreg Roach     * @return string
70961ec755SGreg Roach     */
7149a243cbSGreg Roach    public function title(): string
72c1010edaSGreg Roach    {
73bbb76c12SGreg Roach        /* I18N: Name of a module. Abbreviation for “Frequently Asked Questions” */
74bbb76c12SGreg Roach        return I18N::translate('FAQ');
758c2e8227SGreg Roach    }
768c2e8227SGreg Roach
77961ec755SGreg Roach    /**
78961ec755SGreg Roach     * A sentence describing what this module does.
79961ec755SGreg Roach     *
80961ec755SGreg Roach     * @return string
81961ec755SGreg Roach     */
8249a243cbSGreg Roach    public function description(): string
83c1010edaSGreg Roach    {
84bbb76c12SGreg Roach        /* I18N: Description of the “FAQ” module */
85bbb76c12SGreg Roach        return I18N::translate('A list of frequently asked questions and answers.');
868c2e8227SGreg Roach    }
878c2e8227SGreg Roach
8876692c8bSGreg Roach    /**
8949a243cbSGreg Roach     * The default position for this menu.  It can be changed in the control panel.
900ee13198SGreg Roach     *
910ee13198SGreg Roach     * @return int
920ee13198SGreg Roach     */
938f53f488SRico Sonntag    public function defaultMenuOrder(): int
94c1010edaSGreg Roach    {
95353b36abSGreg Roach        return 8;
968c2e8227SGreg Roach    }
978c2e8227SGreg Roach
980ee13198SGreg Roach    /**
990ee13198SGreg Roach     * A menu, to be added to the main application menu.
1000ee13198SGreg Roach     *
101aee13b6dSGreg Roach     * @param Tree $tree
102aee13b6dSGreg Roach     *
1030ee13198SGreg Roach     * @return Menu|null
1040ee13198SGreg Roach     */
10546295629SGreg Roach    public function getMenu(Tree $tree): ?Menu
106c1010edaSGreg Roach    {
10777654037SGreg Roach        if ($this->faqsExist($tree, WT_LOCALE)) {
10849a243cbSGreg Roach            return new Menu($this->title(), route('module', [
10926684e68SGreg Roach                'module' => $this->name(),
110c1010edaSGreg Roach                'action' => 'Show',
1119022ab66SGreg Roach                'tree'   => $tree->name(),
112c1010edaSGreg Roach            ]), 'menu-help');
1138c2e8227SGreg Roach        }
114b2ce94c6SRico Sonntag
115b2ce94c6SRico Sonntag        return null;
1168c2e8227SGreg Roach    }
117aee13b6dSGreg Roach
118aee13b6dSGreg Roach    /**
11957ab2231SGreg Roach     * @param ServerRequestInterface $request
120aee13b6dSGreg Roach     *
1216ccdf4f0SGreg Roach     * @return ResponseInterface
122aee13b6dSGreg Roach     */
12357ab2231SGreg Roach    public function getAdminAction(ServerRequestInterface $request): ResponseInterface
124c1010edaSGreg Roach    {
125aee13b6dSGreg Roach        $this->layout = 'layouts/administration';
126aee13b6dSGreg Roach
127*1d1f373cSGreg Roach        // This module can't run without a tree
128*1d1f373cSGreg Roach        $tree = $request->getQueryParams()['tree'] ?? '';
129*1d1f373cSGreg Roach        $tree = $this->tree_service->findByName($tree) ?? $this->tree_service->all()->first();
130*1d1f373cSGreg Roach        if (!$tree instanceof Tree) {
131*1d1f373cSGreg Roach            return redirect(route(ControlPanel::class));
132*1d1f373cSGreg Roach        }
1335229eadeSGreg Roach
13426348dcdSGreg Roach        $faqs = $this->faqsForTree($tree);
135aee13b6dSGreg Roach
13677654037SGreg Roach        $min_block_order = DB::table('block')
13726684e68SGreg Roach            ->where('module_name', '=', $this->name())
1380b5fd0a6SGreg Roach            ->where(static function (Builder $query) use ($tree): void {
13977654037SGreg Roach                $query
14077654037SGreg Roach                    ->whereNull('gedcom_id')
14177654037SGreg Roach                    ->orWhere('gedcom_id', '=', $tree->id());
14277654037SGreg Roach            })
14377654037SGreg Roach            ->min('block_order');
144aee13b6dSGreg Roach
14577654037SGreg Roach        $max_block_order = DB::table('block')
14626684e68SGreg Roach            ->where('module_name', '=', $this->name())
1470b5fd0a6SGreg Roach            ->where(static function (Builder $query) use ($tree): void {
14877654037SGreg Roach                $query
14977654037SGreg Roach                    ->whereNull('gedcom_id')
15077654037SGreg Roach                    ->orWhere('gedcom_id', '=', $tree->id());
15177654037SGreg Roach            })
15277654037SGreg Roach            ->max('block_order');
153aee13b6dSGreg Roach
154cc13d6d8SGreg Roach        $title = I18N::translate('Frequently asked questions') . ' — ' . $tree->title();
155aee13b6dSGreg Roach
156aee13b6dSGreg Roach        return $this->viewResponse('modules/faq/config', [
15783615acfSGreg Roach            'action'          => route('module', ['module' => $this->name(), 'action' => 'Admin']),
158aee13b6dSGreg Roach            'faqs'            => $faqs,
159aee13b6dSGreg Roach            'max_block_order' => $max_block_order,
160aee13b6dSGreg Roach            'min_block_order' => $min_block_order,
16171378461SGreg Roach            'module'          => $this->name(),
162aee13b6dSGreg Roach            'title'           => $title,
163aee13b6dSGreg Roach            'tree'            => $tree,
164aee13b6dSGreg Roach            'tree_names'      => Tree::getNameList(),
165aee13b6dSGreg Roach        ]);
166aee13b6dSGreg Roach    }
167aee13b6dSGreg Roach
168aee13b6dSGreg Roach    /**
1696ccdf4f0SGreg Roach     * @param ServerRequestInterface $request
170aee13b6dSGreg Roach     *
1716ccdf4f0SGreg Roach     * @return ResponseInterface
172aee13b6dSGreg Roach     */
17357ab2231SGreg Roach    public function postAdminDeleteAction(ServerRequestInterface $request): ResponseInterface
174c1010edaSGreg Roach    {
175eb235819SGreg Roach        $block_id = (int) $request->getQueryParams()['block_id'];
176aee13b6dSGreg Roach
17777654037SGreg Roach        DB::table('block_setting')->where('block_id', '=', $block_id)->delete();
178aee13b6dSGreg Roach
17977654037SGreg Roach        DB::table('block')->where('block_id', '=', $block_id)->delete();
180aee13b6dSGreg Roach
181c1010edaSGreg Roach        $url = route('module', [
18226684e68SGreg Roach            'module' => $this->name(),
183c1010edaSGreg Roach            'action' => 'Admin',
184c1010edaSGreg Roach        ]);
185aee13b6dSGreg Roach
1866ccdf4f0SGreg Roach        return redirect($url);
187aee13b6dSGreg Roach    }
188aee13b6dSGreg Roach
189aee13b6dSGreg Roach    /**
1906ccdf4f0SGreg Roach     * @param ServerRequestInterface $request
191aee13b6dSGreg Roach     *
1926ccdf4f0SGreg Roach     * @return ResponseInterface
193aee13b6dSGreg Roach     */
19457ab2231SGreg Roach    public function postAdminMoveDownAction(ServerRequestInterface $request): ResponseInterface
195c1010edaSGreg Roach    {
196eb235819SGreg Roach        $block_id = (int) $request->getQueryParams()['block_id'];
197aee13b6dSGreg Roach
19877654037SGreg Roach        $block_order = DB::table('block')
19977654037SGreg Roach            ->where('block_id', '=', $block_id)
20077654037SGreg Roach            ->value('block_order');
201aee13b6dSGreg Roach
20277654037SGreg Roach        $swap_block = DB::table('block')
20326684e68SGreg Roach            ->where('module_name', '=', $this->name())
20477654037SGreg Roach            ->where('block_order', '>', $block_order)
205*1d1f373cSGreg Roach            ->orderBy('block_order', 'asc')
20677654037SGreg Roach            ->first();
207aee13b6dSGreg Roach
208*1d1f373cSGreg Roach        if ($block_order !== null && $swap_block !== null) {
20977654037SGreg Roach            DB::table('block')
21077654037SGreg Roach                ->where('block_id', '=', $block_id)
21177654037SGreg Roach                ->update([
212aee13b6dSGreg Roach                    'block_order' => $swap_block->block_order,
213aee13b6dSGreg Roach                ]);
21477654037SGreg Roach
21577654037SGreg Roach            DB::table('block')
21677654037SGreg Roach                ->where('block_id', '=', $swap_block->block_id)
21777654037SGreg Roach                ->update([
218aee13b6dSGreg Roach                    'block_order' => $block_order,
219aee13b6dSGreg Roach                ]);
220aee13b6dSGreg Roach        }
221aee13b6dSGreg Roach
222*1d1f373cSGreg Roach        return response();
223aee13b6dSGreg Roach    }
224aee13b6dSGreg Roach
225aee13b6dSGreg Roach    /**
2266ccdf4f0SGreg Roach     * @param ServerRequestInterface $request
227aee13b6dSGreg Roach     *
2286ccdf4f0SGreg Roach     * @return ResponseInterface
229aee13b6dSGreg Roach     */
23057ab2231SGreg Roach    public function postAdminMoveUpAction(ServerRequestInterface $request): ResponseInterface
231c1010edaSGreg Roach    {
232eb235819SGreg Roach        $block_id = (int) $request->getQueryParams()['block_id'];
233aee13b6dSGreg Roach
23477654037SGreg Roach        $block_order = DB::table('block')
23577654037SGreg Roach            ->where('block_id', '=', $block_id)
23677654037SGreg Roach            ->value('block_order');
237aee13b6dSGreg Roach
23877654037SGreg Roach        $swap_block = DB::table('block')
23926684e68SGreg Roach            ->where('module_name', '=', $this->name())
24077654037SGreg Roach            ->where('block_order', '<', $block_order)
241*1d1f373cSGreg Roach            ->orderBy('block_order', 'desc')
24277654037SGreg Roach            ->first();
243aee13b6dSGreg Roach
244*1d1f373cSGreg Roach        if ($block_order !== null && $swap_block !== null) {
24577654037SGreg Roach            DB::table('block')
24677654037SGreg Roach                ->where('block_id', '=', $block_id)
24777654037SGreg Roach                ->update([
248aee13b6dSGreg Roach                    'block_order' => $swap_block->block_order,
249aee13b6dSGreg Roach                ]);
25077654037SGreg Roach
25177654037SGreg Roach            DB::table('block')
25277654037SGreg Roach                ->where('block_id', '=', $swap_block->block_id)
25377654037SGreg Roach                ->update([
254aee13b6dSGreg Roach                    'block_order' => $block_order,
255aee13b6dSGreg Roach                ]);
256aee13b6dSGreg Roach        }
257aee13b6dSGreg Roach
258*1d1f373cSGreg Roach        return response();
259aee13b6dSGreg Roach    }
260aee13b6dSGreg Roach
261aee13b6dSGreg Roach    /**
2626ccdf4f0SGreg Roach     * @param ServerRequestInterface $request
263aee13b6dSGreg Roach     *
2646ccdf4f0SGreg Roach     * @return ResponseInterface
265aee13b6dSGreg Roach     */
26657ab2231SGreg Roach    public function getAdminEditAction(ServerRequestInterface $request): ResponseInterface
267c1010edaSGreg Roach    {
268aee13b6dSGreg Roach        $this->layout = 'layouts/administration';
269aee13b6dSGreg Roach
27057ab2231SGreg Roach        $tree     = $request->getAttribute('tree');
271eb235819SGreg Roach        $block_id = (int) ($request->getQueryParams()['block_id'] ?? 0);
272aee13b6dSGreg Roach
273aee13b6dSGreg Roach        if ($block_id === 0) {
274aee13b6dSGreg Roach            // Creating a new faq
275aee13b6dSGreg Roach            $header  = '';
276aee13b6dSGreg Roach            $faqbody = '';
27777654037SGreg Roach
27877654037SGreg Roach            $block_order = 1 + (int) DB::table('block')
27926684e68SGreg Roach                    ->where('module_name', '=', $this->name())
28077654037SGreg Roach                    ->max('block_order');
28177654037SGreg Roach
282aee13b6dSGreg Roach            $languages = [];
283aee13b6dSGreg Roach
284aee13b6dSGreg Roach            $title = I18N::translate('Add an FAQ');
285aee13b6dSGreg Roach        } else {
286aee13b6dSGreg Roach            // Editing an existing faq
287aee13b6dSGreg Roach            $header  = $this->getBlockSetting($block_id, 'header');
288aee13b6dSGreg Roach            $faqbody = $this->getBlockSetting($block_id, 'faqbody');
28977654037SGreg Roach
29077654037SGreg Roach            $block_order = DB::table('block')
29177654037SGreg Roach                ->where('block_id', '=', $block_id)
29277654037SGreg Roach                ->value('block_order');
29377654037SGreg Roach
294aee13b6dSGreg Roach            $languages = explode(',', $this->getBlockSetting($block_id, 'languages'));
295aee13b6dSGreg Roach
296aee13b6dSGreg Roach            $title = I18N::translate('Edit the FAQ');
297aee13b6dSGreg Roach        }
298aee13b6dSGreg Roach
299b6c326d8SGreg Roach        $tree_names = ['' => I18N::translate('All')] + Tree::getIdList();
300b6c326d8SGreg Roach
301aee13b6dSGreg Roach        return $this->viewResponse('modules/faq/edit', [
302aee13b6dSGreg Roach            'block_id'    => $block_id,
303aee13b6dSGreg Roach            'block_order' => $block_order,
304aee13b6dSGreg Roach            'header'      => $header,
305aee13b6dSGreg Roach            'faqbody'     => $faqbody,
306aee13b6dSGreg Roach            'languages'   => $languages,
307aee13b6dSGreg Roach            'title'       => $title,
308aee13b6dSGreg Roach            'tree'        => $tree,
309b6c326d8SGreg Roach            'tree_names'  => $tree_names,
310aee13b6dSGreg Roach        ]);
311aee13b6dSGreg Roach    }
312aee13b6dSGreg Roach
313aee13b6dSGreg Roach    /**
3146ccdf4f0SGreg Roach     * @param ServerRequestInterface $request
315aee13b6dSGreg Roach     *
3166ccdf4f0SGreg Roach     * @return ResponseInterface
317aee13b6dSGreg Roach     */
31857ab2231SGreg Roach    public function postAdminEditAction(ServerRequestInterface $request): ResponseInterface
319c1010edaSGreg Roach    {
32057ab2231SGreg Roach        $tree     = $request->getAttribute('tree');
321eb235819SGreg Roach        $block_id = (int) ($request->getQueryParams()['block_id'] ?? 0);
322eb235819SGreg Roach
323eb235819SGreg Roach        $params = $request->getParsedBody();
324eb235819SGreg Roach
325eb235819SGreg Roach        $faqbody     = $params['faqbody'];
326eb235819SGreg Roach        $header      = $params['header'];
327eb235819SGreg Roach        $languages   = $params['languages'] ?? [];
328eb235819SGreg Roach        $gedcom_id   = (int) $params['gedcom_id'] ?: null;
329eb235819SGreg Roach        $block_order = (int) $params['block_order'];
330aee13b6dSGreg Roach
33150d6f48cSGreg Roach        $faqbody = $this->html_service->sanitize($faqbody);
33250d6f48cSGreg Roach        $header  = $this->html_service->sanitize($header);
33350d6f48cSGreg Roach
334aee13b6dSGreg Roach        if ($block_id !== 0) {
33577654037SGreg Roach            DB::table('block')
33677654037SGreg Roach                ->where('block_id', '=', $block_id)
33777654037SGreg Roach                ->update([
33877654037SGreg Roach                    'gedcom_id'   => $gedcom_id,
33977654037SGreg Roach                    'block_order' => $block_order,
340aee13b6dSGreg Roach                ]);
341aee13b6dSGreg Roach        } else {
34277654037SGreg Roach            DB::table('block')->insert([
34377654037SGreg Roach                'gedcom_id'   => $gedcom_id,
34426684e68SGreg Roach                'module_name' => $this->name(),
34577654037SGreg Roach                'block_order' => $block_order,
346aee13b6dSGreg Roach            ]);
347aee13b6dSGreg Roach
34877654037SGreg Roach            $block_id = (int) DB::connection()->getPdo()->lastInsertId();
349aee13b6dSGreg Roach        }
350aee13b6dSGreg Roach
351aee13b6dSGreg Roach        $this->setBlockSetting($block_id, 'faqbody', $faqbody);
352aee13b6dSGreg Roach        $this->setBlockSetting($block_id, 'header', $header);
353aee13b6dSGreg Roach        $this->setBlockSetting($block_id, 'languages', implode(',', $languages));
354aee13b6dSGreg Roach
355c1010edaSGreg Roach        $url = route('module', [
35626684e68SGreg Roach            'module' => $this->name(),
357c1010edaSGreg Roach            'action' => 'Admin',
3589022ab66SGreg Roach            'tree'   => $tree->name(),
359c1010edaSGreg Roach        ]);
360aee13b6dSGreg Roach
3616ccdf4f0SGreg Roach        return redirect($url);
362aee13b6dSGreg Roach    }
363aee13b6dSGreg Roach
364b998dbceSGreg Roach    /**
36557ab2231SGreg Roach     * @param ServerRequestInterface $request
366b998dbceSGreg Roach     *
3676ccdf4f0SGreg Roach     * @return ResponseInterface
368b998dbceSGreg Roach     */
36957ab2231SGreg Roach    public function getShowAction(ServerRequestInterface $request): ResponseInterface
370c1010edaSGreg Roach    {
37157ab2231SGreg Roach        $tree = $request->getAttribute('tree');
3725229eadeSGreg Roach        assert($tree instanceof Tree, new InvalidArgumentException());
37357ab2231SGreg Roach
3748de50a4eSGreg Roach        // Filter foreign languages.
37577654037SGreg Roach        $faqs = $this->faqsForTree($tree)
3760b5fd0a6SGreg Roach            ->filter(static function (stdClass $faq): bool {
37722d65e5aSGreg Roach                return $faq->languages === '' || in_array(WT_LOCALE, explode(',', $faq->languages), true);
3788de50a4eSGreg Roach            });
379aee13b6dSGreg Roach
380aee13b6dSGreg Roach        return $this->viewResponse('modules/faq/show', [
3818de50a4eSGreg Roach            'faqs'  => $faqs,
382aee13b6dSGreg Roach            'title' => I18N::translate('Frequently asked questions'),
3838de50a4eSGreg Roach            'tree'  => $tree,
384aee13b6dSGreg Roach        ]);
385aee13b6dSGreg Roach    }
38677654037SGreg Roach
38777654037SGreg Roach    /**
38877654037SGreg Roach     * @param Tree $tree
38977654037SGreg Roach     *
39077654037SGreg Roach     * @return Collection
39177654037SGreg Roach     */
39277654037SGreg Roach    private function faqsForTree(Tree $tree): Collection
39377654037SGreg Roach    {
39477654037SGreg Roach        return DB::table('block')
39577654037SGreg Roach            ->join('block_setting AS bs1', 'bs1.block_id', '=', 'block.block_id')
39677654037SGreg Roach            ->join('block_setting AS bs2', 'bs2.block_id', '=', 'block.block_id')
39777654037SGreg Roach            ->join('block_setting AS bs3', 'bs3.block_id', '=', 'block.block_id')
39826684e68SGreg Roach            ->where('module_name', '=', $this->name())
39977654037SGreg Roach            ->where('bs1.setting_name', '=', 'header')
40077654037SGreg Roach            ->where('bs2.setting_name', '=', 'faqbody')
40177654037SGreg Roach            ->where('bs3.setting_name', '=', 'languages')
4020b5fd0a6SGreg Roach            ->where(static function (Builder $query) use ($tree): void {
40377654037SGreg Roach                $query
40477654037SGreg Roach                    ->whereNull('gedcom_id')
40577654037SGreg Roach                    ->orWhere('gedcom_id', '=', $tree->id());
40677654037SGreg Roach            })
40777654037SGreg Roach            ->orderBy('block_order')
40877654037SGreg Roach            ->select(['block.block_id', 'block_order', 'gedcom_id', 'bs1.setting_value AS header', 'bs2.setting_value AS faqbody', 'bs3.setting_value AS languages'])
40977654037SGreg Roach            ->get();
41077654037SGreg Roach    }
41177654037SGreg Roach
41277654037SGreg Roach    /**
41377654037SGreg Roach     * @param Tree   $tree
41477654037SGreg Roach     * @param string $language
41577654037SGreg Roach     *
41677654037SGreg Roach     * @return bool
41777654037SGreg Roach     */
41877654037SGreg Roach    private function faqsExist(Tree $tree, string $language): bool
41977654037SGreg Roach    {
42077654037SGreg Roach        return DB::table('block')
42177654037SGreg Roach            ->join('block_setting', 'block_setting.block_id', '=', 'block.block_id')
42226684e68SGreg Roach            ->where('module_name', '=', $this->name())
42377654037SGreg Roach            ->where('setting_name', '=', 'languages')
4240b5fd0a6SGreg Roach            ->where(static function (Builder $query) use ($tree): void {
42577654037SGreg Roach                $query
42677654037SGreg Roach                    ->whereNull('gedcom_id')
42777654037SGreg Roach                    ->orWhere('gedcom_id', '=', $tree->id());
42877654037SGreg Roach            })
42977654037SGreg Roach            ->select(['setting_value AS languages'])
43077654037SGreg Roach            ->get()
4310b5fd0a6SGreg Roach            ->filter(static function (stdClass $faq) use ($language): bool {
4320b5fd0a6SGreg Roach                return $faq->languages === '' || in_array($language, explode(',', $faq->languages), true);
43377654037SGreg Roach            })
43477654037SGreg Roach            ->isNotEmpty();
43577654037SGreg Roach    }
4368c2e8227SGreg Roach}
437