1<?php 2/** 3 * webtrees: online genealogy 4 * Copyright (C) 2018 webtrees development team 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16namespace Fisharebest\Webtrees\Module; 17 18use Fisharebest\Webtrees\Auth; 19use Fisharebest\Webtrees\Database; 20use Fisharebest\Webtrees\Filter; 21use Fisharebest\Webtrees\GedcomRecord; 22use Fisharebest\Webtrees\I18N; 23use Fisharebest\Webtrees\Tree; 24 25/** 26 * Class ResearchTaskModule 27 */ 28class ResearchTaskModule extends AbstractModule implements ModuleBlockInterface { 29 const DEFAULT_SHOW_OTHER = '1'; 30 const DEFAULT_SHOW_UNASSIGNED = '1'; 31 const DEFAULT_SHOW_FUTURE = '1'; 32 const DEFAULT_BLOCK = '1'; 33 34 /** {@inheritdoc} */ 35 public function getTitle() { 36 return /* I18N: Name of a module. Tasks that need further research. */ I18N::translate('Research tasks'); 37 } 38 39 /** {@inheritdoc} */ 40 public function getDescription() { 41 return /* I18N: Description of “Research tasks” module */ I18N::translate('A list of tasks and activities that are linked to the family tree.'); 42 } 43 44 /** 45 * Generate the HTML content of this block. 46 * 47 * @param Tree $tree 48 * @param int $block_id 49 * @param bool $template 50 * @param string[] $cfg 51 * 52 * @return string 53 */ 54 public function getBlock(Tree $tree, int $block_id, bool $template = true, array $cfg = []): string { 55 global $ctype; 56 57 $show_other = $this->getBlockSetting($block_id, 'show_other', self::DEFAULT_SHOW_OTHER); 58 $show_unassigned = $this->getBlockSetting($block_id, 'show_unassigned', self::DEFAULT_SHOW_UNASSIGNED); 59 $show_future = $this->getBlockSetting($block_id, 'show_future', self::DEFAULT_SHOW_FUTURE); 60 61 extract($cfg, EXTR_OVERWRITE); 62 63 $end_jd = $show_future ? 99999999 : WT_CLIENT_JD; 64 65 $xrefs = Database::prepare( 66 "SELECT DISTINCT d_gid FROM `##dates`" . 67 " WHERE d_file = :tree_id AND d_fact = '_TODO' AND d_julianday1 < :jd" 68 )->execute([ 69 'tree_id' => $tree->getTreeId(), 70 'jd' => $end_jd, 71 ])->fetchOneColumn(); 72 73 $records = array_map(function ($xref) use ($tree) { 74 return GedcomRecord::getInstance($xref, $tree); 75 }, $xrefs); 76 77 $tasks = []; 78 79 foreach ($records as $record) { 80 foreach ($record->getFacts('_TODO') as $task) { 81 $user_name = $task->getAttribute('_WT_USER'); 82 83 if ($user_name === Auth::user()->getUserName() || empty($user_name) && $show_unassigned || !empty($user_name) && $show_other) { 84 $tasks[] = $task; 85 } 86 } 87 } 88 89 if (empty($records)) { 90 $content = '<p>' . I18N::translate('There are no research tasks in this family tree.') . '</p>'; 91 } else { 92 $content = view('blocks/research-tasks', ['tasks' => $tasks]); 93 } 94 95 if ($template) { 96 if ($ctype === 'gedcom' && Auth::isManager($tree)) { 97 $config_url = route('tree-page-block-edit', ['block_id' => $block_id, 'ged' => $tree->getName()]); 98 } elseif ($ctype === 'user' && Auth::check()) { 99 $config_url = route('user-page-block-edit', ['block_id' => $block_id, 'ged' => $tree->getName()]); 100 } else { 101 $config_url = ''; 102 } 103 104 return view('blocks/template', [ 105 'block' => str_replace('_', '-', $this->getName()), 106 'id' => $block_id, 107 'config_url' => $config_url, 108 'title' => $this->getTitle(), 109 'content' => $content, 110 ]); 111 } else { 112 return $content; 113 } 114 } 115 116 /** {@inheritdoc} */ 117 public function loadAjax(): bool { 118 return false; 119 } 120 121 /** {@inheritdoc} */ 122 public function isUserBlock(): bool { 123 return true; 124 } 125 126 /** {@inheritdoc} */ 127 public function isGedcomBlock(): bool { 128 return true; 129 } 130 131 /** 132 * An HTML form to edit block settings 133 * 134 * @param Tree $tree 135 * @param int $block_id 136 * 137 * @return void 138 */ 139 public function configureBlock(Tree $tree, int $block_id) { 140 if ($_SERVER['REQUEST_METHOD'] === 'POST') { 141 $this->setBlockSetting($block_id, 'show_other', Filter::postBool('show_other')); 142 $this->setBlockSetting($block_id, 'show_unassigned', Filter::postBool('show_unassigned')); 143 $this->setBlockSetting($block_id, 'show_future', Filter::postBool('show_future')); 144 145 return; 146 } 147 148 $show_other = $this->getBlockSetting($block_id, 'show_other', self::DEFAULT_SHOW_OTHER); 149 $show_unassigned = $this->getBlockSetting($block_id, 'show_unassigned', self::DEFAULT_SHOW_UNASSIGNED); 150 $show_future = $this->getBlockSetting($block_id, 'show_future', self::DEFAULT_SHOW_FUTURE); 151 152 echo view('blocks/research-tasks-config', [ 153 'show_future' => $show_future, 154 'show_other' => $show_other, 155 'show_unassigned' => $show_unassigned, 156 ]); 157 158 } 159} 160