/** * Get a list of all active (enabled) modules. * * @return AbstractModule[] */ private static function getActiveModules() { /** @var AbstractModule[] - Only query the database once. */ static $modules; if ($modules === null) { $module_names = Database::prepare("SELECT SQL_CACHE module_name FROM `##module` WHERE status = 'enabled'")->fetchOneColumn(); $modules = array(); foreach ($module_names as $module_name) { try { $module = (include WT_ROOT . WT_MODULES_DIR . $module_name . '/module.php'); if ($module instanceof AbstractModule) { $modules[$module->getName()] = $module; } else { throw new \Exception(); } } catch (\Exception $ex) { // The module has been deleted or is broken? Disable it. Log::addConfigurationLog("Module {$module_name} is missing or broken - disabling it"); Database::prepare("UPDATE `##module` SET status = 'disabled' WHERE module_name = :module_name")->execute(array('module_name' => $module_name)); } } } return $modules; }
/** * Set the tree’s user-configuration settings. * * @param User $user * @param string $setting_name * @param string $setting_value * * @return $this */ public function setUserPreference(User $user, $setting_name, $setting_value) { if ($this->getUserPreference($user, $setting_name) !== $setting_value) { // Update the database if ($setting_value === null) { Database::prepare("DELETE FROM `##user_gedcom_setting` WHERE gedcom_id = :tree_id AND user_id = :user_id AND setting_name = :setting_name")->execute(array('tree_id' => $this->tree_id, 'user_id' => $user->getUserId(), 'setting_name' => $setting_name)); } else { Database::prepare("REPLACE INTO `##user_gedcom_setting` (user_id, gedcom_id, setting_name, setting_value) VALUES (:user_id, :tree_id, :setting_name, LEFT(:setting_value, 255))")->execute(array('user_id' => $user->getUserId(), 'tree_id' => $this->tree_id, 'setting_name' => $setting_name, 'setting_value' => $setting_value)); } // Update our cache $this->user_preferences[$user->getUserId()][$setting_name] = $setting_value; // Audit log of changes Log::addConfigurationLog('Tree setting "' . $setting_name . '" set to "' . $setting_value . '" for user "' . $user->getUserName() . '"', $this); } return $this; }
public function modAction($mod_action) { switch ($mod_action) { case 'admin_config': if (Filter::postBool('save')) { $this->setSetting('FRL_PLUGINS', serialize(Filter::post('NEW_FRL_PLUGINS'))); Log::addConfigurationLog($this->getTitle() . ' config updated'); } $template = new AdminTemplate(); return $template->pageContent(); case 'admin_reset': Database::prepare("DELETE FROM `##module_setting` WHERE setting_name LIKE 'FRL%'")->execute(); Log::addConfigurationLog($this->getTitle() . ' reset to default values'); header('Location: ' . $this->getConfigLink()); break; default: http_response_code(404); break; } }
/** * {inhericDoc} * @see \MyArtJaub\Webtrees\Module\AdminTasks\Model\TaskProviderInterface::deleteTask() */ public function deleteTask($task_name) { try { Database::beginTransaction(); Database::prepare('DELETE FROM `##maj_admintasks` WHERE majat_name= :task_name')->execute(array('task_name' => $task_name)); Database::prepare('DELETE FROM `##gedcom_setting` WHERE setting_name LIKE :setting_name')->execute(array('setting_name' => 'MAJ_AT_' . $task_name . '%')); Database::commit(); Log::addConfigurationLog('Admin Task ' . $task_name . ' has been deleted from disk - deleting it from DB'); return true; } catch (\Exception $ex) { Database::rollback(); Log::addErrorLog('An error occurred while deleting Admin Task ' . $task_name . '. Exception: ' . $ex->getMessage()); return false; } }
/** {@inheritdoc} */ public function modAction($mod_action) { Database::updateSchema(self::SCHEMA_MIGRATION_PREFIX, self::SCHEMA_SETTING_NAME, self::SCHEMA_TARGET_VERSION); switch ($mod_action) { case 'admin_config': $template = new AdminTemplate(); return $template->pageContent(); case 'admin_search': // new settings $surname = Filter::post('SURNAME'); $pid = Filter::post('PID'); if ($surname) { $soundex_std = Filter::postBool('soundex_std'); $soundex_dm = Filter::postBool('soundex_dm'); $indis = $this->module()->indisArray($surname, $soundex_std, $soundex_dm); usort($indis, 'Fisharebest\\Webtrees\\Individual::compareBirthDate'); if (isset($indis) && count($indis) > 0) { $pid = $indis[0]->getXref(); } else { $result['error'] = I18N::translate('Error: The surname you entered doesn’t exist in this tree.'); } } if (isset($pid)) { $FTV_SETTINGS = unserialize($this->getSetting('FTV_SETTINGS')); if ($this->module()->searchArray($this->module()->searchArray($FTV_SETTINGS, 'TREE', Filter::getInteger('tree')), 'PID', $pid)) { if ($surname) { $result['error'] = I18N::translate('Error: The root person belonging to this surname already exists'); } else { $result['error'] = I18N::translate('Error: A root person with ID %s already exists', $pid); } } else { $record = Individual::getInstance($pid, $this->tree); if ($record) { $root = $record->getFullName() . ' (' . $record->getLifeSpan() . ')'; $title = $this->module()->getPageLink($pid); $result = array('access_level' => '2', 'pid' => $pid, 'root' => $root, 'sort' => count($this->module()->searchArray($FTV_SETTINGS, 'TREE', Filter::getInteger('tree'))) + 1, 'surname' => $this->module()->getSurname($pid), 'title' => $title, 'tree' => Filter::getInteger('tree')); } else { if (empty($result['error'])) { $result['error'] = I18N::translate('Error: A person with ID %s does not exist in this tree', $pid); } } } } echo json_encode($result); break; case 'admin_add': $FTV_SETTINGS = unserialize($this->getSetting('FTV_SETTINGS')); $NEW_FTV_SETTINGS = $FTV_SETTINGS; $NEW_FTV_SETTINGS[] = array('TREE' => Filter::getInteger('tree'), 'SURNAME' => Filter::post('surname'), 'PID' => Filter::post('pid'), 'ACCESS_LEVEL' => Filter::postInteger('access_level'), 'SORT' => Filter::postInteger('sort')); $this->setSetting('FTV_SETTINGS', serialize(array_values($NEW_FTV_SETTINGS))); Log::addConfigurationLog($this->getTitle() . ' config updated'); break; case 'admin_update': $FTV_SETTINGS = unserialize($this->getSetting('FTV_SETTINGS')); $new_surname = Filter::postArray('surname'); $new_access_level = Filter::postArray('access_level'); $new_sort = Filter::postArray('sort'); foreach ($new_surname as $key => $new_surname) { $FTV_SETTINGS[$key]['SURNAME'] = $new_surname; } foreach ($new_access_level as $key => $new_access_level) { $FTV_SETTINGS[$key]['ACCESS_LEVEL'] = $new_access_level; } foreach ($new_sort as $key => $new_sort) { $FTV_SETTINGS[$key]['SORT'] = $new_sort; } $NEW_FTV_SETTINGS = $this->module()->sortArray($FTV_SETTINGS, 'SORT'); $this->setSetting('FTV_SETTINGS', serialize($NEW_FTV_SETTINGS)); break; case 'admin_save': $FTV_OPTIONS = unserialize($this->getSetting('FTV_OPTIONS')); $FTV_OPTIONS[Filter::getInteger('tree')] = Filter::postArray('NEW_FTV_OPTIONS'); $this->setSetting('FTV_OPTIONS', serialize($FTV_OPTIONS)); Log::addConfigurationLog($this->getTitle() . ' config updated'); // the cache has to be recreated because the image options could have been changed $this->module()->emptyCache(); break; case 'admin_reset': $FTV_OPTIONS = unserialize($this->getSetting('FTV_OPTIONS')); unset($FTV_OPTIONS[Filter::getInteger('tree')]); $this->setSetting('FTV_OPTIONS', serialize($FTV_OPTIONS)); Log::addConfigurationLog($this->getTitle() . ' options set to default'); break; case 'admin_delete': $FTV_SETTINGS = unserialize($this->getSetting('FTV_SETTINGS')); unset($FTV_SETTINGS[Filter::getInteger('key')]); $this->setSetting('FTV_SETTINGS', serialize($FTV_SETTINGS)); Log::addConfigurationLog($this->getTitle() . ' item deleted'); break; case 'page': $template = new PageTemplate(); return $template->pageContent(); // See mediafirewall.php // See mediafirewall.php case 'thumbnail': $mid = Filter::get('mid', WT_REGEX_XREF); $media = Media::getInstance($mid, $this->tree); $mimetype = $media->mimeType(); $cache_filename = $this->module()->cacheFileName($media); $filetime = filemtime($cache_filename); $filetimeHeader = gmdate('D, d M Y H:i:s', $filetime) . ' GMT'; $expireOffset = 3600 * 24 * 7; // tell browser to cache this image for 7 days $expireHeader = gmdate('D, d M Y H:i:s', WT_TIMESTAMP + $expireOffset) . ' GMT'; $etag = $media->getEtag(); $filesize = filesize($cache_filename); // parse IF_MODIFIED_SINCE header from client $if_modified_since = 'x'; if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { $if_modified_since = preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']); } // parse IF_NONE_MATCH header from client $if_none_match = 'x'; if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) { $if_none_match = str_replace('"', '', $_SERVER['HTTP_IF_NONE_MATCH']); } // add caching headers. allow browser to cache file, but not proxy header('Last-Modified: ' . $filetimeHeader); header('ETag: "' . $etag . '"'); header('Expires: ' . $expireHeader); header('Cache-Control: max-age=' . $expireOffset . ', s-maxage=0, proxy-revalidate'); // if this file is already in the user’s cache, don’t resend it // first check if the if_modified_since param matches if ($if_modified_since === $filetimeHeader) { // then check if the etag matches if ($if_none_match === $etag) { http_response_code(304); return; } } // send headers for the image header('Content-Type: ' . $mimetype); header('Content-Disposition: filename="' . basename($cache_filename) . '"'); header('Content-Length: ' . $filesize); // Some servers disable fpassthru() and readfile() if (function_exists('readfile')) { readfile($cache_filename); } else { $fp = fopen($cache_filename, 'rb'); if (function_exists('fpassthru')) { fpassthru($fp); } else { while (!feof($fp)) { echo fread($fp, 65536); } } fclose($fp); } break; case 'show_pdf': $template = new PdfTemplate(); return $template->pageBody(); case 'pdf_data': $template = new PdfTemplate(); return $template->pageData(); case 'pdf_thumb_data': $xref = Filter::get('mid'); $mediaobject = Media::getInstance($xref, $this->tree); $thumb = Filter::get('thumb'); if ($thumb === '2') { // Fancy thumb echo $this->module()->cacheFileName($mediaobject); } else { echo $mediaobject->getServerFilename('thumb'); } break; default: http_response_code(404); break; } }
/** * GeoAnalysis@delete */ public function delete() { global $WT_TREE; $controller = new JsonController(); $ga_id = Filter::getInteger('ga_id'); $ga = $this->provider->getGeoAnalysis($ga_id, false); $controller->restrictAccess(true && Auth::isManager($WT_TREE) && $ga); $res = array('geoanalysis' => $ga->getId(), 'error' => null); try { $this->provider->deleteGeoAnalysis($ga); Log::addConfigurationLog('Module ' . $this->module->getName() . ' : Geo Analysis ID "' . $ga->getId() . '" has been deleted.'); } catch (\Exception $ex) { $res['error'] = $ex->getMessage(); Log::addErrorLog('Module ' . $this->module->getName() . ' : Geo Analysis ID "' . $ga->getId() . '" could not be deleted. Error: ' . $ex->getMessage()); } $controller->pageHeader(); if ($res['error']) { http_response_code(500); } $controller->encode($res); }
/** * AdminConfig@generateToken * * Ajax call to generate a new token. Display the token, if generated. * Tokens call only be generated by a site administrator. * */ public function generateToken() { $controller = new AjaxController(); $controller->restrictAccess(Auth::isAdmin()); $token = Functions::generateRandomToken(); $this->module->setSetting('MAJ_AT_FORCE_EXEC_TOKEN', $token); Log::addConfigurationLog($this->module->getTitle() . ' : New token generated.'); $controller->pageHeader(); echo $token; }
/** {@inheritdoc} */ public function modAction($mod_action) { switch ($mod_action) { case 'admin_config': if (Filter::postBool('save') && Filter::checkCsrf()) { $this->setSetting('FTV_PDF_ACCESS_LEVEL', Filter::postInteger('NEW_FTV_PDF_ACCESS_LEVEL')); Log::addConfigurationLog($this->getTitle() . ' config updated'); } $template = new AdminTemplate(); return $template->pageContent(); case 'full_pdf': echo $this->module()->printPage(0); break; case 'write_pdf': $tmp_dir = WT_DATA_DIR . 'ftv_pdf_tmp/'; if (file_exists($tmp_dir)) { File::delete($tmp_dir); } File::mkdir($tmp_dir); $template = new PdfTemplate(); return $template->pageBody(); case 'output_pdf': $file = WT_DATA_DIR . 'ftv_pdf_tmp/' . Filter::get('title') . '.pdf'; if (file_exists($file)) { ob_start(); header('Content-Description: File Transfer'); header('Content-Type: application/pdf'); header('Content-Disposition: attachment; filename="' . basename($file) . '"'); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); ob_clean(); ob_end_flush(); readfile($file); File::delete(dirname($file)); } else { FlashMessages::addMessage(I18N::translate('The file %s could not be created.', basename($file)), 'danger'); Header('Location:' . WT_BASE_URL . 'module.php?mod=fancy_treeview&mod_action=page&rootid=' . Filter::get('rootid') . '&ged=' . Filter::get('ged')); } break; default: http_response_code(404); break; } }
/** * AdminConfig@save */ public function save() { global $WT_TREE; $tmp_contrl = new PageController(); $tmp_contrl->restrictAccess(Auth::isManager($WT_TREE) && Filter::checkCsrf()); $ga_id = Filter::postInteger('ga_id'); $description = Filter::post('description'); $analysislevel = Filter::postInteger('analysislevel'); $use_map = Filter::postBool('use_map'); if ($use_map) { $map_file = base64_decode(Filter::post('map_file')); $map_top_level = Filter::postInteger('map_top_level'); } $use_flags = Filter::postBool('use_flags'); $gen_details = Filter::postInteger('gen_details'); $success = false; if ($ga_id) { $ga = $this->provider->getGeoAnalysis($ga_id, false); if ($ga) { $ga->setTitle($description); $ga->setAnalysisLevel($analysislevel + 1); $options = $ga->getOptions(); if ($options) { $options->setUsingFlags($use_flags); $options->setMaxDetailsInGen($gen_details); if ($use_map) { $options->setMap(new OutlineMap($map_file)); $options->setMapLevel($map_top_level + 1); } else { $options->setMap(null); } } $res = $this->provider->updateGeoAnalysis($ga); if ($res) { FlashMessages::addMessage(I18N::translate('The geographical dispersion analysis “%s” has been successfully updated', $res->getTitle()), 'success'); Log::addConfigurationLog('Module ' . $this->module->getName() . ' : Geo Analysis ID “' . $res->getId() . '” has been updated.'); $ga = $res; $success = true; } else { FlashMessages::addMessage(I18N::translate('An error occured while updating the geographical dispersion analysis “%s”', $ga->getTitle()), 'danger'); Log::addConfigurationLog('Module ' . $this->module->getName() . ' : Geo Analysis ID “' . $ga->getId() . '” could not be updated. See error log.'); } } } else { $ga = $this->provider->createGeoAnalysis($description, $analysislevel + 1, $use_map ? $map_file : null, $use_map ? $map_top_level + 1 : null, $use_flags, $gen_details); if ($ga) { FlashMessages::addMessage(I18N::translate('The geographical dispersion analysis “%s” has been successfully added.', $ga->getTitle()), 'success'); Log::addConfigurationLog('Module ' . $this->module->getName() . ' : Geo Analysis ID “' . $ga->getId() . '” has been added.'); $success = true; } else { FlashMessages::addMessage(I18N::translate('An error occured while adding the geographical dispersion analysis “%s”', $description), 'danger'); Log::addConfigurationLog('Module ' . $this->module->getName() . ' : Geo Analysis “' . $description . '” could not be added. See error log.'); } } $redirection_url = 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig&ged=' . $WT_TREE->getNameUrl(); if (!$success) { if ($ga) { $redirection_url = 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig@edit&ga_id=' . $ga->getId() . '&ged=' . $WT_TREE->getNameUrl(); } else { $redirection_url = 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig@add&ged=' . $WT_TREE->getNameUrl(); } } header('Location: ' . WT_BASE_URL . $redirection_url); }
/** * Task@save */ public function save() { $tmp_contrl = new PageController(); $tmp_contrl->restrictAccess(Auth::isAdmin() && Filter::checkCsrf()); $task_name = Filter::post('task'); $frequency = Filter::postInteger('frequency'); $is_limited = Filter::postInteger('is_limited', 0, 1); $nb_occur = Filter::postInteger('nb_occur'); $task = $this->provider->getTask($task_name, false); $success = false; if ($task) { $task->setFrequency($frequency); if ($is_limited == 1) { $task->setRemainingOccurrences($nb_occur); } else { $task->setRemainingOccurrences(0); } $res = $task->save(); if ($res) { if ($task instanceof MyArtJaub\Webtrees\Module\AdminTasks\Model\ConfigurableTaskInterface) { $res = $task->saveConfig(); if (!$res) { FlashMessages::addMessage(I18N::translate('An error occured while updating the specific settings of administrative task “%s”', $task->getTitle()), 'danger'); Log::addConfigurationLog('Module ' . $this->module->getName() . ' : AdminTask “' . $task->getName() . '” specific settings could not be updated. See error log.'); } } if ($res) { FlashMessages::addMessage(I18N::translate('The administrative task “%s” has been successfully updated', $task->getTitle()), 'success'); Log::addConfigurationLog('Module ' . $this->module->getName() . ' : AdminTask “' . $task->getName() . '” has been updated.'); $success = true; } } else { FlashMessages::addMessage(I18N::translate('An error occured while updating the administrative task “%s”', $task->getTitle()), 'danger'); Log::addConfigurationLog('Module ' . $this->module->getName() . ' : AdminTask “' . $task->getName() . '” could not be updated. See error log.'); } } $redirection_url = 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig'; if (!$success) { $redirection_url = 'module.php?mod=' . $this->module->getName() . '&mod_action=Task@edit&task=' . $task->getName(); } header('Location: ' . WT_BASE_URL . $redirection_url); }