1<?php 2namespace Fisharebest\Webtrees; 3 4/** 5 * webtrees: online genealogy 6 * Copyright (C) 2015 webtrees development team 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19/** 20 * Class ReviewChangesModule 21 */ 22class ReviewChangesModule extends AbstractModule implements ModuleBlockInterface { 23 /** {@inheritdoc} */ 24 public function getTitle() { 25 return /* I18N: Name of a module */ I18N::translate('Pending changes'); 26 } 27 28 /** {@inheritdoc} */ 29 public function getDescription() { 30 return /* I18N: Description of the “Pending changes” module */ I18N::translate('A list of changes that need moderator approval, and email notifications.'); 31 } 32 33 /** {@inheritdoc} */ 34 public function getBlock($block_id, $template = true, $cfg = null) { 35 global $ctype, $WT_TREE; 36 37 $sendmail = $this->getBlockSetting($block_id, 'sendmail', '1'); 38 $days = $this->getBlockSetting($block_id, 'days', '1'); 39 $block = $this->getBlockSetting($block_id, 'block', '1'); 40 41 if ($cfg) { 42 foreach (array('days', 'sendmail', 'block') as $name) { 43 if (array_key_exists($name, $cfg)) { 44 $$name = $cfg[$name]; 45 } 46 } 47 } 48 49 $changes = Database::prepare( 50 "SELECT 1" . 51 " FROM `##change`" . 52 " WHERE status='pending'" . 53 " LIMIT 1" 54 )->fetchOne(); 55 56 if ($changes && $sendmail == 'yes') { 57 // There are pending changes - tell moderators/managers/administrators about them. 58 if (WT_TIMESTAMP - Site::getPreference('LAST_CHANGE_EMAIL') > (60 * 60 * 24 * $days)) { 59 // Which users have pending changes? 60 foreach (User::all() as $user) { 61 if ($user->getPreference('contactmethod') !== 'none') { 62 foreach (Tree::getAll() as $tree) { 63 if ($tree->hasPendingEdit() && Auth::isManager($tree, $user)) { 64 I18N::init($user->getPreference('language')); 65 Mail::systemMessage( 66 $tree, 67 $user, 68 I18N::translate('Pending changes'), 69 I18N::translate('There are pending changes for you to moderate.') . 70 Mail::EOL . Mail::EOL . 71 '<a href="' . WT_BASE_URL . 'index.php?ged=' . $WT_TREE->getNameUrl() . '">' . WT_BASE_URL . 'index.php?ged=' . $WT_TREE->getNameUrl() . '</a>' 72 ); 73 I18N::init(WT_LOCALE); 74 } 75 } 76 } 77 } 78 Site::setPreference('LAST_CHANGE_EMAIL', WT_TIMESTAMP); 79 } 80 } 81 if (Auth::isEditor($WT_TREE) && $WT_TREE->hasPendingEdit()) { 82 $id = $this->getName() . $block_id; 83 $class = $this->getName() . '_block'; 84 if ($ctype === 'user' || Auth::isManager($WT_TREE)) { 85 $title = '<a class="icon-admin" title="' . I18N::translate('Configure') . '" href="block_edit.php?block_id=' . $block_id . '&ged=' . $WT_TREE->getNameHtml() . '&ctype=' . $ctype . '"></a>'; 86 } else { 87 $title = ''; 88 } 89 $title .= $this->getTitle(); 90 91 $content = ''; 92 if (Auth::isModerator($WT_TREE)) { 93 $content .= "<a href=\"#\" onclick=\"window.open('edit_changes.php','_blank', chan_window_specs); return false;\">" . I18N::translate('There are pending changes for you to moderate.') . "</a><br>"; 94 } 95 if ($sendmail == "yes") { 96 $content .= I18N::translate('Last email reminder was sent ') . format_timestamp(Site::getPreference('LAST_CHANGE_EMAIL')) . "<br>"; 97 $content .= I18N::translate('Next email reminder will be sent after ') . format_timestamp(Site::getPreference('LAST_CHANGE_EMAIL') + (60 * 60 * 24 * $days)) . "<br><br>"; 98 } 99 $content .= '<ul>'; 100 $changes = Database::prepare( 101 "SELECT xref" . 102 " FROM `##change`" . 103 " WHERE status='pending'" . 104 " AND gedcom_id=?" . 105 " GROUP BY xref" 106 )->execute(array($WT_TREE->getTreeId()))->fetchAll(); 107 foreach ($changes as $change) { 108 $record = GedcomRecord::getInstance($change->xref, $WT_TREE); 109 if ($record->canShow()) { 110 $content .= '<li><a href="' . $record->getHtmlUrl() . '">' . $record->getFullName() . '</a></li>'; 111 } 112 } 113 $content .= '</ul>'; 114 115 if ($template) { 116 if ($block) { 117 $class .= ' small_inner_block'; 118 } 119 120 return Theme::theme()->formatBlock($id, $title, $class, $content); 121 } else { 122 return $content; 123 } 124 } 125 } 126 127 /** {@inheritdoc} */ 128 public function loadAjax() { 129 return false; 130 } 131 132 /** {@inheritdoc} */ 133 public function isUserBlock() { 134 return true; 135 } 136 137 /** {@inheritdoc} */ 138 public function isGedcomBlock() { 139 return true; 140 } 141 142 /** {@inheritdoc} */ 143 public function configureBlock($block_id) { 144 if (Filter::postBool('save') && Filter::checkCsrf()) { 145 $this->setBlockSetting($block_id, 'days', Filter::postInteger('num', 1, 180, 1)); 146 $this->setBlockSetting($block_id, 'sendmail', Filter::postBool('sendmail')); 147 $this->setBlockSetting($block_id, 'block', Filter::postBool('block')); 148 } 149 150 $sendmail = $this->getBlockSetting($block_id, 'sendmail', '1'); 151 $days = $this->getBlockSetting($block_id, 'days', '1'); 152 $block = $this->getBlockSetting($block_id, 'block', '1'); 153 154 ?> 155 <tr> 156 <td colspan="2"> 157 <?php echo I18N::translate('This block will show editors a list of records with pending changes that need to be approved by a moderator. It also generates daily emails to moderators whenever pending changes exist.'); ?> 158 </td> 159 </tr> 160 161 <?php 162 echo '<tr><td class="descriptionbox wrap width33">'; 163 echo I18N::translate('Send out reminder emails?'); 164 echo '</td><td class="optionbox">'; 165 echo edit_field_yes_no('sendmail', $sendmail); 166 echo '<br>'; 167 echo I18N::translate('Reminder email frequency (days)') . " <input type='text' name='days' value='" . $days . "' size='2'>"; 168 echo '</td></tr>'; 169 170 echo '<tr><td class="descriptionbox wrap width33">'; 171 echo /* I18N: label for a yes/no option */ I18N::translate('Add a scrollbar when block contents grow'); 172 echo '</td><td class="optionbox">'; 173 echo edit_field_yes_no('block', $block); 174 echo '</td></tr>'; 175 } 176} 177