diff options
Diffstat (limited to 'app/Http/Controllers/AdminController.php')
| -rw-r--r-- | app/Http/Controllers/AdminController.php | 3721 |
1 files changed, 1907 insertions, 1814 deletions
diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php index 2d72da0491..9f984ac8be 100644 --- a/app/Http/Controllers/AdminController.php +++ b/app/Http/Controllers/AdminController.php @@ -53,2016 +53,2109 @@ use Throwable; /** * Controller for the administration pages */ -class AdminController extends AbstractBaseController { - // This is a list of old files and directories, from earlier versions of webtrees. - // git diff 1.7.9..master --name-status | grep ^D - const OLD_FILES = [ - // Removed in 1.0.2 - WT_ROOT . 'language/en.mo', - // Removed in 1.0.3 - WT_ROOT . 'themechange.php', - // Removed in 1.1.0 - WT_ROOT . 'addremotelink.php', - WT_ROOT . 'addsearchlink.php', - WT_ROOT . 'client.php', - WT_ROOT . 'dir_editor.php', - WT_ROOT . 'editconfig_gedcom.php', - WT_ROOT . 'editgedcoms.php', - WT_ROOT . 'edit_merge.php', - WT_ROOT . 'edit_news.php', - WT_ROOT . 'genservice.php', - WT_ROOT . 'logs.php', - WT_ROOT . 'manageservers.php', - WT_ROOT . 'media.php', - WT_ROOT . 'module_admin.php', - //WT_ROOT.'modules', // Do not delete - users may have stored custom modules/data here - WT_ROOT . 'opensearch.php', - WT_ROOT . 'PEAR.php', - WT_ROOT . 'pgv_to_wt.php', - WT_ROOT . 'places', - //WT_ROOT.'robots.txt', // Do not delete this - it may contain user data - WT_ROOT . 'serviceClientTest.php', - WT_ROOT . 'siteconfig.php', - WT_ROOT . 'SOAP', - WT_ROOT . 'themes/clouds/mozilla.css', - WT_ROOT . 'themes/clouds/netscape.css', - WT_ROOT . 'themes/colors/mozilla.css', - WT_ROOT . 'themes/colors/netscape.css', - WT_ROOT . 'themes/fab/mozilla.css', - WT_ROOT . 'themes/fab/netscape.css', - WT_ROOT . 'themes/minimal/mozilla.css', - WT_ROOT . 'themes/minimal/netscape.css', - WT_ROOT . 'themes/webtrees/mozilla.css', - WT_ROOT . 'themes/webtrees/netscape.css', - WT_ROOT . 'themes/webtrees/style_rtl.css', - WT_ROOT . 'themes/xenea/mozilla.css', - WT_ROOT . 'themes/xenea/netscape.css', - WT_ROOT . 'uploadmedia.php', - WT_ROOT . 'useradmin.php', - WT_ROOT . 'webservice', - WT_ROOT . 'wtinfo.php', - // Removed in 1.1.2 - WT_ROOT . 'treenav.php', - // Removed in 1.2.0 - WT_ROOT . 'themes/clouds/jquery', - WT_ROOT . 'themes/colors/jquery', - WT_ROOT . 'themes/fab/jquery', - WT_ROOT . 'themes/minimal/jquery', - WT_ROOT . 'themes/webtrees/jquery', - WT_ROOT . 'themes/xenea/jquery', - // Removed in 1.2.2 - WT_ROOT . 'themes/clouds/chrome.css', - WT_ROOT . 'themes/clouds/opera.css', - WT_ROOT . 'themes/clouds/print.css', - WT_ROOT . 'themes/clouds/style_rtl.css', - WT_ROOT . 'themes/colors/chrome.css', - WT_ROOT . 'themes/colors/opera.css', - WT_ROOT . 'themes/colors/print.css', - WT_ROOT . 'themes/colors/style_rtl.css', - WT_ROOT . 'themes/fab/chrome.css', - WT_ROOT . 'themes/fab/opera.css', - WT_ROOT . 'themes/minimal/chrome.css', - WT_ROOT . 'themes/minimal/opera.css', - WT_ROOT . 'themes/minimal/print.css', - WT_ROOT . 'themes/minimal/style_rtl.css', - WT_ROOT . 'themes/xenea/chrome.css', - WT_ROOT . 'themes/xenea/opera.css', - WT_ROOT . 'themes/xenea/print.css', - WT_ROOT . 'themes/xenea/style_rtl.css', - // Removed in 1.2.3 - //WT_ROOT.'modules_v2', // Do not delete - users may have stored custom modules/data here - // Removed in 1.2.4 - WT_ROOT . 'modules_v3/gedcom_favorites/help_text.php', - WT_ROOT . 'modules_v3/GEDFact_assistant/_MEDIA/media_3_find.php', - WT_ROOT . 'modules_v3/GEDFact_assistant/_MEDIA/media_3_search_add.php', - WT_ROOT . 'modules_v3/GEDFact_assistant/_MEDIA/media_5_input.js', - WT_ROOT . 'modules_v3/GEDFact_assistant/_MEDIA/media_5_input.php', - WT_ROOT . 'modules_v3/GEDFact_assistant/_MEDIA/media_7_parse_addLinksTbl.php', - WT_ROOT . 'modules_v3/GEDFact_assistant/_MEDIA/media_query_1a.php', - WT_ROOT . 'modules_v3/GEDFact_assistant/_MEDIA/media_query_2a.php', - WT_ROOT . 'modules_v3/GEDFact_assistant/_MEDIA/media_query_3a.php', - WT_ROOT . 'modules_v3/lightbox/css/album_page_RTL2.css', - WT_ROOT . 'modules_v3/lightbox/css/album_page_RTL.css', - WT_ROOT . 'modules_v3/lightbox/css/album_page_RTL_ff.css', - WT_ROOT . 'modules_v3/lightbox/css/clearbox_music.css', - WT_ROOT . 'modules_v3/lightbox/css/clearbox_music_RTL.css', - WT_ROOT . 'modules_v3/user_favorites/db_schema', - WT_ROOT . 'modules_v3/user_favorites/help_text.php', - WT_ROOT . 'search_engine.php', - WT_ROOT . 'themes/clouds/modules.css', - WT_ROOT . 'themes/colors/modules.css', - WT_ROOT . 'themes/fab/modules.css', - WT_ROOT . 'themes/minimal/modules.css', - WT_ROOT . 'themes/webtrees/modules.css', - WT_ROOT . 'themes/xenea/modules.css', - // Removed in 1.2.5 - WT_ROOT . 'modules_v3/clippings/index.php', - WT_ROOT . 'modules_v3/googlemap/css/googlemap_style.css', - WT_ROOT . 'modules_v3/googlemap/css/wt_v3_places_edit.css', - WT_ROOT . 'modules_v3/googlemap/index.php', - WT_ROOT . 'modules_v3/lightbox/index.php', - WT_ROOT . 'modules_v3/recent_changes/help_text.php', - WT_ROOT . 'modules_v3/todays_events/help_text.php', - WT_ROOT . 'sidebar.php', - // Removed in 1.2.6 - WT_ROOT . 'modules_v3/sitemap/admin_index.php', - WT_ROOT . 'modules_v3/sitemap/help_text.php', - WT_ROOT . 'modules_v3/tree/css/styles', - WT_ROOT . 'modules_v3/tree/css/treebottom.gif', - WT_ROOT . 'modules_v3/tree/css/treebottomleft.gif', - WT_ROOT . 'modules_v3/tree/css/treebottomright.gif', - WT_ROOT . 'modules_v3/tree/css/tree.jpg', - WT_ROOT . 'modules_v3/tree/css/treeleft.gif', - WT_ROOT . 'modules_v3/tree/css/treeright.gif', - WT_ROOT . 'modules_v3/tree/css/treetop.gif', - WT_ROOT . 'modules_v3/tree/css/treetopleft.gif', - WT_ROOT . 'modules_v3/tree/css/treetopright.gif', - WT_ROOT . 'modules_v3/tree/css/treeview_print.css', - WT_ROOT . 'modules_v3/tree/help_text.php', - WT_ROOT . 'modules_v3/tree/images/print.png', - // Removed in 1.2.7 - WT_ROOT . 'login_register.php', - WT_ROOT . 'modules_v3/top10_givnnames/help_text.php', - WT_ROOT . 'modules_v3/top10_surnames/help_text.php', - // Removed in 1.3.0 - WT_ROOT . 'admin_site_ipaddress.php', - WT_ROOT . 'downloadgedcom.php', - WT_ROOT . 'export_gedcom.php', - WT_ROOT . 'gedcheck.php', - WT_ROOT . 'images', - WT_ROOT . 'modules_v3/googlemap/admin_editconfig.php', - WT_ROOT . 'modules_v3/googlemap/admin_placecheck.php', - WT_ROOT . 'modules_v3/googlemap/flags.php', - WT_ROOT . 'modules_v3/googlemap/images/pedigree_map.gif', - WT_ROOT . 'modules_v3/googlemap/pedigree_map.php', - WT_ROOT . 'modules_v3/lightbox/admin_config.php', - WT_ROOT . 'modules_v3/lightbox/album.php', - WT_ROOT . 'modules_v3/tree/css/vline.jpg', - // Removed in 1.3.1 - WT_ROOT . 'imageflush.php', - WT_ROOT . 'modules_v3/googlemap/wt_v3_pedigree_map.js.php', - WT_ROOT . 'modules_v3/lightbox/js/tip_balloon_RTL.js', - // Removed in 1.3.2 - WT_ROOT . 'modules_v3/address_report', - WT_ROOT . 'modules_v3/lightbox/functions/lb_horiz_sort.php', - WT_ROOT . 'modules_v3/random_media/help_text.php', - // Removed in 1.4.0 - WT_ROOT . 'imageview.php', - WT_ROOT . 'media/MediaInfo.txt', - WT_ROOT . 'media/thumbs/ThumbsInfo.txt', - WT_ROOT . 'modules_v3/GEDFact_assistant/css/media_0_inverselink.css', - WT_ROOT . 'modules_v3/lightbox/help_text.php', - WT_ROOT . 'modules_v3/lightbox/images/blank.gif', - WT_ROOT . 'modules_v3/lightbox/images/close_1.gif', - WT_ROOT . 'modules_v3/lightbox/images/image_add.gif', - WT_ROOT . 'modules_v3/lightbox/images/image_copy.gif', - WT_ROOT . 'modules_v3/lightbox/images/image_delete.gif', - WT_ROOT . 'modules_v3/lightbox/images/image_edit.gif', - WT_ROOT . 'modules_v3/lightbox/images/image_link.gif', - WT_ROOT . 'modules_v3/lightbox/images/images.gif', - WT_ROOT . 'modules_v3/lightbox/images/image_view.gif', - WT_ROOT . 'modules_v3/lightbox/images/loading.gif', - WT_ROOT . 'modules_v3/lightbox/images/next.gif', - WT_ROOT . 'modules_v3/lightbox/images/nextlabel.gif', - WT_ROOT . 'modules_v3/lightbox/images/norm_2.gif', - WT_ROOT . 'modules_v3/lightbox/images/overlay.png', - WT_ROOT . 'modules_v3/lightbox/images/prev.gif', - WT_ROOT . 'modules_v3/lightbox/images/prevlabel.gif', - WT_ROOT . 'modules_v3/lightbox/images/private.gif', - WT_ROOT . 'modules_v3/lightbox/images/slideshow.jpg', - WT_ROOT . 'modules_v3/lightbox/images/transp80px.gif', - WT_ROOT . 'modules_v3/lightbox/images/zoom_1.gif', - WT_ROOT . 'modules_v3/lightbox/js', - WT_ROOT . 'modules_v3/lightbox/music', - WT_ROOT . 'modules_v3/lightbox/pic', - WT_ROOT . 'themes/webtrees/chrome.css', - // Removed in 1.4.1 - WT_ROOT . 'modules_v3/lightbox/images/image_edit.png', - WT_ROOT . 'modules_v3/lightbox/images/image_view.png', - // Removed in 1.4.2 - WT_ROOT . 'modules_v3/lightbox/images/image_view.png', - WT_ROOT . 'modules_v3/top10_pageviews/help_text.php', - WT_ROOT . 'themes/clouds/jquery-ui-1.10.0', - WT_ROOT . 'themes/colors/jquery-ui-1.10.0', - WT_ROOT . 'themes/fab/jquery-ui-1.10.0', - WT_ROOT . 'themes/minimal/jquery-ui-1.10.0', - WT_ROOT . 'themes/webtrees/jquery-ui-1.10.0', - WT_ROOT . 'themes/xenea/jquery-ui-1.10.0', - // Removed in 1.5.0 - WT_ROOT . 'modules_v3/GEDFact_assistant/_CENS/census_note_decode.php', - WT_ROOT . 'modules_v3/GEDFact_assistant/_CENS/census_asst_date.php', - WT_ROOT . 'modules_v3/googlemap/wt_v3_googlemap.js.php', - WT_ROOT . 'modules_v3/lightbox/functions/lightbox_print_media.php', - WT_ROOT . 'modules_v3/upcoming_events/help_text.php', - WT_ROOT . 'modules_v3/stories/help_text.php', - WT_ROOT . 'modules_v3/user_messages/help_text.php', - WT_ROOT . 'themes/clouds/favicon.png', - WT_ROOT . 'themes/clouds/images', - WT_ROOT . 'themes/clouds/msie.css', - WT_ROOT . 'themes/clouds/style.css', - WT_ROOT . 'themes/colors/css', - WT_ROOT . 'themes/colors/favicon.png', - WT_ROOT . 'themes/colors/images', - WT_ROOT . 'themes/colors/ipad.css', - WT_ROOT . 'themes/colors/msie.css', - WT_ROOT . 'themes/fab/favicon.png', - WT_ROOT . 'themes/fab/images', - WT_ROOT . 'themes/fab/msie.css', - WT_ROOT . 'themes/fab/style.css', - WT_ROOT . 'themes/minimal/favicon.png', - WT_ROOT . 'themes/minimal/images', - WT_ROOT . 'themes/minimal/msie.css', - WT_ROOT . 'themes/minimal/style.css', - WT_ROOT . 'themes/webtrees/favicon.png', - WT_ROOT . 'themes/webtrees/images', - WT_ROOT . 'themes/webtrees/msie.css', - WT_ROOT . 'themes/webtrees/style.css', - WT_ROOT . 'themes/xenea/favicon.png', - WT_ROOT . 'themes/xenea/images', - WT_ROOT . 'themes/xenea/msie.css', - WT_ROOT . 'themes/xenea/style.css', - // Removed in 1.5.1 - WT_ROOT . 'themes/clouds/css-1.5.0', - WT_ROOT . 'themes/colors/css-1.5.0', - WT_ROOT . 'themes/fab/css-1.5.0', - WT_ROOT . 'themes/minimal/css-1.5.0', - WT_ROOT . 'themes/webtrees/css-1.5.0', - WT_ROOT . 'themes/xenea/css-1.5.0', - // Removed in 1.5.2 - WT_ROOT . 'themes/clouds/css-1.5.1', - WT_ROOT . 'themes/colors/css-1.5.1', - WT_ROOT . 'themes/fab/css-1.5.1', - WT_ROOT . 'themes/minimal/css-1.5.1', - WT_ROOT . 'themes/webtrees/css-1.5.1', - WT_ROOT . 'themes/xenea/css-1.5.1', - // Removed in 1.5.3 - WT_ROOT . 'modules_v3/GEDFact_assistant/_CENS/census_asst_help.php', - WT_ROOT . 'modules_v3/googlemap/admin_places.php', - WT_ROOT . 'modules_v3/googlemap/defaultconfig.php', - WT_ROOT . 'modules_v3/googlemap/googlemap.php', - WT_ROOT . 'modules_v3/googlemap/placehierarchy.php', - WT_ROOT . 'modules_v3/googlemap/places_edit.php', - WT_ROOT . 'modules_v3/googlemap/util.js', - WT_ROOT . 'modules_v3/googlemap/wt_v3_places_edit.js.php', - WT_ROOT . 'modules_v3/googlemap/wt_v3_places_edit_overlays.js.php', - WT_ROOT . 'modules_v3/googlemap/wt_v3_street_view.php', - WT_ROOT . 'readme.html', - WT_ROOT . 'themes/clouds/css-1.5.2', - WT_ROOT . 'themes/colors/css-1.5.2', - WT_ROOT . 'themes/fab/css-1.5.2', - WT_ROOT . 'themes/minimal/css-1.5.2', - WT_ROOT . 'themes/webtrees/css-1.5.2', - WT_ROOT . 'themes/xenea/css-1.5.2', - // Removed in 1.6.0 - WT_ROOT . 'downloadbackup.php', - WT_ROOT . 'modules_v3/ckeditor/ckeditor-4.3.2-custom', - WT_ROOT . 'site-php-version.php', - WT_ROOT . 'themes/clouds/css-1.5.3', - WT_ROOT . 'themes/colors/css-1.5.3', - WT_ROOT . 'themes/fab/css-1.5.3', - WT_ROOT . 'themes/minimal/css-1.5.3', - WT_ROOT . 'themes/webtrees/css-1.5.3', - WT_ROOT . 'themes/xenea/css-1.5.3', - // Removed in 1.6.2 - WT_ROOT . 'themes/clouds/jquery-ui-1.10.3', - WT_ROOT . 'themes/colors/css-1.6.0', - WT_ROOT . 'themes/colors/jquery-ui-1.10.3', - WT_ROOT . 'themes/fab/css-1.6.0', - WT_ROOT . 'themes/fab/jquery-ui-1.10.3', - WT_ROOT . 'themes/minimal/css-1.6.0', - WT_ROOT . 'themes/minimal/jquery-ui-1.10.3', - WT_ROOT . 'themes/webtrees/css-1.6.0', - WT_ROOT . 'themes/webtrees/jquery-ui-1.10.3', - WT_ROOT . 'themes/xenea/css-1.6.0', - WT_ROOT . 'themes/xenea/jquery-ui-1.10.3', - // Removed in 1.7.0 - WT_ROOT . 'admin_site_other.php', - WT_ROOT . 'js', - WT_ROOT . 'language/en_GB.mo', - // Replaced with en-GB.mo - WT_ROOT . 'language/en_US.mo', - // Replaced with en-US.mo - WT_ROOT . 'language/pt_BR.mo', - // Replaced with pt-BR.mo - WT_ROOT . 'language/zh_CN.mo', - // Replaced with zh-Hans.mo - WT_ROOT . 'language/extra', - WT_ROOT . 'library', - WT_ROOT . 'modules_v3/batch_update/admin_batch_update.php', - WT_ROOT . 'modules_v3/batch_update/plugins', - WT_ROOT . 'modules_v3/charts/help_text.php', - WT_ROOT . 'modules_v3/ckeditor/ckeditor-4.4.1-custom', - WT_ROOT . 'modules_v3/clippings/clippings_ctrl.php', - WT_ROOT . 'modules_v3/clippings/help_text.php', - WT_ROOT . 'modules_v3/faq/help_text.php', - WT_ROOT . 'modules_v3/gedcom_favorites/db_schema', - WT_ROOT . 'modules_v3/gedcom_news/db_schema', - WT_ROOT . 'modules_v3/googlemap/db_schema', - WT_ROOT . 'modules_v3/googlemap/help_text.php', - WT_ROOT . 'modules_v3/html/help_text.php', - WT_ROOT . 'modules_v3/logged_in/help_text.php', - WT_ROOT . 'modules_v3/review_changes/help_text.php', - WT_ROOT . 'modules_v3/todo/help_text.php', - WT_ROOT . 'modules_v3/tree/class_treeview.php', - WT_ROOT . 'modules_v3/user_blog/db_schema', - WT_ROOT . 'modules_v3/yahrzeit/help_text.php', - WT_ROOT . 'save.php', - WT_ROOT . 'themes/clouds/css-1.6.2', - WT_ROOT . 'themes/clouds/templates', - WT_ROOT . 'themes/clouds/header.php', - WT_ROOT . 'themes/clouds/footer.php', - WT_ROOT . 'themes/colors/css-1.6.2', - WT_ROOT . 'themes/colors/templates', - WT_ROOT . 'themes/colors/header.php', - WT_ROOT . 'themes/colors/footer.php', - WT_ROOT . 'themes/fab/css-1.6.2', - WT_ROOT . 'themes/fab/templates', - WT_ROOT . 'themes/fab/header.php', - WT_ROOT . 'themes/fab/footer.php', - WT_ROOT . 'themes/minimal/css-1.6.2', - WT_ROOT . 'themes/minimal/templates', - WT_ROOT . 'themes/minimal/header.php', - WT_ROOT . 'themes/minimal/footer.php', - WT_ROOT . 'themes/webtrees/css-1.6.2', - WT_ROOT . 'themes/webtrees/templates', - WT_ROOT . 'themes/webtrees/header.php', - WT_ROOT . 'themes/webtrees/footer.php', - WT_ROOT . 'themes/xenea/css-1.6.2', - WT_ROOT . 'themes/xenea/templates', - WT_ROOT . 'themes/xenea/header.php', - WT_ROOT . 'themes/xenea/footer.php', - // Removed in 1.7.2 - WT_ROOT . 'assets/js-1.7.0', - // Removed in 1.7.3 - WT_ROOT . 'modules_v3/GEDFact_assistant/census/date.js', - WT_ROOT . 'modules_v3/GEDFact_assistant/census/dynamicoptionlist.js', - // Removed in 1.7.4 - WT_ROOT . 'assets/js-1.7.2', - WT_ROOT . 'themes/clouds/css-1.7.0', - WT_ROOT . 'themes/colors/css-1.7.0', - WT_ROOT . 'themes/fab/css-1.7.0', - WT_ROOT . 'themes/minimal/css-1.7.0', - WT_ROOT . 'themes/webtrees/css-1.7.0', - WT_ROOT . 'themes/xenea/css-1.7.0', - // Removed in 1.7.5 - WT_ROOT . 'themes/clouds/css-1.7.4', - WT_ROOT . 'themes/colors/css-1.7.4', - WT_ROOT . 'themes/fab/css-1.7.4', - WT_ROOT . 'themes/minimal/css-1.7.4', - WT_ROOT . 'themes/webtrees/css-1.7.4', - WT_ROOT . 'themes/xenea/css-1.7.4', - // Removed in 1.7.7 - WT_ROOT . 'assets/js-1.7.4', - WT_ROOT . 'modules_v3/googlemap/images/css_sprite_facts.png', - WT_ROOT . 'modules_v3/googlemap/images/flag_shadow.png', - WT_ROOT . 'modules_v3/googlemap/images/shadow-left-large.png', - WT_ROOT . 'modules_v3/googlemap/images/shadow-left-small.png', - WT_ROOT . 'modules_v3/googlemap/images/shadow-right-large.png', - WT_ROOT . 'modules_v3/googlemap/images/shadow-right-small.png', - WT_ROOT . 'modules_v3/googlemap/images/shadow50.png', - WT_ROOT . 'modules_v3/googlemap/images/transparent-left-large.png', - WT_ROOT . 'modules_v3/googlemap/images/transparent-left-small.png', - WT_ROOT . 'modules_v3/googlemap/images/transparent-right-large.png', - WT_ROOT . 'modules_v3/googlemap/images/transparent-right-small.png', - // Removed in 1.7.8 - WT_ROOT . 'themes/clouds/css-1.7.5', - WT_ROOT . 'themes/colors/css-1.7.5', - WT_ROOT . 'themes/fab/css-1.7.5', - WT_ROOT . 'themes/minimal/css-1.7.5', - WT_ROOT . 'themes/webtrees/css-1.7.5', - WT_ROOT . 'themes/xenea/css-1.7.5', - // Removed in 2.0.0 - WT_ROOT . 'action.php', - WT_ROOT . 'addmedia.php', - WT_ROOT . 'addmin.php', - WT_ROOT . 'admin_media.php', - WT_ROOT . 'admin_media_upload.php', - WT_ROOT . 'admin_module_blocks.php', - WT_ROOT . 'admin_module_charts.php', - WT_ROOT . 'admin_module_menus.php', - WT_ROOT . 'admin_module_reports.php', - WT_ROOT . 'admin_module_sidebar.php', - WT_ROOT . 'admin_module_tabs.php', - WT_ROOT . 'admin_modules.php', - WT_ROOT . 'admin_pgv_to_wt.php', - WT_ROOT . 'admin_site_access.php', - WT_ROOT . 'admin_site_change.php', - WT_ROOT . 'admin_site_clean.php', - WT_ROOT . 'admin_site_config.php', - WT_ROOT . 'admin_site_info.php', - WT_ROOT . 'admin_site_logs.php', - WT_ROOT . 'admin_site_merge.php', - WT_ROOT . 'admin_site_readme.php', - WT_ROOT . 'admin_site_upgrade.php', - WT_ROOT . 'admin_trees_check.php', - WT_ROOT . 'admin_trees_config.php', - WT_ROOT . 'admin_trees_download.php', - WT_ROOT . 'admin_trees_duplicates.php', - WT_ROOT . 'admin_trees_export.php', - WT_ROOT . 'admin_trees_manage.php', - WT_ROOT . 'admin_trees_merge.php', - WT_ROOT . 'admin_trees_places.php', - WT_ROOT . 'admin_trees_renumber.php', - WT_ROOT . 'admin_trees_unconnected.php', - WT_ROOT . 'admin_users.php', - WT_ROOT . 'admin_users_bulk.php', - WT_ROOT . 'ancestry.php', - WT_ROOT . 'app/Controller', - WT_ROOT . 'app/HitCounter.php', - WT_ROOT . 'app/Module/ClippingsCart/ClippingsCartController.php', - WT_ROOT . 'app/Module/FamiliesSidebarModule.php', - WT_ROOT . 'app/Module/FamilyTreeFavorites', - WT_ROOT . 'app/Module/GoogleMaps', - WT_ROOT . 'app/Module/IndividualSidebarModule.php', - WT_ROOT . 'app/Module/PageMenuModule.php', - WT_ROOT . 'app/SpecialChars', - WT_ROOT . 'assets/js-1.7.7', - WT_ROOT . 'assets/js-1.7.9', - WT_ROOT . 'autocomplete.php', - WT_ROOT . 'block_edit.php', - WT_ROOT . 'branches.php', - WT_ROOT . 'calendar.php', - WT_ROOT . 'compact.php', - WT_ROOT . 'data/html_purifier_cache', - WT_ROOT . 'descendancy.php', - WT_ROOT . 'editnews.php', - WT_ROOT . 'edituser.php', - WT_ROOT . 'edit_changes.php', - WT_ROOT . 'edit_interface.php', - WT_ROOT . 'expand_view.php', - WT_ROOT . 'familybook.php', - WT_ROOT . 'famlist.php', - WT_ROOT . 'fanchart.php', - WT_ROOT . 'find.php', - WT_ROOT . 'help_text.php', - WT_ROOT . 'hourglass.php', - WT_ROOT . 'hourglass_ajax.php', - WT_ROOT . 'import.php', - WT_ROOT . 'includes', - WT_ROOT . 'index_edit.php', - WT_ROOT . 'indilist.php', - WT_ROOT . 'inverselink.php', - WT_ROOT . 'lifespan.php', - WT_ROOT . 'login.php', - WT_ROOT . 'logout.php', - WT_ROOT . 'mediafirewall.php', - WT_ROOT . 'medialist.php', - WT_ROOT . 'message.php', - WT_ROOT . 'module.php', - WT_ROOT . 'notelist.php', - WT_ROOT . 'packages', - WT_ROOT . 'pedigree.php', - WT_ROOT . 'relationship.php', - WT_ROOT . 'repolist.php', - WT_ROOT . 'reportengine.php', - WT_ROOT . 'search.php', - WT_ROOT . 'search_advanced.php', - WT_ROOT . 'site-offline.php', - WT_ROOT . 'site-unavailable.php', - WT_ROOT . 'sourcelist.php', - WT_ROOT . 'statistics.php', - WT_ROOT . 'statisticsplot.php', - WT_ROOT . 'themes/_administration', - WT_ROOT . 'themes/_custom', - WT_ROOT . 'themes/clouds/css-1.7.8', - WT_ROOT . 'themes/clouds/jquery-ui-1.11.2', - WT_ROOT . 'themes/colors/css-1.7.8', - WT_ROOT . 'themes/colors/jquery-ui-1.11.2', - WT_ROOT . 'themes/fab/css-1.7.8', - WT_ROOT . 'themes/fab/jquery-ui-1.11.2', - WT_ROOT . 'themes/minimal/css-1.7.8', - WT_ROOT . 'themes/minimal/jquery-ui-1.11.2', - WT_ROOT . 'themes/webtrees/css-1.7.8', - WT_ROOT . 'themes/webtrees/jquery-ui-1.11.2', - WT_ROOT . 'themes/xenea/css-1.7.8', - WT_ROOT . 'themes/xenea/jquery-ui-1.11.2', - WT_ROOT . 'timeline.php', - ]; +class AdminController extends AbstractBaseController +{ + // This is a list of old files and directories, from earlier versions of webtrees. + // git diff 1.7.9..master --name-status | grep ^D + const OLD_FILES = [ + // Removed in 1.0.2 + WT_ROOT . 'language/en.mo', + // Removed in 1.0.3 + WT_ROOT . 'themechange.php', + // Removed in 1.1.0 + WT_ROOT . 'addremotelink.php', + WT_ROOT . 'addsearchlink.php', + WT_ROOT . 'client.php', + WT_ROOT . 'dir_editor.php', + WT_ROOT . 'editconfig_gedcom.php', + WT_ROOT . 'editgedcoms.php', + WT_ROOT . 'edit_merge.php', + WT_ROOT . 'edit_news.php', + WT_ROOT . 'genservice.php', + WT_ROOT . 'logs.php', + WT_ROOT . 'manageservers.php', + WT_ROOT . 'media.php', + WT_ROOT . 'module_admin.php', + //WT_ROOT.'modules', // Do not delete - users may have stored custom modules/data here + WT_ROOT . 'opensearch.php', + WT_ROOT . 'PEAR.php', + WT_ROOT . 'pgv_to_wt.php', + WT_ROOT . 'places', + //WT_ROOT.'robots.txt', // Do not delete this - it may contain user data + WT_ROOT . 'serviceClientTest.php', + WT_ROOT . 'siteconfig.php', + WT_ROOT . 'SOAP', + WT_ROOT . 'themes/clouds/mozilla.css', + WT_ROOT . 'themes/clouds/netscape.css', + WT_ROOT . 'themes/colors/mozilla.css', + WT_ROOT . 'themes/colors/netscape.css', + WT_ROOT . 'themes/fab/mozilla.css', + WT_ROOT . 'themes/fab/netscape.css', + WT_ROOT . 'themes/minimal/mozilla.css', + WT_ROOT . 'themes/minimal/netscape.css', + WT_ROOT . 'themes/webtrees/mozilla.css', + WT_ROOT . 'themes/webtrees/netscape.css', + WT_ROOT . 'themes/webtrees/style_rtl.css', + WT_ROOT . 'themes/xenea/mozilla.css', + WT_ROOT . 'themes/xenea/netscape.css', + WT_ROOT . 'uploadmedia.php', + WT_ROOT . 'useradmin.php', + WT_ROOT . 'webservice', + WT_ROOT . 'wtinfo.php', + // Removed in 1.1.2 + WT_ROOT . 'treenav.php', + // Removed in 1.2.0 + WT_ROOT . 'themes/clouds/jquery', + WT_ROOT . 'themes/colors/jquery', + WT_ROOT . 'themes/fab/jquery', + WT_ROOT . 'themes/minimal/jquery', + WT_ROOT . 'themes/webtrees/jquery', + WT_ROOT . 'themes/xenea/jquery', + // Removed in 1.2.2 + WT_ROOT . 'themes/clouds/chrome.css', + WT_ROOT . 'themes/clouds/opera.css', + WT_ROOT . 'themes/clouds/print.css', + WT_ROOT . 'themes/clouds/style_rtl.css', + WT_ROOT . 'themes/colors/chrome.css', + WT_ROOT . 'themes/colors/opera.css', + WT_ROOT . 'themes/colors/print.css', + WT_ROOT . 'themes/colors/style_rtl.css', + WT_ROOT . 'themes/fab/chrome.css', + WT_ROOT . 'themes/fab/opera.css', + WT_ROOT . 'themes/minimal/chrome.css', + WT_ROOT . 'themes/minimal/opera.css', + WT_ROOT . 'themes/minimal/print.css', + WT_ROOT . 'themes/minimal/style_rtl.css', + WT_ROOT . 'themes/xenea/chrome.css', + WT_ROOT . 'themes/xenea/opera.css', + WT_ROOT . 'themes/xenea/print.css', + WT_ROOT . 'themes/xenea/style_rtl.css', + // Removed in 1.2.3 + //WT_ROOT.'modules_v2', // Do not delete - users may have stored custom modules/data here + // Removed in 1.2.4 + WT_ROOT . 'modules_v3/gedcom_favorites/help_text.php', + WT_ROOT . 'modules_v3/GEDFact_assistant/_MEDIA/media_3_find.php', + WT_ROOT . 'modules_v3/GEDFact_assistant/_MEDIA/media_3_search_add.php', + WT_ROOT . 'modules_v3/GEDFact_assistant/_MEDIA/media_5_input.js', + WT_ROOT . 'modules_v3/GEDFact_assistant/_MEDIA/media_5_input.php', + WT_ROOT . 'modules_v3/GEDFact_assistant/_MEDIA/media_7_parse_addLinksTbl.php', + WT_ROOT . 'modules_v3/GEDFact_assistant/_MEDIA/media_query_1a.php', + WT_ROOT . 'modules_v3/GEDFact_assistant/_MEDIA/media_query_2a.php', + WT_ROOT . 'modules_v3/GEDFact_assistant/_MEDIA/media_query_3a.php', + WT_ROOT . 'modules_v3/lightbox/css/album_page_RTL2.css', + WT_ROOT . 'modules_v3/lightbox/css/album_page_RTL.css', + WT_ROOT . 'modules_v3/lightbox/css/album_page_RTL_ff.css', + WT_ROOT . 'modules_v3/lightbox/css/clearbox_music.css', + WT_ROOT . 'modules_v3/lightbox/css/clearbox_music_RTL.css', + WT_ROOT . 'modules_v3/user_favorites/db_schema', + WT_ROOT . 'modules_v3/user_favorites/help_text.php', + WT_ROOT . 'search_engine.php', + WT_ROOT . 'themes/clouds/modules.css', + WT_ROOT . 'themes/colors/modules.css', + WT_ROOT . 'themes/fab/modules.css', + WT_ROOT . 'themes/minimal/modules.css', + WT_ROOT . 'themes/webtrees/modules.css', + WT_ROOT . 'themes/xenea/modules.css', + // Removed in 1.2.5 + WT_ROOT . 'modules_v3/clippings/index.php', + WT_ROOT . 'modules_v3/googlemap/css/googlemap_style.css', + WT_ROOT . 'modules_v3/googlemap/css/wt_v3_places_edit.css', + WT_ROOT . 'modules_v3/googlemap/index.php', + WT_ROOT . 'modules_v3/lightbox/index.php', + WT_ROOT . 'modules_v3/recent_changes/help_text.php', + WT_ROOT . 'modules_v3/todays_events/help_text.php', + WT_ROOT . 'sidebar.php', + // Removed in 1.2.6 + WT_ROOT . 'modules_v3/sitemap/admin_index.php', + WT_ROOT . 'modules_v3/sitemap/help_text.php', + WT_ROOT . 'modules_v3/tree/css/styles', + WT_ROOT . 'modules_v3/tree/css/treebottom.gif', + WT_ROOT . 'modules_v3/tree/css/treebottomleft.gif', + WT_ROOT . 'modules_v3/tree/css/treebottomright.gif', + WT_ROOT . 'modules_v3/tree/css/tree.jpg', + WT_ROOT . 'modules_v3/tree/css/treeleft.gif', + WT_ROOT . 'modules_v3/tree/css/treeright.gif', + WT_ROOT . 'modules_v3/tree/css/treetop.gif', + WT_ROOT . 'modules_v3/tree/css/treetopleft.gif', + WT_ROOT . 'modules_v3/tree/css/treetopright.gif', + WT_ROOT . 'modules_v3/tree/css/treeview_print.css', + WT_ROOT . 'modules_v3/tree/help_text.php', + WT_ROOT . 'modules_v3/tree/images/print.png', + // Removed in 1.2.7 + WT_ROOT . 'login_register.php', + WT_ROOT . 'modules_v3/top10_givnnames/help_text.php', + WT_ROOT . 'modules_v3/top10_surnames/help_text.php', + // Removed in 1.3.0 + WT_ROOT . 'admin_site_ipaddress.php', + WT_ROOT . 'downloadgedcom.php', + WT_ROOT . 'export_gedcom.php', + WT_ROOT . 'gedcheck.php', + WT_ROOT . 'images', + WT_ROOT . 'modules_v3/googlemap/admin_editconfig.php', + WT_ROOT . 'modules_v3/googlemap/admin_placecheck.php', + WT_ROOT . 'modules_v3/googlemap/flags.php', + WT_ROOT . 'modules_v3/googlemap/images/pedigree_map.gif', + WT_ROOT . 'modules_v3/googlemap/pedigree_map.php', + WT_ROOT . 'modules_v3/lightbox/admin_config.php', + WT_ROOT . 'modules_v3/lightbox/album.php', + WT_ROOT . 'modules_v3/tree/css/vline.jpg', + // Removed in 1.3.1 + WT_ROOT . 'imageflush.php', + WT_ROOT . 'modules_v3/googlemap/wt_v3_pedigree_map.js.php', + WT_ROOT . 'modules_v3/lightbox/js/tip_balloon_RTL.js', + // Removed in 1.3.2 + WT_ROOT . 'modules_v3/address_report', + WT_ROOT . 'modules_v3/lightbox/functions/lb_horiz_sort.php', + WT_ROOT . 'modules_v3/random_media/help_text.php', + // Removed in 1.4.0 + WT_ROOT . 'imageview.php', + WT_ROOT . 'media/MediaInfo.txt', + WT_ROOT . 'media/thumbs/ThumbsInfo.txt', + WT_ROOT . 'modules_v3/GEDFact_assistant/css/media_0_inverselink.css', + WT_ROOT . 'modules_v3/lightbox/help_text.php', + WT_ROOT . 'modules_v3/lightbox/images/blank.gif', + WT_ROOT . 'modules_v3/lightbox/images/close_1.gif', + WT_ROOT . 'modules_v3/lightbox/images/image_add.gif', + WT_ROOT . 'modules_v3/lightbox/images/image_copy.gif', + WT_ROOT . 'modules_v3/lightbox/images/image_delete.gif', + WT_ROOT . 'modules_v3/lightbox/images/image_edit.gif', + WT_ROOT . 'modules_v3/lightbox/images/image_link.gif', + WT_ROOT . 'modules_v3/lightbox/images/images.gif', + WT_ROOT . 'modules_v3/lightbox/images/image_view.gif', + WT_ROOT . 'modules_v3/lightbox/images/loading.gif', + WT_ROOT . 'modules_v3/lightbox/images/next.gif', + WT_ROOT . 'modules_v3/lightbox/images/nextlabel.gif', + WT_ROOT . 'modules_v3/lightbox/images/norm_2.gif', + WT_ROOT . 'modules_v3/lightbox/images/overlay.png', + WT_ROOT . 'modules_v3/lightbox/images/prev.gif', + WT_ROOT . 'modules_v3/lightbox/images/prevlabel.gif', + WT_ROOT . 'modules_v3/lightbox/images/private.gif', + WT_ROOT . 'modules_v3/lightbox/images/slideshow.jpg', + WT_ROOT . 'modules_v3/lightbox/images/transp80px.gif', + WT_ROOT . 'modules_v3/lightbox/images/zoom_1.gif', + WT_ROOT . 'modules_v3/lightbox/js', + WT_ROOT . 'modules_v3/lightbox/music', + WT_ROOT . 'modules_v3/lightbox/pic', + WT_ROOT . 'themes/webtrees/chrome.css', + // Removed in 1.4.1 + WT_ROOT . 'modules_v3/lightbox/images/image_edit.png', + WT_ROOT . 'modules_v3/lightbox/images/image_view.png', + // Removed in 1.4.2 + WT_ROOT . 'modules_v3/lightbox/images/image_view.png', + WT_ROOT . 'modules_v3/top10_pageviews/help_text.php', + WT_ROOT . 'themes/clouds/jquery-ui-1.10.0', + WT_ROOT . 'themes/colors/jquery-ui-1.10.0', + WT_ROOT . 'themes/fab/jquery-ui-1.10.0', + WT_ROOT . 'themes/minimal/jquery-ui-1.10.0', + WT_ROOT . 'themes/webtrees/jquery-ui-1.10.0', + WT_ROOT . 'themes/xenea/jquery-ui-1.10.0', + // Removed in 1.5.0 + WT_ROOT . 'modules_v3/GEDFact_assistant/_CENS/census_note_decode.php', + WT_ROOT . 'modules_v3/GEDFact_assistant/_CENS/census_asst_date.php', + WT_ROOT . 'modules_v3/googlemap/wt_v3_googlemap.js.php', + WT_ROOT . 'modules_v3/lightbox/functions/lightbox_print_media.php', + WT_ROOT . 'modules_v3/upcoming_events/help_text.php', + WT_ROOT . 'modules_v3/stories/help_text.php', + WT_ROOT . 'modules_v3/user_messages/help_text.php', + WT_ROOT . 'themes/clouds/favicon.png', + WT_ROOT . 'themes/clouds/images', + WT_ROOT . 'themes/clouds/msie.css', + WT_ROOT . 'themes/clouds/style.css', + WT_ROOT . 'themes/colors/css', + WT_ROOT . 'themes/colors/favicon.png', + WT_ROOT . 'themes/colors/images', + WT_ROOT . 'themes/colors/ipad.css', + WT_ROOT . 'themes/colors/msie.css', + WT_ROOT . 'themes/fab/favicon.png', + WT_ROOT . 'themes/fab/images', + WT_ROOT . 'themes/fab/msie.css', + WT_ROOT . 'themes/fab/style.css', + WT_ROOT . 'themes/minimal/favicon.png', + WT_ROOT . 'themes/minimal/images', + WT_ROOT . 'themes/minimal/msie.css', + WT_ROOT . 'themes/minimal/style.css', + WT_ROOT . 'themes/webtrees/favicon.png', + WT_ROOT . 'themes/webtrees/images', + WT_ROOT . 'themes/webtrees/msie.css', + WT_ROOT . 'themes/webtrees/style.css', + WT_ROOT . 'themes/xenea/favicon.png', + WT_ROOT . 'themes/xenea/images', + WT_ROOT . 'themes/xenea/msie.css', + WT_ROOT . 'themes/xenea/style.css', + // Removed in 1.5.1 + WT_ROOT . 'themes/clouds/css-1.5.0', + WT_ROOT . 'themes/colors/css-1.5.0', + WT_ROOT . 'themes/fab/css-1.5.0', + WT_ROOT . 'themes/minimal/css-1.5.0', + WT_ROOT . 'themes/webtrees/css-1.5.0', + WT_ROOT . 'themes/xenea/css-1.5.0', + // Removed in 1.5.2 + WT_ROOT . 'themes/clouds/css-1.5.1', + WT_ROOT . 'themes/colors/css-1.5.1', + WT_ROOT . 'themes/fab/css-1.5.1', + WT_ROOT . 'themes/minimal/css-1.5.1', + WT_ROOT . 'themes/webtrees/css-1.5.1', + WT_ROOT . 'themes/xenea/css-1.5.1', + // Removed in 1.5.3 + WT_ROOT . 'modules_v3/GEDFact_assistant/_CENS/census_asst_help.php', + WT_ROOT . 'modules_v3/googlemap/admin_places.php', + WT_ROOT . 'modules_v3/googlemap/defaultconfig.php', + WT_ROOT . 'modules_v3/googlemap/googlemap.php', + WT_ROOT . 'modules_v3/googlemap/placehierarchy.php', + WT_ROOT . 'modules_v3/googlemap/places_edit.php', + WT_ROOT . 'modules_v3/googlemap/util.js', + WT_ROOT . 'modules_v3/googlemap/wt_v3_places_edit.js.php', + WT_ROOT . 'modules_v3/googlemap/wt_v3_places_edit_overlays.js.php', + WT_ROOT . 'modules_v3/googlemap/wt_v3_street_view.php', + WT_ROOT . 'readme.html', + WT_ROOT . 'themes/clouds/css-1.5.2', + WT_ROOT . 'themes/colors/css-1.5.2', + WT_ROOT . 'themes/fab/css-1.5.2', + WT_ROOT . 'themes/minimal/css-1.5.2', + WT_ROOT . 'themes/webtrees/css-1.5.2', + WT_ROOT . 'themes/xenea/css-1.5.2', + // Removed in 1.6.0 + WT_ROOT . 'downloadbackup.php', + WT_ROOT . 'modules_v3/ckeditor/ckeditor-4.3.2-custom', + WT_ROOT . 'site-php-version.php', + WT_ROOT . 'themes/clouds/css-1.5.3', + WT_ROOT . 'themes/colors/css-1.5.3', + WT_ROOT . 'themes/fab/css-1.5.3', + WT_ROOT . 'themes/minimal/css-1.5.3', + WT_ROOT . 'themes/webtrees/css-1.5.3', + WT_ROOT . 'themes/xenea/css-1.5.3', + // Removed in 1.6.2 + WT_ROOT . 'themes/clouds/jquery-ui-1.10.3', + WT_ROOT . 'themes/colors/css-1.6.0', + WT_ROOT . 'themes/colors/jquery-ui-1.10.3', + WT_ROOT . 'themes/fab/css-1.6.0', + WT_ROOT . 'themes/fab/jquery-ui-1.10.3', + WT_ROOT . 'themes/minimal/css-1.6.0', + WT_ROOT . 'themes/minimal/jquery-ui-1.10.3', + WT_ROOT . 'themes/webtrees/css-1.6.0', + WT_ROOT . 'themes/webtrees/jquery-ui-1.10.3', + WT_ROOT . 'themes/xenea/css-1.6.0', + WT_ROOT . 'themes/xenea/jquery-ui-1.10.3', + // Removed in 1.7.0 + WT_ROOT . 'admin_site_other.php', + WT_ROOT . 'js', + WT_ROOT . 'language/en_GB.mo', + // Replaced with en-GB.mo + WT_ROOT . 'language/en_US.mo', + // Replaced with en-US.mo + WT_ROOT . 'language/pt_BR.mo', + // Replaced with pt-BR.mo + WT_ROOT . 'language/zh_CN.mo', + // Replaced with zh-Hans.mo + WT_ROOT . 'language/extra', + WT_ROOT . 'library', + WT_ROOT . 'modules_v3/batch_update/admin_batch_update.php', + WT_ROOT . 'modules_v3/batch_update/plugins', + WT_ROOT . 'modules_v3/charts/help_text.php', + WT_ROOT . 'modules_v3/ckeditor/ckeditor-4.4.1-custom', + WT_ROOT . 'modules_v3/clippings/clippings_ctrl.php', + WT_ROOT . 'modules_v3/clippings/help_text.php', + WT_ROOT . 'modules_v3/faq/help_text.php', + WT_ROOT . 'modules_v3/gedcom_favorites/db_schema', + WT_ROOT . 'modules_v3/gedcom_news/db_schema', + WT_ROOT . 'modules_v3/googlemap/db_schema', + WT_ROOT . 'modules_v3/googlemap/help_text.php', + WT_ROOT . 'modules_v3/html/help_text.php', + WT_ROOT . 'modules_v3/logged_in/help_text.php', + WT_ROOT . 'modules_v3/review_changes/help_text.php', + WT_ROOT . 'modules_v3/todo/help_text.php', + WT_ROOT . 'modules_v3/tree/class_treeview.php', + WT_ROOT . 'modules_v3/user_blog/db_schema', + WT_ROOT . 'modules_v3/yahrzeit/help_text.php', + WT_ROOT . 'save.php', + WT_ROOT . 'themes/clouds/css-1.6.2', + WT_ROOT . 'themes/clouds/templates', + WT_ROOT . 'themes/clouds/header.php', + WT_ROOT . 'themes/clouds/footer.php', + WT_ROOT . 'themes/colors/css-1.6.2', + WT_ROOT . 'themes/colors/templates', + WT_ROOT . 'themes/colors/header.php', + WT_ROOT . 'themes/colors/footer.php', + WT_ROOT . 'themes/fab/css-1.6.2', + WT_ROOT . 'themes/fab/templates', + WT_ROOT . 'themes/fab/header.php', + WT_ROOT . 'themes/fab/footer.php', + WT_ROOT . 'themes/minimal/css-1.6.2', + WT_ROOT . 'themes/minimal/templates', + WT_ROOT . 'themes/minimal/header.php', + WT_ROOT . 'themes/minimal/footer.php', + WT_ROOT . 'themes/webtrees/css-1.6.2', + WT_ROOT . 'themes/webtrees/templates', + WT_ROOT . 'themes/webtrees/header.php', + WT_ROOT . 'themes/webtrees/footer.php', + WT_ROOT . 'themes/xenea/css-1.6.2', + WT_ROOT . 'themes/xenea/templates', + WT_ROOT . 'themes/xenea/header.php', + WT_ROOT . 'themes/xenea/footer.php', + // Removed in 1.7.2 + WT_ROOT . 'assets/js-1.7.0', + // Removed in 1.7.3 + WT_ROOT . 'modules_v3/GEDFact_assistant/census/date.js', + WT_ROOT . 'modules_v3/GEDFact_assistant/census/dynamicoptionlist.js', + // Removed in 1.7.4 + WT_ROOT . 'assets/js-1.7.2', + WT_ROOT . 'themes/clouds/css-1.7.0', + WT_ROOT . 'themes/colors/css-1.7.0', + WT_ROOT . 'themes/fab/css-1.7.0', + WT_ROOT . 'themes/minimal/css-1.7.0', + WT_ROOT . 'themes/webtrees/css-1.7.0', + WT_ROOT . 'themes/xenea/css-1.7.0', + // Removed in 1.7.5 + WT_ROOT . 'themes/clouds/css-1.7.4', + WT_ROOT . 'themes/colors/css-1.7.4', + WT_ROOT . 'themes/fab/css-1.7.4', + WT_ROOT . 'themes/minimal/css-1.7.4', + WT_ROOT . 'themes/webtrees/css-1.7.4', + WT_ROOT . 'themes/xenea/css-1.7.4', + // Removed in 1.7.7 + WT_ROOT . 'assets/js-1.7.4', + WT_ROOT . 'modules_v3/googlemap/images/css_sprite_facts.png', + WT_ROOT . 'modules_v3/googlemap/images/flag_shadow.png', + WT_ROOT . 'modules_v3/googlemap/images/shadow-left-large.png', + WT_ROOT . 'modules_v3/googlemap/images/shadow-left-small.png', + WT_ROOT . 'modules_v3/googlemap/images/shadow-right-large.png', + WT_ROOT . 'modules_v3/googlemap/images/shadow-right-small.png', + WT_ROOT . 'modules_v3/googlemap/images/shadow50.png', + WT_ROOT . 'modules_v3/googlemap/images/transparent-left-large.png', + WT_ROOT . 'modules_v3/googlemap/images/transparent-left-small.png', + WT_ROOT . 'modules_v3/googlemap/images/transparent-right-large.png', + WT_ROOT . 'modules_v3/googlemap/images/transparent-right-small.png', + // Removed in 1.7.8 + WT_ROOT . 'themes/clouds/css-1.7.5', + WT_ROOT . 'themes/colors/css-1.7.5', + WT_ROOT . 'themes/fab/css-1.7.5', + WT_ROOT . 'themes/minimal/css-1.7.5', + WT_ROOT . 'themes/webtrees/css-1.7.5', + WT_ROOT . 'themes/xenea/css-1.7.5', + // Removed in 2.0.0 + WT_ROOT . 'action.php', + WT_ROOT . 'addmedia.php', + WT_ROOT . 'addmin.php', + WT_ROOT . 'admin_media.php', + WT_ROOT . 'admin_media_upload.php', + WT_ROOT . 'admin_module_blocks.php', + WT_ROOT . 'admin_module_charts.php', + WT_ROOT . 'admin_module_menus.php', + WT_ROOT . 'admin_module_reports.php', + WT_ROOT . 'admin_module_sidebar.php', + WT_ROOT . 'admin_module_tabs.php', + WT_ROOT . 'admin_modules.php', + WT_ROOT . 'admin_pgv_to_wt.php', + WT_ROOT . 'admin_site_access.php', + WT_ROOT . 'admin_site_change.php', + WT_ROOT . 'admin_site_clean.php', + WT_ROOT . 'admin_site_config.php', + WT_ROOT . 'admin_site_info.php', + WT_ROOT . 'admin_site_logs.php', + WT_ROOT . 'admin_site_merge.php', + WT_ROOT . 'admin_site_readme.php', + WT_ROOT . 'admin_site_upgrade.php', + WT_ROOT . 'admin_trees_check.php', + WT_ROOT . 'admin_trees_config.php', + WT_ROOT . 'admin_trees_download.php', + WT_ROOT . 'admin_trees_duplicates.php', + WT_ROOT . 'admin_trees_export.php', + WT_ROOT . 'admin_trees_manage.php', + WT_ROOT . 'admin_trees_merge.php', + WT_ROOT . 'admin_trees_places.php', + WT_ROOT . 'admin_trees_renumber.php', + WT_ROOT . 'admin_trees_unconnected.php', + WT_ROOT . 'admin_users.php', + WT_ROOT . 'admin_users_bulk.php', + WT_ROOT . 'ancestry.php', + WT_ROOT . 'app/Controller', + WT_ROOT . 'app/HitCounter.php', + WT_ROOT . 'app/Module/ClippingsCart/ClippingsCartController.php', + WT_ROOT . 'app/Module/FamiliesSidebarModule.php', + WT_ROOT . 'app/Module/FamilyTreeFavorites', + WT_ROOT . 'app/Module/GoogleMaps', + WT_ROOT . 'app/Module/IndividualSidebarModule.php', + WT_ROOT . 'app/Module/PageMenuModule.php', + WT_ROOT . 'app/SpecialChars', + WT_ROOT . 'assets/js-1.7.7', + WT_ROOT . 'assets/js-1.7.9', + WT_ROOT . 'autocomplete.php', + WT_ROOT . 'block_edit.php', + WT_ROOT . 'branches.php', + WT_ROOT . 'calendar.php', + WT_ROOT . 'compact.php', + WT_ROOT . 'data/html_purifier_cache', + WT_ROOT . 'descendancy.php', + WT_ROOT . 'editnews.php', + WT_ROOT . 'edituser.php', + WT_ROOT . 'edit_changes.php', + WT_ROOT . 'edit_interface.php', + WT_ROOT . 'expand_view.php', + WT_ROOT . 'familybook.php', + WT_ROOT . 'famlist.php', + WT_ROOT . 'fanchart.php', + WT_ROOT . 'find.php', + WT_ROOT . 'help_text.php', + WT_ROOT . 'hourglass.php', + WT_ROOT . 'hourglass_ajax.php', + WT_ROOT . 'import.php', + WT_ROOT . 'includes', + WT_ROOT . 'index_edit.php', + WT_ROOT . 'indilist.php', + WT_ROOT . 'inverselink.php', + WT_ROOT . 'lifespan.php', + WT_ROOT . 'login.php', + WT_ROOT . 'logout.php', + WT_ROOT . 'mediafirewall.php', + WT_ROOT . 'medialist.php', + WT_ROOT . 'message.php', + WT_ROOT . 'module.php', + WT_ROOT . 'notelist.php', + WT_ROOT . 'packages', + WT_ROOT . 'pedigree.php', + WT_ROOT . 'relationship.php', + WT_ROOT . 'repolist.php', + WT_ROOT . 'reportengine.php', + WT_ROOT . 'search.php', + WT_ROOT . 'search_advanced.php', + WT_ROOT . 'site-offline.php', + WT_ROOT . 'site-unavailable.php', + WT_ROOT . 'sourcelist.php', + WT_ROOT . 'statistics.php', + WT_ROOT . 'statisticsplot.php', + WT_ROOT . 'themes/_administration', + WT_ROOT . 'themes/_custom', + WT_ROOT . 'themes/clouds/css-1.7.8', + WT_ROOT . 'themes/clouds/jquery-ui-1.11.2', + WT_ROOT . 'themes/colors/css-1.7.8', + WT_ROOT . 'themes/colors/jquery-ui-1.11.2', + WT_ROOT . 'themes/fab/css-1.7.8', + WT_ROOT . 'themes/fab/jquery-ui-1.11.2', + WT_ROOT . 'themes/minimal/css-1.7.8', + WT_ROOT . 'themes/minimal/jquery-ui-1.11.2', + WT_ROOT . 'themes/webtrees/css-1.7.8', + WT_ROOT . 'themes/webtrees/jquery-ui-1.11.2', + WT_ROOT . 'themes/xenea/css-1.7.8', + WT_ROOT . 'themes/xenea/jquery-ui-1.11.2', + WT_ROOT . 'timeline.php', + ]; - protected $layout = 'layouts/administration'; + protected $layout = 'layouts/administration'; - /** - * Show the admin page for blocks. - * - * @return Response - */ - public function blocks(): Response { - return $this->components('block', 'blocks', I18N::translate('Block'), I18N::translate('Blocks')); - } + /** + * Show the admin page for blocks. + * + * @return Response + */ + public function blocks(): Response + { + return $this->components('block', 'blocks', I18N::translate('Block'), I18N::translate('Blocks')); + } - /** - * Show the admin page for charts. - * - * @return Response - */ - public function charts(): Response { - return $this->components('chart', 'charts', I18N::translate('Chart'), I18N::translate('Charts')); - } + /** + * Show the admin page for charts. + * + * @return Response + */ + public function charts(): Response + { + return $this->components('chart', 'charts', I18N::translate('Chart'), I18N::translate('Charts')); + } - /** - * The control panel shows a summary of the site and links to admin functions. - * - * @return Response - */ - public function controlPanel(): Response { - return $this->viewResponse('admin/control-panel', [ - 'title' => I18N::translate('Control panel'), - 'server_warnings' => $this->serverWarnings(), - 'latest_version' => $this->latestVersion(), - 'all_users' => User::all(), - 'administrators' => User::administrators(), - 'managers' => User::managers(), - 'moderators' => User::moderators(), - 'unapproved' => User::unapproved(), - 'unverified' => User::unverified(), - 'all_trees' => Tree::getAll(), - 'changes' => $this->totalChanges(), - 'individuals' => $this->totalIndividuals(), - 'families' => $this->totalFamilies(), - 'sources' => $this->totalSources(), - 'media' => $this->totalMediaObjects(), - 'repositories' => $this->totalRepositories(), - 'notes' => $this->totalNotes(), - 'files_to_delete' => $this->filesToDelete(), - 'all_modules' => Module::getInstalledModules('disabled'), - 'deleted_modules' => $this->deletedModuleNames(), - 'config_modules' => Module::configurableModules(), - ]); - } + /** + * The control panel shows a summary of the site and links to admin functions. + * + * @return Response + */ + public function controlPanel(): Response + { + return $this->viewResponse('admin/control-panel', [ + 'title' => I18N::translate('Control panel'), + 'server_warnings' => $this->serverWarnings(), + 'latest_version' => $this->latestVersion(), + 'all_users' => User::all(), + 'administrators' => User::administrators(), + 'managers' => User::managers(), + 'moderators' => User::moderators(), + 'unapproved' => User::unapproved(), + 'unverified' => User::unverified(), + 'all_trees' => Tree::getAll(), + 'changes' => $this->totalChanges(), + 'individuals' => $this->totalIndividuals(), + 'families' => $this->totalFamilies(), + 'sources' => $this->totalSources(), + 'media' => $this->totalMediaObjects(), + 'repositories' => $this->totalRepositories(), + 'notes' => $this->totalNotes(), + 'files_to_delete' => $this->filesToDelete(), + 'all_modules' => Module::getInstalledModules('disabled'), + 'deleted_modules' => $this->deletedModuleNames(), + 'config_modules' => Module::configurableModules(), + ]); + } - /** - * Managers see a restricted version of the contol panel. - * - * @return Response - */ - public function controlPanelManager(): Response { - $all_trees = array_filter(Tree::getAll(), function (Tree $tree) { - return Auth::isManager($tree); - }); + /** + * Managers see a restricted version of the contol panel. + * + * @return Response + */ + public function controlPanelManager(): Response + { + $all_trees = array_filter(Tree::getAll(), function (Tree $tree) { + return Auth::isManager($tree); + }); - return $this->viewResponse('admin/control-panel-manager', [ - 'title' => I18N::translate('Control panel'), - 'all_trees' => $all_trees, - 'changes' => $this->totalChanges(), - 'individuals' => $this->totalIndividuals(), - 'families' => $this->totalFamilies(), - 'sources' => $this->totalSources(), - 'media' => $this->totalMediaObjects(), - 'repositories' => $this->totalRepositories(), - 'notes' => $this->totalNotes(), - ]); - } + return $this->viewResponse('admin/control-panel-manager', [ + 'title' => I18N::translate('Control panel'), + 'all_trees' => $all_trees, + 'changes' => $this->totalChanges(), + 'individuals' => $this->totalIndividuals(), + 'families' => $this->totalFamilies(), + 'sources' => $this->totalSources(), + 'media' => $this->totalMediaObjects(), + 'repositories' => $this->totalRepositories(), + 'notes' => $this->totalNotes(), + ]); + } - /** - * Show the edit history for a tree. - * - * @param Request $request - * - * @return Response - */ - public function changesLog(Request $request): Response { - $tree_list = []; - foreach (Tree::getAll() as $tree) { - if (Auth::isManager($tree)) { - $tree_list[$tree->getName()] = $tree->getTitle(); - } - } + /** + * Show the edit history for a tree. + * + * @param Request $request + * + * @return Response + */ + public function changesLog(Request $request): Response + { + $tree_list = []; + foreach (Tree::getAll() as $tree) { + if (Auth::isManager($tree)) { + $tree_list[$tree->getName()] = $tree->getTitle(); + } + } - $user_list = ['' => '']; - foreach (User::all() as $tmp_user) { - $user_list[$tmp_user->getUserName()] = $tmp_user->getUserName(); - } + $user_list = ['' => '']; + foreach (User::all() as $tmp_user) { + $user_list[$tmp_user->getUserName()] = $tmp_user->getUserName(); + } - // First and last change in the database. - $earliest = Database::prepare("SELECT IFNULL(DATE(MIN(change_time)), CURDATE()) FROM `##change`")->fetchOne(); - $latest = Database::prepare("SELECT IFNULL(DATE(MAX(change_time)), CURDATE()) FROM `##change`")->fetchOne(); + // First and last change in the database. + $earliest = Database::prepare("SELECT IFNULL(DATE(MIN(change_time)), CURDATE()) FROM `##change`")->fetchOne(); + $latest = Database::prepare("SELECT IFNULL(DATE(MAX(change_time)), CURDATE()) FROM `##change`")->fetchOne(); - $action = $request->get('action'); - $ged = $request->get('ged'); - $from = $request->get('from', $earliest); - $to = $request->get('to', $latest); - $type = $request->get('type', ''); - $oldged = $request->get('oldged', ''); - $newged = $request->get('newged', ''); - $xref = $request->get('xref', ''); - $username = $request->get('username', ''); - $search = $request->get('search', []); - $search = $search['value'] ?? null; + $action = $request->get('action'); + $ged = $request->get('ged'); + $from = $request->get('from', $earliest); + $to = $request->get('to', $latest); + $type = $request->get('type', ''); + $oldged = $request->get('oldged', ''); + $newged = $request->get('newged', ''); + $xref = $request->get('xref', ''); + $username = $request->get('username', ''); + $search = $request->get('search', []); + $search = $search['value'] ?? null; - if (!array_key_exists($ged, $tree_list)) { - $ged = reset($tree_list); - } + if (!array_key_exists($ged, $tree_list)) { + $ged = reset($tree_list); + } - $statuses = [ - '' => '', - 'accepted' => /* I18N: the status of an edit accepted/rejected/pending */ - I18N::translate('accepted'), - 'rejected' => /* I18N: the status of an edit accepted/rejected/pending */ - I18N::translate('rejected'), - 'pending' => /* I18N: the status of an edit accepted/rejected/pending */ - I18N::translate('pending'), - ]; + $statuses = [ + '' => '', + 'accepted' => /* I18N: the status of an edit accepted/rejected/pending */ + I18N::translate('accepted'), + 'rejected' => /* I18N: the status of an edit accepted/rejected/pending */ + I18N::translate('rejected'), + 'pending' => /* I18N: the status of an edit accepted/rejected/pending */ + I18N::translate('pending'), + ]; - return $this->viewResponse('admin/changes-log', [ - 'action' => $action, - 'earliest' => $earliest, - 'from' => $from, - 'ged' => $ged, - 'latest' => $latest, - 'newged' => $newged, - 'oldged' => $oldged, - 'search' => $search, - 'statuses' => $statuses, - 'title' => I18N::translate('Changes log'), - 'to' => $to, - 'tree_list' => $tree_list, - 'type' => $type, - 'username' => $username, - 'user_list' => $user_list, - 'xref' => $xref, - ]); - } + return $this->viewResponse('admin/changes-log', [ + 'action' => $action, + 'earliest' => $earliest, + 'from' => $from, + 'ged' => $ged, + 'latest' => $latest, + 'newged' => $newged, + 'oldged' => $oldged, + 'search' => $search, + 'statuses' => $statuses, + 'title' => I18N::translate('Changes log'), + 'to' => $to, + 'tree_list' => $tree_list, + 'type' => $type, + 'username' => $username, + 'user_list' => $user_list, + 'xref' => $xref, + ]); + } - /** - * Show the edit history for a tree. - * - * @param Request $request - * - * @return Response - */ - public function changesLogData(Request $request): Response { - list($select, , $where, $args1) = $this->changesQuery($request); - list($order_by, $limit, $args2) = $this->dataTablesPagination($request); + /** + * Show the edit history for a tree. + * + * @param Request $request + * + * @return Response + */ + public function changesLogData(Request $request): Response + { + list($select, , $where, $args1) = $this->changesQuery($request); + list($order_by, $limit, $args2) = $this->dataTablesPagination($request); - $rows = Database::prepare( - $select . $where . $order_by . $limit - )->execute(array_merge($args1, $args2))->fetchAll(); + $rows = Database::prepare( + $select . $where . $order_by . $limit + )->execute(array_merge($args1, $args2))->fetchAll(); - // Total filtered/unfiltered rows - $recordsFiltered = (int) Database::prepare("SELECT FOUND_ROWS()")->fetchOne(); - $recordsTotal = (int) Database::prepare("SELECT COUNT(*) FROM `##change`")->fetchOne(); + // Total filtered/unfiltered rows + $recordsFiltered = (int)Database::prepare("SELECT FOUND_ROWS()")->fetchOne(); + $recordsTotal = (int)Database::prepare("SELECT COUNT(*) FROM `##change`")->fetchOne(); - $data = []; - $algorithm = new MyersDiff; + $data = []; + $algorithm = new MyersDiff; - foreach ($rows as $row) { - $old_lines = preg_split('/[\n]+/', $row->old_gedcom, -1, PREG_SPLIT_NO_EMPTY); - $new_lines = preg_split('/[\n]+/', $row->new_gedcom, -1, PREG_SPLIT_NO_EMPTY); + foreach ($rows as $row) { + $old_lines = preg_split('/[\n]+/', $row->old_gedcom, -1, PREG_SPLIT_NO_EMPTY); + $new_lines = preg_split('/[\n]+/', $row->new_gedcom, -1, PREG_SPLIT_NO_EMPTY); - $differences = $algorithm->calculate($old_lines, $new_lines); - $diff_lines = []; + $differences = $algorithm->calculate($old_lines, $new_lines); + $diff_lines = []; - foreach ($differences as $difference) { - switch ($difference[1]) { - case MyersDiff::DELETE: - $diff_lines[] = '<del>' . $difference[0] . '</del>'; - break; - case MyersDiff::INSERT: - $diff_lines[] = '<ins>' . $difference[0] . '</ins>'; - break; - default: - $diff_lines[] = $difference[0]; - } - } + foreach ($differences as $difference) { + switch ($difference[1]) { + case MyersDiff::DELETE: + $diff_lines[] = '<del>' . $difference[0] . '</del>'; + break; + case MyersDiff::INSERT: + $diff_lines[] = '<ins>' . $difference[0] . '</ins>'; + break; + default: + $diff_lines[] = $difference[0]; + } + } - // Only convert valid xrefs to links - $tree = Tree::findByName($row->gedcom_name); - $record = GedcomRecord::getInstance($row->xref, $tree); - $data[] = [ - $row->change_id, - $row->change_time, - I18N::translate($row->status), - $record ? '<a href="' . e($record->url()) . '">' . $record->getXref() . '</a>' : $row->xref, - '<div class="gedcom-data" dir="ltr">' . - preg_replace_callback('/@(' . WT_REGEX_XREF . ')@/', - function ($match) use ($tree) { - $record = GedcomRecord::getInstance($match[1], $tree); + // Only convert valid xrefs to links + $tree = Tree::findByName($row->gedcom_name); + $record = GedcomRecord::getInstance($row->xref, $tree); + $data[] = [ + $row->change_id, + $row->change_time, + I18N::translate($row->status), + $record ? '<a href="' . e($record->url()) . '">' . $record->getXref() . '</a>' : $row->xref, + '<div class="gedcom-data" dir="ltr">' . + preg_replace_callback('/@(' . WT_REGEX_XREF . ')@/', + function ($match) use ($tree) { + $record = GedcomRecord::getInstance($match[1], $tree); - return $record ? '<a href="' . e($record->url()) . '">' . $match[0] . '</a>' : $match[0]; - }, - implode("\n", $diff_lines) - ) . - '</div>', - $row->user_name, - $row->gedcom_name, - ]; - } + return $record ? '<a href="' . e($record->url()) . '">' . $match[0] . '</a>' : $match[0]; + }, + implode("\n", $diff_lines) + ) . + '</div>', + $row->user_name, + $row->gedcom_name, + ]; + } - // See http://www.datatables.net/usage/server-side - return new JsonResponse([ - 'draw' => (int) $request->get('draw'), - 'recordsTotal' => $recordsTotal, - 'recordsFiltered' => $recordsFiltered, - 'data' => $data, - ]); - } + // See http://www.datatables.net/usage/server-side + return new JsonResponse([ + 'draw' => (int)$request->get('draw'), + 'recordsTotal' => $recordsTotal, + 'recordsFiltered' => $recordsFiltered, + 'data' => $data, + ]); + } - /** - * Show the edit history for a tree. - * - * @param Request $request - * - * @return Response - */ - public function changesLogDownload(Request $request): Response { - list($select, , $where, $args) = $this->changesQuery($request); + /** + * Show the edit history for a tree. + * + * @param Request $request + * + * @return Response + */ + public function changesLogDownload(Request $request): Response + { + list($select, , $where, $args) = $this->changesQuery($request); - $rows = Database::prepare($select . $where)->execute($args)->fetchAll(); + $rows = Database::prepare($select . $where)->execute($args)->fetchAll(); - // Convert to CSV - $rows = array_map(function (stdClass $row) { - return implode(',', [ - '"' . $row->change_time . '"', - '"' . $row->status . '"', - '"' . $row->xref . '"', - '"' . strtr($row->old_gedcom, '"', '""') . '"', - '"' . strtr($row->new_gedcom, '"', '""') . '"', - '"' . strtr($row->user_name, '"', '""') . '"', - '"' . strtr($row->gedcom_name, '"', '""') . '"', - ]); - }, $rows); + // Convert to CSV + $rows = array_map(function (stdClass $row) { + return implode(',', [ + '"' . $row->change_time . '"', + '"' . $row->status . '"', + '"' . $row->xref . '"', + '"' . strtr($row->old_gedcom, '"', '""') . '"', + '"' . strtr($row->new_gedcom, '"', '""') . '"', + '"' . strtr($row->user_name, '"', '""') . '"', + '"' . strtr($row->gedcom_name, '"', '""') . '"', + ]); + }, $rows); - $response = new Response(implode("\n", $rows)); - $disposition = $response->headers->makeDisposition( - ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'changes.csv' - ); - $response->headers->set('Content-Disposition', $disposition); - $response->headers->set('Content-Type', 'text/csv; charset=UTF-8'); + $response = new Response(implode("\n", $rows)); + $disposition = $response->headers->makeDisposition( + ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'changes.csv' + ); + $response->headers->set('Content-Disposition', $disposition); + $response->headers->set('Content-Type', 'text/csv; charset=UTF-8'); - return $response; - } + return $response; + } - /** - * Delete the database settings for a deleted module. - * - * @param Request $request - * - * @return RedirectResponse - */ - public function deleteModuleSettings(Request $request): RedirectResponse { - $module_name = $request->get('module_name'); + /** + * Delete the database settings for a deleted module. + * + * @param Request $request + * + * @return RedirectResponse + */ + public function deleteModuleSettings(Request $request): RedirectResponse + { + $module_name = $request->get('module_name'); - Database::prepare( - "DELETE `##block_setting` FROM `##block_setting` JOIN `##block` USING (block_id) JOIN `##module` USING (module_name) WHERE module_name = :module_name" - )->execute([ - 'module_name' => $module_name, - ]); + Database::prepare( + "DELETE `##block_setting` FROM `##block_setting` JOIN `##block` USING (block_id) JOIN `##module` USING (module_name) WHERE module_name = :module_name" + )->execute([ + 'module_name' => $module_name, + ]); - Database::prepare( - "DELETE `##block` FROM `##block` JOIN `##module` USING (module_name) WHERE module_name = :module_name" - )->execute([ - 'module_name' => $module_name, - ]); + Database::prepare( + "DELETE `##block` FROM `##block` JOIN `##module` USING (module_name) WHERE module_name = :module_name" + )->execute([ + 'module_name' => $module_name, + ]); - Database::prepare( - "DELETE FROM `##module_setting` WHERE module_name = :module_name" - )->execute([ - 'module_name' => $module_name, - ]); + Database::prepare( + "DELETE FROM `##module_setting` WHERE module_name = :module_name" + )->execute([ + 'module_name' => $module_name, + ]); - Database::prepare( - "DELETE FROM `##module_privacy` WHERE module_name = :module_name" - )->execute([ - 'module_name' => $module_name, - ]); + Database::prepare( + "DELETE FROM `##module_privacy` WHERE module_name = :module_name" + )->execute([ + 'module_name' => $module_name, + ]); - Database::prepare( - "DELETE FROM `##module` WHERE module_name = :module_name" - )->execute([ - 'module_name' => $module_name, - ]); + Database::prepare( + "DELETE FROM `##module` WHERE module_name = :module_name" + )->execute([ + 'module_name' => $module_name, + ]); - FlashMessages::addMessage(I18N::translate('The preferences for the module “%s” have been deleted.', $module_name), 'success'); + FlashMessages::addMessage(I18N::translate('The preferences for the module “%s” have been deleted.', $module_name), 'success'); - return new RedirectResponse(route('admin-modules')); - } + return new RedirectResponse(route('admin-modules')); + } - /** - * If media objects are wronly linked to top-level records, reattach them - * to facts/events. - * - * @return Response - */ - public function fixLevel0Media(): Response { - return $this->viewResponse('admin/fix-level-0-media', [ - 'title' => I18N::translate('Link media objects to facts and events'), - ]); - } + /** + * If media objects are wronly linked to top-level records, reattach them + * to facts/events. + * + * @return Response + */ + public function fixLevel0Media(): Response + { + return $this->viewResponse('admin/fix-level-0-media', [ + 'title' => I18N::translate('Link media objects to facts and events'), + ]); + } - /** - * Move a link to a media object from a level 0 record to a level 1 record. - * - * @param Request $request - * - * @return Response - */ - public function fixLevel0MediaAction(Request $request): Response { - $fact_id = $request->get('fact_id'); - $indi_xref = $request->get('indi_xref'); - $obje_xref = $request->get('obje_xref'); - $tree_id = $request->get('tree_id'); + /** + * Move a link to a media object from a level 0 record to a level 1 record. + * + * @param Request $request + * + * @return Response + */ + public function fixLevel0MediaAction(Request $request): Response + { + $fact_id = $request->get('fact_id'); + $indi_xref = $request->get('indi_xref'); + $obje_xref = $request->get('obje_xref'); + $tree_id = $request->get('tree_id'); - $tree = Tree::findById($tree_id); - if ($tree !== null) { - $individual = Individual::getInstance($indi_xref, $tree); - $media = Media::getInstance($obje_xref, $tree); - if ($individual !== null && $media !== null) { - foreach ($individual->getFacts() as $fact1) { - if ($fact1->getFactId() === $fact_id) { - $individual->updateFact($fact_id, $fact1->getGedcom() . "\n2 OBJE @" . $obje_xref . '@', false); - foreach ($individual->getFacts('OBJE') as $fact2) { - if ($fact2->getTarget() === $media) { - $individual->deleteFact($fact2->getFactId(), false); - } - } - break; - } - } - } - } + $tree = Tree::findById($tree_id); + if ($tree !== null) { + $individual = Individual::getInstance($indi_xref, $tree); + $media = Media::getInstance($obje_xref, $tree); + if ($individual !== null && $media !== null) { + foreach ($individual->getFacts() as $fact1) { + if ($fact1->getFactId() === $fact_id) { + $individual->updateFact($fact_id, $fact1->getGedcom() . "\n2 OBJE @" . $obje_xref . '@', false); + foreach ($individual->getFacts('OBJE') as $fact2) { + if ($fact2->getTarget() === $media) { + $individual->deleteFact($fact2->getFactId(), false); + } + } + break; + } + } + } + } - return new Response; - } + return new Response; + } - /** - * If media objects are wronly linked to top-level records, reattach them - * to facts/events. - * - * @param Request $request - * - * @return JsonResponse - */ - public function fixLevel0MediaData(Request $request): JsonResponse { - $ignore_facts = ['FAMC', 'FAMS', 'NAME', 'SEX', 'CHAN', 'NOTE', 'OBJE', 'SOUR', 'RESN']; + /** + * If media objects are wronly linked to top-level records, reattach them + * to facts/events. + * + * @param Request $request + * + * @return JsonResponse + */ + public function fixLevel0MediaData(Request $request): JsonResponse + { + $ignore_facts = [ + 'FAMC', + 'FAMS', + 'NAME', + 'SEX', + 'CHAN', + 'NOTE', + 'OBJE', + 'SOUR', + 'RESN', + ]; - $start = (int) $request->get('start', 0); - $length = (int) $request->get('length', 20); - $search = $request->get('search', []); - $search = $search['value'] ?? ''; + $start = (int)$request->get('start', 0); + $length = (int)$request->get('length', 20); + $search = $request->get('search', []); + $search = $search['value'] ?? ''; - $select1 = "SELECT SQL_CALC_FOUND_ROWS m.*, i.* from `##media` AS m" . - " JOIN `##media_file` USING (m_id, m_file)" . - " JOIN `##link` AS l ON m.m_file = l.l_file AND m.m_id = l.l_to" . - " JOIN `##individuals` AS i ON l.l_file = i.i_file AND l.l_from = i.i_id" . - " WHERE i.i_gedcom LIKE CONCAT('%\n1 OBJE @', m.m_id, '@%')"; + $select1 = "SELECT SQL_CALC_FOUND_ROWS m.*, i.* from `##media` AS m" . + " JOIN `##media_file` USING (m_id, m_file)" . + " JOIN `##link` AS l ON m.m_file = l.l_file AND m.m_id = l.l_to" . + " JOIN `##individuals` AS i ON l.l_file = i.i_file AND l.l_from = i.i_id" . + " WHERE i.i_gedcom LIKE CONCAT('%\n1 OBJE @', m.m_id, '@%')"; - $select2 = "SELECT SQL_CALC_FOUND_ROWS count(*) from `##media` AS m" . - " JOIN `##media_file` USING (m_id, m_file)" . - " JOIN `##link` AS l ON m.m_file = l.l_file AND m.m_id = l.l_to" . - " JOIN `##individuals` AS i ON l.l_file = i.i_file AND l.l_from = i.i_id" . - " WHERE i.i_gedcom LIKE CONCAT('%\n1 OBJE @', m.m_id, '@%')"; + $select2 = "SELECT SQL_CALC_FOUND_ROWS count(*) from `##media` AS m" . + " JOIN `##media_file` USING (m_id, m_file)" . + " JOIN `##link` AS l ON m.m_file = l.l_file AND m.m_id = l.l_to" . + " JOIN `##individuals` AS i ON l.l_file = i.i_file AND l.l_from = i.i_id" . + " WHERE i.i_gedcom LIKE CONCAT('%\n1 OBJE @', m.m_id, '@%')"; - $where = ''; - $args = []; + $where = ''; + $args = []; - if ($search !== '') { - $where .= " AND (multimedia_file_refn LIKE CONCAT('%', :search1, '%') OR multimedia_file_refn LIKE CONCAT('%', :search2, '%'))"; - $args['search1'] = $search; - $args['search2'] = $search; - } + if ($search !== '') { + $where .= " AND (multimedia_file_refn LIKE CONCAT('%', :search1, '%') OR multimedia_file_refn LIKE CONCAT('%', :search2, '%'))"; + $args['search1'] = $search; + $args['search2'] = $search; + } - $limit = " LIMIT :limit OFFSET :offset"; - $args['limit'] = $length; - $args['offset'] = $start; + $limit = " LIMIT :limit OFFSET :offset"; + $args['limit'] = $length; + $args['offset'] = $start; - // Need a consistent order - $order_by = " ORDER BY i.i_file, i.i_id, m.m_id"; + // Need a consistent order + $order_by = " ORDER BY i.i_file, i.i_id, m.m_id"; - $data = Database::prepare( - $select1 . $where . $order_by . $limit - )->execute( - $args - )->fetchAll(); + $data = Database::prepare( + $select1 . $where . $order_by . $limit + )->execute( + $args + )->fetchAll(); - // Total filtered/unfiltered rows - $recordsFiltered = (int) Database::prepare("SELECT FOUND_ROWS()")->fetchOne(); - $recordsTotal = (int) Database::prepare($select2)->fetchOne(); + // Total filtered/unfiltered rows + $recordsFiltered = (int)Database::prepare("SELECT FOUND_ROWS()")->fetchOne(); + $recordsTotal = (int)Database::prepare($select2)->fetchOne(); - // Turn each row from the query into a row for the table - $data = array_map(function (stdClass $datum) use ($ignore_facts) { - $tree = Tree::findById($datum->m_file); - $media = Media::getInstance($datum->m_id, $tree, $datum->m_gedcom); - $individual = Individual::getInstance($datum->i_id, $tree, $datum->i_gedcom); + // Turn each row from the query into a row for the table + $data = array_map(function (stdClass $datum) use ($ignore_facts) { + $tree = Tree::findById($datum->m_file); + $media = Media::getInstance($datum->m_id, $tree, $datum->m_gedcom); + $individual = Individual::getInstance($datum->i_id, $tree, $datum->i_gedcom); - $facts = $individual->getFacts(null, true); - $facts = array_filter($facts, function (Fact $fact) use ($ignore_facts) { - return !$fact->isPendingDeletion() && !in_array($fact->getTag(), $ignore_facts); - }); + $facts = $individual->getFacts(null, true); + $facts = array_filter($facts, function (Fact $fact) use ($ignore_facts) { + return !$fact->isPendingDeletion() && !in_array($fact->getTag(), $ignore_facts); + }); - // The link to the media object may have been deleted in a pending change. - $deleted = true; - foreach ($individual->getFacts('OBJE') as $fact) { - if ($fact->getTarget() === $media && !$fact->isPendingDeletion()) { - $deleted = false; - } - } - if ($deleted) { - $facts = []; - } + // The link to the media object may have been deleted in a pending change. + $deleted = true; + foreach ($individual->getFacts('OBJE') as $fact) { + if ($fact->getTarget() === $media && !$fact->isPendingDeletion()) { + $deleted = false; + } + } + if ($deleted) { + $facts = []; + } - $facts = array_map(function (Fact $fact) use ($individual, $media) { - return view('admin/fix-level-0-media-action', [ - 'fact' => $fact, - 'individual' => $individual, - 'media' => $media, - ]); - }, $facts); + $facts = array_map(function (Fact $fact) use ($individual, $media) { + return view('admin/fix-level-0-media-action', [ + 'fact' => $fact, + 'individual' => $individual, + 'media' => $media, + ]); + }, $facts); - return [ - $tree->getName(), - $media->displayImage(100, 100, 'fit', ['class' => 'img-thumbnail']), - '<a href="' . e($media->url()) . '">' . $media->getFullName() . '</a>', - '<a href="' . e($individual->url()) . '">' . $individual->getFullName() . '</a>', - implode(' ', $facts), - ]; - }, $data); + return [ + $tree->getName(), + $media->displayImage(100, 100, 'fit', ['class' => 'img-thumbnail']), + '<a href="' . e($media->url()) . '">' . $media->getFullName() . '</a>', + '<a href="' . e($individual->url()) . '">' . $individual->getFullName() . '</a>', + implode(' ', $facts), + ]; + }, $data); - return new JsonResponse([ - 'draw' => (int) $request->get('draw'), - 'recordsTotal' => $recordsTotal, - 'recordsFiltered' => $recordsFiltered, - 'data' => $data, - ]); - } + return new JsonResponse([ + 'draw' => (int)$request->get('draw'), + 'recordsTotal' => $recordsTotal, + 'recordsFiltered' => $recordsFiltered, + 'data' => $data, + ]); + } - /** - * Import custom thumbnails from webtres 1.x. - * - * @return Response - */ - public function webtrees1Thumbnails(): Response { - return $this->viewResponse('admin/webtrees1-thumbnails', [ - 'title' => I18N::translate('Import custom thumbnails from webtrees version 1'), - ]); - } + /** + * Import custom thumbnails from webtres 1.x. + * + * @return Response + */ + public function webtrees1Thumbnails(): Response + { + return $this->viewResponse('admin/webtrees1-thumbnails', [ + 'title' => I18N::translate('Import custom thumbnails from webtrees version 1'), + ]); + } - /** - * Import custom thumbnails from webtres 1.x. - * - * @param Request $request - * - * @return Response - */ - public function webtrees1ThumbnailsAction(Request $request): Response { - $thumbnail = $request->get('thumbnail', ''); - $action = $request->get('action', ''); - $xrefs = $request->get('xref', []); - $geds = $request->get('ged', []); + /** + * Import custom thumbnails from webtres 1.x. + * + * @param Request $request + * + * @return Response + */ + public function webtrees1ThumbnailsAction(Request $request): Response + { + $thumbnail = $request->get('thumbnail', ''); + $action = $request->get('action', ''); + $xrefs = $request->get('xref', []); + $geds = $request->get('ged', []); - $media_objects = []; + $media_objects = []; - foreach ($xrefs as $key => $xref) { - $tree = Tree::findByName($geds[$key]); - $media_objects[] = Media::getInstance($xref, $tree); - } + foreach ($xrefs as $key => $xref) { + $tree = Tree::findByName($geds[$key]); + $media_objects[] = Media::getInstance($xref, $tree); + } - $thumbnail = WT_DATA_DIR . $thumbnail; + $thumbnail = WT_DATA_DIR . $thumbnail; - switch ($action) { - case 'delete': - if (file_exists($thumbnail)) { - unlink($thumbnail); - } - break; + switch ($action) { + case 'delete': + if (file_exists($thumbnail)) { + unlink($thumbnail); + } + break; - case 'add': - $image_size = getimagesize($thumbnail); - list(, $extension) = explode('/', $image_size['mime']); - $move_to = dirname(dirname($thumbnail)) . '/' . sha1_file($thumbnail) . '.' . $extension; - rename($thumbnail, $move_to); + case 'add': + $image_size = getimagesize($thumbnail); + list(, $extension) = explode('/', $image_size['mime']); + $move_to = dirname(dirname($thumbnail)) . '/' . sha1_file($thumbnail) . '.' . $extension; + rename($thumbnail, $move_to); - foreach ($media_objects as $media_object) { - $prefix = WT_DATA_DIR . $media_object->getTree()->getPreference('MEDIA_DIRECTORY'); - $gedcom = "1 FILE " . substr($move_to, strlen($prefix)) . "\n2 FORM " . $extension; + foreach ($media_objects as $media_object) { + $prefix = WT_DATA_DIR . $media_object->getTree()->getPreference('MEDIA_DIRECTORY'); + $gedcom = "1 FILE " . substr($move_to, strlen($prefix)) . "\n2 FORM " . $extension; - if ($media_object->firstImageFile() === null) { - // The media object doesn't have an image. Add this as a secondary file. - $media_object->createFact($gedcom, true); - } else { - // The media object already has an image. Show this custom one in preference. - $gedcom = '0 @' . $media_object->getXref() . "@ OBJE\n" . $gedcom; - foreach ($media_object->getFacts() as $fact) { - $gedcom .= "\n" . $fact->getGedcom(); - } - $media_object->updateRecord($gedcom, true); - } + if ($media_object->firstImageFile() === null) { + // The media object doesn't have an image. Add this as a secondary file. + $media_object->createFact($gedcom, true); + } else { + // The media object already has an image. Show this custom one in preference. + $gedcom = '0 @' . $media_object->getXref() . "@ OBJE\n" . $gedcom; + foreach ($media_object->getFacts() as $fact) { + $gedcom .= "\n" . $fact->getGedcom(); + } + $media_object->updateRecord($gedcom, true); + } - // Accept the changes, to keep the filesystem in sync with the GEDCOM data. - FunctionsImport::acceptAllChanges($media_object->getxref(), $media_object->getTree()); - } - break; - } + // Accept the changes, to keep the filesystem in sync with the GEDCOM data. + FunctionsImport::acceptAllChanges($media_object->getxref(), $media_object->getTree()); + } + break; + } - return new JsonResponse([]); - } + return new JsonResponse([]); + } - /** - * Import custom thumbnails from webtres 1.x. - * - * @param Request $request - * - * @return JsonResponse - */ - public function webtrees1ThumbnailsData(Request $request): JsonResponse { - $start = (int) $request->get('start', 0); - $length = (int) $request->get('length', 20); - $search = $request->get('search', []); - $search = $search['value'] ?? ''; + /** + * Import custom thumbnails from webtres 1.x. + * + * @param Request $request + * + * @return JsonResponse + */ + public function webtrees1ThumbnailsData(Request $request): JsonResponse + { + $start = (int)$request->get('start', 0); + $length = (int)$request->get('length', 20); + $search = $request->get('search', []); + $search = $search['value'] ?? ''; - // Fetch all thumbnails - $thumbnails = []; + // Fetch all thumbnails + $thumbnails = []; - $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(WT_DATA_DIR, FilesystemIterator::FOLLOW_SYMLINKS)); + $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(WT_DATA_DIR, FilesystemIterator::FOLLOW_SYMLINKS)); - foreach ($iterator as $iteration) { - if ($iteration->isFile() && strpos($iteration->getPathname(), '/thumbs/') !== false) { - $thumbnails[] = $iteration->getPathname(); - } - } + foreach ($iterator as $iteration) { + if ($iteration->isFile() && strpos($iteration->getPathname(), '/thumbs/') !== false) { + $thumbnails[] = $iteration->getPathname(); + } + } - $recordsTotal = count($thumbnails); + $recordsTotal = count($thumbnails); - if ($search !== '') { - $thumbnails = array_filter($thumbnails, function (string $thumbnail) use ($search) { - return stripos($thumbnail, $search) !== false; - }); - } + if ($search !== '') { + $thumbnails = array_filter($thumbnails, function (string $thumbnail) use ($search) { + return stripos($thumbnail, $search) !== false; + }); + } - $recordsFiltered = count($thumbnails); + $recordsFiltered = count($thumbnails); - $thumbnails = array_slice($thumbnails, $start, $length); + $thumbnails = array_slice($thumbnails, $start, $length); - // Turn each filename into a row for the table - $data = array_map(function (string $thumbnail) { - $original = $this->findOriginalFileFromThumbnail($thumbnail); + // Turn each filename into a row for the table + $data = array_map(function (string $thumbnail) { + $original = $this->findOriginalFileFromThumbnail($thumbnail); - $original_url = route('unused-media-thumbnail', [ - 'folder' => dirname($original), - 'file' => basename($original), - 'w' => 100, - 'h' => 100, - ]); - $thumbnail_url = route('unused-media-thumbnail', [ - 'folder' => dirname($thumbnail), - 'file' => basename($thumbnail), - 'w' => 100, - 'h' => 100, - ]); + $original_url = route('unused-media-thumbnail', [ + 'folder' => dirname($original), + 'file' => basename($original), + 'w' => 100, + 'h' => 100, + ]); + $thumbnail_url = route('unused-media-thumbnail', [ + 'folder' => dirname($thumbnail), + 'file' => basename($thumbnail), + 'w' => 100, + 'h' => 100, + ]); - $difference = $this->imageDiff($thumbnail, $original); + $difference = $this->imageDiff($thumbnail, $original); - $original_path = substr($original, strlen(WT_DATA_DIR)); - $thumbnail_path = substr($thumbnail, strlen(WT_DATA_DIR)); + $original_path = substr($original, strlen(WT_DATA_DIR)); + $thumbnail_path = substr($thumbnail, strlen(WT_DATA_DIR)); - $media = $this->findMediaObjectsForMediaFile($original_path); + $media = $this->findMediaObjectsForMediaFile($original_path); - $media_links = array_map(function (Media $media) { - return '<a href="' . e($media->url()) . '">' . $media->getFullName() . '</a>'; - }, $media); + $media_links = array_map(function (Media $media) { + return '<a href="' . e($media->url()) . '">' . $media->getFullName() . '</a>'; + }, $media); - $media_links = implode('<br>', $media_links); + $media_links = implode('<br>', $media_links); - $action = view('admin/webtrees1-thumbnails-form', [ - 'difference' => $difference, - 'media' => $media, - 'thumbnail' => $thumbnail_path, - ]); + $action = view('admin/webtrees1-thumbnails-form', [ + 'difference' => $difference, + 'media' => $media, + 'thumbnail' => $thumbnail_path, + ]); - return [ - '<img src="' . e($thumbnail_url) . '" title="' . e($thumbnail_path) . '">', - '<img src="' . e($original_url) . '" title="' . e($original_path) . '">', - $media_links, - I18N::percentage($difference / 100.0, 0), - $action, - ]; - }, $thumbnails); + return [ + '<img src="' . e($thumbnail_url) . '" title="' . e($thumbnail_path) . '">', + '<img src="' . e($original_url) . '" title="' . e($original_path) . '">', + $media_links, + I18N::percentage($difference / 100.0, 0), + $action, + ]; + }, $thumbnails); - return new JsonResponse([ - 'draw' => (int) $request->get('draw'), - 'recordsTotal' => $recordsTotal, - 'recordsFiltered' => $recordsFiltered, - 'data' => $data, - ]); - } + return new JsonResponse([ + 'draw' => (int)$request->get('draw'), + 'recordsTotal' => $recordsTotal, + 'recordsFiltered' => $recordsFiltered, + 'data' => $data, + ]); + } - /** - * Merge two genealogy records. - * - * @param Request $request - * - * @return Response - */ - public function mergeRecords(Request $request): Response { - /** @var Tree $tree */ - $tree = $request->attributes->get('tree'); - $title = I18N::translate('Merge records') . ' — ' . e($tree->getTitle()); + /** + * Merge two genealogy records. + * + * @param Request $request + * + * @return Response + */ + public function mergeRecords(Request $request): Response + { + /** @var Tree $tree */ + $tree = $request->attributes->get('tree'); + $title = I18N::translate('Merge records') . ' — ' . e($tree->getTitle()); - $xref1 = $request->get('xref1', ''); - $xref2 = $request->get('xref2', ''); + $xref1 = $request->get('xref1', ''); + $xref2 = $request->get('xref2', ''); - $record1 = GedcomRecord::getInstance($xref1, $tree); - $record2 = GedcomRecord::getInstance($xref2, $tree); + $record1 = GedcomRecord::getInstance($xref1, $tree); + $record2 = GedcomRecord::getInstance($xref2, $tree); - if ($xref1 !== '' && $record1 === null) { - $xref1 = ''; - } + if ($xref1 !== '' && $record1 === null) { + $xref1 = ''; + } - if ($xref2 !== '' && $record2 === null) { - $xref2 = ''; - } + if ($xref2 !== '' && $record2 === null) { + $xref2 = ''; + } - if ($record1 === $record2) { - $xref2 = ''; - } + if ($record1 === $record2) { + $xref2 = ''; + } - if ($record1 !== null && $record2 && $record1::RECORD_TYPE !== $record2::RECORD_TYPE) { - $xref2 = ''; - } + if ($record1 !== null && $record2 && $record1::RECORD_TYPE !== $record2::RECORD_TYPE) { + $xref2 = ''; + } - if ($xref1 === '' || $xref2 === '') { - return $this->viewResponse('admin/merge-records-step-1', [ - 'individual1' => $record1 instanceof Individual ? $record1 : null, - 'individual2' => $record2 instanceof Individual ? $record2 : null, - 'family1' => $record1 instanceof Family ? $record1 : null, - 'family2' => $record2 instanceof Family ? $record2 : null, - 'source1' => $record1 instanceof Source ? $record1 : null, - 'source2' => $record2 instanceof Source ? $record2 : null, - 'repository1' => $record1 instanceof Repository ? $record1 : null, - 'repository2' => $record2 instanceof Repository ? $record2 : null, - 'media1' => $record1 instanceof Media ? $record1 : null, - 'media2' => $record2 instanceof Media ? $record2 : null, - 'note1' => $record1 instanceof Note ? $record1 : null, - 'note2' => $record2 instanceof Note ? $record2 : null, - 'title' => $title, - ]); - } + if ($xref1 === '' || $xref2 === '') { + return $this->viewResponse('admin/merge-records-step-1', [ + 'individual1' => $record1 instanceof Individual ? $record1 : null, + 'individual2' => $record2 instanceof Individual ? $record2 : null, + 'family1' => $record1 instanceof Family ? $record1 : null, + 'family2' => $record2 instanceof Family ? $record2 : null, + 'source1' => $record1 instanceof Source ? $record1 : null, + 'source2' => $record2 instanceof Source ? $record2 : null, + 'repository1' => $record1 instanceof Repository ? $record1 : null, + 'repository2' => $record2 instanceof Repository ? $record2 : null, + 'media1' => $record1 instanceof Media ? $record1 : null, + 'media2' => $record2 instanceof Media ? $record2 : null, + 'note1' => $record1 instanceof Note ? $record1 : null, + 'note2' => $record2 instanceof Note ? $record2 : null, + 'title' => $title, + ]); + } - // Facts found both records - $facts = []; - // Facts found in only one record - $facts1 = []; - $facts2 = []; + // Facts found both records + $facts = []; + // Facts found in only one record + $facts1 = []; + $facts2 = []; - foreach ($record1->getFacts() as $fact) { - if (!$fact->isPendingDeletion() && $fact->getTag() !== 'CHAN') { - $facts1[$fact->getFactId()] = $fact; - } - } + foreach ($record1->getFacts() as $fact) { + if (!$fact->isPendingDeletion() && $fact->getTag() !== 'CHAN') { + $facts1[$fact->getFactId()] = $fact; + } + } - foreach ($record2->getFacts() as $fact) { - if (!$fact->isPendingDeletion() && $fact->getTag() !== 'CHAN') { - $facts2[$fact->getFactId()] = $fact; - } - } + foreach ($record2->getFacts() as $fact) { + if (!$fact->isPendingDeletion() && $fact->getTag() !== 'CHAN') { + $facts2[$fact->getFactId()] = $fact; + } + } - foreach ($facts1 as $id1 => $fact1) { - foreach ($facts2 as $id2 => $fact2) { - if ($fact1->getFactId() === $fact2->getFactId()) { - $facts[] = $fact1; - unset($facts1[$id1]); - unset($facts2[$id2]); - } - } - } + foreach ($facts1 as $id1 => $fact1) { + foreach ($facts2 as $id2 => $fact2) { + if ($fact1->getFactId() === $fact2->getFactId()) { + $facts[] = $fact1; + unset($facts1[$id1]); + unset($facts2[$id2]); + } + } + } - return $this->viewResponse('admin/merge-records-step-2', [ - 'facts' => $facts, - 'facts1' => $facts1, - 'facts2' => $facts2, - 'record1' => $record1, - 'record2' => $record2, - 'title' => $title, - ]); - } + return $this->viewResponse('admin/merge-records-step-2', [ + 'facts' => $facts, + 'facts1' => $facts1, + 'facts2' => $facts2, + 'record1' => $record1, + 'record2' => $record2, + 'title' => $title, + ]); + } - /** - * @param Request $request - * - * @return Response - */ - public function mergeRecordsAction(Request $request): Response { - /** @var Tree $tree */ - $tree = $request->attributes->get('tree'); - $xref1 = $request->get('xref1', ''); - $xref2 = $request->get('xref2', ''); - $keep1 = $request->get('keep1', []); - $keep2 = $request->get('keep2', []); + /** + * @param Request $request + * + * @return Response + */ + public function mergeRecordsAction(Request $request): Response + { + /** @var Tree $tree */ + $tree = $request->attributes->get('tree'); + $xref1 = $request->get('xref1', ''); + $xref2 = $request->get('xref2', ''); + $keep1 = $request->get('keep1', []); + $keep2 = $request->get('keep2', []); - $record1 = GedcomRecord::getInstance($xref1, $tree); - $record2 = GedcomRecord::getInstance($xref2, $tree); + $record1 = GedcomRecord::getInstance($xref1, $tree); + $record2 = GedcomRecord::getInstance($xref2, $tree); - // Facts found both records - $facts = []; - // Facts found in only one record - $facts1 = []; - $facts2 = []; + // Facts found both records + $facts = []; + // Facts found in only one record + $facts1 = []; + $facts2 = []; - foreach ($record1->getFacts() as $fact) { - if (!$fact->isPendingDeletion() && $fact->getTag() !== 'CHAN') { - $facts1[$fact->getFactId()] = $fact; - } - } + foreach ($record1->getFacts() as $fact) { + if (!$fact->isPendingDeletion() && $fact->getTag() !== 'CHAN') { + $facts1[$fact->getFactId()] = $fact; + } + } - foreach ($record2->getFacts() as $fact) { - if (!$fact->isPendingDeletion() && $fact->getTag() !== 'CHAN') { - $facts2[$fact->getFactId()] = $fact; - } - } + foreach ($record2->getFacts() as $fact) { + if (!$fact->isPendingDeletion() && $fact->getTag() !== 'CHAN') { + $facts2[$fact->getFactId()] = $fact; + } + } - // If we are not auto-accepting, then we can show a link to the pending deletion - if (Auth::user()->getPreference('auto_accept')) { - $record2_name = $record2->getFullName(); - } else { - $record2_name = '<a class="alert-link" href="' . e($record2->url()) . '">' . $record2->getFullName() . '</a>'; - } + // If we are not auto-accepting, then we can show a link to the pending deletion + if (Auth::user()->getPreference('auto_accept')) { + $record2_name = $record2->getFullName(); + } else { + $record2_name = '<a class="alert-link" href="' . e($record2->url()) . '">' . $record2->getFullName() . '</a>'; + } - // Update records that link to the one we will be removing. - $ids = FunctionsDb::fetchAllLinks($xref2, $tree->getTreeId()); + // Update records that link to the one we will be removing. + $ids = FunctionsDb::fetchAllLinks($xref2, $tree->getTreeId()); - foreach ($ids as $id) { - $record = GedcomRecord::getInstance($id, $tree); - if (!$record->isPendingDeletion()) { - FlashMessages::addMessage(I18N::translate( - /* I18N: The placeholders are the names of individuals, sources, etc. */ - 'The link from “%1$s” to “%2$s” has been updated.', - '<a class="alert-link" href="' . e($record->url()) . '">' . $record->getFullName() . '</a>', - $record2_name - ), 'info'); - $gedcom = str_replace('@' . $xref2 . '@', '@' . $xref1 . '@', $record->getGedcom()); - $gedcom = preg_replace( - '/(\n1.*@.+@.*(?:(?:\n[2-9].*)*))((?:\n1.*(?:\n[2-9].*)*)*\1)/', - '$2', - $gedcom - ); - $record->updateRecord($gedcom, true); - } - } + foreach ($ids as $id) { + $record = GedcomRecord::getInstance($id, $tree); + if (!$record->isPendingDeletion()) { + FlashMessages::addMessage(I18N::translate( + /* I18N: The placeholders are the names of individuals, sources, etc. */ + 'The link from “%1$s” to “%2$s” has been updated.', + '<a class="alert-link" href="' . e($record->url()) . '">' . $record->getFullName() . '</a>', + $record2_name + ), 'info'); + $gedcom = str_replace('@' . $xref2 . '@', '@' . $xref1 . '@', $record->getGedcom()); + $gedcom = preg_replace( + '/(\n1.*@.+@.*(?:(?:\n[2-9].*)*))((?:\n1.*(?:\n[2-9].*)*)*\1)/', + '$2', + $gedcom + ); + $record->updateRecord($gedcom, true); + } + } - // Update any linked user-accounts - Database::prepare( - "UPDATE `##user_gedcom_setting`" . - " SET setting_value=?" . - " WHERE gedcom_id=? AND setting_name='gedcomid' AND setting_value=?" - )->execute([$xref2, $tree->getTreeId(), $xref1]); + // Update any linked user-accounts + Database::prepare( + "UPDATE `##user_gedcom_setting`" . + " SET setting_value=?" . + " WHERE gedcom_id=? AND setting_name='gedcomid' AND setting_value=?" + )->execute([ + $xref2, + $tree->getTreeId(), + $xref1, + ]); - // Merge hit counters - $hits = Database::prepare( - "SELECT page_name, SUM(page_count)" . - " FROM `##hit_counter`" . - " WHERE gedcom_id=? AND page_parameter IN (?, ?)" . - " GROUP BY page_name" - )->execute([$tree->getTreeId(), $xref1, $xref2])->fetchAssoc(); + // Merge hit counters + $hits = Database::prepare( + "SELECT page_name, SUM(page_count)" . + " FROM `##hit_counter`" . + " WHERE gedcom_id=? AND page_parameter IN (?, ?)" . + " GROUP BY page_name" + )->execute([ + $tree->getTreeId(), + $xref1, + $xref2, + ])->fetchAssoc(); - foreach ($hits as $page_name => $page_count) { - Database::prepare( - "UPDATE `##hit_counter` SET page_count=?" . - " WHERE gedcom_id=? AND page_name=? AND page_parameter=?" - )->execute([$page_count, $tree->getTreeId(), $page_name, $xref1]); - } + foreach ($hits as $page_name => $page_count) { + Database::prepare( + "UPDATE `##hit_counter` SET page_count=?" . + " WHERE gedcom_id=? AND page_name=? AND page_parameter=?" + )->execute([ + $page_count, + $tree->getTreeId(), + $page_name, + $xref1, + ]); + } - Database::prepare( - "DELETE FROM `##hit_counter`" . - " WHERE gedcom_id=? AND page_parameter=?" - )->execute([$tree->getTreeId(), $xref2]); + Database::prepare( + "DELETE FROM `##hit_counter`" . + " WHERE gedcom_id=? AND page_parameter=?" + )->execute([ + $tree->getTreeId(), + $xref2, + ]); - $gedcom = '0 @' . $record1->getXref() . '@ ' . $record1::RECORD_TYPE; - foreach ($facts as $fact_id => $fact) { - $gedcom .= "\n" . $fact->getGedcom(); - } - foreach ($facts1 as $fact_id => $fact) { - if (in_array($fact_id, $keep1)) { - $gedcom .= "\n" . $fact->getGedcom(); - } - } - foreach ($facts2 as $fact_id => $fact) { - if (in_array($fact_id, $keep2)) { - $gedcom .= "\n" . $fact->getGedcom(); - } - } + $gedcom = '0 @' . $record1->getXref() . '@ ' . $record1::RECORD_TYPE; + foreach ($facts as $fact_id => $fact) { + $gedcom .= "\n" . $fact->getGedcom(); + } + foreach ($facts1 as $fact_id => $fact) { + if (in_array($fact_id, $keep1)) { + $gedcom .= "\n" . $fact->getGedcom(); + } + } + foreach ($facts2 as $fact_id => $fact) { + if (in_array($fact_id, $keep2)) { + $gedcom .= "\n" . $fact->getGedcom(); + } + } - $record1->updateRecord($gedcom, true); - $record2->deleteRecord(); - FunctionsDb::updateFavorites($xref2, $xref1, $tree); - FlashMessages::addMessage(I18N::translate( - /* I18N: Records are individuals, sources, etc. */ - 'The records “%1$s” and “%2$s” have been merged.', - '<a class="alert-link" href="' . e($record1->url()) . '">' . $record1->getFullName() . '</a>', - $record2_name - ), 'success'); + $record1->updateRecord($gedcom, true); + $record2->deleteRecord(); + FunctionsDb::updateFavorites($xref2, $xref1, $tree); + FlashMessages::addMessage(I18N::translate( + /* I18N: Records are individuals, sources, etc. */ + 'The records “%1$s” and “%2$s” have been merged.', + '<a class="alert-link" href="' . e($record1->url()) . '">' . $record1->getFullName() . '</a>', + $record2_name + ), 'success'); - return new RedirectResponse(route('merge-records', ['ged' => $tree->getName()])); - } + return new RedirectResponse(route('merge-records', ['ged' => $tree->getName()])); + } - /** - * Show the administrator a list of modules. - * - * @return Response - */ - public function modules(): Response { - $module_status = Database::prepare("SELECT module_name, status FROM `##module`")->fetchAssoc(); + /** + * Show the administrator a list of modules. + * + * @return Response + */ + public function modules(): Response + { + $module_status = Database::prepare("SELECT module_name, status FROM `##module`")->fetchAssoc(); - return $this->viewResponse('admin/modules', [ - 'title' => I18N::translate('Module administration'), - 'modules' => Module::getInstalledModules('disabled'), - 'module_status' => $module_status, - 'deleted_modules' => $this->deletedModuleNames(), - 'core_module_names' => Module::CORE_MODULES, - ]); - } + return $this->viewResponse('admin/modules', [ + 'title' => I18N::translate('Module administration'), + 'modules' => Module::getInstalledModules('disabled'), + 'module_status' => $module_status, + 'deleted_modules' => $this->deletedModuleNames(), + 'core_module_names' => Module::CORE_MODULES, + ]); + } - /** - * Show the admin page for menus. - * - * @return Response - */ - public function menus(): Response { - return $this->components('menu', 'menus', I18N::translate('Menu'), I18N::translate('Menus')); - } + /** + * Show the admin page for menus. + * + * @return Response + */ + public function menus(): Response + { + return $this->components('menu', 'menus', I18N::translate('Menu'), I18N::translate('Menus')); + } - /** - * Show the admin page for reports. - * - * @return Response - */ - public function reports(): Response { - return $this->components('report', 'reports', I18N::translate('Report'), I18N::translate('Reports')); - } + /** + * Show the admin page for reports. + * + * @return Response + */ + public function reports(): Response + { + return $this->components('report', 'reports', I18N::translate('Report'), I18N::translate('Reports')); + } - /** - * Show the admin page for sidebars. - * - * @return Response - */ - public function sidebars(): Response { - return $this->components('sidebar', 'sidebars', I18N::translate('Sidebar'), I18N::translate('Sidebars')); - } + /** + * Show the admin page for sidebars. + * + * @return Response + */ + public function sidebars(): Response + { + return $this->components('sidebar', 'sidebars', I18N::translate('Sidebar'), I18N::translate('Sidebars')); + } - /** - * Show the admin page for tabs. - * - * @return Response - */ - public function tabs(): Response { - return $this->components('tab', 'tabs', I18N::translate('Tab'), I18N::translate('Tabs')); - } + /** + * Show the admin page for tabs. + * + * @return Response + */ + public function tabs(): Response + { + return $this->components('tab', 'tabs', I18N::translate('Tab'), I18N::translate('Tabs')); + } - /** - * @param Request $request - * - * @return Response - */ - public function treePrivacyEdit(Request $request): Response { - /** @var Tree $tree */ - $tree = $request->attributes->get('tree'); - $title = e($tree->getName()) . ' — ' . I18N::translate('Privacy'); - $all_tags = $this->tagsForPrivacy($tree); - $privacy_constants = $this->privacyConstants(); - $privacy_restrictions = $this->privacyRestrictions($tree); + /** + * @param Request $request + * + * @return Response + */ + public function treePrivacyEdit(Request $request): Response + { + /** @var Tree $tree */ + $tree = $request->attributes->get('tree'); + $title = e($tree->getName()) . ' — ' . I18N::translate('Privacy'); + $all_tags = $this->tagsForPrivacy($tree); + $privacy_constants = $this->privacyConstants(); + $privacy_restrictions = $this->privacyRestrictions($tree); - return $this->viewResponse('admin/trees-privacy', [ - 'all_tags' => $all_tags, - 'count_trees' => count(Tree::getAll()), - 'privacy_constants' => $privacy_constants, - 'privacy_restrictions' => $privacy_restrictions, - 'title' => $title, - ]); - } + return $this->viewResponse('admin/trees-privacy', [ + 'all_tags' => $all_tags, + 'count_trees' => count(Tree::getAll()), + 'privacy_constants' => $privacy_constants, + 'privacy_restrictions' => $privacy_restrictions, + 'title' => $title, + ]); + } - /** - * @param Request $request - * - * @return RedirectResponse - */ - public function treePrivacyUpdate(Request $request): RedirectResponse { - /** @var Tree $tree */ - $tree = $request->attributes->get('tree'); + /** + * @param Request $request + * + * @return RedirectResponse + */ + public function treePrivacyUpdate(Request $request): RedirectResponse + { + /** @var Tree $tree */ + $tree = $request->attributes->get('tree'); - foreach ((array) $request->get('delete') as $default_resn_id) { - Database::prepare( - "DELETE FROM `##default_resn` WHERE default_resn_id = :default_resn_id" - )->execute([ - 'default_resn_id' => $default_resn_id, - ]); - } + foreach ((array)$request->get('delete') as $default_resn_id) { + Database::prepare( + "DELETE FROM `##default_resn` WHERE default_resn_id = :default_resn_id" + )->execute([ + 'default_resn_id' => $default_resn_id, + ]); + } - $xrefs = (array) $request->get('xref'); - $tag_types = (array) $request->get('tag_type'); - $resns = (array) $request->get('resn'); + $xrefs = (array)$request->get('xref'); + $tag_types = (array)$request->get('tag_type'); + $resns = (array)$request->get('resn'); - foreach ($xrefs as $n => $xref) { - $tag_type = (string) $tag_types[$n]; - $resn = (string) $resns[$n]; + foreach ($xrefs as $n => $xref) { + $tag_type = (string)$tag_types[$n]; + $resn = (string)$resns[$n]; - if ($tag_type !== '' || $xref !== '') { - // Delete any existing data - if ($xref === '') { - Database::prepare( - "DELETE FROM `##default_resn` WHERE gedcom_id = :tree_id AND tag_type = :tag_type AND xref IS NULL" - )->execute([ - 'tree_id' => $tree->getTreeId(), - 'tag_type' => $tag_type, - ]); - } - if ($tag_type === '') { - Database::prepare( - "DELETE FROM `##default_resn` WHERE gedcom_id = ? AND xref = ? AND tag_type IS NULL" - )->execute([ - 'tree_id' => $tree->getTreeId(), - 'xref' => $xref, - ]); - } + if ($tag_type !== '' || $xref !== '') { + // Delete any existing data + if ($xref === '') { + Database::prepare( + "DELETE FROM `##default_resn` WHERE gedcom_id = :tree_id AND tag_type = :tag_type AND xref IS NULL" + )->execute([ + 'tree_id' => $tree->getTreeId(), + 'tag_type' => $tag_type, + ]); + } + if ($tag_type === '') { + Database::prepare( + "DELETE FROM `##default_resn` WHERE gedcom_id = ? AND xref = ? AND tag_type IS NULL" + )->execute([ + 'tree_id' => $tree->getTreeId(), + 'xref' => $xref, + ]); + } - // Add (or update) the new data - Database::prepare( - "REPLACE INTO `##default_resn` (gedcom_id, xref, tag_type, resn)" . - " VALUES (:tree_id, NULLIF(:xref, ''), NULLIF(:tag_type, ''), :resn)" - )->execute([ - 'tree_id' => $tree->getTreeId(), - 'xref' => $xref, - 'tag_type' => $tag_type, - 'resn' => $resn, - ]); - } - } + // Add (or update) the new data + Database::prepare( + "REPLACE INTO `##default_resn` (gedcom_id, xref, tag_type, resn)" . + " VALUES (:tree_id, NULLIF(:xref, ''), NULLIF(:tag_type, ''), :resn)" + )->execute([ + 'tree_id' => $tree->getTreeId(), + 'xref' => $xref, + 'tag_type' => $tag_type, + 'resn' => $resn, + ]); + } + } - $tree->setPreference('HIDE_LIVE_PEOPLE', $request->get('HIDE_LIVE_PEOPLE')); - $tree->setPreference('KEEP_ALIVE_YEARS_BIRTH', $request->get('KEEP_ALIVE_YEARS_BIRTH', '0')); - $tree->setPreference('KEEP_ALIVE_YEARS_DEATH', $request->get('KEEP_ALIVE_YEARS_DEATH', '0')); - $tree->setPreference('MAX_ALIVE_AGE', $request->get('MAX_ALIVE_AGE', '100')); - $tree->setPreference('REQUIRE_AUTHENTICATION', $request->get('REQUIRE_AUTHENTICATION')); - $tree->setPreference('SHOW_DEAD_PEOPLE', $request->get('SHOW_DEAD_PEOPLE')); - $tree->setPreference('SHOW_LIVING_NAMES', $request->get('SHOW_LIVING_NAMES')); - $tree->setPreference('SHOW_PRIVATE_RELATIONSHIPS', $request->get('SHOW_PRIVATE_RELATIONSHIPS')); + $tree->setPreference('HIDE_LIVE_PEOPLE', $request->get('HIDE_LIVE_PEOPLE')); + $tree->setPreference('KEEP_ALIVE_YEARS_BIRTH', $request->get('KEEP_ALIVE_YEARS_BIRTH', '0')); + $tree->setPreference('KEEP_ALIVE_YEARS_DEATH', $request->get('KEEP_ALIVE_YEARS_DEATH', '0')); + $tree->setPreference('MAX_ALIVE_AGE', $request->get('MAX_ALIVE_AGE', '100')); + $tree->setPreference('REQUIRE_AUTHENTICATION', $request->get('REQUIRE_AUTHENTICATION')); + $tree->setPreference('SHOW_DEAD_PEOPLE', $request->get('SHOW_DEAD_PEOPLE')); + $tree->setPreference('SHOW_LIVING_NAMES', $request->get('SHOW_LIVING_NAMES')); + $tree->setPreference('SHOW_PRIVATE_RELATIONSHIPS', $request->get('SHOW_PRIVATE_RELATIONSHIPS')); - FlashMessages::addMessage(I18N::translate('The preferences for the family tree “%s” have been updated.', e($tree->getTitle()), 'success')); + FlashMessages::addMessage(I18N::translate('The preferences for the family tree “%s” have been updated.', e($tree->getTitle()), 'success')); - // Coming soon... - if ((bool) $request->get('all_trees')) { - FlashMessages::addMessage(I18N::translate('The preferences for all family trees have been updated.', e($tree->getTitle())), 'success'); - } - if ((bool) $request->get('new_trees')) { - FlashMessages::addMessage(I18N::translate('The preferences for new family trees have been updated.', e($tree->getTitle())), 'success'); - } + // Coming soon... + if ((bool)$request->get('all_trees')) { + FlashMessages::addMessage(I18N::translate('The preferences for all family trees have been updated.', e($tree->getTitle())), 'success'); + } + if ((bool)$request->get('new_trees')) { + FlashMessages::addMessage(I18N::translate('The preferences for new family trees have been updated.', e($tree->getTitle())), 'success'); + } - return new RedirectResponse(route('admin-trees', ['ged' => $tree->getName()])); - } + return new RedirectResponse(route('admin-trees', ['ged' => $tree->getName()])); + } - /** - * Update the access levels of the modules. - * - * @param Request $request - * - * @return RedirectResponse - */ - public function updateModuleAccess(Request $request): RedirectResponse { - $component = $request->get('component'); - $modules = Module::getAllModulesByComponent($component); + /** + * Update the access levels of the modules. + * + * @param Request $request + * + * @return RedirectResponse + */ + public function updateModuleAccess(Request $request): RedirectResponse + { + $component = $request->get('component'); + $modules = Module::getAllModulesByComponent($component); - foreach ($modules as $module) { - foreach (Tree::getAll() as $tree) { - $key = 'access-' . $module->getName() . '-' . $tree->getTreeId(); - $access_level = (int) $request->get($key, $module->defaultAccessLevel()); + foreach ($modules as $module) { + foreach (Tree::getAll() as $tree) { + $key = 'access-' . $module->getName() . '-' . $tree->getTreeId(); + $access_level = (int)$request->get($key, $module->defaultAccessLevel()); - Database::prepare("REPLACE INTO `##module_privacy` (module_name, gedcom_id, component, access_level)" . " VALUES (:module_name, :tree_id, :component, :access_level)")->execute([ - 'module_name' => $module->getName(), - 'tree_id' => $tree->getTreeId(), - 'component' => $component, - 'access_level' => $access_level, - ]); - } - } + Database::prepare("REPLACE INTO `##module_privacy` (module_name, gedcom_id, component, access_level)" . " VALUES (:module_name, :tree_id, :component, :access_level)")->execute([ + 'module_name' => $module->getName(), + 'tree_id' => $tree->getTreeId(), + 'component' => $component, + 'access_level' => $access_level, + ]); + } + } - return new RedirectResponse(route('admin-' . $component . 's')); - } + return new RedirectResponse(route('admin-' . $component . 's')); + } - /** - * Update the enabled/disabled status of the modules. - * - * @param Request $request - * - * @return RedirectResponse - */ - public function updateModuleStatus(Request $request): RedirectResponse { - $modules = Module::getInstalledModules('disabled'); - $module_status = Database::prepare("SELECT module_name, status FROM `##module`")->fetchAssoc(); + /** + * Update the enabled/disabled status of the modules. + * + * @param Request $request + * + * @return RedirectResponse + */ + public function updateModuleStatus(Request $request): RedirectResponse + { + $modules = Module::getInstalledModules('disabled'); + $module_status = Database::prepare("SELECT module_name, status FROM `##module`")->fetchAssoc(); - foreach ($modules as $module) { - $new_status = (bool) $request->get('status-' . $module->getName()) ? 'enabled' : 'disabled'; - $old_status = $module_status[$module->getName()]; + foreach ($modules as $module) { + $new_status = (bool)$request->get('status-' . $module->getName()) ? 'enabled' : 'disabled'; + $old_status = $module_status[$module->getName()]; - if ($new_status !== $old_status) { - Database::prepare("UPDATE `##module` SET status = :status WHERE module_name = :module_name")->execute([ - 'status' => $new_status, - 'module_name' => $module->getName(), - ]); + if ($new_status !== $old_status) { + Database::prepare("UPDATE `##module` SET status = :status WHERE module_name = :module_name")->execute([ + 'status' => $new_status, + 'module_name' => $module->getName(), + ]); - if ($new_status === 'enabled') { - FlashMessages::addMessage(I18N::translate('The module “%s” has been enabled.', $module->getTitle()), 'success'); - } else { - FlashMessages::addMessage(I18N::translate('The module “%s” has been disabled.', $module->getTitle()), 'success'); - } - } - } + if ($new_status === 'enabled') { + FlashMessages::addMessage(I18N::translate('The module “%s” has been enabled.', $module->getTitle()), 'success'); + } else { + FlashMessages::addMessage(I18N::translate('The module “%s” has been disabled.', $module->getTitle()), 'success'); + } + } + } - return new RedirectResponse(route('admin-modules')); - } + return new RedirectResponse(route('admin-modules')); + } - /** - * Create a response object from a view. - * - * @param string $name - * @param mixed[] $data - * @param int $status - * - * @return Response - */ - protected function viewResponse($name, $data, $status = Response::HTTP_OK): Response { - $html = view($this->layout, [ - 'content' => view($name, $data), - 'title' => strip_tags($data['title']), - ]); + /** + * Create a response object from a view. + * + * @param string $name + * @param mixed[] $data + * @param int $status + * + * @return Response + */ + protected function viewResponse($name, $data, $status = Response::HTTP_OK): Response + { + $html = view($this->layout, [ + 'content' => view($name, $data), + 'title' => strip_tags($data['title']), + ]); - return new Response($html, $status); - } + return new Response($html, $status); + } - /** - * Generate a WHERE clause for filtering the changes log. - * - * @param Request $request - * - * @return array - * - */ - private function changesQuery(Request $request): array { - $from = $request->get('from', ''); - $to = $request->get('to', ''); - $type = $request->get('type', ''); - $oldged = $request->get('oldged', ''); - $newged = $request->get('newged', ''); - $xref = $request->get('xref', ''); - $username = $request->get('username', ''); - $ged = $request->get('ged', ''); - $search = $request->get('search', ''); - $search = $search['value'] ?? ''; + /** + * Generate a WHERE clause for filtering the changes log. + * + * @param Request $request + * + * @return array + * + */ + private function changesQuery(Request $request): array + { + $from = $request->get('from', ''); + $to = $request->get('to', ''); + $type = $request->get('type', ''); + $oldged = $request->get('oldged', ''); + $newged = $request->get('newged', ''); + $xref = $request->get('xref', ''); + $username = $request->get('username', ''); + $ged = $request->get('ged', ''); + $search = $request->get('search', ''); + $search = $search['value'] ?? ''; - $where = ' WHERE 1'; - $args = []; - if ($search !== '') { - $where .= " AND (old_gedcom LIKE CONCAT('%', :search_1, '%') OR new_gedcom LIKE CONCAT('%', :search_2, '%'))"; - $args['search_1'] = $search; - $args['search_2'] = $search; - } - if ($from !== '') { - $where .= " AND change_time >= :from"; - $args['from'] = $from; - } - if ($to !== '') { - $where .= ' AND change_time < TIMESTAMPADD(DAY, 1 , :to)'; // before end of the day - $args['to'] = $to; - } - if ($type !== '') { - $where .= ' AND status = :status'; - $args['status'] = $type; - } - if ($oldged !== '') { - $where .= " AND old_gedcom LIKE CONCAT('%', :old_ged, '%')"; - $args['old_ged'] = $oldged; - } - if ($newged !== '') { - $where .= " AND new_gedcom LIKE CONCAT('%', :new_ged, '%')"; - $args['new_ged'] = $newged; - } - if ($xref !== '') { - $where .= " AND xref = :xref"; - $args['xref'] = $xref; - } - if ($username !== '') { - $where .= " AND user_name LIKE CONCAT('%', :user, '%')"; - $args['user'] = $username; - } - if ($ged !== '') { - $where .= " AND gedcom_name LIKE CONCAT('%', :ged, '%')"; - $args['ged'] = $ged; - } + $where = ' WHERE 1'; + $args = []; + if ($search !== '') { + $where .= " AND (old_gedcom LIKE CONCAT('%', :search_1, '%') OR new_gedcom LIKE CONCAT('%', :search_2, '%'))"; + $args['search_1'] = $search; + $args['search_2'] = $search; + } + if ($from !== '') { + $where .= " AND change_time >= :from"; + $args['from'] = $from; + } + if ($to !== '') { + $where .= ' AND change_time < TIMESTAMPADD(DAY, 1 , :to)'; // before end of the day + $args['to'] = $to; + } + if ($type !== '') { + $where .= ' AND status = :status'; + $args['status'] = $type; + } + if ($oldged !== '') { + $where .= " AND old_gedcom LIKE CONCAT('%', :old_ged, '%')"; + $args['old_ged'] = $oldged; + } + if ($newged !== '') { + $where .= " AND new_gedcom LIKE CONCAT('%', :new_ged, '%')"; + $args['new_ged'] = $newged; + } + if ($xref !== '') { + $where .= " AND xref = :xref"; + $args['xref'] = $xref; + } + if ($username !== '') { + $where .= " AND user_name LIKE CONCAT('%', :user, '%')"; + $args['user'] = $username; + } + if ($ged !== '') { + $where .= " AND gedcom_name LIKE CONCAT('%', :ged, '%')"; + $args['ged'] = $ged; + } - $select = "SELECT SQL_CALC_FOUND_ROWS change_id, change_time, status, xref, old_gedcom, new_gedcom, IFNULL(user_name, '<none>') AS user_name, gedcom_name FROM `##change`"; - $delete = 'DELETE `##change` FROM `##change`'; + $select = "SELECT SQL_CALC_FOUND_ROWS change_id, change_time, status, xref, old_gedcom, new_gedcom, IFNULL(user_name, '<none>') AS user_name, gedcom_name FROM `##change`"; + $delete = 'DELETE `##change` FROM `##change`'; - $join = ' LEFT JOIN `##user` USING (user_id) JOIN `##gedcom` USING (gedcom_id)'; + $join = ' LEFT JOIN `##user` USING (user_id) JOIN `##gedcom` USING (gedcom_id)'; - return [$select . $join, $delete . $join, $where, $args]; - } + return [ + $select . $join, + $delete . $join, + $where, + $args, + ]; + } - /** - * Show the admin page for blocks, charts, menus, reports, sidebars, tabs, etc.. - * - * @param string $component - * @param string $route - * @param string $component_title - * @param string $title - * - * @return Response - */ - private function components($component, $route, $component_title, $title): Response { - return $this->viewResponse('admin/module-components', [ - 'component' => $component, - 'component_title' => $component_title, - 'modules' => Module::getAllModulesByComponent($component), - 'title' => $title, - 'route' => $route, - ]); - } + /** + * Show the admin page for blocks, charts, menus, reports, sidebars, tabs, etc.. + * + * @param string $component + * @param string $route + * @param string $component_title + * @param string $title + * + * @return Response + */ + private function components($component, $route, $component_title, $title): Response + { + return $this->viewResponse('admin/module-components', [ + 'component' => $component, + 'component_title' => $component_title, + 'modules' => Module::getAllModulesByComponent($component), + 'title' => $title, + 'route' => $route, + ]); + } - /** - * Conver request parameters into paging/sorting for datatables - * - * @param $request - * - * @return array - */ - private function dataTablesPagination(Request $request): array { - $start = (int) $request->get('start', '0'); - $length = (int) $request->get('length', '0'); - $order = $request->get('order', []); - $args = []; + /** + * Conver request parameters into paging/sorting for datatables + * + * @param $request + * + * @return array + */ + private function dataTablesPagination(Request $request): array + { + $start = (int)$request->get('start', '0'); + $length = (int)$request->get('length', '0'); + $order = $request->get('order', []); + $args = []; - if (is_array($order) && !empty($order)) { - $order_by = ' ORDER BY '; - foreach ($order as $key => $value) { - if ($key > 0) { - $order_by .= ','; - } - // Columns in datatables are numbered from zero. - // Columns in MySQL are numbered starting with one. - switch ($value['dir']) { - case 'asc': - $order_by .= (1 + $value['column']) . ' ASC '; - break; - case 'desc': - $order_by .= (1 + $value['column']) . ' DESC '; - break; - } - } - } else { - $order_by = ''; - } + if (is_array($order) && !empty($order)) { + $order_by = ' ORDER BY '; + foreach ($order as $key => $value) { + if ($key > 0) { + $order_by .= ','; + } + // Columns in datatables are numbered from zero. + // Columns in MySQL are numbered starting with one. + switch ($value['dir']) { + case 'asc': + $order_by .= (1 + $value['column']) . ' ASC '; + break; + case 'desc': + $order_by .= (1 + $value['column']) . ' DESC '; + break; + } + } + } else { + $order_by = ''; + } - if ($length) { - Auth::user()->setPreference('admin_site_change_page_size', $length); - $limit = ' LIMIT :limit OFFSET :offset'; - $args['limit'] = $length; - $args['offset'] = $start; - } else { - $limit = ""; - } + if ($length) { + Auth::user()->setPreference('admin_site_change_page_size', $length); + $limit = ' LIMIT :limit OFFSET :offset'; + $args['limit'] = $length; + $args['offset'] = $start; + } else { + $limit = ""; + } - return [$order_by, $limit, $args]; - } + return [ + $order_by, + $limit, + $args, + ]; + } - /** - * Generate a list of module names which exist in the database but not on disk. - * - * @return string[] - */ - private function deletedModuleNames() { - $database_modules = Database::prepare("SELECT module_name FROM `##module`")->fetchOneColumn(); - $disk_modules = Module::getInstalledModules('disabled'); + /** + * Generate a list of module names which exist in the database but not on disk. + * + * @return string[] + */ + private function deletedModuleNames() + { + $database_modules = Database::prepare("SELECT module_name FROM `##module`")->fetchOneColumn(); + $disk_modules = Module::getInstalledModules('disabled'); - return array_diff($database_modules, array_keys($disk_modules)); - } + return array_diff($database_modules, array_keys($disk_modules)); + } - /** - * A list of old files that need to be deleted. - * - * @return string[] - */ - private function filesToDelete() { - $files_to_delete = []; - foreach (self::OLD_FILES as $file) { - // Delete the file, if we can. - if (file_exists($file) && !File::delete($file)) { - $files_to_delete[] = $file; - } - } + /** + * A list of old files that need to be deleted. + * + * @return string[] + */ + private function filesToDelete() + { + $files_to_delete = []; + foreach (self::OLD_FILES as $file) { + // Delete the file, if we can. + if (file_exists($file) && !File::delete($file)) { + $files_to_delete[] = $file; + } + } - return $files_to_delete; - } + return $files_to_delete; + } - /** - * Find the media object that uses a particular media file. - * - * @param string $file - * - * @return Media[] - */ - private function findMediaObjectsForMediaFile(string $file): array { - $rows = Database::prepare( - "SELECT DISTINCT m.*" . - " FROM `##media` as m" . - " JOIN `##media_file` USING (m_file, m_id)" . - " JOIN `##gedcom_setting` ON (m_file = gedcom_id AND setting_name = 'MEDIA_DIRECTORY')" . - " WHERE CONCAT(setting_value, multimedia_file_refn) = :file" - )->execute([ - 'file' => $file, - ])->fetchAll(); + /** + * Find the media object that uses a particular media file. + * + * @param string $file + * + * @return Media[] + */ + private function findMediaObjectsForMediaFile(string $file): array + { + $rows = Database::prepare( + "SELECT DISTINCT m.*" . + " FROM `##media` as m" . + " JOIN `##media_file` USING (m_file, m_id)" . + " JOIN `##gedcom_setting` ON (m_file = gedcom_id AND setting_name = 'MEDIA_DIRECTORY')" . + " WHERE CONCAT(setting_value, multimedia_file_refn) = :file" + )->execute([ + 'file' => $file, + ])->fetchAll(); - $media = []; + $media = []; - foreach ($rows as $row) { - $tree = Tree::findById($row->m_file); - $media[] = Media::getInstance($row->m_id, $tree, $row->m_gedcom); - } + foreach ($rows as $row) { + $tree = Tree::findById($row->m_file); + $media[] = Media::getInstance($row->m_id, $tree, $row->m_gedcom); + } - return array_filter($media); - } + return array_filter($media); + } - /** - * Find the original image that corresponds to a (webtrees 1.x) thumbnail file. - * - * @param string $thumbnail - * - * @return string - */ - private function findOriginalFileFromThumbnail(string $thumbnail): string { - // First option - a file with the same name - $original = str_replace('/thumbs/', '/', $thumbnail); + /** + * Find the original image that corresponds to a (webtrees 1.x) thumbnail file. + * + * @param string $thumbnail + * + * @return string + */ + private function findOriginalFileFromThumbnail(string $thumbnail): string + { + // First option - a file with the same name + $original = str_replace('/thumbs/', '/', $thumbnail); - // Second option - a .PNG thumbnail for some other image type - if (substr_compare($original, '.png', -4, 4) === 0) { - $pattern = substr($original, 0, -3) . '*'; - $matches = glob($pattern); - if (!empty($matches) && is_file($matches[0])) { - $original = $matches[0]; - } - } + // Second option - a .PNG thumbnail for some other image type + if (substr_compare($original, '.png', -4, 4) === 0) { + $pattern = substr($original, 0, -3) . '*'; + $matches = glob($pattern); + if (!empty($matches) && is_file($matches[0])) { + $original = $matches[0]; + } + } - return $original; - } + return $original; + } - /** - * Compare two images, and return a quantified difference. - * - * 0 (different) ... 100 (same) - * - * @param string $thumbanil - * @param string $original - * - * @return int - */ - private function imageDiff($thumbanil, $original): int { - try { - if (getimagesize($thumbanil) === false) { - return 100; - } - } catch (Throwable $ex) { - // If the first file is not an image then similarity is unimportant. - // Response with an exact match, so the GUI will recommend deleting it. - return 100; - } + /** + * Compare two images, and return a quantified difference. + * + * 0 (different) ... 100 (same) + * + * @param string $thumbanil + * @param string $original + * + * @return int + */ + private function imageDiff($thumbanil, $original): int + { + try { + if (getimagesize($thumbanil) === false) { + return 100; + } + } catch (Throwable $ex) { + // If the first file is not an image then similarity is unimportant. + // Response with an exact match, so the GUI will recommend deleting it. + return 100; + } - try { - if (getimagesize($original) === false) { - return 0; - } - } catch (Throwable $ex) { - // If the first file is not an image then the thumbnail . - // Response with an exact mismatch, so the GUI will recommend importing it. - return 0; - } + try { + if (getimagesize($original) === false) { + return 0; + } + } catch (Throwable $ex) { + // If the first file is not an image then the thumbnail . + // Response with an exact mismatch, so the GUI will recommend importing it. + return 0; + } - $pixels1 = $this->scaledImagePixels($thumbanil); - $pixels2 = $this->scaledImagePixels($original); + $pixels1 = $this->scaledImagePixels($thumbanil); + $pixels2 = $this->scaledImagePixels($original); - $max_difference = 0; + $max_difference = 0; - foreach ($pixels1 as $x => $row) { - foreach ($row as $y => $pixel) { - $max_difference = max($max_difference, abs($pixel - $pixels2[$x][$y])); - } - } + foreach ($pixels1 as $x => $row) { + foreach ($row as $y => $pixel) { + $max_difference = max($max_difference, abs($pixel - $pixels2[$x][$y])); + } + } - // The maximum difference is 255 (black versus white). - return 100 - (int) ($max_difference * 100 / 255); - } + // The maximum difference is 255 (black versus white). + return 100 - (int)($max_difference * 100 / 255); + } - /** - * Scale an image to 10x10 and read the individual pixels. - * - * This is a slow operation, add we will do it many times on - * the "import wetbrees 1 thumbnails" page so cache the results. - * - * @param string $path - * - * @return int[][] - */ - private function scaledImagePixels($path): array { - $size = 10; - $sha1 = sha1_file($path); - $cache_file = WT_DATA_DIR . 'cache/' . $sha1 . '.php'; + /** + * Scale an image to 10x10 and read the individual pixels. + * + * This is a slow operation, add we will do it many times on + * the "import wetbrees 1 thumbnails" page so cache the results. + * + * @param string $path + * + * @return int[][] + */ + private function scaledImagePixels($path): array + { + $size = 10; + $sha1 = sha1_file($path); + $cache_file = WT_DATA_DIR . 'cache/' . $sha1 . '.php'; - if (file_exists($cache_file)) { - return include $cache_file; - } + if (file_exists($cache_file)) { + return include $cache_file; + } - $manager = new ImageManager; - $image = $manager->make($path)->resize($size, $size); + $manager = new ImageManager; + $image = $manager->make($path)->resize($size, $size); - $pixels = []; - for ($x = 0; $x < $size; ++$x) { - $pixels[$x] = []; - for ($y = 0; $y < $size; ++$y) { - $pixel = $image->pickColor($x, $y); - $pixels[$x][$y] = (int) (($pixel[0] + $pixel[1] + $pixel[2]) / 3); - } - } + $pixels = []; + for ($x = 0; $x < $size; ++$x) { + $pixels[$x] = []; + for ($y = 0; $y < $size; ++$y) { + $pixel = $image->pickColor($x, $y); + $pixels[$x][$y] = (int)(($pixel[0] + $pixel[1] + $pixel[2]) / 3); + } + } - file_put_contents($cache_file, '<?php return ' . var_export($pixels, true) . ';'); + file_put_contents($cache_file, '<?php return ' . var_export($pixels, true) . ';'); - return $pixels; - } + return $pixels; + } - /** - * Look for the latest version of webtrees. - * - * @return string - */ - private function latestVersion() { - $latest_version_txt = Functions::fetchLatestVersion(); - if (preg_match('/^[0-9.]+\|[0-9.]+\|/', $latest_version_txt)) { - list($latest_version) = explode('|', $latest_version_txt); - } else { - // Cannot determine the latest version. - $latest_version = ''; - } + /** + * Look for the latest version of webtrees. + * + * @return string + */ + private function latestVersion() + { + $latest_version_txt = Functions::fetchLatestVersion(); + if (preg_match('/^[0-9.]+\|[0-9.]+\|/', $latest_version_txt)) { + list($latest_version) = explode('|', $latest_version_txt); + } else { + // Cannot determine the latest version. + $latest_version = ''; + } - return $latest_version; - } + return $latest_version; + } - /** - * Names of our privacy levels - * - * @return array - */ - private function privacyConstants(): array { - return [ - 'none' => I18N::translate('Show to visitors'), - 'privacy' => I18N::translate('Show to members'), - 'confidential' => I18N::translate('Show to managers'), - 'hidden' => I18N::translate('Hide from everyone'), - ]; - } + /** + * Names of our privacy levels + * + * @return array + */ + private function privacyConstants(): array + { + return [ + 'none' => I18N::translate('Show to visitors'), + 'privacy' => I18N::translate('Show to members'), + 'confidential' => I18N::translate('Show to managers'), + 'hidden' => I18N::translate('Hide from everyone'), + ]; + } - /** - * The current privacy restrictions for a tree. - * - * @param Tree $tree - * - * @return array - */ - private function privacyRestrictions(Tree $tree): array { - $restrictions = Database::prepare( - "SELECT default_resn_id, tag_type, xref, resn" . - " FROM `##default_resn`" . - " LEFT JOIN `##name` ON (gedcom_id = n_file AND xref = n_id AND n_num = 0)" . - " WHERE gedcom_id = :tree_id" - )->execute([ - 'tree_id' => $tree->getTreeId(), - ])->fetchAll(); + /** + * The current privacy restrictions for a tree. + * + * @param Tree $tree + * + * @return array + */ + private function privacyRestrictions(Tree $tree): array + { + $restrictions = Database::prepare( + "SELECT default_resn_id, tag_type, xref, resn" . + " FROM `##default_resn`" . + " LEFT JOIN `##name` ON (gedcom_id = n_file AND xref = n_id AND n_num = 0)" . + " WHERE gedcom_id = :tree_id" + )->execute([ + 'tree_id' => $tree->getTreeId(), + ])->fetchAll(); - foreach ($restrictions as $resn) { - $resn->record = GedcomRecord::getInstance($resn->xref, $tree); - if ($resn->tag_type) { - $resn->tag_label = GedcomTag::getLabel($resn->tag_type); - } else { - $resn->tag_label = ''; - } - } + foreach ($restrictions as $resn) { + $resn->record = GedcomRecord::getInstance($resn->xref, $tree); + if ($resn->tag_type) { + $resn->tag_label = GedcomTag::getLabel($resn->tag_type); + } else { + $resn->tag_label = ''; + } + } - usort($restrictions, function (stdClass $x, stdClass $y) { - return I18N::strcasecmp($x->tag_label, $y->tag_label); - }); + usort($restrictions, function (stdClass $x, stdClass $y) { + return I18N::strcasecmp($x->tag_label, $y->tag_label); + }); - return $restrictions; - } + return $restrictions; + } - /** - * Generate a list of potential problems with the server. - * - * @return string[] - */ - private function serverWarnings() { - $php_support_url = 'https://secure.php.net/supported-versions.php'; - $version_parts = explode('.', PHP_VERSION); - $php_minor_version = $version_parts[0] . $version_parts[1]; - $today = date('Y-m-d'); - $warnings = []; + /** + * Generate a list of potential problems with the server. + * + * @return string[] + */ + private function serverWarnings() + { + $php_support_url = 'https://secure.php.net/supported-versions.php'; + $version_parts = explode('.', PHP_VERSION); + $php_minor_version = $version_parts[0] . $version_parts[1]; + $today = date('Y-m-d'); + $warnings = []; - if ($php_minor_version === '70' && $today >= '2017-12-03' || $php_minor_version === '71' && $today >= '2019-12-01') { - $warnings[] = I18N::translate('Your web server is using PHP version %s, which is no longer receiving security updates. You should upgrade to a later version as soon as possible.', PHP_VERSION) . ' <a href="' . $php_support_url . '">' . $php_support_url . '</a>'; - } elseif ($php_minor_version === '70' && $today >= '2017-12-03' || $php_minor_version === '71' && $today >= '2018-12-01') { - $warnings[] = I18N::translate('Your web server is using PHP version %s, which is no longer maintained. You should upgrade to a later version.', PHP_VERSION) . ' <a href="' . $php_support_url . '">' . $php_support_url . '</a>'; - } + if ($php_minor_version === '70' && $today >= '2017-12-03' || $php_minor_version === '71' && $today >= '2019-12-01') { + $warnings[] = I18N::translate('Your web server is using PHP version %s, which is no longer receiving security updates. You should upgrade to a later version as soon as possible.', PHP_VERSION) . ' <a href="' . $php_support_url . '">' . $php_support_url . '</a>'; + } elseif ($php_minor_version === '70' && $today >= '2017-12-03' || $php_minor_version === '71' && $today >= '2018-12-01') { + $warnings[] = I18N::translate('Your web server is using PHP version %s, which is no longer maintained. You should upgrade to a later version.', PHP_VERSION) . ' <a href="' . $php_support_url . '">' . $php_support_url . '</a>'; + } - return $warnings; - } + return $warnings; + } - /** - * Generate a list of potential problems with the server. - * - * @param Tree $tree - * - * @return string[] - */ - private function tagsForPrivacy(Tree $tree): array { - $tags = array_unique(array_merge( - explode(',', $tree->getPreference('INDI_FACTS_ADD')), - explode(',', $tree->getPreference('INDI_FACTS_UNIQUE')), - explode(',', $tree->getPreference('FAM_FACTS_ADD')), - explode(',', $tree->getPreference('FAM_FACTS_UNIQUE')), - explode(',', $tree->getPreference('NOTE_FACTS_ADD')), - explode(',', $tree->getPreference('NOTE_FACTS_UNIQUE')), - explode(',', $tree->getPreference('SOUR_FACTS_ADD')), - explode(',', $tree->getPreference('SOUR_FACTS_UNIQUE')), - explode(',', $tree->getPreference('REPO_FACTS_ADD')), - explode(',', $tree->getPreference('REPO_FACTS_UNIQUE')), - ['SOUR', 'REPO', 'OBJE', '_PRIM', 'NOTE', 'SUBM', 'SUBN', '_UID', 'CHAN'] - )); + /** + * Generate a list of potential problems with the server. + * + * @param Tree $tree + * + * @return string[] + */ + private function tagsForPrivacy(Tree $tree): array + { + $tags = array_unique(array_merge( + explode(',', $tree->getPreference('INDI_FACTS_ADD')), + explode(',', $tree->getPreference('INDI_FACTS_UNIQUE')), + explode(',', $tree->getPreference('FAM_FACTS_ADD')), + explode(',', $tree->getPreference('FAM_FACTS_UNIQUE')), + explode(',', $tree->getPreference('NOTE_FACTS_ADD')), + explode(',', $tree->getPreference('NOTE_FACTS_UNIQUE')), + explode(',', $tree->getPreference('SOUR_FACTS_ADD')), + explode(',', $tree->getPreference('SOUR_FACTS_UNIQUE')), + explode(',', $tree->getPreference('REPO_FACTS_ADD')), + explode(',', $tree->getPreference('REPO_FACTS_UNIQUE')), + [ + 'SOUR', + 'REPO', + 'OBJE', + '_PRIM', + 'NOTE', + 'SUBM', + 'SUBN', + '_UID', + 'CHAN', + ] + )); - $all_tags = []; - foreach ($tags as $tag) { - if ($tag) { - $all_tags[$tag] = GedcomTag::getLabel($tag); - } - } + $all_tags = []; + foreach ($tags as $tag) { + if ($tag) { + $all_tags[$tag] = GedcomTag::getLabel($tag); + } + } - uasort($all_tags, '\Fisharebest\Webtrees\I18N::strcasecmp'); + uasort($all_tags, '\Fisharebest\Webtrees\I18N::strcasecmp'); - return $all_tags; - } + return $all_tags; + } - /** - * Count the number of pending changes in each tree. - * - * @return string[] - */ - private function totalChanges() { - return Database::prepare("SELECT g.gedcom_id, COUNT(change_id)" . " FROM `##gedcom` AS g" . " LEFT JOIN `##change` AS c ON g.gedcom_id = c.gedcom_id AND status = 'pending'" . " GROUP BY g.gedcom_id")->fetchAssoc(); - } + /** + * Count the number of pending changes in each tree. + * + * @return string[] + */ + private function totalChanges() + { + return Database::prepare("SELECT g.gedcom_id, COUNT(change_id)" . " FROM `##gedcom` AS g" . " LEFT JOIN `##change` AS c ON g.gedcom_id = c.gedcom_id AND status = 'pending'" . " GROUP BY g.gedcom_id")->fetchAssoc(); + } - /** - * Count the number of families in each tree. - * - * @return string[] - */ - private function totalFamilies() { - return Database::prepare("SELECT gedcom_id, COUNT(f_id)" . " FROM `##gedcom`" . " LEFT JOIN `##families` ON gedcom_id = f_file" . " GROUP BY gedcom_id")->fetchAssoc(); - } + /** + * Count the number of families in each tree. + * + * @return string[] + */ + private function totalFamilies() + { + return Database::prepare("SELECT gedcom_id, COUNT(f_id)" . " FROM `##gedcom`" . " LEFT JOIN `##families` ON gedcom_id = f_file" . " GROUP BY gedcom_id")->fetchAssoc(); + } - /** - * Count the number of individuals in each tree. - * - * @return string[] - */ - private function totalIndividuals() { - return Database::prepare("SELECT gedcom_id, COUNT(i_id)" . " FROM `##gedcom`" . " LEFT JOIN `##individuals` ON gedcom_id = i_file" . " GROUP BY gedcom_id")->fetchAssoc(); - } + /** + * Count the number of individuals in each tree. + * + * @return string[] + */ + private function totalIndividuals() + { + return Database::prepare("SELECT gedcom_id, COUNT(i_id)" . " FROM `##gedcom`" . " LEFT JOIN `##individuals` ON gedcom_id = i_file" . " GROUP BY gedcom_id")->fetchAssoc(); + } - /** - * Count the number of media objects in each tree. - * - * @return string[] - */ - private function totalMediaObjects() { - return Database::prepare("SELECT gedcom_id, COUNT(m_id)" . " FROM `##gedcom`" . " LEFT JOIN `##media` ON gedcom_id = m_file" . " GROUP BY gedcom_id")->fetchAssoc(); - } + /** + * Count the number of media objects in each tree. + * + * @return string[] + */ + private function totalMediaObjects() + { + return Database::prepare("SELECT gedcom_id, COUNT(m_id)" . " FROM `##gedcom`" . " LEFT JOIN `##media` ON gedcom_id = m_file" . " GROUP BY gedcom_id")->fetchAssoc(); + } - /** - * Count the number of notes in each tree. - * - * @return string[] - */ - private function totalNotes() { - return Database::prepare("SELECT gedcom_id, COUNT(o_id)" . " FROM `##gedcom`" . " LEFT JOIN `##other` ON gedcom_id = o_file AND o_type = 'NOTE'" . " GROUP BY gedcom_id" + /** + * Count the number of notes in each tree. + * + * @return string[] + */ + private function totalNotes() + { + return Database::prepare("SELECT gedcom_id, COUNT(o_id)" . " FROM `##gedcom`" . " LEFT JOIN `##other` ON gedcom_id = o_file AND o_type = 'NOTE'" . " GROUP BY gedcom_id" - )->fetchAssoc(); - } + )->fetchAssoc(); + } - /** - * Count the number of repositorie in each tree. - * - * @return string[] - */ - private function totalRepositories() { - return Database::prepare("SELECT gedcom_id, COUNT(o_id)" . " FROM `##gedcom`" . " LEFT JOIN `##other` ON gedcom_id = o_file AND o_type = 'REPO'" . " GROUP BY gedcom_id")->fetchAssoc(); - } + /** + * Count the number of repositorie in each tree. + * + * @return string[] + */ + private function totalRepositories() + { + return Database::prepare("SELECT gedcom_id, COUNT(o_id)" . " FROM `##gedcom`" . " LEFT JOIN `##other` ON gedcom_id = o_file AND o_type = 'REPO'" . " GROUP BY gedcom_id")->fetchAssoc(); + } - /** - * Count the number of sources in each tree. - * - * @return string[] - */ - private function totalSources() { - return Database::prepare("SELECT gedcom_id, COUNT(s_id)" . " FROM `##gedcom`" . " LEFT JOIN `##sources` ON gedcom_id = s_file" . " GROUP BY gedcom_id")->fetchAssoc(); - } + /** + * Count the number of sources in each tree. + * + * @return string[] + */ + private function totalSources() + { + return Database::prepare("SELECT gedcom_id, COUNT(s_id)" . " FROM `##gedcom`" . " LEFT JOIN `##sources` ON gedcom_id = s_file" . " GROUP BY gedcom_id")->fetchAssoc(); + } } |
