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 */ 17e7f56f2aSGreg Roachdeclare(strict_types=1); 18e7f56f2aSGreg Roach 1976692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module; 2076692c8bSGreg Roach 21*71378461SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\ModuleAction; 220e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N; 230e62c4b8SGreg Roachuse Fisharebest\Webtrees\Menu; 2450d6f48cSGreg Roachuse Fisharebest\Webtrees\Services\HtmlService; 250e62c4b8SGreg Roachuse Fisharebest\Webtrees\Tree; 2677654037SGreg Roachuse Illuminate\Database\Capsule\Manager as DB; 2777654037SGreg Roachuse Illuminate\Database\Query\Builder; 2877654037SGreg Roachuse Illuminate\Support\Collection; 296ccdf4f0SGreg Roachuse Psr\Http\Message\ResponseInterface; 306ccdf4f0SGreg Roachuse Psr\Http\Message\ServerRequestInterface; 318de50a4eSGreg Roachuse stdClass; 328c2e8227SGreg Roach 338c2e8227SGreg Roach/** 348c2e8227SGreg Roach * Class FrequentlyAskedQuestionsModule 358c2e8227SGreg Roach */ 3637eb8894SGreg Roachclass FrequentlyAskedQuestionsModule extends AbstractModule implements ModuleConfigInterface, ModuleMenuInterface 37c1010edaSGreg Roach{ 3849a243cbSGreg Roach use ModuleConfigTrait; 3949a243cbSGreg Roach use ModuleMenuTrait; 4049a243cbSGreg Roach 4150d6f48cSGreg Roach /** @var HtmlService */ 4250d6f48cSGreg Roach private $html_service; 4350d6f48cSGreg Roach 4450d6f48cSGreg Roach /** 4550d6f48cSGreg Roach * HtmlBlockModule bootstrap. 4650d6f48cSGreg Roach * 4750d6f48cSGreg Roach * @param HtmlService $html_service 4850d6f48cSGreg Roach */ 4950d6f48cSGreg Roach public function boot(HtmlService $html_service) 5050d6f48cSGreg Roach { 5150d6f48cSGreg Roach $this->html_service = $html_service; 5250d6f48cSGreg Roach } 5350d6f48cSGreg Roach 54961ec755SGreg Roach /** 550cfd6963SGreg Roach * How should this module be identified in the control panel, etc.? 56961ec755SGreg Roach * 57961ec755SGreg Roach * @return string 58961ec755SGreg Roach */ 5949a243cbSGreg Roach public function title(): string 60c1010edaSGreg Roach { 61bbb76c12SGreg Roach /* I18N: Name of a module. Abbreviation for “Frequently Asked Questions” */ 62bbb76c12SGreg Roach return I18N::translate('FAQ'); 638c2e8227SGreg Roach } 648c2e8227SGreg Roach 65961ec755SGreg Roach /** 66961ec755SGreg Roach * A sentence describing what this module does. 67961ec755SGreg Roach * 68961ec755SGreg Roach * @return string 69961ec755SGreg Roach */ 7049a243cbSGreg Roach public function description(): string 71c1010edaSGreg Roach { 72bbb76c12SGreg Roach /* I18N: Description of the “FAQ” module */ 73bbb76c12SGreg Roach return I18N::translate('A list of frequently asked questions and answers.'); 748c2e8227SGreg Roach } 758c2e8227SGreg Roach 7676692c8bSGreg Roach /** 7749a243cbSGreg Roach * The default position for this menu. It can be changed in the control panel. 780ee13198SGreg Roach * 790ee13198SGreg Roach * @return int 800ee13198SGreg Roach */ 818f53f488SRico Sonntag public function defaultMenuOrder(): int 82c1010edaSGreg Roach { 83353b36abSGreg Roach return 8; 848c2e8227SGreg Roach } 858c2e8227SGreg Roach 860ee13198SGreg Roach /** 870ee13198SGreg Roach * A menu, to be added to the main application menu. 880ee13198SGreg Roach * 89aee13b6dSGreg Roach * @param Tree $tree 90aee13b6dSGreg Roach * 910ee13198SGreg Roach * @return Menu|null 920ee13198SGreg Roach */ 9346295629SGreg Roach public function getMenu(Tree $tree): ?Menu 94c1010edaSGreg Roach { 9577654037SGreg Roach if ($this->faqsExist($tree, WT_LOCALE)) { 9649a243cbSGreg Roach return new Menu($this->title(), route('module', [ 9726684e68SGreg Roach 'module' => $this->name(), 98c1010edaSGreg Roach 'action' => 'Show', 99aa6f03bbSGreg Roach 'ged' => $tree->name(), 100c1010edaSGreg Roach ]), 'menu-help'); 1018c2e8227SGreg Roach } 102b2ce94c6SRico Sonntag 103b2ce94c6SRico Sonntag return null; 1048c2e8227SGreg Roach } 105aee13b6dSGreg Roach 106aee13b6dSGreg Roach /** 10757ab2231SGreg Roach * @param ServerRequestInterface $request 108aee13b6dSGreg Roach * 1096ccdf4f0SGreg Roach * @return ResponseInterface 110aee13b6dSGreg Roach */ 11157ab2231SGreg Roach public function getAdminAction(ServerRequestInterface $request): ResponseInterface 112c1010edaSGreg Roach { 113aee13b6dSGreg Roach $this->layout = 'layouts/administration'; 114aee13b6dSGreg Roach 11557ab2231SGreg Roach $tree = $request->getAttribute('tree'); 11626348dcdSGreg Roach $faqs = $this->faqsForTree($tree); 117aee13b6dSGreg Roach 11877654037SGreg Roach $min_block_order = DB::table('block') 11926684e68SGreg Roach ->where('module_name', '=', $this->name()) 1200b5fd0a6SGreg Roach ->where(static function (Builder $query) use ($tree): void { 12177654037SGreg Roach $query 12277654037SGreg Roach ->whereNull('gedcom_id') 12377654037SGreg Roach ->orWhere('gedcom_id', '=', $tree->id()); 12477654037SGreg Roach }) 12577654037SGreg Roach ->min('block_order'); 126aee13b6dSGreg Roach 12777654037SGreg Roach $max_block_order = DB::table('block') 12826684e68SGreg Roach ->where('module_name', '=', $this->name()) 1290b5fd0a6SGreg Roach ->where(static function (Builder $query) use ($tree): void { 13077654037SGreg Roach $query 13177654037SGreg Roach ->whereNull('gedcom_id') 13277654037SGreg Roach ->orWhere('gedcom_id', '=', $tree->id()); 13377654037SGreg Roach }) 13477654037SGreg Roach ->max('block_order'); 135aee13b6dSGreg Roach 136cc13d6d8SGreg Roach $title = I18N::translate('Frequently asked questions') . ' — ' . $tree->title(); 137aee13b6dSGreg Roach 138aee13b6dSGreg Roach return $this->viewResponse('modules/faq/config', [ 13983615acfSGreg Roach 'action' => route('module', ['module' => $this->name(), 'action' => 'Admin']), 140aee13b6dSGreg Roach 'faqs' => $faqs, 141aee13b6dSGreg Roach 'max_block_order' => $max_block_order, 142aee13b6dSGreg Roach 'min_block_order' => $min_block_order, 143*71378461SGreg Roach 'module' => $this->name(), 144aee13b6dSGreg Roach 'title' => $title, 145aee13b6dSGreg Roach 'tree' => $tree, 146aee13b6dSGreg Roach 'tree_names' => Tree::getNameList(), 147aee13b6dSGreg Roach ]); 148aee13b6dSGreg Roach } 149aee13b6dSGreg Roach 150aee13b6dSGreg Roach /** 1516ccdf4f0SGreg Roach * @param ServerRequestInterface $request 152aee13b6dSGreg Roach * 1536ccdf4f0SGreg Roach * @return ResponseInterface 154aee13b6dSGreg Roach */ 15557ab2231SGreg Roach public function postAdminDeleteAction(ServerRequestInterface $request): ResponseInterface 156c1010edaSGreg Roach { 15757ab2231SGreg Roach $tree = $request->getAttribute('tree'); 158eb235819SGreg Roach $block_id = (int) $request->getQueryParams()['block_id']; 159aee13b6dSGreg Roach 16077654037SGreg Roach DB::table('block_setting')->where('block_id', '=', $block_id)->delete(); 161aee13b6dSGreg Roach 16277654037SGreg Roach DB::table('block')->where('block_id', '=', $block_id)->delete(); 163aee13b6dSGreg Roach 164c1010edaSGreg Roach $url = route('module', [ 16526684e68SGreg Roach 'module' => $this->name(), 166c1010edaSGreg Roach 'action' => 'Admin', 167aa6f03bbSGreg Roach 'ged' => $tree->name(), 168c1010edaSGreg Roach ]); 169aee13b6dSGreg Roach 1706ccdf4f0SGreg Roach return redirect($url); 171aee13b6dSGreg Roach } 172aee13b6dSGreg Roach 173aee13b6dSGreg Roach /** 1746ccdf4f0SGreg Roach * @param ServerRequestInterface $request 175aee13b6dSGreg Roach * 1766ccdf4f0SGreg Roach * @return ResponseInterface 177aee13b6dSGreg Roach */ 17857ab2231SGreg Roach public function postAdminMoveDownAction(ServerRequestInterface $request): ResponseInterface 179c1010edaSGreg Roach { 18057ab2231SGreg Roach $tree = $request->getAttribute('tree'); 181eb235819SGreg Roach $block_id = (int) $request->getQueryParams()['block_id']; 182aee13b6dSGreg Roach 18377654037SGreg Roach $block_order = DB::table('block') 18477654037SGreg Roach ->where('block_id', '=', $block_id) 18577654037SGreg Roach ->value('block_order'); 186aee13b6dSGreg Roach 18777654037SGreg Roach $swap_block = DB::table('block') 18826684e68SGreg Roach ->where('module_name', '=', $this->name()) 189eb235819SGreg Roach ->where('block_order', '=', function (Builder $query) use ($block_order): void { 19077654037SGreg Roach $query 19177654037SGreg Roach ->from('block') 19226684e68SGreg Roach ->where('module_name', '=', $this->name()) 19377654037SGreg Roach ->where('block_order', '>', $block_order) 194a69f5655SGreg Roach ->min('block_order'); 19577654037SGreg Roach }) 19677654037SGreg Roach ->select(['block_order', 'block_id']) 19777654037SGreg Roach ->first(); 198aee13b6dSGreg Roach 199aee13b6dSGreg Roach if ($swap_block !== null) { 20077654037SGreg Roach DB::table('block') 20177654037SGreg Roach ->where('block_id', '=', $block_id) 20277654037SGreg Roach ->update([ 203aee13b6dSGreg Roach 'block_order' => $swap_block->block_order, 204aee13b6dSGreg Roach ]); 20577654037SGreg Roach 20677654037SGreg Roach DB::table('block') 20777654037SGreg Roach ->where('block_id', '=', $swap_block->block_id) 20877654037SGreg Roach ->update([ 209aee13b6dSGreg Roach 'block_order' => $block_order, 210aee13b6dSGreg Roach ]); 211aee13b6dSGreg Roach } 212aee13b6dSGreg Roach 213c1010edaSGreg Roach $url = route('module', [ 21426684e68SGreg Roach 'module' => $this->name(), 215c1010edaSGreg Roach 'action' => 'Admin', 216aa6f03bbSGreg Roach 'ged' => $tree->name(), 217c1010edaSGreg Roach ]); 218aee13b6dSGreg Roach 2196ccdf4f0SGreg Roach return redirect($url); 220aee13b6dSGreg Roach } 221aee13b6dSGreg Roach 222aee13b6dSGreg Roach /** 2236ccdf4f0SGreg Roach * @param ServerRequestInterface $request 224aee13b6dSGreg Roach * 2256ccdf4f0SGreg Roach * @return ResponseInterface 226aee13b6dSGreg Roach */ 22757ab2231SGreg Roach public function postAdminMoveUpAction(ServerRequestInterface $request): ResponseInterface 228c1010edaSGreg Roach { 22957ab2231SGreg Roach $tree = $request->getAttribute('tree'); 230eb235819SGreg Roach $block_id = (int) $request->getQueryParams()['block_id']; 231aee13b6dSGreg Roach 23277654037SGreg Roach $block_order = DB::table('block') 23377654037SGreg Roach ->where('block_id', '=', $block_id) 23477654037SGreg Roach ->value('block_order'); 235aee13b6dSGreg Roach 23677654037SGreg Roach $swap_block = DB::table('block') 23726684e68SGreg Roach ->where('module_name', '=', $this->name()) 238a69f5655SGreg Roach ->where('block_order', '=', function (Builder $query) use ($block_order): void { 23977654037SGreg Roach $query 24077654037SGreg Roach ->from('block') 24126684e68SGreg Roach ->where('module_name', '=', $this->name()) 24277654037SGreg Roach ->where('block_order', '<', $block_order) 243a69f5655SGreg Roach ->max('block_order'); 24477654037SGreg Roach }) 24577654037SGreg Roach ->select(['block_order', 'block_id']) 24677654037SGreg Roach ->first(); 247aee13b6dSGreg Roach 248aee13b6dSGreg Roach if ($swap_block !== null) { 24977654037SGreg Roach DB::table('block') 25077654037SGreg Roach ->where('block_id', '=', $block_id) 25177654037SGreg Roach ->update([ 252aee13b6dSGreg Roach 'block_order' => $swap_block->block_order, 253aee13b6dSGreg Roach ]); 25477654037SGreg Roach 25577654037SGreg Roach DB::table('block') 25677654037SGreg Roach ->where('block_id', '=', $swap_block->block_id) 25777654037SGreg Roach ->update([ 258aee13b6dSGreg Roach 'block_order' => $block_order, 259aee13b6dSGreg Roach ]); 260aee13b6dSGreg Roach } 261aee13b6dSGreg Roach 262c1010edaSGreg Roach $url = route('module', [ 26326684e68SGreg Roach 'module' => $this->name(), 264c1010edaSGreg Roach 'action' => 'Admin', 265aa6f03bbSGreg Roach 'ged' => $tree->name(), 266c1010edaSGreg Roach ]); 267aee13b6dSGreg Roach 2686ccdf4f0SGreg Roach return redirect($url); 269aee13b6dSGreg Roach } 270aee13b6dSGreg Roach 271aee13b6dSGreg Roach /** 2726ccdf4f0SGreg Roach * @param ServerRequestInterface $request 273aee13b6dSGreg Roach * 2746ccdf4f0SGreg Roach * @return ResponseInterface 275aee13b6dSGreg Roach */ 27657ab2231SGreg Roach public function getAdminEditAction(ServerRequestInterface $request): ResponseInterface 277c1010edaSGreg Roach { 278aee13b6dSGreg Roach $this->layout = 'layouts/administration'; 279aee13b6dSGreg Roach 28057ab2231SGreg Roach $tree = $request->getAttribute('tree'); 281eb235819SGreg Roach $block_id = (int) ($request->getQueryParams()['block_id'] ?? 0); 282aee13b6dSGreg Roach 283aee13b6dSGreg Roach if ($block_id === 0) { 284aee13b6dSGreg Roach // Creating a new faq 285aee13b6dSGreg Roach $header = ''; 286aee13b6dSGreg Roach $faqbody = ''; 28777654037SGreg Roach 28877654037SGreg Roach $block_order = 1 + (int) DB::table('block') 28926684e68SGreg Roach ->where('module_name', '=', $this->name()) 29077654037SGreg Roach ->max('block_order'); 29177654037SGreg Roach 292aee13b6dSGreg Roach $languages = []; 293aee13b6dSGreg Roach 294aee13b6dSGreg Roach $title = I18N::translate('Add an FAQ'); 295aee13b6dSGreg Roach } else { 296aee13b6dSGreg Roach // Editing an existing faq 297aee13b6dSGreg Roach $header = $this->getBlockSetting($block_id, 'header'); 298aee13b6dSGreg Roach $faqbody = $this->getBlockSetting($block_id, 'faqbody'); 29977654037SGreg Roach 30077654037SGreg Roach $block_order = DB::table('block') 30177654037SGreg Roach ->where('block_id', '=', $block_id) 30277654037SGreg Roach ->value('block_order'); 30377654037SGreg Roach 304aee13b6dSGreg Roach $languages = explode(',', $this->getBlockSetting($block_id, 'languages')); 305aee13b6dSGreg Roach 306aee13b6dSGreg Roach $title = I18N::translate('Edit the FAQ'); 307aee13b6dSGreg Roach } 308aee13b6dSGreg Roach 309b6c326d8SGreg Roach $tree_names = ['' => I18N::translate('All')] + Tree::getIdList(); 310b6c326d8SGreg Roach 311aee13b6dSGreg Roach return $this->viewResponse('modules/faq/edit', [ 312aee13b6dSGreg Roach 'block_id' => $block_id, 313aee13b6dSGreg Roach 'block_order' => $block_order, 314aee13b6dSGreg Roach 'header' => $header, 315aee13b6dSGreg Roach 'faqbody' => $faqbody, 316aee13b6dSGreg Roach 'languages' => $languages, 317aee13b6dSGreg Roach 'title' => $title, 318aee13b6dSGreg Roach 'tree' => $tree, 319b6c326d8SGreg Roach 'tree_names' => $tree_names, 320aee13b6dSGreg Roach ]); 321aee13b6dSGreg Roach } 322aee13b6dSGreg Roach 323aee13b6dSGreg Roach /** 3246ccdf4f0SGreg Roach * @param ServerRequestInterface $request 325aee13b6dSGreg Roach * 3266ccdf4f0SGreg Roach * @return ResponseInterface 327aee13b6dSGreg Roach */ 32857ab2231SGreg Roach public function postAdminEditAction(ServerRequestInterface $request): ResponseInterface 329c1010edaSGreg Roach { 33057ab2231SGreg Roach $tree = $request->getAttribute('tree'); 331eb235819SGreg Roach $block_id = (int) ($request->getQueryParams()['block_id'] ?? 0); 332eb235819SGreg Roach 333eb235819SGreg Roach $params = $request->getParsedBody(); 334eb235819SGreg Roach 335eb235819SGreg Roach $faqbody = $params['faqbody']; 336eb235819SGreg Roach $header = $params['header']; 337eb235819SGreg Roach $languages = $params['languages'] ?? []; 338eb235819SGreg Roach $gedcom_id = (int) $params['gedcom_id'] ?: null; 339eb235819SGreg Roach $block_order = (int) $params['block_order']; 340aee13b6dSGreg Roach 34150d6f48cSGreg Roach $faqbody = $this->html_service->sanitize($faqbody); 34250d6f48cSGreg Roach $header = $this->html_service->sanitize($header); 34350d6f48cSGreg Roach 344aee13b6dSGreg Roach if ($block_id !== 0) { 34577654037SGreg Roach DB::table('block') 34677654037SGreg Roach ->where('block_id', '=', $block_id) 34777654037SGreg Roach ->update([ 34877654037SGreg Roach 'gedcom_id' => $gedcom_id, 34977654037SGreg Roach 'block_order' => $block_order, 350aee13b6dSGreg Roach ]); 351aee13b6dSGreg Roach } else { 35277654037SGreg Roach DB::table('block')->insert([ 35377654037SGreg Roach 'gedcom_id' => $gedcom_id, 35426684e68SGreg Roach 'module_name' => $this->name(), 35577654037SGreg Roach 'block_order' => $block_order, 356aee13b6dSGreg Roach ]); 357aee13b6dSGreg Roach 35877654037SGreg Roach $block_id = (int) DB::connection()->getPdo()->lastInsertId(); 359aee13b6dSGreg Roach } 360aee13b6dSGreg Roach 361aee13b6dSGreg Roach $this->setBlockSetting($block_id, 'faqbody', $faqbody); 362aee13b6dSGreg Roach $this->setBlockSetting($block_id, 'header', $header); 363aee13b6dSGreg Roach $this->setBlockSetting($block_id, 'languages', implode(',', $languages)); 364aee13b6dSGreg Roach 365c1010edaSGreg Roach $url = route('module', [ 36626684e68SGreg Roach 'module' => $this->name(), 367c1010edaSGreg Roach 'action' => 'Admin', 368aa6f03bbSGreg Roach 'ged' => $tree->name(), 369c1010edaSGreg Roach ]); 370aee13b6dSGreg Roach 3716ccdf4f0SGreg Roach return redirect($url); 372aee13b6dSGreg Roach } 373aee13b6dSGreg Roach 374b998dbceSGreg Roach /** 37557ab2231SGreg Roach * @param ServerRequestInterface $request 376b998dbceSGreg Roach * 3776ccdf4f0SGreg Roach * @return ResponseInterface 378b998dbceSGreg Roach */ 37957ab2231SGreg Roach public function getShowAction(ServerRequestInterface $request): ResponseInterface 380c1010edaSGreg Roach { 38157ab2231SGreg Roach $tree = $request->getAttribute('tree'); 38257ab2231SGreg Roach 3838de50a4eSGreg Roach // Filter foreign languages. 38477654037SGreg Roach $faqs = $this->faqsForTree($tree) 3850b5fd0a6SGreg Roach ->filter(static function (stdClass $faq): bool { 38622d65e5aSGreg Roach return $faq->languages === '' || in_array(WT_LOCALE, explode(',', $faq->languages), true); 3878de50a4eSGreg Roach }); 388aee13b6dSGreg Roach 389aee13b6dSGreg Roach return $this->viewResponse('modules/faq/show', [ 3908de50a4eSGreg Roach 'faqs' => $faqs, 391aee13b6dSGreg Roach 'title' => I18N::translate('Frequently asked questions'), 3928de50a4eSGreg Roach 'tree' => $tree, 393aee13b6dSGreg Roach ]); 394aee13b6dSGreg Roach } 39577654037SGreg Roach 39677654037SGreg Roach /** 39777654037SGreg Roach * @param Tree $tree 39877654037SGreg Roach * 39977654037SGreg Roach * @return Collection 40077654037SGreg Roach */ 40177654037SGreg Roach private function faqsForTree(Tree $tree): Collection 40277654037SGreg Roach { 40377654037SGreg Roach return DB::table('block') 40477654037SGreg Roach ->join('block_setting AS bs1', 'bs1.block_id', '=', 'block.block_id') 40577654037SGreg Roach ->join('block_setting AS bs2', 'bs2.block_id', '=', 'block.block_id') 40677654037SGreg Roach ->join('block_setting AS bs3', 'bs3.block_id', '=', 'block.block_id') 40726684e68SGreg Roach ->where('module_name', '=', $this->name()) 40877654037SGreg Roach ->where('bs1.setting_name', '=', 'header') 40977654037SGreg Roach ->where('bs2.setting_name', '=', 'faqbody') 41077654037SGreg Roach ->where('bs3.setting_name', '=', 'languages') 4110b5fd0a6SGreg Roach ->where(static function (Builder $query) use ($tree): void { 41277654037SGreg Roach $query 41377654037SGreg Roach ->whereNull('gedcom_id') 41477654037SGreg Roach ->orWhere('gedcom_id', '=', $tree->id()); 41577654037SGreg Roach }) 41677654037SGreg Roach ->orderBy('block_order') 41777654037SGreg Roach ->select(['block.block_id', 'block_order', 'gedcom_id', 'bs1.setting_value AS header', 'bs2.setting_value AS faqbody', 'bs3.setting_value AS languages']) 41877654037SGreg Roach ->get(); 41977654037SGreg Roach } 42077654037SGreg Roach 42177654037SGreg Roach /** 42277654037SGreg Roach * @param Tree $tree 42377654037SGreg Roach * @param string $language 42477654037SGreg Roach * 42577654037SGreg Roach * @return bool 42677654037SGreg Roach */ 42777654037SGreg Roach private function faqsExist(Tree $tree, string $language): bool 42877654037SGreg Roach { 42977654037SGreg Roach return DB::table('block') 43077654037SGreg Roach ->join('block_setting', 'block_setting.block_id', '=', 'block.block_id') 43126684e68SGreg Roach ->where('module_name', '=', $this->name()) 43277654037SGreg Roach ->where('setting_name', '=', 'languages') 4330b5fd0a6SGreg Roach ->where(static function (Builder $query) use ($tree): void { 43477654037SGreg Roach $query 43577654037SGreg Roach ->whereNull('gedcom_id') 43677654037SGreg Roach ->orWhere('gedcom_id', '=', $tree->id()); 43777654037SGreg Roach }) 43877654037SGreg Roach ->select(['setting_value AS languages']) 43977654037SGreg Roach ->get() 4400b5fd0a6SGreg Roach ->filter(static function (stdClass $faq) use ($language): bool { 4410b5fd0a6SGreg Roach return $faq->languages === '' || in_array($language, explode(',', $faq->languages), true); 44277654037SGreg Roach }) 44377654037SGreg Roach ->isNotEmpty(); 44477654037SGreg Roach } 4458c2e8227SGreg Roach} 446