1<?php 2/** 3 * webtrees: online genealogy 4 * Copyright (C) 2019 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; 17 18use Fisharebest\Webtrees\Controller\PageController; 19use Fisharebest\Webtrees\Functions\FunctionsEdit; 20use Fisharebest\Webtrees\Module\AbstractModule; 21use Fisharebest\Webtrees\Module\ModuleBlockInterface; 22use Fisharebest\Webtrees\Module\ModuleChartInterface; 23use Fisharebest\Webtrees\Module\ModuleConfigInterface; 24use Fisharebest\Webtrees\Module\ModuleMenuInterface; 25use Fisharebest\Webtrees\Module\ModuleReportInterface; 26use Fisharebest\Webtrees\Module\ModuleSidebarInterface; 27use Fisharebest\Webtrees\Module\ModuleTabInterface; 28use Fisharebest\Webtrees\Module\ModuleThemeInterface; 29 30define('WT_SCRIPT_NAME', 'admin_modules.php'); 31require 'includes/session.php'; 32 33$controller = new PageController; 34$controller 35 ->restrictAccess(Auth::isAdmin()) 36 ->setPageTitle(I18N::translate('Module administration')); 37 38$modules = Module::getInstalledModules('disabled'); 39$module_status = Database::prepare("SELECT module_name, status FROM `##module`")->fetchAssoc(); 40 41uasort($modules, function (AbstractModule $x, AbstractModule $y) { 42 return I18N::strcasecmp($x->getTitle(), $y->getTitle()); 43}); 44 45if (Filter::post('action') === 'update_mods' && Filter::checkCsrf()) { 46 foreach ($modules as $module) { 47 $new_status = Filter::post('status-' . $module->getName(), '[01]'); 48 if ($new_status !== null) { 49 $new_status = $new_status ? 'enabled' : 'disabled'; 50 $old_status = $module_status[$module->getName()]; 51 if ($new_status !== $old_status) { 52 Database::prepare("UPDATE `##module` SET status=? WHERE module_name=?")->execute(array($new_status, $module->getName())); 53 if ($new_status === 'disabled') { 54 FlashMessages::addMessage(I18N::translate('The module “%s” has been disabled.', $module->getTitle()), 'success'); 55 } else { 56 FlashMessages::addMessage(I18N::translate('The module “%s” has been enabled.', $module->getTitle()), 'success'); 57 } 58 } 59 } 60 } 61 62 header('Location: ' . WT_BASE_URL . 'admin_modules.php'); 63 64 return; 65} 66 67if (Filter::post('action') === 'delete' && Filter::checkCsrf()) { 68 $module_name = Filter::post('module_name'); 69 Database::prepare( 70 "DELETE `##block_setting`" . 71 " FROM `##block_setting`" . 72 " JOIN `##block` USING (block_id)" . 73 " JOIN `##module` USING (module_name)" . 74 " WHERE module_name=?" 75 )->execute(array($module_name)); 76 Database::prepare( 77 "DELETE `##block`" . 78 " FROM `##block`" . 79 " JOIN `##module` USING (module_name)" . 80 " WHERE module_name=?" 81 )->execute(array($module_name)); 82 Database::prepare("DELETE FROM `##module_setting` WHERE module_name=?")->execute(array($module_name)); 83 Database::prepare("DELETE FROM `##module_privacy` WHERE module_name=?")->execute(array($module_name)); 84 Database::prepare("DELETE FROM `##module` WHERE module_name=?")->execute(array($module_name)); 85 86 FlashMessages::addMessage(I18N::translate('The preferences for the module “%s” have been deleted.', $module_name), 'success'); 87 88 header('Location: ' . WT_BASE_URL . 'admin_modules.php'); 89 90 return; 91} 92 93// The module can’t be found on disk? 94// Don't delete it automatically. It may be temporarily missing, after a re-installation, etc. 95foreach ($module_status as $module_name => $status) { 96 if (!array_key_exists($module_name, $modules)) { 97 $html = 98 I18N::translate('Preferences exist for the module “%s”, but this module no longer exists.', '<span dir="ltr">' . $module_name . '</span>') . 99 '<form method="post" class="form-inline">' . 100 Filter::getCsrf() . 101 '<input type="hidden" name="action" value="delete">' . 102 '<input type="hidden" name="module_name" value="' . $module_name . '">' . 103 '<button type="submit" class="btn btn-link">' . I18N::translate('Delete the preferences for this module.') . '</button>' . 104 '</form>'; 105 FlashMessages::addMessage($html, 'warning'); 106 } 107} 108 109$controller 110 ->pageHeader() 111 ->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL) 112 ->addExternalJavascript(WT_DATATABLES_BOOTSTRAP_JS_URL) 113 ->addInlineJavascript(' 114 function reindexMods(id) { 115 jQuery("#" + id + " input").each( 116 function (index, value) { 117 value.value = index+1; 118 }); 119 } 120 jQuery("#installed_table").dataTable( { 121 paging: false, 122 ' . I18N::datatablesI18N() . ', 123 sorting: [[ 1, "asc" ]], 124 columns : [ 125 { sortable: false, class: "center" }, 126 null, 127 null, 128 { class: "center" }, 129 { class: "center" }, 130 { class: "center" }, 131 { class: "center" }, 132 { class: "center" }, 133 { class: "center" }, 134 { class: "center", visible: false } // The Module system does not yet include themes 135 ] 136 }); 137 '); 138 139?> 140<ol class="breadcrumb small"> 141 <li><a href="admin.php"><?php echo I18N::translate('Control panel'); ?></a></li> 142 <li class="active"><?php echo $controller->getPageTitle(); ?></li> 143</ol> 144 145<h1><?php echo $controller->getPageTitle(); ?></h1> 146 147<form method="post" action="<?php echo WT_SCRIPT_NAME; ?>"> 148 <input type="hidden" name="action" value="update_mods"> 149 <?php echo Filter::getCsrf(); ?> 150 <table class="table table-bordered table-hover table-condensed table-module-administration"> 151 <caption class="sr-only"> 152 <?php echo I18N::translate('Module administration'); ?> 153 </caption> 154 <thead> 155 <tr> 156 <th><?php echo I18N::translate('Enabled'); ?></th> 157 <th><?php echo I18N::translate('Module'); ?></th> 158 <th><?php echo I18N::translate('Description'); ?></th> 159 <th class="hidden-xs"><a href="admin_module_menus.php"><?php echo I18N::translate('Menus'); ?></a></th> 160 <th class="hidden-xs"><a href="admin_module_tabs.php"><?php echo I18N::translate('Tabs'); ?></a></th> 161 <th class="hidden-xs"><a href="admin_module_sidebar.php"><?php echo I18N::translate('Sidebars'); ?></a></th> 162 <th class="hidden-xs"><a href="admin_module_blocks.php"><?php echo I18N::translate('Blocks'); ?></a></th> 163 <th class="hidden-xs"><a href="admin_module_charts.php"><?php echo I18N::translate('Charts'); ?></a></th> 164 <th class="hidden-xs"><a href="admin_module_reports.php"><?php echo I18N::translate('Reports'); ?></a></th> 165 <th class="hidden"><?php echo I18N::translate('Themes'); ?></th> 166 </tr> 167 </thead> 168 <tbody> 169 <?php foreach ($modules as $module_name => $module): ?> 170 <tr> 171 <td class="text-center"> 172 <?php echo FunctionsEdit::twoStateCheckbox('status-' . $module->getName(), $module_status[$module_name] === 'enabled') ?> 173 </td> 174 <td> 175 <?php if ($module instanceof ModuleConfigInterface): ?> 176 <a href="<?php echo $module->getConfigLink() ?>"> 177 <?php echo $module->getTitle() ?> <i class="fa fa-cogs"></i> 178 </a> 179 <?php else: ?> 180 <?php echo $module->getTitle() ?> 181 <?php endif; ?> 182 <?php if (!in_array($module->getName(), Module::getCoreModuleNames())): ?> 183 <br> 184 <?php endif; ?> 185 </td> 186 <td> 187 <?php echo '', $module->getDescription() ?> 188 <?php if (!in_array($module->getName(), Module::getCoreModuleNames())): ?> 189 <br> 190 <i class="fa fa-asterisk"></i> 191 <?php echo I18N::translate('Custom module') ?> 192 <?php if ($module::CUSTOM_VERSION): ?> 193 - <?php echo I18N::translate('Version') ?> <?php echo $module::CUSTOM_VERSION ?> 194 <?php endif; ?> 195 <?php if ($module::CUSTOM_WEBSITE): ?> 196 - <a href="<?php echo $module::CUSTOM_WEBSITE ?>"> 197 <?php echo $module::CUSTOM_WEBSITE ?> 198 </a> 199 <?php endif; ?> 200 <?php endif; ?> 201 </td> 202 <td class="text-center text-muted hidden-xs"> 203 <?php if ($module instanceof ModuleMenuInterface): ?> 204 <i class="fa fa-list-ul" title="<?php echo I18N::translate('Menu') ?>"></i> 205 <?php else: ?> 206 - 207 <?php endif; ?> 208 </td> 209 <td class="text-center text-muted hidden-xs"> 210 <?php if ($module instanceof ModuleTabInterface): ?> 211 <i class="fa fa-folder" title="<?php echo I18N::translate('Tab') ?>"></i> 212 <?php else: ?> 213 - 214 <?php endif; ?> 215 </td> 216 <td class="text-center text-muted hidden-xs"> 217 <?php if ($module instanceof ModuleSidebarInterface): ?> 218 <i class="fa fa-th-large" title="<?php echo I18N::translate('Sidebar') ?>"></i> 219 <?php else: ?> 220 - 221 <?php endif; ?> 222 </td> 223 <td class="text-center text-muted hidden-xs"> 224 <?php if ($module instanceof ModuleBlockInterface): ?> 225 <?php if ($module->isUserBlock()): ?> 226 <i class="fa fa-user" title="<?php echo I18N::translate('My page') ?>"></i> 227 <?php endif; ?> 228 <?php if ($module->isUserBlock()): ?> 229 <i class="fa fa-tree" title="<?php echo I18N::translate('Home page') ?>"></i> 230 <?php endif; ?> 231 <?php else: ?> 232 - 233 <?php endif; ?> 234 </td> 235 <td class="text-center text-muted hidden-xs"> 236 <?php if ($module instanceof ModuleChartInterface): ?> 237 <i class="fa fa-share-alt" title="<?php echo I18N::translate('Chart') ?>"></i> 238 <?php else: ?> 239 - 240 <?php endif; ?> 241 </td> 242 <td class="text-center text-muted hidden-xs"> 243 <?php if ($module instanceof ModuleReportInterface): ?> 244 <i class="fa fa-file" title="<?php echo I18N::translate('Report') ?>"></i> 245 <?php else: ?> 246 - 247 <?php endif; ?> 248 </td> 249 <td class="text-center text-muted hidden"> 250 <?php if ($module instanceof ModuleThemeInterface): ?> 251 <i class="fa fa-check" title="<?php echo I18N::translate('Theme') ?>"></i> 252 <?php else: ?> 253 - 254 <?php endif; ?> 255 </td> 256 </tr> 257 <?php endforeach; ?> 258 </tbody> 259 </table> 260 <button class="btn btn-primary" type="submit"> 261 <i class="fa fa-check"></i> 262 <?php echo I18N::translate('save'); ?></button> 263</form> 264