18c2e8227SGreg Roach<?php 23976b470SGreg Roach 38c2e8227SGreg Roach/** 48c2e8227SGreg Roach * webtrees: online genealogy 5*d11be702SGreg Roach * Copyright (C) 2023 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 1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>. 168c2e8227SGreg Roach */ 17fcfa147eSGreg Roach 18e7f56f2aSGreg Roachdeclare(strict_types=1); 19e7f56f2aSGreg Roach 2076692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module; 2176692c8bSGreg Roach 221d1f373cSGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\ControlPanel; 230e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N; 240e62c4b8SGreg Roachuse Fisharebest\Webtrees\Menu; 2550d6f48cSGreg Roachuse Fisharebest\Webtrees\Services\HtmlService; 261d1f373cSGreg Roachuse Fisharebest\Webtrees\Services\TreeService; 27431d5e92SGreg Roachuse Fisharebest\Webtrees\Site; 280e62c4b8SGreg Roachuse Fisharebest\Webtrees\Tree; 29b55cbc6bSGreg Roachuse Fisharebest\Webtrees\Validator; 3077654037SGreg Roachuse Illuminate\Database\Capsule\Manager as DB; 3177654037SGreg Roachuse Illuminate\Database\Query\Builder; 3277654037SGreg Roachuse Illuminate\Support\Collection; 336ccdf4f0SGreg Roachuse Psr\Http\Message\ResponseInterface; 346ccdf4f0SGreg Roachuse Psr\Http\Message\ServerRequestInterface; 35f3874e19SGreg Roach 3610e06497SGreg Roachuse function in_array; 371d1f373cSGreg Roachuse function redirect; 381d1f373cSGreg 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 4843f2f523SGreg Roach private HtmlService $html_service; 4950d6f48cSGreg Roach 5043f2f523SGreg Roach private TreeService $tree_service; 511d1f373cSGreg Roach 5250d6f48cSGreg Roach /** 53ce42304aSGreg Roach * FrequentlyAskedQuestionsModule constructor. 5450d6f48cSGreg Roach * 5550d6f48cSGreg Roach * @param HtmlService $html_service 561d1f373cSGreg Roach * @param TreeService $tree_service 5750d6f48cSGreg Roach */ 581d1f373cSGreg Roach public function __construct(HtmlService $html_service, TreeService $tree_service) 5950d6f48cSGreg Roach { 6050d6f48cSGreg Roach $this->html_service = $html_service; 611d1f373cSGreg Roach $this->tree_service = $tree_service; 6250d6f48cSGreg Roach } 6350d6f48cSGreg Roach 64961ec755SGreg Roach /** 650cfd6963SGreg Roach * How should this module be identified in the control panel, etc.? 66961ec755SGreg Roach * 67961ec755SGreg Roach * @return string 68961ec755SGreg Roach */ 6949a243cbSGreg Roach public function title(): string 70c1010edaSGreg Roach { 71bbb76c12SGreg Roach /* I18N: Name of a module. Abbreviation for “Frequently Asked Questions” */ 72bbb76c12SGreg Roach return I18N::translate('FAQ'); 738c2e8227SGreg Roach } 748c2e8227SGreg Roach 75961ec755SGreg Roach /** 76961ec755SGreg Roach * A sentence describing what this module does. 77961ec755SGreg Roach * 78961ec755SGreg Roach * @return string 79961ec755SGreg Roach */ 8049a243cbSGreg Roach public function description(): string 81c1010edaSGreg Roach { 82bbb76c12SGreg Roach /* I18N: Description of the “FAQ” module */ 83bbb76c12SGreg Roach return I18N::translate('A list of frequently asked questions and answers.'); 848c2e8227SGreg Roach } 858c2e8227SGreg Roach 8676692c8bSGreg Roach /** 8749a243cbSGreg Roach * The default position for this menu. It can be changed in the control panel. 880ee13198SGreg Roach * 890ee13198SGreg Roach * @return int 900ee13198SGreg Roach */ 918f53f488SRico Sonntag public function defaultMenuOrder(): int 92c1010edaSGreg Roach { 93353b36abSGreg Roach return 8; 948c2e8227SGreg Roach } 958c2e8227SGreg Roach 960ee13198SGreg Roach /** 970ee13198SGreg Roach * A menu, to be added to the main application menu. 980ee13198SGreg Roach * 99aee13b6dSGreg Roach * @param Tree $tree 100aee13b6dSGreg Roach * 1010ee13198SGreg Roach * @return Menu|null 1020ee13198SGreg Roach */ 10346295629SGreg Roach public function getMenu(Tree $tree): ?Menu 104c1010edaSGreg Roach { 10565cf5706SGreg Roach if ($this->faqsExist($tree, I18N::languageTag())) { 10649a243cbSGreg Roach return new Menu($this->title(), route('module', [ 10726684e68SGreg Roach 'module' => $this->name(), 108c1010edaSGreg Roach 'action' => 'Show', 1099022ab66SGreg Roach 'tree' => $tree->name(), 11008362db4SGreg Roach ]), 'menu-faq'); 1118c2e8227SGreg Roach } 112b2ce94c6SRico Sonntag 113b2ce94c6SRico Sonntag return null; 1148c2e8227SGreg Roach } 115aee13b6dSGreg Roach 116aee13b6dSGreg Roach /** 11757ab2231SGreg Roach * @param ServerRequestInterface $request 118aee13b6dSGreg Roach * 1196ccdf4f0SGreg Roach * @return ResponseInterface 120aee13b6dSGreg Roach */ 12157ab2231SGreg Roach public function getAdminAction(ServerRequestInterface $request): ResponseInterface 122c1010edaSGreg Roach { 123aee13b6dSGreg Roach $this->layout = 'layouts/administration'; 124aee13b6dSGreg Roach 1251d1f373cSGreg Roach // This module can't run without a tree 126b55cbc6bSGreg Roach $tree = Validator::attributes($request)->treeOptional(); 127e218f363SGreg Roach 1281d1f373cSGreg Roach if (!$tree instanceof Tree) { 129431d5e92SGreg Roach $trees = $this->tree_service->all(); 130431d5e92SGreg Roach 131431d5e92SGreg Roach $tree = $trees->get(Site::getPreference('DEFAULT_GEDCOM')) ?? $trees->first(); 132431d5e92SGreg Roach 133e218f363SGreg Roach if ($tree instanceof Tree) { 134e218f363SGreg Roach return redirect(route('module', ['module' => $this->name(), 'action' => 'Admin', 'tree' => $tree->name()])); 135e218f363SGreg Roach } 136e218f363SGreg Roach 1371d1f373cSGreg Roach return redirect(route(ControlPanel::class)); 1381d1f373cSGreg Roach } 1395229eadeSGreg Roach 14026348dcdSGreg Roach $faqs = $this->faqsForTree($tree); 141aee13b6dSGreg Roach 142748dbe15SGreg Roach $min_block_order = (int) DB::table('block') 14326684e68SGreg Roach ->where('module_name', '=', $this->name()) 1440b5fd0a6SGreg Roach ->where(static function (Builder $query) use ($tree): void { 14577654037SGreg Roach $query 14677654037SGreg Roach ->whereNull('gedcom_id') 14777654037SGreg Roach ->orWhere('gedcom_id', '=', $tree->id()); 14877654037SGreg Roach }) 14977654037SGreg Roach ->min('block_order'); 150aee13b6dSGreg Roach 151748dbe15SGreg Roach $max_block_order = (int) DB::table('block') 15226684e68SGreg Roach ->where('module_name', '=', $this->name()) 1530b5fd0a6SGreg Roach ->where(static function (Builder $query) use ($tree): void { 15477654037SGreg Roach $query 15577654037SGreg Roach ->whereNull('gedcom_id') 15677654037SGreg Roach ->orWhere('gedcom_id', '=', $tree->id()); 15777654037SGreg Roach }) 15877654037SGreg Roach ->max('block_order'); 159aee13b6dSGreg Roach 160cc13d6d8SGreg Roach $title = I18N::translate('Frequently asked questions') . ' — ' . $tree->title(); 161aee13b6dSGreg Roach 162aee13b6dSGreg Roach return $this->viewResponse('modules/faq/config', [ 16383615acfSGreg Roach 'action' => route('module', ['module' => $this->name(), 'action' => 'Admin']), 164aee13b6dSGreg Roach 'faqs' => $faqs, 165aee13b6dSGreg Roach 'max_block_order' => $max_block_order, 166aee13b6dSGreg Roach 'min_block_order' => $min_block_order, 16771378461SGreg Roach 'module' => $this->name(), 168aee13b6dSGreg Roach 'title' => $title, 169aee13b6dSGreg Roach 'tree' => $tree, 1701e653452SGreg Roach 'tree_names' => $this->tree_service->titles(), 171aee13b6dSGreg Roach ]); 172aee13b6dSGreg Roach } 173aee13b6dSGreg Roach 174aee13b6dSGreg Roach /** 1756ccdf4f0SGreg Roach * @param ServerRequestInterface $request 176aee13b6dSGreg Roach * 1776ccdf4f0SGreg Roach * @return ResponseInterface 178aee13b6dSGreg Roach */ 179e218f363SGreg Roach public function postAdminAction(ServerRequestInterface $request): ResponseInterface 180e218f363SGreg Roach { 181e218f363SGreg Roach return redirect(route('module', [ 182e218f363SGreg Roach 'module' => $this->name(), 183e218f363SGreg Roach 'action' => 'Admin', 184748dbe15SGreg Roach 'tree' => Validator::parsedBody($request)->string('tree'), 185e218f363SGreg Roach ])); 186e218f363SGreg Roach } 187e218f363SGreg Roach 188e218f363SGreg Roach /** 189e218f363SGreg Roach * @param ServerRequestInterface $request 190e218f363SGreg Roach * 191e218f363SGreg Roach * @return ResponseInterface 192e218f363SGreg Roach */ 19357ab2231SGreg Roach public function postAdminDeleteAction(ServerRequestInterface $request): ResponseInterface 194c1010edaSGreg Roach { 195748dbe15SGreg Roach $block_id = Validator::queryParams($request)->integer('block_id'); 196aee13b6dSGreg Roach 19777654037SGreg Roach DB::table('block_setting')->where('block_id', '=', $block_id)->delete(); 198aee13b6dSGreg Roach 19977654037SGreg Roach DB::table('block')->where('block_id', '=', $block_id)->delete(); 200aee13b6dSGreg Roach 201c1010edaSGreg Roach $url = route('module', [ 20226684e68SGreg Roach 'module' => $this->name(), 203c1010edaSGreg Roach 'action' => 'Admin', 204c1010edaSGreg Roach ]); 205aee13b6dSGreg Roach 2066ccdf4f0SGreg Roach return redirect($url); 207aee13b6dSGreg Roach } 208aee13b6dSGreg Roach 209aee13b6dSGreg Roach /** 2106ccdf4f0SGreg Roach * @param ServerRequestInterface $request 211aee13b6dSGreg Roach * 2126ccdf4f0SGreg Roach * @return ResponseInterface 213aee13b6dSGreg Roach */ 21457ab2231SGreg Roach public function postAdminMoveDownAction(ServerRequestInterface $request): ResponseInterface 215c1010edaSGreg Roach { 216748dbe15SGreg Roach $block_id = Validator::queryParams($request)->integer('block_id'); 217aee13b6dSGreg Roach 21877654037SGreg Roach $block_order = DB::table('block') 21977654037SGreg Roach ->where('block_id', '=', $block_id) 22077654037SGreg Roach ->value('block_order'); 221aee13b6dSGreg Roach 22277654037SGreg Roach $swap_block = DB::table('block') 22326684e68SGreg Roach ->where('module_name', '=', $this->name()) 22477654037SGreg Roach ->where('block_order', '>', $block_order) 225a9866bf2SGreg Roach ->orderBy('block_order') 22677654037SGreg Roach ->first(); 227aee13b6dSGreg Roach 2281d1f373cSGreg Roach if ($block_order !== null && $swap_block !== null) { 22977654037SGreg Roach DB::table('block') 23077654037SGreg Roach ->where('block_id', '=', $block_id) 23177654037SGreg Roach ->update([ 232aee13b6dSGreg Roach 'block_order' => $swap_block->block_order, 233aee13b6dSGreg Roach ]); 23477654037SGreg Roach 23577654037SGreg Roach DB::table('block') 23677654037SGreg Roach ->where('block_id', '=', $swap_block->block_id) 23777654037SGreg Roach ->update([ 238aee13b6dSGreg Roach 'block_order' => $block_order, 239aee13b6dSGreg Roach ]); 240aee13b6dSGreg Roach } 241aee13b6dSGreg Roach 2421d1f373cSGreg Roach return response(); 243aee13b6dSGreg Roach } 244aee13b6dSGreg Roach 245aee13b6dSGreg Roach /** 2466ccdf4f0SGreg Roach * @param ServerRequestInterface $request 247aee13b6dSGreg Roach * 2486ccdf4f0SGreg Roach * @return ResponseInterface 249aee13b6dSGreg Roach */ 25057ab2231SGreg Roach public function postAdminMoveUpAction(ServerRequestInterface $request): ResponseInterface 251c1010edaSGreg Roach { 252748dbe15SGreg Roach $block_id = Validator::queryParams($request)->integer('block_id'); 253aee13b6dSGreg Roach 25477654037SGreg Roach $block_order = DB::table('block') 25577654037SGreg Roach ->where('block_id', '=', $block_id) 25677654037SGreg Roach ->value('block_order'); 257aee13b6dSGreg Roach 25877654037SGreg Roach $swap_block = DB::table('block') 25926684e68SGreg Roach ->where('module_name', '=', $this->name()) 26077654037SGreg Roach ->where('block_order', '<', $block_order) 2611d1f373cSGreg Roach ->orderBy('block_order', 'desc') 26277654037SGreg Roach ->first(); 263aee13b6dSGreg Roach 2641d1f373cSGreg Roach if ($block_order !== null && $swap_block !== null) { 26577654037SGreg Roach DB::table('block') 26677654037SGreg Roach ->where('block_id', '=', $block_id) 26777654037SGreg Roach ->update([ 268aee13b6dSGreg Roach 'block_order' => $swap_block->block_order, 269aee13b6dSGreg Roach ]); 27077654037SGreg Roach 27177654037SGreg Roach DB::table('block') 27277654037SGreg Roach ->where('block_id', '=', $swap_block->block_id) 27377654037SGreg Roach ->update([ 274aee13b6dSGreg Roach 'block_order' => $block_order, 275aee13b6dSGreg Roach ]); 276aee13b6dSGreg Roach } 277aee13b6dSGreg Roach 2781d1f373cSGreg Roach return response(); 279aee13b6dSGreg Roach } 280aee13b6dSGreg Roach 281aee13b6dSGreg Roach /** 2826ccdf4f0SGreg Roach * @param ServerRequestInterface $request 283aee13b6dSGreg Roach * 2846ccdf4f0SGreg Roach * @return ResponseInterface 285aee13b6dSGreg Roach */ 28657ab2231SGreg Roach public function getAdminEditAction(ServerRequestInterface $request): ResponseInterface 287c1010edaSGreg Roach { 288aee13b6dSGreg Roach $this->layout = 'layouts/administration'; 289aee13b6dSGreg Roach 290748dbe15SGreg Roach $block_id = Validator::queryParams($request)->integer('block_id', 0); 291aee13b6dSGreg Roach 292aee13b6dSGreg Roach if ($block_id === 0) { 293aee13b6dSGreg Roach // Creating a new faq 294aee13b6dSGreg Roach $header = ''; 2951e653452SGreg Roach $body = ''; 2961e653452SGreg Roach $gedcom_id = null; 2971e653452SGreg Roach $block_order = 1 + (int) DB::table('block')->where('module_name', '=', $this->name())->max('block_order'); 29877654037SGreg Roach 299aee13b6dSGreg Roach $languages = []; 300aee13b6dSGreg Roach 301aee13b6dSGreg Roach $title = I18N::translate('Add an FAQ'); 302aee13b6dSGreg Roach } else { 303aee13b6dSGreg Roach // Editing an existing faq 304aee13b6dSGreg Roach $header = $this->getBlockSetting($block_id, 'header'); 3051e653452SGreg Roach $body = $this->getBlockSetting($block_id, 'faqbody'); 3061e653452SGreg Roach $gedcom_id = DB::table('block')->where('block_id', '=', $block_id)->value('gedcom_id'); 3071e653452SGreg Roach $block_order = DB::table('block')->where('block_id', '=', $block_id)->value('block_order'); 30877654037SGreg Roach 309aee13b6dSGreg Roach $languages = explode(',', $this->getBlockSetting($block_id, 'languages')); 310aee13b6dSGreg Roach 311aee13b6dSGreg Roach $title = I18N::translate('Edit the FAQ'); 312aee13b6dSGreg Roach } 313aee13b6dSGreg Roach 3141e653452SGreg Roach $gedcom_ids = $this->tree_service->all() 3151e653452SGreg Roach ->mapWithKeys(static function (Tree $tree): array { 3161e653452SGreg Roach return [$tree->id() => $tree->title()]; 3171e653452SGreg Roach }) 3181e653452SGreg Roach ->all(); 3191e653452SGreg Roach 3201e653452SGreg Roach $gedcom_ids = ['' => I18N::translate('All')] + $gedcom_ids; 321b6c326d8SGreg Roach 322aee13b6dSGreg Roach return $this->viewResponse('modules/faq/edit', [ 323aee13b6dSGreg Roach 'block_id' => $block_id, 324aee13b6dSGreg Roach 'block_order' => $block_order, 325aee13b6dSGreg Roach 'header' => $header, 3261e653452SGreg Roach 'body' => $body, 327aee13b6dSGreg Roach 'languages' => $languages, 328aee13b6dSGreg Roach 'title' => $title, 3291e653452SGreg Roach 'gedcom_id' => $gedcom_id, 3301e653452SGreg Roach 'gedcom_ids' => $gedcom_ids, 331aee13b6dSGreg Roach ]); 332aee13b6dSGreg Roach } 333aee13b6dSGreg Roach 334aee13b6dSGreg Roach /** 3356ccdf4f0SGreg Roach * @param ServerRequestInterface $request 336aee13b6dSGreg Roach * 3376ccdf4f0SGreg Roach * @return ResponseInterface 338aee13b6dSGreg Roach */ 33957ab2231SGreg Roach public function postAdminEditAction(ServerRequestInterface $request): ResponseInterface 340c1010edaSGreg Roach { 341748dbe15SGreg Roach $block_id = Validator::queryParams($request)->integer('block_id', 0); 342748dbe15SGreg Roach $body = Validator::parsedBody($request)->string('body'); 343748dbe15SGreg Roach $header = Validator::parsedBody($request)->string('header'); 344748dbe15SGreg Roach $languages = Validator::parsedBody($request)->array('languages'); 345748dbe15SGreg Roach $gedcom_id = Validator::parsedBody($request)->string('gedcom_id'); 346748dbe15SGreg Roach $block_order = Validator::parsedBody($request)->integer('block_order'); 347aee13b6dSGreg Roach 3481e653452SGreg Roach if ($gedcom_id === '') { 3491e653452SGreg Roach $gedcom_id = null; 3501e653452SGreg Roach } 3511e653452SGreg Roach 3521e653452SGreg Roach $body = $this->html_service->sanitize($body); 35350d6f48cSGreg Roach $header = $this->html_service->sanitize($header); 35450d6f48cSGreg Roach 355aee13b6dSGreg Roach if ($block_id !== 0) { 35677654037SGreg Roach DB::table('block') 35777654037SGreg Roach ->where('block_id', '=', $block_id) 35877654037SGreg Roach ->update([ 35977654037SGreg Roach 'gedcom_id' => $gedcom_id, 36077654037SGreg Roach 'block_order' => $block_order, 361aee13b6dSGreg Roach ]); 362aee13b6dSGreg Roach } else { 36377654037SGreg Roach DB::table('block')->insert([ 36477654037SGreg Roach 'gedcom_id' => $gedcom_id, 36526684e68SGreg Roach 'module_name' => $this->name(), 36677654037SGreg Roach 'block_order' => $block_order, 367aee13b6dSGreg Roach ]); 368aee13b6dSGreg Roach 36977654037SGreg Roach $block_id = (int) DB::connection()->getPdo()->lastInsertId(); 370aee13b6dSGreg Roach } 371aee13b6dSGreg Roach 3721e653452SGreg Roach $this->setBlockSetting($block_id, 'faqbody', $body); 373aee13b6dSGreg Roach $this->setBlockSetting($block_id, 'header', $header); 374aee13b6dSGreg Roach $this->setBlockSetting($block_id, 'languages', implode(',', $languages)); 375aee13b6dSGreg Roach 376c1010edaSGreg Roach $url = route('module', [ 37726684e68SGreg Roach 'module' => $this->name(), 378c1010edaSGreg Roach 'action' => 'Admin', 379c1010edaSGreg Roach ]); 380aee13b6dSGreg Roach 3816ccdf4f0SGreg Roach return redirect($url); 382aee13b6dSGreg Roach } 383aee13b6dSGreg Roach 384b998dbceSGreg Roach /** 38557ab2231SGreg Roach * @param ServerRequestInterface $request 386b998dbceSGreg Roach * 3876ccdf4f0SGreg Roach * @return ResponseInterface 388b998dbceSGreg Roach */ 38957ab2231SGreg Roach public function getShowAction(ServerRequestInterface $request): ResponseInterface 390c1010edaSGreg Roach { 391b55cbc6bSGreg Roach $tree = Validator::attributes($request)->tree(); 39257ab2231SGreg Roach 3938de50a4eSGreg Roach // Filter foreign languages. 39477654037SGreg Roach $faqs = $this->faqsForTree($tree) 395f70bcff5SGreg Roach ->filter(static function (object $faq): bool { 39665cf5706SGreg Roach return $faq->languages === '' || in_array(I18N::languageTag(), explode(',', $faq->languages), true); 3978de50a4eSGreg Roach }); 398aee13b6dSGreg Roach 399aee13b6dSGreg Roach return $this->viewResponse('modules/faq/show', [ 4008de50a4eSGreg Roach 'faqs' => $faqs, 401aee13b6dSGreg Roach 'title' => I18N::translate('Frequently asked questions'), 4028de50a4eSGreg Roach 'tree' => $tree, 403aee13b6dSGreg Roach ]); 404aee13b6dSGreg Roach } 40577654037SGreg Roach 40677654037SGreg Roach /** 40777654037SGreg Roach * @param Tree $tree 40877654037SGreg Roach * 40936779af1SGreg Roach * @return Collection<int,object> 41077654037SGreg Roach */ 41177654037SGreg Roach private function faqsForTree(Tree $tree): Collection 41277654037SGreg Roach { 41377654037SGreg Roach return DB::table('block') 41477654037SGreg Roach ->join('block_setting AS bs1', 'bs1.block_id', '=', 'block.block_id') 41577654037SGreg Roach ->join('block_setting AS bs2', 'bs2.block_id', '=', 'block.block_id') 41677654037SGreg Roach ->join('block_setting AS bs3', 'bs3.block_id', '=', 'block.block_id') 41726684e68SGreg Roach ->where('module_name', '=', $this->name()) 41877654037SGreg Roach ->where('bs1.setting_name', '=', 'header') 41977654037SGreg Roach ->where('bs2.setting_name', '=', 'faqbody') 42077654037SGreg Roach ->where('bs3.setting_name', '=', 'languages') 4210b5fd0a6SGreg Roach ->where(static function (Builder $query) use ($tree): void { 42277654037SGreg Roach $query 42377654037SGreg Roach ->whereNull('gedcom_id') 42477654037SGreg Roach ->orWhere('gedcom_id', '=', $tree->id()); 42577654037SGreg Roach }) 42677654037SGreg Roach ->orderBy('block_order') 42777654037SGreg Roach ->select(['block.block_id', 'block_order', 'gedcom_id', 'bs1.setting_value AS header', 'bs2.setting_value AS faqbody', 'bs3.setting_value AS languages']) 428748dbe15SGreg Roach ->get() 429748dbe15SGreg Roach ->map(static function (object $row): object { 430748dbe15SGreg Roach $row->block_id = (int) $row->block_id; 431748dbe15SGreg Roach $row->block_order = (int) $row->block_order; 432748dbe15SGreg Roach $row->gedcom_id = (int) $row->gedcom_id; 433748dbe15SGreg Roach 434748dbe15SGreg Roach return $row; 435748dbe15SGreg Roach }); 43677654037SGreg Roach } 43777654037SGreg Roach 43877654037SGreg Roach /** 43977654037SGreg Roach * @param Tree $tree 44077654037SGreg Roach * @param string $language 44177654037SGreg Roach * 44277654037SGreg Roach * @return bool 44377654037SGreg Roach */ 44477654037SGreg Roach private function faqsExist(Tree $tree, string $language): bool 44577654037SGreg Roach { 44677654037SGreg Roach return DB::table('block') 44777654037SGreg Roach ->join('block_setting', 'block_setting.block_id', '=', 'block.block_id') 44826684e68SGreg Roach ->where('module_name', '=', $this->name()) 44977654037SGreg Roach ->where('setting_name', '=', 'languages') 4500b5fd0a6SGreg Roach ->where(static function (Builder $query) use ($tree): void { 45177654037SGreg Roach $query 45277654037SGreg Roach ->whereNull('gedcom_id') 45377654037SGreg Roach ->orWhere('gedcom_id', '=', $tree->id()); 45477654037SGreg Roach }) 45577654037SGreg Roach ->select(['setting_value AS languages']) 45677654037SGreg Roach ->get() 457f70bcff5SGreg Roach ->filter(static function (object $faq) use ($language): bool { 4580b5fd0a6SGreg Roach return $faq->languages === '' || in_array($language, explode(',', $faq->languages), true); 45977654037SGreg Roach }) 46077654037SGreg Roach ->isNotEmpty(); 46177654037SGreg Roach } 4628c2e8227SGreg Roach} 463