summaryrefslogtreecommitdiff
path: root/app/Module.php
diff options
context:
space:
mode:
Diffstat (limited to 'app/Module.php')
-rw-r--r--app/Module.php1117
1 files changed, 592 insertions, 525 deletions
diff --git a/app/Module.php b/app/Module.php
index a5bd4fa862..8864028681 100644
--- a/app/Module.php
+++ b/app/Module.php
@@ -29,564 +29,631 @@ use League\Flysystem\Exception;
/**
* Functions for managing and maintaining modules.
*/
-class Module {
- // We use a list of core modules to help identify custom ones.
- const CORE_MODULES = [
- 'GEDFact_assistant',
- 'ahnentafel_report',
- 'ancestors_chart',
- 'batch_update',
- 'bdm_report',
- 'birth_report',
- 'cemetery_report',
- 'change_report',
- 'charts',
- 'ckeditor',
- 'clippings',
- 'compact_tree_chart',
- 'death_report',
- 'descendancy',
- 'descendancy_chart',
- 'descendancy_report',
- 'extra_info',
- 'fact_sources',
- 'family_book_chart',
- 'family_group_report',
- 'family_nav',
- 'fan_chart',
- 'faq',
- 'gedcom_block',
- 'gedcom_favorites',
- 'gedcom_news',
- 'gedcom_stats',
- 'hourglass_chart',
- 'html',
- 'individual_ext_report',
- 'individual_report',
- 'lifespans_chart',
- 'lightbox',
- 'logged_in',
- 'login_block',
- 'marriage_report',
- 'media',
- 'missing_facts_report',
- 'notes',
- 'occupation_report',
- 'pedigree_chart',
- 'pedigree_report',
- 'personal_facts',
- 'random_media',
- 'recent_changes',
- 'relationships_chart',
- 'relative_ext_report',
- 'relatives',
- 'review_changes',
- 'sitemap',
- 'sources_tab',
- 'statistics_chart',
- 'stories',
- 'theme_select',
- 'timeline_chart',
- 'todays_events',
- 'todo',
- 'top10_givnnames',
- 'top10_pageviews',
- 'top10_surnames',
- 'tree',
- 'upcoming_events',
- 'user_blog',
- 'user_favorites',
- 'user_messages',
- 'user_welcome',
- 'yahrzeit',
- ];
+class Module
+{
+ // We use a list of core modules to help identify custom ones.
+ const CORE_MODULES = [
+ 'GEDFact_assistant',
+ 'ahnentafel_report',
+ 'ancestors_chart',
+ 'batch_update',
+ 'bdm_report',
+ 'birth_report',
+ 'cemetery_report',
+ 'change_report',
+ 'charts',
+ 'ckeditor',
+ 'clippings',
+ 'compact_tree_chart',
+ 'death_report',
+ 'descendancy',
+ 'descendancy_chart',
+ 'descendancy_report',
+ 'extra_info',
+ 'fact_sources',
+ 'family_book_chart',
+ 'family_group_report',
+ 'family_nav',
+ 'fan_chart',
+ 'faq',
+ 'gedcom_block',
+ 'gedcom_favorites',
+ 'gedcom_news',
+ 'gedcom_stats',
+ 'hourglass_chart',
+ 'html',
+ 'individual_ext_report',
+ 'individual_report',
+ 'lifespans_chart',
+ 'lightbox',
+ 'logged_in',
+ 'login_block',
+ 'marriage_report',
+ 'media',
+ 'missing_facts_report',
+ 'notes',
+ 'occupation_report',
+ 'pedigree_chart',
+ 'pedigree_report',
+ 'personal_facts',
+ 'random_media',
+ 'recent_changes',
+ 'relationships_chart',
+ 'relative_ext_report',
+ 'relatives',
+ 'review_changes',
+ 'sitemap',
+ 'sources_tab',
+ 'statistics_chart',
+ 'stories',
+ 'theme_select',
+ 'timeline_chart',
+ 'todays_events',
+ 'todo',
+ 'top10_givnnames',
+ 'top10_pageviews',
+ 'top10_surnames',
+ 'tree',
+ 'upcoming_events',
+ 'user_blog',
+ 'user_favorites',
+ 'user_messages',
+ 'user_welcome',
+ 'yahrzeit',
+ ];
- /** @var AbstractModule[] */
- private static $modules = [];
+ /** @var AbstractModule[] */
+ private static $modules = [];
- /**
- * Load a module from a file. Since third-party modules may declare classes or functions,
- * we must only load each file once.
- *
- * @param string $file
- *
- * @return AbstractModule|null
- */
- private static function loadModule($file) {
- if (!array_key_exists($file, self::$modules)) {
- self::$modules[$file] = null;
- try {
- $module = include $file;
- if ($module instanceof AbstractModule) {
- self::$modules[$file] = $module;
- }
- } catch (Exception $ex) {
- DebugBar::addThrowable($ex);
+ /**
+ * Load a module from a file. Since third-party modules may declare classes or functions,
+ * we must only load each file once.
+ *
+ * @param string $file
+ *
+ * @return AbstractModule|null
+ */
+ private static function loadModule($file)
+ {
+ if (!array_key_exists($file, self::$modules)) {
+ self::$modules[$file] = null;
+ try {
+ $module = include $file;
+ if ($module instanceof AbstractModule) {
+ self::$modules[$file] = $module;
+ }
+ } catch (Exception $ex) {
+ DebugBar::addThrowable($ex);
- Log::addErrorLog($ex->getMessage());
- }
- }
+ Log::addErrorLog($ex->getMessage());
+ }
+ }
- return self::$modules[$file];
- }
+ return self::$modules[$file];
+ }
- /**
- * Get a list of all core modules. We need to identify
- * third-party during upgrade and on the module admin page.
- *
- * @return string[]
- */
- public static function getCoreModuleNames() {
- return [
- 'GEDFact_assistant',
- 'ahnentafel_report',
- 'ancestors_chart',
- 'batch_update',
- 'bdm_report',
- 'birth_report',
- 'cemetery_report',
- 'change_report',
- 'charts',
- //'ckeditor',
- 'clippings',
- 'compact_tree_chart',
- 'death_report',
- 'descendancy',
- 'descendancy_chart',
- 'descendancy_report',
- 'extra_info',
- 'fact_sources',
- 'families',
- 'family_book_chart',
- 'family_group_report',
- 'family_nav',
- 'fan_chart',
- 'faq',
- 'gedcom_block',
- 'gedcom_favorites',
- 'gedcom_news',
- 'gedcom_stats',
- 'googlemap',
- 'hourglass_chart',
- 'html',
- 'individual_ext_report',
- 'individual_report',
- 'individuals',
- 'lifespans_chart',
- 'lightbox',
- 'logged_in',
- 'login_block',
- 'marriage_report',
- 'media',
- 'missing_facts_report',
- 'notes',
- 'occupation_report',
- 'openstreetmap',
- 'pedigree_chart',
- 'pedigree_report',
- 'personal_facts',
- 'random_media',
- 'recent_changes',
- 'relationships_chart',
- 'relative_ext_report',
- 'relatives',
- 'review_changes',
- 'sitemap',
- 'sources_tab',
- 'statistics_chart',
- 'stories',
- 'theme_select',
- 'timeline_chart',
- 'todays_events',
- 'todo',
- 'top10_givnnames',
- 'top10_pageviews',
- 'top10_surnames',
- 'tree',
- 'upcoming_events',
- 'user_blog',
- 'user_favorites',
- 'user_messages',
- 'user_welcome',
- 'yahrzeit',
- ];
- }
+ /**
+ * Get a list of all core modules. We need to identify
+ * third-party during upgrade and on the module admin page.
+ *
+ * @return string[]
+ */
+ public static function getCoreModuleNames()
+ {
+ return [
+ 'GEDFact_assistant',
+ 'ahnentafel_report',
+ 'ancestors_chart',
+ 'batch_update',
+ 'bdm_report',
+ 'birth_report',
+ 'cemetery_report',
+ 'change_report',
+ 'charts',
+ //'ckeditor',
+ 'clippings',
+ 'compact_tree_chart',
+ 'death_report',
+ 'descendancy',
+ 'descendancy_chart',
+ 'descendancy_report',
+ 'extra_info',
+ 'fact_sources',
+ 'families',
+ 'family_book_chart',
+ 'family_group_report',
+ 'family_nav',
+ 'fan_chart',
+ 'faq',
+ 'gedcom_block',
+ 'gedcom_favorites',
+ 'gedcom_news',
+ 'gedcom_stats',
+ 'googlemap',
+ 'hourglass_chart',
+ 'html',
+ 'individual_ext_report',
+ 'individual_report',
+ 'individuals',
+ 'lifespans_chart',
+ 'lightbox',
+ 'logged_in',
+ 'login_block',
+ 'marriage_report',
+ 'media',
+ 'missing_facts_report',
+ 'notes',
+ 'occupation_report',
+ 'openstreetmap',
+ 'pedigree_chart',
+ 'pedigree_report',
+ 'personal_facts',
+ 'random_media',
+ 'recent_changes',
+ 'relationships_chart',
+ 'relative_ext_report',
+ 'relatives',
+ 'review_changes',
+ 'sitemap',
+ 'sources_tab',
+ 'statistics_chart',
+ 'stories',
+ 'theme_select',
+ 'timeline_chart',
+ 'todays_events',
+ 'todo',
+ 'top10_givnnames',
+ 'top10_pageviews',
+ 'top10_surnames',
+ 'tree',
+ 'upcoming_events',
+ 'user_blog',
+ 'user_favorites',
+ 'user_messages',
+ 'user_welcome',
+ 'yahrzeit',
+ ];
+ }
- /**
- * Get a list of all active (enabled) modules.
- *
- * @return AbstractModule[]
- */
- private static function getActiveModules() {
- /** @var AbstractModule[] - Only query the database once. */
- static $modules;
+ /**
+ * 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 module_name FROM `##module` WHERE status = 'enabled'"
- )->fetchOneColumn();
+ if ($modules === null) {
+ $module_names = Database::prepare(
+ "SELECT module_name FROM `##module` WHERE status = 'enabled'"
+ )->fetchOneColumn();
- $modules = [];
- foreach ($module_names as $module_name) {
- try {
- $module = self::loadModule(WT_ROOT . WT_MODULES_DIR . $module_name . '/module.php');
- if ($module instanceof AbstractModule) {
- $modules[$module->getName()] = $module;
- } else {
- throw new \Exception;
- }
- } catch (\Exception $ex) {
- DebugBar::addThrowable($ex);
+ $modules = [];
+ foreach ($module_names as $module_name) {
+ try {
+ $module = self::loadModule(WT_ROOT . WT_MODULES_DIR . $module_name . '/module.php');
+ if ($module instanceof AbstractModule) {
+ $modules[$module->getName()] = $module;
+ } else {
+ throw new \Exception;
+ }
+ } catch (\Exception $ex) {
+ DebugBar::addThrowable($ex);
- // The module has been deleted or is broken? Disable it.
- Log::addConfigurationLog("Module {$module_name} is missing or broken - disabling it. " . $ex->getMessage(), null);
- Database::prepare(
- "UPDATE `##module` SET status = 'disabled' WHERE module_name = :module_name"
- )->execute([
- 'module_name' => $module_name,
- ]);
- }
- }
- }
+ // The module has been deleted or is broken? Disable it.
+ Log::addConfigurationLog("Module {$module_name} is missing or broken - disabling it. " . $ex->getMessage(), null);
+ Database::prepare(
+ "UPDATE `##module` SET status = 'disabled' WHERE module_name = :module_name"
+ )->execute([
+ 'module_name' => $module_name,
+ ]);
+ }
+ }
+ }
- return $modules;
- }
+ return $modules;
+ }
- /**
- * Get a list of modules which (a) provide a specific function and (b) we have permission to see.
- *
- * We cannot currently use auto-loading for modules, as there may be user-defined
- * modules about which the auto-loader knows nothing.
- *
- * @param Tree $tree
- * @param string $component The type of module, such as "tab", "report" or "menu"
- *
- * @return ModuleBlockInterface[]|ModuleChartInterface[]|ModuleMenuInterface[]|ModuleReportInterface[]|ModuleSidebarInterface[]|ModuleTabInterface[]|ModuleThemeInterface[]
- */
- private static function getActiveModulesByComponent(Tree $tree, $component) {
- $module_names = Database::prepare(
- "SELECT module_name" .
- " FROM `##module`" .
- " JOIN `##module_privacy` USING (module_name)" .
- " WHERE gedcom_id = :tree_id AND component = :component AND status = 'enabled' AND access_level >= :access_level" .
- " ORDER BY CASE component WHEN 'menu' THEN menu_order WHEN 'sidebar' THEN sidebar_order WHEN 'tab' THEN tab_order ELSE 0 END, module_name"
- )->execute([
- 'tree_id' => $tree->getTreeId(),
- 'component' => $component,
- 'access_level' => Auth::accessLevel($tree),
- ])->fetchOneColumn();
+ /**
+ * Get a list of modules which (a) provide a specific function and (b) we have permission to see.
+ *
+ * We cannot currently use auto-loading for modules, as there may be user-defined
+ * modules about which the auto-loader knows nothing.
+ *
+ * @param Tree $tree
+ * @param string $component The type of module, such as "tab", "report" or "menu"
+ *
+ * @return ModuleBlockInterface[]|ModuleChartInterface[]|ModuleMenuInterface[]|ModuleReportInterface[]|ModuleSidebarInterface[]|ModuleTabInterface[]|ModuleThemeInterface[]
+ */
+ private static function getActiveModulesByComponent(Tree $tree, $component)
+ {
+ $module_names = Database::prepare(
+ "SELECT module_name" .
+ " FROM `##module`" .
+ " JOIN `##module_privacy` USING (module_name)" .
+ " WHERE gedcom_id = :tree_id AND component = :component AND status = 'enabled' AND access_level >= :access_level" .
+ " ORDER BY CASE component WHEN 'menu' THEN menu_order WHEN 'sidebar' THEN sidebar_order WHEN 'tab' THEN tab_order ELSE 0 END, module_name"
+ )->execute([
+ 'tree_id' => $tree->getTreeId(),
+ 'component' => $component,
+ 'access_level' => Auth::accessLevel($tree),
+ ])->fetchOneColumn();
- $array = [];
- foreach ($module_names as $module_name) {
- $interface = '\Fisharebest\Webtrees\Module\Module' . ucfirst($component) . 'Interface';
- $module = self::getModuleByName($module_name);
- if ($module instanceof $interface) {
- $array[$module_name] = $module;
- }
- }
+ $array = [];
+ foreach ($module_names as $module_name) {
+ $interface = '\Fisharebest\Webtrees\Module\Module' . ucfirst($component) . 'Interface';
+ $module = self::getModuleByName($module_name);
+ if ($module instanceof $interface) {
+ $array[$module_name] = $module;
+ }
+ }
- // The order of menus/sidebars/tabs is defined in the database. Others are sorted by name.
- if ($component !== 'menu' && $component !== 'sidebar' && $component !== 'tab') {
- uasort($array, function (AbstractModule $x, AbstractModule $y) {
- return I18N::strcasecmp($x->getTitle(), $y->getTitle());
- });
- }
+ // The order of menus/sidebars/tabs is defined in the database. Others are sorted by name.
+ if ($component !== 'menu' && $component !== 'sidebar' && $component !== 'tab') {
+ uasort($array, function (AbstractModule $x, AbstractModule $y) {
+ return I18N::strcasecmp($x->getTitle(), $y->getTitle());
+ });
+ }
- return $array;
- }
+ return $array;
+ }
- /**
- * Get a list of all modules, enabled or not, which provide a specific function.
- *
- * We cannot currently use auto-loading for modules, as there may be user-defined
- * modules about which the auto-loader knows nothing.
- *
- * @param string $component The type of module, such as "tab", "report" or "menu"
- *
- * @return AbstractModule[]
- */
- public static function getAllModulesByComponent($component) {
- $module_names = Database::prepare(
- "SELECT module_name" .
- " FROM `##module`" .
- " ORDER BY CASE :component WHEN 'menu' THEN menu_order WHEN 'sidebar' THEN sidebar_order WHEN 'tab' THEN tab_order ELSE 0 END, module_name"
- )->execute([
- 'component' => $component,
- ])->fetchOneColumn();
+ /**
+ * Get a list of all modules, enabled or not, which provide a specific function.
+ *
+ * We cannot currently use auto-loading for modules, as there may be user-defined
+ * modules about which the auto-loader knows nothing.
+ *
+ * @param string $component The type of module, such as "tab", "report" or "menu"
+ *
+ * @return AbstractModule[]
+ */
+ public static function getAllModulesByComponent($component)
+ {
+ $module_names = Database::prepare(
+ "SELECT module_name" .
+ " FROM `##module`" .
+ " ORDER BY CASE :component WHEN 'menu' THEN menu_order WHEN 'sidebar' THEN sidebar_order WHEN 'tab' THEN tab_order ELSE 0 END, module_name"
+ )->execute([
+ 'component' => $component,
+ ])->fetchOneColumn();
- $array = [];
- foreach ($module_names as $module_name) {
- $interface = '\Fisharebest\Webtrees\Module\Module' . ucfirst($component) . 'Interface';
- $module = self::getModuleByName($module_name);
- if ($module instanceof $interface) {
- $array[$module_name] = $module;
- }
- }
+ $array = [];
+ foreach ($module_names as $module_name) {
+ $interface = '\Fisharebest\Webtrees\Module\Module' . ucfirst($component) . 'Interface';
+ $module = self::getModuleByName($module_name);
+ if ($module instanceof $interface) {
+ $array[$module_name] = $module;
+ }
+ }
- // The order of menus/sidebars/tabs is defined in the database. Others are sorted by name.
- if ($component !== 'menu' && $component !== 'sidebar' && $component !== 'tab') {
- uasort($array, function (AbstractModule $x, AbstractModule $y) {
- return I18N::strcasecmp($x->getTitle(), $y->getTitle());
- });
- }
+ // The order of menus/sidebars/tabs is defined in the database. Others are sorted by name.
+ if ($component !== 'menu' && $component !== 'sidebar' && $component !== 'tab') {
+ uasort($array, function (AbstractModule $x, AbstractModule $y) {
+ return I18N::strcasecmp($x->getTitle(), $y->getTitle());
+ });
+ }
- return $array;
- }
+ return $array;
+ }
- /**
- * Get a list of modules which (a) provide a block and (b) we have permission to see.
- *
- * @param Tree $tree
- *
- * @return ModuleBlockInterface[]
- */
- public static function getActiveBlocks(Tree $tree) {
- return self::getActiveModulesByComponent($tree, 'block');
- }
+ /**
+ * Get a list of modules which (a) provide a block and (b) we have permission to see.
+ *
+ * @param Tree $tree
+ *
+ * @return ModuleBlockInterface[]
+ */
+ public static function getActiveBlocks(Tree $tree)
+ {
+ return self::getActiveModulesByComponent($tree, 'block');
+ }
- /**
- * Get a list of modules which (a) provide a chart and (b) we have permission to see.
- *
- * @param Tree $tree
- *
- * @return ModuleChartInterface[]
- */
- public static function getActiveCharts(Tree $tree) {
- return self::getActiveModulesByComponent($tree, 'chart');
- }
+ /**
+ * Get a list of modules which (a) provide a chart and (b) we have permission to see.
+ *
+ * @param Tree $tree
+ *
+ * @return ModuleChartInterface[]
+ */
+ public static function getActiveCharts(Tree $tree)
+ {
+ return self::getActiveModulesByComponent($tree, 'chart');
+ }
- /**
- * Get a list of modules which (a) provide a chart and (b) we have permission to see.
- *
- * @param Tree $tree
- * @param string $module
- *
- * @return bool
- */
- public static function isActiveChart(Tree $tree, $module) {
- return array_key_exists($module, self::getActiveModulesByComponent($tree, 'chart'));
- }
+ /**
+ * Get a list of modules which (a) provide a chart and (b) we have permission to see.
+ *
+ * @param Tree $tree
+ * @param string $module
+ *
+ * @return bool
+ */
+ public static function isActiveChart(Tree $tree, $module)
+ {
+ return array_key_exists($module, self::getActiveModulesByComponent($tree, 'chart'));
+ }
- /**
- * Get a list of module names which have configuration options.
- *
- * @return ModuleConfigInterface[]
- */
- public static function configurableModules() {
- $modules = array_filter(self::getInstalledModules('disabled'), function (AbstractModule $module) {
- return $module instanceof ModuleConfigInterface;
- });
+ /**
+ * Get a list of module names which have configuration options.
+ *
+ * @return ModuleConfigInterface[]
+ */
+ public static function configurableModules()
+ {
+ $modules = array_filter(self::getInstalledModules('disabled'), function (AbstractModule $module) {
+ return $module instanceof ModuleConfigInterface;
+ });
- // Exclude disabled modules
- $enabled_modules = Database::prepare("SELECT module_name, status FROM `##module` WHERE status='enabled'")->fetchOneColumn();
+ // Exclude disabled modules
+ $enabled_modules = Database::prepare("SELECT module_name, status FROM `##module` WHERE status='enabled'")->fetchOneColumn();
- return array_filter($modules, function (AbstractModule $module) use ($enabled_modules) {
- return in_array($module->getName(), $enabled_modules);
- });
- }
+ return array_filter($modules, function (AbstractModule $module) use ($enabled_modules) {
+ return in_array($module->getName(), $enabled_modules);
+ });
+ }
- /**
- * Get a list of modules which (a) provide a menu and (b) we have permission to see.
- *
- * @param Tree $tree
- *
- * @return ModuleMenuInterface[]
- */
- public static function getActiveMenus(Tree $tree) {
- return self::getActiveModulesByComponent($tree, 'menu');
- }
+ /**
+ * Get a list of modules which (a) provide a menu and (b) we have permission to see.
+ *
+ * @param Tree $tree
+ *
+ * @return ModuleMenuInterface[]
+ */
+ public static function getActiveMenus(Tree $tree)
+ {
+ return self::getActiveModulesByComponent($tree, 'menu');
+ }
- /**
- * Get a list of modules which (a) provide a report and (b) we have permission to see.
- *
- * @param Tree $tree
- *
- * @return ModuleReportInterface[]
- */
- public static function getActiveReports(Tree $tree) {
- return self::getActiveModulesByComponent($tree, 'report');
- }
+ /**
+ * Get a list of modules which (a) provide a report and (b) we have permission to see.
+ *
+ * @param Tree $tree
+ *
+ * @return ModuleReportInterface[]
+ */
+ public static function getActiveReports(Tree $tree)
+ {
+ return self::getActiveModulesByComponent($tree, 'report');
+ }
- /**
- * Get a list of modules which (a) provide a sidebar and (b) we have permission to see.
- *
- * @param Tree $tree
- *
- * @return ModuleSidebarInterface[]
- */
- public static function getActiveSidebars(Tree $tree) {
- return self::getActiveModulesByComponent($tree, 'sidebar');
- }
+ /**
+ * Get a list of modules which (a) provide a sidebar and (b) we have permission to see.
+ *
+ * @param Tree $tree
+ *
+ * @return ModuleSidebarInterface[]
+ */
+ public static function getActiveSidebars(Tree $tree)
+ {
+ return self::getActiveModulesByComponent($tree, 'sidebar');
+ }
- /**
- * Get a list of modules which (a) provide a tab and (b) we have permission to see.
- *
- * @param Tree $tree
- *
- * @return ModuleTabInterface[]
- */
- public static function getActiveTabs(Tree $tree) {
- return self::getActiveModulesByComponent($tree, 'tab');
- }
+ /**
+ * Get a list of modules which (a) provide a tab and (b) we have permission to see.
+ *
+ * @param Tree $tree
+ *
+ * @return ModuleTabInterface[]
+ */
+ public static function getActiveTabs(Tree $tree)
+ {
+ return self::getActiveModulesByComponent($tree, 'tab');
+ }
- /**
- * Get a list of modules which (a) provide a theme and (b) we have permission to see.
- *
- * @param Tree $tree
- *
- * @return ModuleThemeInterface[]
- */
- public static function getActiveThemes(Tree $tree) {
- return self::getActiveModulesByComponent($tree, 'theme');
- }
+ /**
+ * Get a list of modules which (a) provide a theme and (b) we have permission to see.
+ *
+ * @param Tree $tree
+ *
+ * @return ModuleThemeInterface[]
+ */
+ public static function getActiveThemes(Tree $tree)
+ {
+ return self::getActiveModulesByComponent($tree, 'theme');
+ }
- /**
- * Find a specified module, if it is currently active.
- *
- * @param string $module_name
- *
- * @return AbstractModule|null
- */
- public static function getModuleByName($module_name) {
- $modules = self::getActiveModules();
- if (array_key_exists($module_name, $modules)) {
- return $modules[$module_name];
- } else {
- return null;
- }
- }
+ /**
+ * Find a specified module, if it is currently active.
+ *
+ * @param string $module_name
+ *
+ * @return AbstractModule|null
+ */
+ public static function getModuleByName($module_name)
+ {
+ $modules = self::getActiveModules();
+ if (array_key_exists($module_name, $modules)) {
+ return $modules[$module_name];
+ } else {
+ return null;
+ }
+ }
- /**
- * Scan the source code to find a list of all installed modules.
- *
- * During setup, new modules need a status of “enabled”.
- * In admin->modules, new modules need status of “disabled”.
- *
- * @param string $default_status
- *
- * @return AbstractModule[]
- */
- public static function getInstalledModules($default_status) {
- $modules = [];
+ /**
+ * Scan the source code to find a list of all installed modules.
+ *
+ * During setup, new modules need a status of “enabled”.
+ * In admin->modules, new modules need status of “disabled”.
+ *
+ * @param string $default_status
+ *
+ * @return AbstractModule[]
+ */
+ public static function getInstalledModules($default_status)
+ {
+ $modules = [];
- foreach (glob(WT_ROOT . WT_MODULES_DIR . '*/module.php') as $file) {
- try {
- $module = self::loadModule($file);
- if ($module instanceof AbstractModule) {
- $modules[$module->getName()] = $module;
- Database::prepare("INSERT IGNORE INTO `##module` (module_name, status, menu_order, sidebar_order, tab_order) VALUES (?, ?, ?, ?, ?)")->execute([
- $module->getName(),
- $default_status,
- $module instanceof ModuleMenuInterface ? $module->defaultMenuOrder() : null,
- $module instanceof ModuleSidebarInterface ? $module->defaultSidebarOrder() : null,
- $module instanceof ModuleTabInterface ? $module->defaultTabOrder() : null,
- ]);
- // Set the default privcy for this module. Note that this also sets it for the
- // default family tree, with a gedcom_id of -1
- if ($module instanceof ModuleMenuInterface) {
- Database::prepare(
- "INSERT IGNORE INTO `##module_privacy` (module_name, gedcom_id, component, access_level)" .
- " SELECT ?, gedcom_id, 'menu', ?" .
- " FROM `##gedcom`"
- )->execute([$module->getName(), $module->defaultAccessLevel()]);
- }
- if ($module instanceof ModuleSidebarInterface) {
- Database::prepare(
- "INSERT IGNORE INTO `##module_privacy` (module_name, gedcom_id, component, access_level)" .
- " SELECT ?, gedcom_id, 'sidebar', ?" .
- " FROM `##gedcom`"
- )->execute([$module->getName(), $module->defaultAccessLevel()]);
- }
- if ($module instanceof ModuleTabInterface) {
- Database::prepare(
- "INSERT IGNORE INTO `##module_privacy` (module_name, gedcom_id, component, access_level)" .
- " SELECT ?, gedcom_id, 'tab', ?" .
- " FROM `##gedcom`"
- )->execute([$module->getName(), $module->defaultAccessLevel()]);
- }
- if ($module instanceof ModuleBlockInterface) {
- Database::prepare(
- "INSERT IGNORE INTO `##module_privacy` (module_name, gedcom_id, component, access_level)" .
- " SELECT ?, gedcom_id, 'block', ?" .
- " FROM `##gedcom`"
- )->execute([$module->getName(), $module->defaultAccessLevel()]);
- }
- if ($module instanceof ModuleChartInterface) {
- Database::prepare(
- "INSERT IGNORE INTO `##module_privacy` (module_name, gedcom_id, component, access_level)" .
- " SELECT ?, gedcom_id, 'chart', ?" .
- " FROM `##gedcom`"
- )->execute([$module->getName(), $module->defaultAccessLevel()]);
- }
- if ($module instanceof ModuleReportInterface) {
- Database::prepare(
- "INSERT IGNORE INTO `##module_privacy` (module_name, gedcom_id, component, access_level)" .
- " SELECT ?, gedcom_id, 'report', ?" .
- " FROM `##gedcom`"
- )->execute([$module->getName(), $module->defaultAccessLevel()]);
- }
- if ($module instanceof ModuleThemeInterface) {
- Database::prepare(
- "INSERT IGNORE INTO `##module_privacy` (module_name, gedcom_id, component, access_level)" .
- " SELECT ?, gedcom_id, 'theme', ?" .
- " FROM `##gedcom`"
- )->execute([$module->getName(), $module->defaultAccessLevel()]);
- }
- }
- } catch (\Exception $ex) {
- DebugBar::addThrowable($ex);
+ foreach (glob(WT_ROOT . WT_MODULES_DIR . '*/module.php') as $file) {
+ try {
+ $module = self::loadModule($file);
+ if ($module instanceof AbstractModule) {
+ $modules[$module->getName()] = $module;
+ Database::prepare("INSERT IGNORE INTO `##module` (module_name, status, menu_order, sidebar_order, tab_order) VALUES (?, ?, ?, ?, ?)")->execute([
+ $module->getName(),
+ $default_status,
+ $module instanceof ModuleMenuInterface ? $module->defaultMenuOrder() : null,
+ $module instanceof ModuleSidebarInterface ? $module->defaultSidebarOrder() : null,
+ $module instanceof ModuleTabInterface ? $module->defaultTabOrder() : null,
+ ]);
+ // Set the default privcy for this module. Note that this also sets it for the
+ // default family tree, with a gedcom_id of -1
+ if ($module instanceof ModuleMenuInterface) {
+ Database::prepare(
+ "INSERT IGNORE INTO `##module_privacy` (module_name, gedcom_id, component, access_level)" .
+ " SELECT ?, gedcom_id, 'menu', ?" .
+ " FROM `##gedcom`"
+ )->execute([
+ $module->getName(),
+ $module->defaultAccessLevel(),
+ ]);
+ }
+ if ($module instanceof ModuleSidebarInterface) {
+ Database::prepare(
+ "INSERT IGNORE INTO `##module_privacy` (module_name, gedcom_id, component, access_level)" .
+ " SELECT ?, gedcom_id, 'sidebar', ?" .
+ " FROM `##gedcom`"
+ )->execute([
+ $module->getName(),
+ $module->defaultAccessLevel(),
+ ]);
+ }
+ if ($module instanceof ModuleTabInterface) {
+ Database::prepare(
+ "INSERT IGNORE INTO `##module_privacy` (module_name, gedcom_id, component, access_level)" .
+ " SELECT ?, gedcom_id, 'tab', ?" .
+ " FROM `##gedcom`"
+ )->execute([
+ $module->getName(),
+ $module->defaultAccessLevel(),
+ ]);
+ }
+ if ($module instanceof ModuleBlockInterface) {
+ Database::prepare(
+ "INSERT IGNORE INTO `##module_privacy` (module_name, gedcom_id, component, access_level)" .
+ " SELECT ?, gedcom_id, 'block', ?" .
+ " FROM `##gedcom`"
+ )->execute([
+ $module->getName(),
+ $module->defaultAccessLevel(),
+ ]);
+ }
+ if ($module instanceof ModuleChartInterface) {
+ Database::prepare(
+ "INSERT IGNORE INTO `##module_privacy` (module_name, gedcom_id, component, access_level)" .
+ " SELECT ?, gedcom_id, 'chart', ?" .
+ " FROM `##gedcom`"
+ )->execute([
+ $module->getName(),
+ $module->defaultAccessLevel(),
+ ]);
+ }
+ if ($module instanceof ModuleReportInterface) {
+ Database::prepare(
+ "INSERT IGNORE INTO `##module_privacy` (module_name, gedcom_id, component, access_level)" .
+ " SELECT ?, gedcom_id, 'report', ?" .
+ " FROM `##gedcom`"
+ )->execute([
+ $module->getName(),
+ $module->defaultAccessLevel(),
+ ]);
+ }
+ if ($module instanceof ModuleThemeInterface) {
+ Database::prepare(
+ "INSERT IGNORE INTO `##module_privacy` (module_name, gedcom_id, component, access_level)" .
+ " SELECT ?, gedcom_id, 'theme', ?" .
+ " FROM `##gedcom`"
+ )->execute([
+ $module->getName(),
+ $module->defaultAccessLevel(),
+ ]);
+ }
+ }
+ } catch (\Exception $ex) {
+ DebugBar::addThrowable($ex);
- // Old or invalid module?
- Log::addErrorLog($ex->getMessage());
- }
- }
+ // Old or invalid module?
+ Log::addErrorLog($ex->getMessage());
+ }
+ }
- return $modules;
- }
+ return $modules;
+ }
- /**
- * After creating a new family tree, we need to assign the default access
- * rights for each module.
- *
- * @param int $tree_id
- */
- public static function setDefaultAccess($tree_id) {
- foreach (self::getInstalledModules('disabled') as $module) {
- if ($module instanceof ModuleMenuInterface) {
- Database::prepare(
- "INSERT IGNORE `##module_privacy` (module_name, gedcom_id, component, access_level) VALUES (?, ?, 'menu', ?)"
- )->execute([$module->getName(), $tree_id, $module->defaultAccessLevel()]);
- }
- if ($module instanceof ModuleSidebarInterface) {
- Database::prepare(
- "INSERT IGNORE `##module_privacy` (module_name, gedcom_id, component, access_level) VALUES (?, ?, 'sidebar', ?)"
- )->execute([$module->getName(), $tree_id, $module->defaultAccessLevel()]);
- }
- if ($module instanceof ModuleTabInterface) {
- Database::prepare(
- "INSERT IGNORE `##module_privacy` (module_name, gedcom_id, component, access_level) VALUES (?, ?, 'tab', ?)"
- )->execute([$module->getName(), $tree_id, $module->defaultAccessLevel()]);
- }
- if ($module instanceof ModuleBlockInterface) {
- Database::prepare(
- "INSERT IGNORE `##module_privacy` (module_name, gedcom_id, component, access_level) VALUES (?, ?, 'block', ?)"
- )->execute([$module->getName(), $tree_id, $module->defaultAccessLevel()]);
- }
- if ($module instanceof ModuleChartInterface) {
- Database::prepare(
- "INSERT IGNORE `##module_privacy` (module_name, gedcom_id, component, access_level) VALUES (?, ?, 'chart', ?)"
- )->execute([$module->getName(), $tree_id, $module->defaultAccessLevel()]);
- }
- if ($module instanceof ModuleReportInterface) {
- Database::prepare(
- "INSERT IGNORE `##module_privacy` (module_name, gedcom_id, component, access_level) VALUES (?, ?, 'report', ?)"
- )->execute([$module->getName(), $tree_id, $module->defaultAccessLevel()]);
- }
- if ($module instanceof ModuleThemeInterface) {
- Database::prepare(
- "INSERT IGNORE `##module_privacy` (module_name, gedcom_id, component, access_level) VALUES (?, ?, 'theme', ?)"
- )->execute([$module->getName(), $tree_id, $module->defaultAccessLevel()]);
- }
- }
- }
+ /**
+ * After creating a new family tree, we need to assign the default access
+ * rights for each module.
+ *
+ * @param int $tree_id
+ */
+ public static function setDefaultAccess($tree_id)
+ {
+ foreach (self::getInstalledModules('disabled') as $module) {
+ if ($module instanceof ModuleMenuInterface) {
+ Database::prepare(
+ "INSERT IGNORE `##module_privacy` (module_name, gedcom_id, component, access_level) VALUES (?, ?, 'menu', ?)"
+ )->execute([
+ $module->getName(),
+ $tree_id,
+ $module->defaultAccessLevel(),
+ ]);
+ }
+ if ($module instanceof ModuleSidebarInterface) {
+ Database::prepare(
+ "INSERT IGNORE `##module_privacy` (module_name, gedcom_id, component, access_level) VALUES (?, ?, 'sidebar', ?)"
+ )->execute([
+ $module->getName(),
+ $tree_id,
+ $module->defaultAccessLevel(),
+ ]);
+ }
+ if ($module instanceof ModuleTabInterface) {
+ Database::prepare(
+ "INSERT IGNORE `##module_privacy` (module_name, gedcom_id, component, access_level) VALUES (?, ?, 'tab', ?)"
+ )->execute([
+ $module->getName(),
+ $tree_id,
+ $module->defaultAccessLevel(),
+ ]);
+ }
+ if ($module instanceof ModuleBlockInterface) {
+ Database::prepare(
+ "INSERT IGNORE `##module_privacy` (module_name, gedcom_id, component, access_level) VALUES (?, ?, 'block', ?)"
+ )->execute([
+ $module->getName(),
+ $tree_id,
+ $module->defaultAccessLevel(),
+ ]);
+ }
+ if ($module instanceof ModuleChartInterface) {
+ Database::prepare(
+ "INSERT IGNORE `##module_privacy` (module_name, gedcom_id, component, access_level) VALUES (?, ?, 'chart', ?)"
+ )->execute([
+ $module->getName(),
+ $tree_id,
+ $module->defaultAccessLevel(),
+ ]);
+ }
+ if ($module instanceof ModuleReportInterface) {
+ Database::prepare(
+ "INSERT IGNORE `##module_privacy` (module_name, gedcom_id, component, access_level) VALUES (?, ?, 'report', ?)"
+ )->execute([
+ $module->getName(),
+ $tree_id,
+ $module->defaultAccessLevel(),
+ ]);
+ }
+ if ($module instanceof ModuleThemeInterface) {
+ Database::prepare(
+ "INSERT IGNORE `##module_privacy` (module_name, gedcom_id, component, access_level) VALUES (?, ?, 'theme', ?)"
+ )->execute([
+ $module->getName(),
+ $tree_id,
+ $module->defaultAccessLevel(),
+ ]);
+ }
+ }
+ }
}