18c2e8227SGreg Roach<?php 28c2e8227SGreg Roach/** 38c2e8227SGreg Roach * webtrees: online genealogy 41062a142SGreg Roach * Copyright (C) 2018 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 */ 1676692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module; 1776692c8bSGreg Roach 180e62c4b8SGreg Roachuse Fisharebest\Webtrees\Database; 190e62c4b8SGreg Roachuse Fisharebest\Webtrees\Filter; 200e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N; 210e62c4b8SGreg Roachuse Fisharebest\Webtrees\Menu; 220e62c4b8SGreg Roachuse Fisharebest\Webtrees\Tree; 238de50a4eSGreg Roachuse stdClass; 24aee13b6dSGreg Roachuse Symfony\Component\HttpFoundation\RedirectResponse; 25aee13b6dSGreg Roachuse Symfony\Component\HttpFoundation\Request; 26aee13b6dSGreg Roachuse Symfony\Component\HttpFoundation\Response; 278c2e8227SGreg Roach 288c2e8227SGreg Roach/** 298c2e8227SGreg Roach * Class FrequentlyAskedQuestionsModule 308c2e8227SGreg Roach */ 31c1010edaSGreg Roachclass FrequentlyAskedQuestionsModule extends AbstractModule implements ModuleMenuInterface, ModuleConfigInterface 32c1010edaSGreg Roach{ 338c2e8227SGreg Roach /** {@inheritdoc} */ 34c1010edaSGreg Roach public function getTitle() 35c1010edaSGreg Roach { 36aee13b6dSGreg Roach return /* I18N: Name of a module. Abbreviation for “Frequently Asked Questions” */ 37aee13b6dSGreg Roach I18N::translate('FAQ'); 388c2e8227SGreg Roach } 398c2e8227SGreg Roach 408c2e8227SGreg Roach /** {@inheritdoc} */ 41c1010edaSGreg Roach public function getDescription() 42c1010edaSGreg Roach { 43aee13b6dSGreg Roach return /* I18N: Description of the “FAQ” module */ 44aee13b6dSGreg Roach I18N::translate('A list of frequently asked questions and answers.'); 458c2e8227SGreg Roach } 468c2e8227SGreg Roach 4776692c8bSGreg Roach /** 48aee13b6dSGreg Roach * The URL to a page where the user can modify the configuration of this module. 4976692c8bSGreg Roach * 50aee13b6dSGreg Roach * @return string 5176692c8bSGreg Roach */ 52c1010edaSGreg Roach public function getConfigLink() 53c1010edaSGreg Roach { 54c1010edaSGreg Roach return route('module', [ 55c1010edaSGreg Roach 'module' => $this->getName(), 56c1010edaSGreg Roach 'action' => 'Admin', 57c1010edaSGreg Roach ]); 588c2e8227SGreg Roach } 598c2e8227SGreg Roach 608c2e8227SGreg Roach /** 610ee13198SGreg Roach * The user can re-order menus. Until they do, they are shown in this order. 620ee13198SGreg Roach * 630ee13198SGreg Roach * @return int 640ee13198SGreg Roach */ 65c1010edaSGreg Roach public function defaultMenuOrder() 66c1010edaSGreg Roach { 678c2e8227SGreg Roach return 40; 688c2e8227SGreg Roach } 698c2e8227SGreg Roach 700ee13198SGreg Roach /** 710ee13198SGreg Roach * A menu, to be added to the main application menu. 720ee13198SGreg Roach * 73aee13b6dSGreg Roach * @param Tree $tree 74aee13b6dSGreg Roach * 750ee13198SGreg Roach * @return Menu|null 760ee13198SGreg Roach */ 77c1010edaSGreg Roach public function getMenu(Tree $tree) 78c1010edaSGreg Roach { 798c2e8227SGreg Roach $faqs = Database::prepare( 802b6675d7SGreg Roach "SELECT block_id FROM `##block`" . 812b6675d7SGreg Roach " JOIN `##block_setting` USING (block_id)" . 822b6675d7SGreg Roach " WHERE module_name = :module_name AND IFNULL(gedcom_id, :tree_id_1) = :tree_id_2" . 832b6675d7SGreg Roach " AND setting_name='languages' AND (setting_value LIKE CONCAT('%', :locale, '%') OR setting_value='')" 8413abd6f3SGreg Roach )->execute([ 858c2e8227SGreg Roach 'module_name' => $this->getName(), 86aee13b6dSGreg Roach 'tree_id_1' => $tree->getTreeId(), 87aee13b6dSGreg Roach 'tree_id_2' => $tree->getTreeId(), 882b6675d7SGreg Roach 'locale' => WT_LOCALE, 8913abd6f3SGreg Roach ])->fetchAll(); 908c2e8227SGreg Roach 9138a9583bSGreg Roach if ($faqs) { 92c1010edaSGreg Roach return new Menu($this->getTitle(), route('module', [ 93c1010edaSGreg Roach 'module' => 'faq', 94c1010edaSGreg Roach 'action' => 'Show', 95c1010edaSGreg Roach 'ged' => $tree->getName(), 96c1010edaSGreg Roach ]), 'menu-help'); 9738a9583bSGreg Roach } else { 988c2e8227SGreg Roach return null; 998c2e8227SGreg Roach } 1008c2e8227SGreg Roach } 101aee13b6dSGreg Roach 102aee13b6dSGreg Roach /** 103b6db7c1fSGreg Roach * @param Tree $tree 104aee13b6dSGreg Roach * 105aee13b6dSGreg Roach * @return Response 106aee13b6dSGreg Roach */ 107b6db7c1fSGreg Roach public function getAdminAction(Tree $tree): Response 108c1010edaSGreg Roach { 109aee13b6dSGreg Roach $this->layout = 'layouts/administration'; 110aee13b6dSGreg Roach 111aee13b6dSGreg Roach $faqs = Database::prepare( 112aee13b6dSGreg Roach "SELECT block_id, block_order, gedcom_id, bs1.setting_value AS header, bs2.setting_value AS faqbody" . 113aee13b6dSGreg Roach " FROM `##block` b" . 114aee13b6dSGreg Roach " JOIN `##block_setting` bs1 USING (block_id)" . 115aee13b6dSGreg Roach " JOIN `##block_setting` bs2 USING (block_id)" . 116aee13b6dSGreg Roach " WHERE module_name = :module_name" . 117aee13b6dSGreg Roach " AND bs1.setting_name = 'header'" . 118aee13b6dSGreg Roach " AND bs2.setting_name = 'faqbody'" . 119aee13b6dSGreg Roach " AND IFNULL(gedcom_id, :tree_id_1) = :tree_id_2" . 120aee13b6dSGreg Roach " ORDER BY block_order" 121aee13b6dSGreg Roach )->execute([ 122aee13b6dSGreg Roach 'module_name' => $this->getName(), 123aee13b6dSGreg Roach 'tree_id_1' => $tree->getTreeId(), 124aee13b6dSGreg Roach 'tree_id_2' => $tree->getTreeId(), 125aee13b6dSGreg Roach ])->fetchAll(); 126aee13b6dSGreg Roach 127aee13b6dSGreg Roach $min_block_order = Database::prepare( 128aee13b6dSGreg Roach "SELECT MIN(block_order) FROM `##block` WHERE module_name = 'faq' AND (gedcom_id = :tree_id OR gedcom_id IS NULL)" 129aee13b6dSGreg Roach )->execute([ 130aee13b6dSGreg Roach 'tree_id' => $tree->getTreeId(), 131aee13b6dSGreg Roach ])->fetchOne(); 132aee13b6dSGreg Roach 133aee13b6dSGreg Roach $max_block_order = Database::prepare( 134aee13b6dSGreg Roach "SELECT MAX(block_order) FROM `##block` WHERE module_name = 'faq' AND (gedcom_id = :tree_id OR gedcom_id IS NULL)" 135aee13b6dSGreg Roach )->execute([ 136aee13b6dSGreg Roach 'tree_id' => $tree->getTreeId(), 137aee13b6dSGreg Roach ])->fetchOne(); 138aee13b6dSGreg Roach 139aee13b6dSGreg Roach $title = I18N::translate('Frequently asked questions') . ' — ' . $tree->getTitle(); 140aee13b6dSGreg Roach 141aee13b6dSGreg Roach return $this->viewResponse('modules/faq/config', [ 142aee13b6dSGreg Roach 'faqs' => $faqs, 143aee13b6dSGreg Roach 'max_block_order' => $max_block_order, 144aee13b6dSGreg Roach 'min_block_order' => $min_block_order, 145aee13b6dSGreg Roach 'title' => $title, 146aee13b6dSGreg Roach 'tree' => $tree, 147aee13b6dSGreg Roach 'tree_names' => Tree::getNameList(), 148aee13b6dSGreg Roach ]); 149aee13b6dSGreg Roach } 150aee13b6dSGreg Roach 151aee13b6dSGreg Roach /** 152aee13b6dSGreg Roach * @param Request $request 153b6db7c1fSGreg Roach * @param Tree $tree 154aee13b6dSGreg Roach * 155aee13b6dSGreg Roach * @return RedirectResponse 156aee13b6dSGreg Roach */ 157b6db7c1fSGreg Roach public function postAdminDeleteAction(Request $request, Tree $tree): RedirectResponse 158c1010edaSGreg Roach { 159aee13b6dSGreg Roach $block_id = (int)$request->get('block_id'); 160aee13b6dSGreg Roach 161aee13b6dSGreg Roach Database::prepare( 162aee13b6dSGreg Roach "DELETE FROM `##block_setting` WHERE block_id = :block_id" 163aee13b6dSGreg Roach )->execute(['block_id' => $block_id]); 164aee13b6dSGreg Roach 165aee13b6dSGreg Roach Database::prepare( 166aee13b6dSGreg Roach "DELETE FROM `##block` WHERE block_id = :block_id" 167aee13b6dSGreg Roach )->execute(['block_id' => $block_id]); 168aee13b6dSGreg Roach 169aee13b6dSGreg Roach 170c1010edaSGreg Roach $url = route('module', [ 171c1010edaSGreg Roach 'module' => 'faq', 172c1010edaSGreg Roach 'action' => 'Admin', 173c1010edaSGreg Roach 'ged' => $tree->getName(), 174c1010edaSGreg Roach ]); 175aee13b6dSGreg Roach 176aee13b6dSGreg Roach return new RedirectResponse($url); 177aee13b6dSGreg Roach } 178aee13b6dSGreg Roach 179aee13b6dSGreg Roach /** 180aee13b6dSGreg Roach * @param Request $request 181b6db7c1fSGreg Roach * @param Tree $tree 182aee13b6dSGreg Roach * 183aee13b6dSGreg Roach * @return RedirectResponse 184aee13b6dSGreg Roach */ 185b6db7c1fSGreg Roach public function postAdminMoveDownAction(Request $request, Tree $tree): RedirectResponse 186c1010edaSGreg Roach { 187aee13b6dSGreg Roach $block_id = (int)$request->get('block_id'); 188aee13b6dSGreg Roach 189aee13b6dSGreg Roach $block_order = Database::prepare( 190aee13b6dSGreg Roach "SELECT block_order FROM `##block` WHERE block_id = :block_id" 191aee13b6dSGreg Roach )->execute([ 192aee13b6dSGreg Roach 'block_id' => $block_id, 193aee13b6dSGreg Roach ])->fetchOne(); 194aee13b6dSGreg Roach 195aee13b6dSGreg Roach $swap_block = Database::prepare( 196aee13b6dSGreg Roach "SELECT block_order, block_id" . 197aee13b6dSGreg Roach " FROM `##block`" . 198aee13b6dSGreg Roach " WHERE block_order=(" . 199aee13b6dSGreg Roach " SELECT MIN(block_order) FROM `##block` WHERE block_order > :block_order AND module_name = :module_name_1" . 200aee13b6dSGreg Roach " ) AND module_name = :module_name_2" . 201aee13b6dSGreg Roach " LIMIT 1" 202aee13b6dSGreg Roach )->execute([ 203aee13b6dSGreg Roach 'block_order' => $block_order, 204aee13b6dSGreg Roach 'module_name_1' => $this->getName(), 205aee13b6dSGreg Roach 'module_name_2' => $this->getName(), 206aee13b6dSGreg Roach ])->fetchOneRow(); 207aee13b6dSGreg Roach 208aee13b6dSGreg Roach if ($swap_block !== null) { 209aee13b6dSGreg Roach Database::prepare( 210aee13b6dSGreg Roach "UPDATE `##block` SET block_order = :block_order WHERE block_id = :block_id" 211aee13b6dSGreg Roach )->execute([ 212aee13b6dSGreg Roach 'block_order' => $swap_block->block_order, 213aee13b6dSGreg Roach 'block_id' => $block_id, 214aee13b6dSGreg Roach ]); 215aee13b6dSGreg Roach Database::prepare( 216aee13b6dSGreg Roach "UPDATE `##block` SET block_order = :block_order WHERE block_id = :block_id" 217aee13b6dSGreg Roach )->execute([ 218aee13b6dSGreg Roach 'block_order' => $block_order, 219aee13b6dSGreg Roach 'block_id' => $swap_block->block_id, 220aee13b6dSGreg Roach ]); 221aee13b6dSGreg Roach } 222aee13b6dSGreg Roach 223c1010edaSGreg Roach $url = route('module', [ 224c1010edaSGreg Roach 'module' => 'faq', 225c1010edaSGreg Roach 'action' => 'Admin', 226c1010edaSGreg Roach 'ged' => $tree->getName(), 227c1010edaSGreg Roach ]); 228aee13b6dSGreg Roach 229aee13b6dSGreg Roach return new RedirectResponse($url); 230aee13b6dSGreg Roach } 231aee13b6dSGreg Roach 232aee13b6dSGreg Roach /** 233aee13b6dSGreg Roach * @param Request $request 234b6db7c1fSGreg Roach * @param Tree $tree 235aee13b6dSGreg Roach * 236aee13b6dSGreg Roach * @return RedirectResponse 237aee13b6dSGreg Roach */ 238b6db7c1fSGreg Roach public function postAdminMoveUpAction(Request $request, Tree $tree): RedirectResponse 239c1010edaSGreg Roach { 240aee13b6dSGreg Roach $block_id = (int)$request->get('block_id'); 241aee13b6dSGreg Roach 242aee13b6dSGreg Roach $block_order = Database::prepare( 243aee13b6dSGreg Roach "SELECT block_order FROM `##block` WHERE block_id = :block_id" 244aee13b6dSGreg Roach )->execute([ 245aee13b6dSGreg Roach 'block_id' => $block_id, 246aee13b6dSGreg Roach ])->fetchOne(); 247aee13b6dSGreg Roach 248aee13b6dSGreg Roach $swap_block = Database::prepare( 249aee13b6dSGreg Roach "SELECT block_order, block_id" . 250aee13b6dSGreg Roach " FROM `##block`" . 251aee13b6dSGreg Roach " WHERE block_order = (" . 252aee13b6dSGreg Roach " SELECT MAX(block_order) FROM `##block` WHERE block_order < :block_order AND module_name = :module_name_1" . 253aee13b6dSGreg Roach " ) AND module_name = :module_name_2" . 254aee13b6dSGreg Roach " LIMIT 1" 255aee13b6dSGreg Roach )->execute([ 256aee13b6dSGreg Roach 'block_order' => $block_order, 257aee13b6dSGreg Roach 'module_name_1' => $this->getName(), 258aee13b6dSGreg Roach 'module_name_2' => $this->getName(), 259aee13b6dSGreg Roach ])->fetchOneRow(); 260aee13b6dSGreg Roach 261aee13b6dSGreg Roach if ($swap_block !== null) { 262aee13b6dSGreg Roach Database::prepare( 263aee13b6dSGreg Roach "UPDATE `##block` SET block_order = :block_order WHERE block_id = :block_id" 264aee13b6dSGreg Roach )->execute([ 265aee13b6dSGreg Roach 'block_order' => $swap_block->block_order, 266aee13b6dSGreg Roach 'block_id' => $block_id, 267aee13b6dSGreg Roach ]); 268aee13b6dSGreg Roach Database::prepare( 269aee13b6dSGreg Roach "UPDATE `##block` SET block_order = :block_order WHERE block_id = :block_id" 270aee13b6dSGreg Roach )->execute([ 271aee13b6dSGreg Roach 'block_order' => $block_order, 272aee13b6dSGreg Roach 'block_id' => $swap_block->block_id, 273aee13b6dSGreg Roach ]); 274aee13b6dSGreg Roach } 275aee13b6dSGreg Roach 276c1010edaSGreg Roach $url = route('module', [ 277c1010edaSGreg Roach 'module' => 'faq', 278c1010edaSGreg Roach 'action' => 'Admin', 279c1010edaSGreg Roach 'ged' => $tree->getName(), 280c1010edaSGreg Roach ]); 281aee13b6dSGreg Roach 282aee13b6dSGreg Roach return new RedirectResponse($url); 283aee13b6dSGreg Roach } 284aee13b6dSGreg Roach 285aee13b6dSGreg Roach /** 286aee13b6dSGreg Roach * @param Request $request 287b6db7c1fSGreg Roach * @param Tree $tree 288aee13b6dSGreg Roach * 289aee13b6dSGreg Roach * @return Response 290aee13b6dSGreg Roach */ 291b6db7c1fSGreg Roach public function getAdminEditAction(Request $request, Tree $tree): Response 292c1010edaSGreg Roach { 293aee13b6dSGreg Roach $this->layout = 'layouts/administration'; 294aee13b6dSGreg Roach 295aee13b6dSGreg Roach $block_id = (int)$request->get('block_id'); 296aee13b6dSGreg Roach 297aee13b6dSGreg Roach if ($block_id === 0) { 298aee13b6dSGreg Roach // Creating a new faq 299aee13b6dSGreg Roach $header = ''; 300aee13b6dSGreg Roach $faqbody = ''; 301aee13b6dSGreg Roach $block_order = Database::prepare( 302aee13b6dSGreg Roach "SELECT IFNULL(MAX(block_order)+1, 0) FROM `##block` WHERE module_name = :module_name" 303aee13b6dSGreg Roach )->execute([ 304aee13b6dSGreg Roach 'module_name' => $this->getName(), 305aee13b6dSGreg Roach ])->fetchOne(); 306aee13b6dSGreg Roach $languages = []; 307aee13b6dSGreg Roach 308aee13b6dSGreg Roach $title = I18N::translate('Add an FAQ'); 309aee13b6dSGreg Roach } else { 310aee13b6dSGreg Roach // Editing an existing faq 311aee13b6dSGreg Roach $header = $this->getBlockSetting($block_id, 'header'); 312aee13b6dSGreg Roach $faqbody = $this->getBlockSetting($block_id, 'faqbody'); 313aee13b6dSGreg Roach $block_order = Database::prepare( 314aee13b6dSGreg Roach "SELECT block_order FROM `##block` WHERE block_id = :block_id" 315aee13b6dSGreg Roach )->execute(['block_id' => $block_id])->fetchOne(); 316aee13b6dSGreg Roach $languages = explode(',', $this->getBlockSetting($block_id, 'languages')); 317aee13b6dSGreg Roach 318aee13b6dSGreg Roach $title = I18N::translate('Edit the FAQ'); 319aee13b6dSGreg Roach } 320aee13b6dSGreg Roach 321aee13b6dSGreg Roach // @TODO enable CKEDITOR 322aee13b6dSGreg Roach 323aee13b6dSGreg Roach return $this->viewResponse('modules/faq/edit', [ 324aee13b6dSGreg Roach 'block_id' => $block_id, 325aee13b6dSGreg Roach 'block_order' => $block_order, 326aee13b6dSGreg Roach 'header' => $header, 327aee13b6dSGreg Roach 'faqbody' => $faqbody, 328aee13b6dSGreg Roach 'languages' => $languages, 329aee13b6dSGreg Roach 'title' => $title, 330aee13b6dSGreg Roach 'tree' => $tree, 331aee13b6dSGreg Roach 'tree_names' => Tree::getNameList(), 332aee13b6dSGreg Roach ]); 333aee13b6dSGreg Roach } 334aee13b6dSGreg Roach 335aee13b6dSGreg Roach /** 336aee13b6dSGreg Roach * @param Request $request 337b6db7c1fSGreg Roach * @param Tree $tree 338aee13b6dSGreg Roach * 339aee13b6dSGreg Roach * @return RedirectResponse 340aee13b6dSGreg Roach */ 341b6db7c1fSGreg Roach public function postAdminEditAction(Request $request, Tree $tree): RedirectResponse 342c1010edaSGreg Roach { 343aee13b6dSGreg Roach $block_id = (int)$request->get('block_id'); 344aee13b6dSGreg Roach $faqbody = $request->get('faqbody', ''); 345aee13b6dSGreg Roach $header = $request->get('header', ''); 346aee13b6dSGreg Roach $languages = $request->get('languages', []); 347aee13b6dSGreg Roach 348aee13b6dSGreg Roach if ($block_id !== 0) { 349aee13b6dSGreg Roach Database::prepare( 350aee13b6dSGreg Roach "UPDATE `##block` SET gedcom_id = NULLIF(:tree_id, '0'), block_order = :block_order WHERE block_id = :block_id" 351aee13b6dSGreg Roach )->execute([ 352aee13b6dSGreg Roach 'tree_id' => Filter::postInteger('gedcom_id'), 353aee13b6dSGreg Roach 'block_order' => Filter::postInteger('block_order'), 354aee13b6dSGreg Roach 'block_id' => $block_id, 355aee13b6dSGreg Roach ]); 356aee13b6dSGreg Roach } else { 357aee13b6dSGreg Roach Database::prepare( 358aee13b6dSGreg Roach "INSERT INTO `##block` (gedcom_id, module_name, block_order) VALUES (NULLIF(:tree_id, '0'), :module_name, :block_order)" 359aee13b6dSGreg Roach )->execute([ 360aee13b6dSGreg Roach 'tree_id' => Filter::postInteger('gedcom_id'), 361aee13b6dSGreg Roach 'module_name' => $this->getName(), 362aee13b6dSGreg Roach 'block_order' => Filter::postInteger('block_order'), 363aee13b6dSGreg Roach ]); 364aee13b6dSGreg Roach 365aee13b6dSGreg Roach $block_id = Database::getInstance()->lastInsertId(); 366aee13b6dSGreg Roach } 367aee13b6dSGreg Roach 368aee13b6dSGreg Roach $this->setBlockSetting($block_id, 'faqbody', $faqbody); 369aee13b6dSGreg Roach $this->setBlockSetting($block_id, 'header', $header); 370aee13b6dSGreg Roach $this->setBlockSetting($block_id, 'languages', implode(',', $languages)); 371aee13b6dSGreg Roach 372c1010edaSGreg Roach $url = route('module', [ 373c1010edaSGreg Roach 'module' => 'faq', 374c1010edaSGreg Roach 'action' => 'Admin', 375c1010edaSGreg Roach 'ged' => $tree->getName(), 376c1010edaSGreg Roach ]); 377aee13b6dSGreg Roach 378aee13b6dSGreg Roach return new RedirectResponse($url); 379aee13b6dSGreg Roach } 380aee13b6dSGreg Roach 381b998dbceSGreg Roach /** 382b998dbceSGreg Roach * @param Request $request 383b6db7c1fSGreg Roach * @param Tree $tree 384b998dbceSGreg Roach * 385b998dbceSGreg Roach * @return Response 386b998dbceSGreg Roach */ 387b6db7c1fSGreg Roach public function getShowAction(Request $request, Tree $tree): Response 388c1010edaSGreg Roach { 389aee13b6dSGreg Roach $faqs = Database::prepare( 390aee13b6dSGreg Roach "SELECT block_id, bs1.setting_value AS header, bs2.setting_value AS body, bs3.setting_value AS languages" . 391aee13b6dSGreg Roach " FROM `##block` b" . 392aee13b6dSGreg Roach " JOIN `##block_setting` bs1 USING (block_id)" . 393aee13b6dSGreg Roach " JOIN `##block_setting` bs2 USING (block_id)" . 394aee13b6dSGreg Roach " JOIN `##block_setting` bs3 USING (block_id)" . 395aee13b6dSGreg Roach " WHERE module_name = :module_name" . 396aee13b6dSGreg Roach " AND bs1.setting_name = 'header'" . 397aee13b6dSGreg Roach " AND bs2.setting_name = 'faqbody'" . 398aee13b6dSGreg Roach " AND bs3.setting_name = 'languages'" . 399aee13b6dSGreg Roach " AND IFNULL(gedcom_id, :tree_id_1) = :tree_id_2" . 400aee13b6dSGreg Roach " ORDER BY block_order" 401aee13b6dSGreg Roach )->execute([ 402aee13b6dSGreg Roach 'module_name' => $this->getName(), 403aee13b6dSGreg Roach 'tree_id_1' => $tree->getTreeId(), 404aee13b6dSGreg Roach 'tree_id_2' => $tree->getTreeId(), 405aee13b6dSGreg Roach ])->fetchAll(); 406aee13b6dSGreg Roach 4078de50a4eSGreg Roach // Filter foreign languages. 408*492c7072SGreg Roach $faqs = array_filter($faqs, function (stdClass $faq): bool { 4098de50a4eSGreg Roach return $faq->languages === '' || in_array(WT_LOCALE, explode(',', $faq->languages)); 4108de50a4eSGreg Roach }); 411aee13b6dSGreg Roach 412aee13b6dSGreg Roach return $this->viewResponse('modules/faq/show', [ 4138de50a4eSGreg Roach 'faqs' => $faqs, 414aee13b6dSGreg Roach 'title' => I18N::translate('Frequently asked questions'), 4158de50a4eSGreg Roach 'tree' => $tree, 416aee13b6dSGreg Roach ]); 417aee13b6dSGreg Roach } 4188c2e8227SGreg Roach} 419