18c2e8227SGreg Roach<?php 28c2e8227SGreg Roach/** 38c2e8227SGreg Roach * webtrees: online genealogy 48fcd0d32SGreg Roach * Copyright (C) 2019 webtrees development team 58c2e8227SGreg Roach * This program is free software: you can redistribute it and/or modify 68c2e8227SGreg Roach * it under the terms of the GNU General Public License as published by 78c2e8227SGreg Roach * the Free Software Foundation, either version 3 of the License, or 88c2e8227SGreg Roach * (at your option) any later version. 98c2e8227SGreg Roach * This program is distributed in the hope that it will be useful, 108c2e8227SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 118c2e8227SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 128c2e8227SGreg Roach * GNU General Public License for more details. 138c2e8227SGreg Roach * You should have received a copy of the GNU General Public License 148c2e8227SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>. 158c2e8227SGreg Roach */ 16e7f56f2aSGreg Roachdeclare(strict_types=1); 17e7f56f2aSGreg Roach 1876692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module; 1976692c8bSGreg Roach 200e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N; 210e62c4b8SGreg Roachuse Fisharebest\Webtrees\Menu; 2250d6f48cSGreg Roachuse Fisharebest\Webtrees\Services\HtmlService; 230e62c4b8SGreg Roachuse Fisharebest\Webtrees\Tree; 2477654037SGreg Roachuse Illuminate\Database\Capsule\Manager as DB; 2577654037SGreg Roachuse Illuminate\Database\Query\Builder; 2677654037SGreg Roachuse Illuminate\Support\Collection; 276ccdf4f0SGreg Roachuse Psr\Http\Message\ResponseInterface; 286ccdf4f0SGreg Roachuse Psr\Http\Message\ServerRequestInterface; 298de50a4eSGreg Roachuse stdClass; 308c2e8227SGreg Roach 318c2e8227SGreg Roach/** 328c2e8227SGreg Roach * Class FrequentlyAskedQuestionsModule 338c2e8227SGreg Roach */ 3437eb8894SGreg Roachclass FrequentlyAskedQuestionsModule extends AbstractModule implements ModuleConfigInterface, ModuleMenuInterface 35c1010edaSGreg Roach{ 3649a243cbSGreg Roach use ModuleConfigTrait; 3749a243cbSGreg Roach use ModuleMenuTrait; 3849a243cbSGreg Roach 3950d6f48cSGreg Roach /** @var HtmlService */ 4050d6f48cSGreg Roach private $html_service; 4150d6f48cSGreg Roach 4250d6f48cSGreg Roach /** 4350d6f48cSGreg Roach * HtmlBlockModule bootstrap. 4450d6f48cSGreg Roach * 4550d6f48cSGreg Roach * @param HtmlService $html_service 4650d6f48cSGreg Roach */ 4750d6f48cSGreg Roach public function boot(HtmlService $html_service) 4850d6f48cSGreg Roach { 4950d6f48cSGreg Roach $this->html_service = $html_service; 5050d6f48cSGreg Roach } 5150d6f48cSGreg Roach 52961ec755SGreg Roach /** 530cfd6963SGreg Roach * How should this module be identified in the control panel, etc.? 54961ec755SGreg Roach * 55961ec755SGreg Roach * @return string 56961ec755SGreg Roach */ 5749a243cbSGreg Roach public function title(): string 58c1010edaSGreg Roach { 59bbb76c12SGreg Roach /* I18N: Name of a module. Abbreviation for “Frequently Asked Questions” */ 60bbb76c12SGreg Roach return I18N::translate('FAQ'); 618c2e8227SGreg Roach } 628c2e8227SGreg Roach 63961ec755SGreg Roach /** 64961ec755SGreg Roach * A sentence describing what this module does. 65961ec755SGreg Roach * 66961ec755SGreg Roach * @return string 67961ec755SGreg Roach */ 6849a243cbSGreg Roach public function description(): string 69c1010edaSGreg Roach { 70bbb76c12SGreg Roach /* I18N: Description of the “FAQ” module */ 71bbb76c12SGreg Roach return I18N::translate('A list of frequently asked questions and answers.'); 728c2e8227SGreg Roach } 738c2e8227SGreg Roach 7476692c8bSGreg Roach /** 7549a243cbSGreg Roach * The default position for this menu. It can be changed in the control panel. 760ee13198SGreg Roach * 770ee13198SGreg Roach * @return int 780ee13198SGreg Roach */ 798f53f488SRico Sonntag public function defaultMenuOrder(): int 80c1010edaSGreg Roach { 81353b36abSGreg Roach return 8; 828c2e8227SGreg Roach } 838c2e8227SGreg Roach 840ee13198SGreg Roach /** 850ee13198SGreg Roach * A menu, to be added to the main application menu. 860ee13198SGreg Roach * 87aee13b6dSGreg Roach * @param Tree $tree 88aee13b6dSGreg Roach * 890ee13198SGreg Roach * @return Menu|null 900ee13198SGreg Roach */ 9146295629SGreg Roach public function getMenu(Tree $tree): ?Menu 92c1010edaSGreg Roach { 9377654037SGreg Roach if ($this->faqsExist($tree, WT_LOCALE)) { 9449a243cbSGreg Roach return new Menu($this->title(), route('module', [ 9526684e68SGreg Roach 'module' => $this->name(), 96c1010edaSGreg Roach 'action' => 'Show', 97aa6f03bbSGreg Roach 'ged' => $tree->name(), 98c1010edaSGreg Roach ]), 'menu-help'); 998c2e8227SGreg Roach } 100b2ce94c6SRico Sonntag 101b2ce94c6SRico Sonntag return null; 1028c2e8227SGreg Roach } 103aee13b6dSGreg Roach 104aee13b6dSGreg Roach /** 105*57ab2231SGreg Roach * @param ServerRequestInterface $request 106aee13b6dSGreg Roach * 1076ccdf4f0SGreg Roach * @return ResponseInterface 108aee13b6dSGreg Roach */ 109*57ab2231SGreg Roach public function getAdminAction(ServerRequestInterface $request): ResponseInterface 110c1010edaSGreg Roach { 111aee13b6dSGreg Roach $this->layout = 'layouts/administration'; 112aee13b6dSGreg Roach 113*57ab2231SGreg Roach $tree = $request->getAttribute('tree'); 11426348dcdSGreg Roach $faqs = $this->faqsForTree($tree); 115aee13b6dSGreg Roach 11677654037SGreg Roach $min_block_order = DB::table('block') 11726684e68SGreg Roach ->where('module_name', '=', $this->name()) 1180b5fd0a6SGreg Roach ->where(static function (Builder $query) use ($tree): void { 11977654037SGreg Roach $query 12077654037SGreg Roach ->whereNull('gedcom_id') 12177654037SGreg Roach ->orWhere('gedcom_id', '=', $tree->id()); 12277654037SGreg Roach }) 12377654037SGreg Roach ->min('block_order'); 124aee13b6dSGreg Roach 12577654037SGreg Roach $max_block_order = DB::table('block') 12626684e68SGreg Roach ->where('module_name', '=', $this->name()) 1270b5fd0a6SGreg Roach ->where(static function (Builder $query) use ($tree): void { 12877654037SGreg Roach $query 12977654037SGreg Roach ->whereNull('gedcom_id') 13077654037SGreg Roach ->orWhere('gedcom_id', '=', $tree->id()); 13177654037SGreg Roach }) 13277654037SGreg Roach ->max('block_order'); 133aee13b6dSGreg Roach 134cc13d6d8SGreg Roach $title = I18N::translate('Frequently asked questions') . ' — ' . $tree->title(); 135aee13b6dSGreg Roach 136aee13b6dSGreg Roach return $this->viewResponse('modules/faq/config', [ 137aee13b6dSGreg Roach 'faqs' => $faqs, 138aee13b6dSGreg Roach 'max_block_order' => $max_block_order, 139aee13b6dSGreg Roach 'min_block_order' => $min_block_order, 140aee13b6dSGreg Roach 'title' => $title, 141aee13b6dSGreg Roach 'tree' => $tree, 142aee13b6dSGreg Roach 'tree_names' => Tree::getNameList(), 143aee13b6dSGreg Roach ]); 144aee13b6dSGreg Roach } 145aee13b6dSGreg Roach 146aee13b6dSGreg Roach /** 1476ccdf4f0SGreg Roach * @param ServerRequestInterface $request 148aee13b6dSGreg Roach * 1496ccdf4f0SGreg Roach * @return ResponseInterface 150aee13b6dSGreg Roach */ 151*57ab2231SGreg Roach public function postAdminDeleteAction(ServerRequestInterface $request): ResponseInterface 152c1010edaSGreg Roach { 153*57ab2231SGreg Roach $tree = $request->getAttribute('tree'); 154eb235819SGreg Roach $block_id = (int) $request->getQueryParams()['block_id']; 155aee13b6dSGreg Roach 15677654037SGreg Roach DB::table('block_setting')->where('block_id', '=', $block_id)->delete(); 157aee13b6dSGreg Roach 15877654037SGreg Roach DB::table('block')->where('block_id', '=', $block_id)->delete(); 159aee13b6dSGreg Roach 160c1010edaSGreg Roach $url = route('module', [ 16126684e68SGreg Roach 'module' => $this->name(), 162c1010edaSGreg Roach 'action' => 'Admin', 163aa6f03bbSGreg Roach 'ged' => $tree->name(), 164c1010edaSGreg Roach ]); 165aee13b6dSGreg Roach 1666ccdf4f0SGreg Roach return redirect($url); 167aee13b6dSGreg Roach } 168aee13b6dSGreg Roach 169aee13b6dSGreg Roach /** 1706ccdf4f0SGreg Roach * @param ServerRequestInterface $request 171aee13b6dSGreg Roach * 1726ccdf4f0SGreg Roach * @return ResponseInterface 173aee13b6dSGreg Roach */ 174*57ab2231SGreg Roach public function postAdminMoveDownAction(ServerRequestInterface $request): ResponseInterface 175c1010edaSGreg Roach { 176*57ab2231SGreg Roach $tree = $request->getAttribute('tree'); 177eb235819SGreg Roach $block_id = (int) $request->getQueryParams()['block_id']; 178aee13b6dSGreg Roach 17977654037SGreg Roach $block_order = DB::table('block') 18077654037SGreg Roach ->where('block_id', '=', $block_id) 18177654037SGreg Roach ->value('block_order'); 182aee13b6dSGreg Roach 18377654037SGreg Roach $swap_block = DB::table('block') 18426684e68SGreg Roach ->where('module_name', '=', $this->name()) 185eb235819SGreg Roach ->where('block_order', '=', function (Builder $query) use ($block_order): void { 18677654037SGreg Roach $query 18777654037SGreg Roach ->from('block') 18826684e68SGreg Roach ->where('module_name', '=', $this->name()) 18977654037SGreg Roach ->where('block_order', '>', $block_order) 190a69f5655SGreg Roach ->min('block_order'); 19177654037SGreg Roach }) 19277654037SGreg Roach ->select(['block_order', 'block_id']) 19377654037SGreg Roach ->first(); 194aee13b6dSGreg Roach 195aee13b6dSGreg Roach if ($swap_block !== null) { 19677654037SGreg Roach DB::table('block') 19777654037SGreg Roach ->where('block_id', '=', $block_id) 19877654037SGreg Roach ->update([ 199aee13b6dSGreg Roach 'block_order' => $swap_block->block_order, 200aee13b6dSGreg Roach ]); 20177654037SGreg Roach 20277654037SGreg Roach DB::table('block') 20377654037SGreg Roach ->where('block_id', '=', $swap_block->block_id) 20477654037SGreg Roach ->update([ 205aee13b6dSGreg Roach 'block_order' => $block_order, 206aee13b6dSGreg Roach ]); 207aee13b6dSGreg Roach } 208aee13b6dSGreg Roach 209c1010edaSGreg Roach $url = route('module', [ 21026684e68SGreg Roach 'module' => $this->name(), 211c1010edaSGreg Roach 'action' => 'Admin', 212aa6f03bbSGreg Roach 'ged' => $tree->name(), 213c1010edaSGreg Roach ]); 214aee13b6dSGreg Roach 2156ccdf4f0SGreg Roach return redirect($url); 216aee13b6dSGreg Roach } 217aee13b6dSGreg Roach 218aee13b6dSGreg Roach /** 2196ccdf4f0SGreg Roach * @param ServerRequestInterface $request 220aee13b6dSGreg Roach * 2216ccdf4f0SGreg Roach * @return ResponseInterface 222aee13b6dSGreg Roach */ 223*57ab2231SGreg Roach public function postAdminMoveUpAction(ServerRequestInterface $request): ResponseInterface 224c1010edaSGreg Roach { 225*57ab2231SGreg Roach $tree = $request->getAttribute('tree'); 226eb235819SGreg Roach $block_id = (int) $request->getQueryParams()['block_id']; 227aee13b6dSGreg Roach 22877654037SGreg Roach $block_order = DB::table('block') 22977654037SGreg Roach ->where('block_id', '=', $block_id) 23077654037SGreg Roach ->value('block_order'); 231aee13b6dSGreg Roach 23277654037SGreg Roach $swap_block = DB::table('block') 23326684e68SGreg Roach ->where('module_name', '=', $this->name()) 234a69f5655SGreg Roach ->where('block_order', '=', function (Builder $query) use ($block_order): void { 23577654037SGreg Roach $query 23677654037SGreg Roach ->from('block') 23726684e68SGreg Roach ->where('module_name', '=', $this->name()) 23877654037SGreg Roach ->where('block_order', '<', $block_order) 239a69f5655SGreg Roach ->max('block_order'); 24077654037SGreg Roach }) 24177654037SGreg Roach ->select(['block_order', 'block_id']) 24277654037SGreg Roach ->first(); 243aee13b6dSGreg Roach 244aee13b6dSGreg Roach if ($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 258c1010edaSGreg Roach $url = route('module', [ 25926684e68SGreg Roach 'module' => $this->name(), 260c1010edaSGreg Roach 'action' => 'Admin', 261aa6f03bbSGreg Roach 'ged' => $tree->name(), 262c1010edaSGreg Roach ]); 263aee13b6dSGreg Roach 2646ccdf4f0SGreg Roach return redirect($url); 265aee13b6dSGreg Roach } 266aee13b6dSGreg Roach 267aee13b6dSGreg Roach /** 2686ccdf4f0SGreg Roach * @param ServerRequestInterface $request 269aee13b6dSGreg Roach * 2706ccdf4f0SGreg Roach * @return ResponseInterface 271aee13b6dSGreg Roach */ 272*57ab2231SGreg Roach public function getAdminEditAction(ServerRequestInterface $request): ResponseInterface 273c1010edaSGreg Roach { 274aee13b6dSGreg Roach $this->layout = 'layouts/administration'; 275aee13b6dSGreg Roach 276*57ab2231SGreg Roach $tree = $request->getAttribute('tree'); 277eb235819SGreg Roach $block_id = (int) ($request->getQueryParams()['block_id'] ?? 0); 278aee13b6dSGreg Roach 279aee13b6dSGreg Roach if ($block_id === 0) { 280aee13b6dSGreg Roach // Creating a new faq 281aee13b6dSGreg Roach $header = ''; 282aee13b6dSGreg Roach $faqbody = ''; 28377654037SGreg Roach 28477654037SGreg Roach $block_order = 1 + (int) DB::table('block') 28526684e68SGreg Roach ->where('module_name', '=', $this->name()) 28677654037SGreg Roach ->max('block_order'); 28777654037SGreg Roach 288aee13b6dSGreg Roach $languages = []; 289aee13b6dSGreg Roach 290aee13b6dSGreg Roach $title = I18N::translate('Add an FAQ'); 291aee13b6dSGreg Roach } else { 292aee13b6dSGreg Roach // Editing an existing faq 293aee13b6dSGreg Roach $header = $this->getBlockSetting($block_id, 'header'); 294aee13b6dSGreg Roach $faqbody = $this->getBlockSetting($block_id, 'faqbody'); 29577654037SGreg Roach 29677654037SGreg Roach $block_order = DB::table('block') 29777654037SGreg Roach ->where('block_id', '=', $block_id) 29877654037SGreg Roach ->value('block_order'); 29977654037SGreg Roach 300aee13b6dSGreg Roach $languages = explode(',', $this->getBlockSetting($block_id, 'languages')); 301aee13b6dSGreg Roach 302aee13b6dSGreg Roach $title = I18N::translate('Edit the FAQ'); 303aee13b6dSGreg Roach } 304aee13b6dSGreg Roach 305b6c326d8SGreg Roach $tree_names = ['' => I18N::translate('All')] + Tree::getIdList(); 306b6c326d8SGreg Roach 307aee13b6dSGreg Roach return $this->viewResponse('modules/faq/edit', [ 308aee13b6dSGreg Roach 'block_id' => $block_id, 309aee13b6dSGreg Roach 'block_order' => $block_order, 310aee13b6dSGreg Roach 'header' => $header, 311aee13b6dSGreg Roach 'faqbody' => $faqbody, 312aee13b6dSGreg Roach 'languages' => $languages, 313aee13b6dSGreg Roach 'title' => $title, 314aee13b6dSGreg Roach 'tree' => $tree, 315b6c326d8SGreg Roach 'tree_names' => $tree_names, 316aee13b6dSGreg Roach ]); 317aee13b6dSGreg Roach } 318aee13b6dSGreg Roach 319aee13b6dSGreg Roach /** 3206ccdf4f0SGreg Roach * @param ServerRequestInterface $request 321aee13b6dSGreg Roach * 3226ccdf4f0SGreg Roach * @return ResponseInterface 323aee13b6dSGreg Roach */ 324*57ab2231SGreg Roach public function postAdminEditAction(ServerRequestInterface $request): ResponseInterface 325c1010edaSGreg Roach { 326*57ab2231SGreg Roach $tree = $request->getAttribute('tree'); 327eb235819SGreg Roach $block_id = (int) ($request->getQueryParams()['block_id'] ?? 0); 328eb235819SGreg Roach 329eb235819SGreg Roach $params = $request->getParsedBody(); 330eb235819SGreg Roach 331eb235819SGreg Roach $faqbody = $params['faqbody']; 332eb235819SGreg Roach $header = $params['header']; 333eb235819SGreg Roach $languages = $params['languages'] ?? []; 334eb235819SGreg Roach $gedcom_id = (int) $params['gedcom_id'] ?: null; 335eb235819SGreg Roach $block_order = (int) $params['block_order']; 336aee13b6dSGreg Roach 33750d6f48cSGreg Roach $faqbody = $this->html_service->sanitize($faqbody); 33850d6f48cSGreg Roach $header = $this->html_service->sanitize($header); 33950d6f48cSGreg Roach 340aee13b6dSGreg Roach if ($block_id !== 0) { 34177654037SGreg Roach DB::table('block') 34277654037SGreg Roach ->where('block_id', '=', $block_id) 34377654037SGreg Roach ->update([ 34477654037SGreg Roach 'gedcom_id' => $gedcom_id, 34577654037SGreg Roach 'block_order' => $block_order, 346aee13b6dSGreg Roach ]); 347aee13b6dSGreg Roach } else { 34877654037SGreg Roach DB::table('block')->insert([ 34977654037SGreg Roach 'gedcom_id' => $gedcom_id, 35026684e68SGreg Roach 'module_name' => $this->name(), 35177654037SGreg Roach 'block_order' => $block_order, 352aee13b6dSGreg Roach ]); 353aee13b6dSGreg Roach 35477654037SGreg Roach $block_id = (int) DB::connection()->getPdo()->lastInsertId(); 355aee13b6dSGreg Roach } 356aee13b6dSGreg Roach 357aee13b6dSGreg Roach $this->setBlockSetting($block_id, 'faqbody', $faqbody); 358aee13b6dSGreg Roach $this->setBlockSetting($block_id, 'header', $header); 359aee13b6dSGreg Roach $this->setBlockSetting($block_id, 'languages', implode(',', $languages)); 360aee13b6dSGreg Roach 361c1010edaSGreg Roach $url = route('module', [ 36226684e68SGreg Roach 'module' => $this->name(), 363c1010edaSGreg Roach 'action' => 'Admin', 364aa6f03bbSGreg Roach 'ged' => $tree->name(), 365c1010edaSGreg Roach ]); 366aee13b6dSGreg Roach 3676ccdf4f0SGreg Roach return redirect($url); 368aee13b6dSGreg Roach } 369aee13b6dSGreg Roach 370b998dbceSGreg Roach /** 371*57ab2231SGreg Roach * @param ServerRequestInterface $request 372b998dbceSGreg Roach * 3736ccdf4f0SGreg Roach * @return ResponseInterface 374b998dbceSGreg Roach */ 375*57ab2231SGreg Roach public function getShowAction(ServerRequestInterface $request): ResponseInterface 376c1010edaSGreg Roach { 377*57ab2231SGreg Roach $tree = $request->getAttribute('tree'); 378*57ab2231SGreg Roach 3798de50a4eSGreg Roach // Filter foreign languages. 38077654037SGreg Roach $faqs = $this->faqsForTree($tree) 3810b5fd0a6SGreg Roach ->filter(static function (stdClass $faq): bool { 38222d65e5aSGreg Roach return $faq->languages === '' || in_array(WT_LOCALE, explode(',', $faq->languages), true); 3838de50a4eSGreg Roach }); 384aee13b6dSGreg Roach 385aee13b6dSGreg Roach return $this->viewResponse('modules/faq/show', [ 3868de50a4eSGreg Roach 'faqs' => $faqs, 387aee13b6dSGreg Roach 'title' => I18N::translate('Frequently asked questions'), 3888de50a4eSGreg Roach 'tree' => $tree, 389aee13b6dSGreg Roach ]); 390aee13b6dSGreg Roach } 39177654037SGreg Roach 39277654037SGreg Roach /** 39377654037SGreg Roach * @param Tree $tree 39477654037SGreg Roach * 39577654037SGreg Roach * @return Collection 39677654037SGreg Roach */ 39777654037SGreg Roach private function faqsForTree(Tree $tree): Collection 39877654037SGreg Roach { 39977654037SGreg Roach return DB::table('block') 40077654037SGreg Roach ->join('block_setting AS bs1', 'bs1.block_id', '=', 'block.block_id') 40177654037SGreg Roach ->join('block_setting AS bs2', 'bs2.block_id', '=', 'block.block_id') 40277654037SGreg Roach ->join('block_setting AS bs3', 'bs3.block_id', '=', 'block.block_id') 40326684e68SGreg Roach ->where('module_name', '=', $this->name()) 40477654037SGreg Roach ->where('bs1.setting_name', '=', 'header') 40577654037SGreg Roach ->where('bs2.setting_name', '=', 'faqbody') 40677654037SGreg Roach ->where('bs3.setting_name', '=', 'languages') 4070b5fd0a6SGreg Roach ->where(static function (Builder $query) use ($tree): void { 40877654037SGreg Roach $query 40977654037SGreg Roach ->whereNull('gedcom_id') 41077654037SGreg Roach ->orWhere('gedcom_id', '=', $tree->id()); 41177654037SGreg Roach }) 41277654037SGreg Roach ->orderBy('block_order') 41377654037SGreg Roach ->select(['block.block_id', 'block_order', 'gedcom_id', 'bs1.setting_value AS header', 'bs2.setting_value AS faqbody', 'bs3.setting_value AS languages']) 41477654037SGreg Roach ->get(); 41577654037SGreg Roach } 41677654037SGreg Roach 41777654037SGreg Roach /** 41877654037SGreg Roach * @param Tree $tree 41977654037SGreg Roach * @param string $language 42077654037SGreg Roach * 42177654037SGreg Roach * @return bool 42277654037SGreg Roach */ 42377654037SGreg Roach private function faqsExist(Tree $tree, string $language): bool 42477654037SGreg Roach { 42577654037SGreg Roach return DB::table('block') 42677654037SGreg Roach ->join('block_setting', 'block_setting.block_id', '=', 'block.block_id') 42726684e68SGreg Roach ->where('module_name', '=', $this->name()) 42877654037SGreg Roach ->where('setting_name', '=', 'languages') 4290b5fd0a6SGreg Roach ->where(static function (Builder $query) use ($tree): void { 43077654037SGreg Roach $query 43177654037SGreg Roach ->whereNull('gedcom_id') 43277654037SGreg Roach ->orWhere('gedcom_id', '=', $tree->id()); 43377654037SGreg Roach }) 43477654037SGreg Roach ->select(['setting_value AS languages']) 43577654037SGreg Roach ->get() 4360b5fd0a6SGreg Roach ->filter(static function (stdClass $faq) use ($language): bool { 4370b5fd0a6SGreg Roach return $faq->languages === '' || in_array($language, explode(',', $faq->languages), true); 43877654037SGreg Roach }) 43977654037SGreg Roach ->isNotEmpty(); 44077654037SGreg Roach } 4418c2e8227SGreg Roach} 442