@@ -34,34 +34,34 @@ discard block |
||
34 | 34 | $controller = new RepositoryController($record); |
35 | 35 | |
36 | 36 | if ($controller->record && $controller->record->canShow()) { |
37 | - if ($controller->record->isPendingDeletion()) { |
|
38 | - if (Auth::isModerator($controller->record->getTree())) { |
|
39 | - FlashMessages::addMessage(/* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( |
|
40 | - 'This repository has been deleted. You should review the deletion and then %1$s or %2$s it.', |
|
41 | - '<a href="#" onclick="accept_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', |
|
42 | - '<a href="#" onclick="reject_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>' |
|
43 | - ) . ' ' . FunctionsPrint::helpLink('pending_changes'), 'warning'); |
|
44 | - } elseif (Auth::isEditor($controller->record->getTree())) { |
|
45 | - FlashMessages::addMessage(I18N::translate('This repository has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes'), 'warning'); |
|
46 | - } |
|
47 | - } elseif ($controller->record->isPendingAddtion()) { |
|
48 | - if (Auth::isModerator($controller->record->getTree())) { |
|
49 | - FlashMessages::addMessage(/* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( |
|
50 | - 'This repository has been edited. You should review the changes and then %1$s or %2$s them.', |
|
51 | - '<a href="#" onclick="accept_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', |
|
52 | - '<a href="#" onclick="reject_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' |
|
53 | - ) . ' ' . FunctionsPrint::helpLink('pending_changes'), 'warning'); |
|
54 | - } elseif (Auth::isEditor($controller->record->getTree())) { |
|
55 | - FlashMessages::addMessage(I18N::translate('This repository has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes'), 'warning'); |
|
56 | - } |
|
57 | - } |
|
58 | - $controller->pageHeader(); |
|
37 | + if ($controller->record->isPendingDeletion()) { |
|
38 | + if (Auth::isModerator($controller->record->getTree())) { |
|
39 | + FlashMessages::addMessage(/* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( |
|
40 | + 'This repository has been deleted. You should review the deletion and then %1$s or %2$s it.', |
|
41 | + '<a href="#" onclick="accept_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', |
|
42 | + '<a href="#" onclick="reject_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>' |
|
43 | + ) . ' ' . FunctionsPrint::helpLink('pending_changes'), 'warning'); |
|
44 | + } elseif (Auth::isEditor($controller->record->getTree())) { |
|
45 | + FlashMessages::addMessage(I18N::translate('This repository has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes'), 'warning'); |
|
46 | + } |
|
47 | + } elseif ($controller->record->isPendingAddtion()) { |
|
48 | + if (Auth::isModerator($controller->record->getTree())) { |
|
49 | + FlashMessages::addMessage(/* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( |
|
50 | + 'This repository has been edited. You should review the changes and then %1$s or %2$s them.', |
|
51 | + '<a href="#" onclick="accept_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', |
|
52 | + '<a href="#" onclick="reject_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' |
|
53 | + ) . ' ' . FunctionsPrint::helpLink('pending_changes'), 'warning'); |
|
54 | + } elseif (Auth::isEditor($controller->record->getTree())) { |
|
55 | + FlashMessages::addMessage(I18N::translate('This repository has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes'), 'warning'); |
|
56 | + } |
|
57 | + } |
|
58 | + $controller->pageHeader(); |
|
59 | 59 | } else { |
60 | - FlashMessages::addMessage(I18N::translate('This repository does not exist or you do not have permission to view it.'), 'danger'); |
|
61 | - http_response_code(404); |
|
62 | - $controller->pageHeader(); |
|
60 | + FlashMessages::addMessage(I18N::translate('This repository does not exist or you do not have permission to view it.'), 'danger'); |
|
61 | + http_response_code(404); |
|
62 | + $controller->pageHeader(); |
|
63 | 63 | |
64 | - return; |
|
64 | + return; |
|
65 | 65 | } |
66 | 66 | |
67 | 67 | $controller->addInlineJavascript(' |
@@ -82,24 +82,24 @@ discard block |
||
82 | 82 | $facts = $controller->record->getFacts(); |
83 | 83 | |
84 | 84 | usort( |
85 | - $facts, |
|
86 | - function (Fact $x, Fact $y) { |
|
87 | - static $order = array( |
|
88 | - 'NAME' => 0, |
|
89 | - 'ADDR' => 1, |
|
90 | - 'NOTE' => 2, |
|
91 | - 'WWW' => 3, |
|
92 | - 'REFN' => 4, |
|
93 | - 'RIN' => 5, |
|
94 | - '_UID' => 6, |
|
95 | - 'CHAN' => 7, |
|
96 | - ); |
|
97 | - |
|
98 | - return |
|
99 | - (array_key_exists($x->getTag(), $order) ? $order[$x->getTag()] : PHP_INT_MAX) |
|
100 | - - |
|
101 | - (array_key_exists($y->getTag(), $order) ? $order[$y->getTag()] : PHP_INT_MAX); |
|
102 | - } |
|
85 | + $facts, |
|
86 | + function (Fact $x, Fact $y) { |
|
87 | + static $order = array( |
|
88 | + 'NAME' => 0, |
|
89 | + 'ADDR' => 1, |
|
90 | + 'NOTE' => 2, |
|
91 | + 'WWW' => 3, |
|
92 | + 'REFN' => 4, |
|
93 | + 'RIN' => 5, |
|
94 | + '_UID' => 6, |
|
95 | + 'CHAN' => 7, |
|
96 | + ); |
|
97 | + |
|
98 | + return |
|
99 | + (array_key_exists($x->getTag(), $order) ? $order[$x->getTag()] : PHP_INT_MAX) |
|
100 | + - |
|
101 | + (array_key_exists($y->getTag(), $order) ? $order[$y->getTag()] : PHP_INT_MAX); |
|
102 | + } |
|
103 | 103 | ); |
104 | 104 | |
105 | 105 | ?> |
@@ -150,14 +150,14 @@ discard block |
||
150 | 150 | <div id="repo-edit"> |
151 | 151 | <table class="facts_table"> |
152 | 152 | <?php |
153 | - foreach ($facts as $fact) { |
|
154 | - FunctionsPrintFacts::printFact($fact, $controller->record); |
|
155 | - } |
|
156 | - |
|
157 | - if ($controller->record->canEdit()) { |
|
158 | - FunctionsPrint::printAddNewFact($controller->record->getXref(), $facts, 'REPO'); |
|
159 | - } |
|
160 | - ?> |
|
153 | + foreach ($facts as $fact) { |
|
154 | + FunctionsPrintFacts::printFact($fact, $controller->record); |
|
155 | + } |
|
156 | + |
|
157 | + if ($controller->record->canEdit()) { |
|
158 | + FunctionsPrint::printAddNewFact($controller->record->getXref(), $facts, 'REPO'); |
|
159 | + } |
|
160 | + ?> |
|
161 | 161 | </table> |
162 | 162 | </div> |
163 | 163 |
@@ -35,16 +35,16 @@ discard block |
||
35 | 35 | |
36 | 36 | // The default view depends on whether we are logged in |
37 | 37 | if (Auth::check()) { |
38 | - $ctype = Filter::get('ctype', 'gedcom|user', 'user'); |
|
38 | + $ctype = Filter::get('ctype', 'gedcom|user', 'user'); |
|
39 | 39 | } else { |
40 | - $ctype = 'gedcom'; |
|
40 | + $ctype = 'gedcom'; |
|
41 | 41 | } |
42 | 42 | |
43 | 43 | // Get the blocks list |
44 | 44 | if ($ctype === 'user') { |
45 | - $blocks = FunctionsDb::getUserBlocks(Auth::id()); |
|
45 | + $blocks = FunctionsDb::getUserBlocks(Auth::id()); |
|
46 | 46 | } else { |
47 | - $blocks = FunctionsDb::getTreeBlocks($WT_TREE->getTreeId()); |
|
47 | + $blocks = FunctionsDb::getTreeBlocks($WT_TREE->getTreeId()); |
|
48 | 48 | } |
49 | 49 | |
50 | 50 | $active_blocks = Module::getActiveBlocks($WT_TREE); |
@@ -54,91 +54,91 @@ discard block |
||
54 | 54 | |
55 | 55 | // We generate individual blocks using AJAX |
56 | 56 | if ($action === 'ajax') { |
57 | - $controller = new AjaxController; |
|
58 | - $controller->pageHeader(); |
|
57 | + $controller = new AjaxController; |
|
58 | + $controller->pageHeader(); |
|
59 | 59 | |
60 | - // Check we’re displaying an allowable block. |
|
61 | - $block_id = Filter::getInteger('block_id'); |
|
62 | - if (array_key_exists($block_id, $blocks['main'])) { |
|
63 | - $module_name = $blocks['main'][$block_id]; |
|
64 | - } elseif (array_key_exists($block_id, $blocks['side'])) { |
|
65 | - $module_name = $blocks['side'][$block_id]; |
|
66 | - } else { |
|
67 | - return; |
|
68 | - } |
|
69 | - if (array_key_exists($module_name, $active_blocks)) { |
|
70 | - echo $active_blocks[$module_name]->getBlock($block_id); |
|
71 | - } |
|
60 | + // Check we’re displaying an allowable block. |
|
61 | + $block_id = Filter::getInteger('block_id'); |
|
62 | + if (array_key_exists($block_id, $blocks['main'])) { |
|
63 | + $module_name = $blocks['main'][$block_id]; |
|
64 | + } elseif (array_key_exists($block_id, $blocks['side'])) { |
|
65 | + $module_name = $blocks['side'][$block_id]; |
|
66 | + } else { |
|
67 | + return; |
|
68 | + } |
|
69 | + if (array_key_exists($module_name, $active_blocks)) { |
|
70 | + echo $active_blocks[$module_name]->getBlock($block_id); |
|
71 | + } |
|
72 | 72 | |
73 | - return; |
|
73 | + return; |
|
74 | 74 | } |
75 | 75 | |
76 | 76 | // Redirect search engines to the full URL |
77 | 77 | if (Filter::get('ctype') !== $ctype || Filter::get('ged') !== $WT_TREE->getName()) { |
78 | - header('Location: ' . WT_BASE_URL . 'index.php?ctype=' . $ctype . '&ged=' . $WT_TREE->getNameUrl()); |
|
78 | + header('Location: ' . WT_BASE_URL . 'index.php?ctype=' . $ctype . '&ged=' . $WT_TREE->getNameUrl()); |
|
79 | 79 | |
80 | - return; |
|
80 | + return; |
|
81 | 81 | } |
82 | 82 | |
83 | 83 | $controller = new PageController; |
84 | 84 | if ($ctype === 'user') { |
85 | - $controller->restrictAccess(Auth::check()); |
|
85 | + $controller->restrictAccess(Auth::check()); |
|
86 | 86 | } |
87 | 87 | $controller |
88 | - ->setPageTitle($ctype === 'user' ? I18N::translate('My page') : $WT_TREE->getTitle()) |
|
89 | - ->setMetaRobots('index,follow') |
|
90 | - ->pageHeader() |
|
91 | - // By default jQuery modifies AJAX URLs to disable caching, causing JS libraries to be loaded many times. |
|
92 | - ->addInlineJavascript('jQuery.ajaxSetup({cache:true});'); |
|
88 | + ->setPageTitle($ctype === 'user' ? I18N::translate('My page') : $WT_TREE->getTitle()) |
|
89 | + ->setMetaRobots('index,follow') |
|
90 | + ->pageHeader() |
|
91 | + // By default jQuery modifies AJAX URLs to disable caching, causing JS libraries to be loaded many times. |
|
92 | + ->addInlineJavascript('jQuery.ajaxSetup({cache:true});'); |
|
93 | 93 | |
94 | 94 | if ($ctype === 'user') { |
95 | - echo '<div id="my-page">'; |
|
96 | - echo '<h2 class="center">', I18N::translate('My page'), '</h2>'; |
|
95 | + echo '<div id="my-page">'; |
|
96 | + echo '<h2 class="center">', I18N::translate('My page'), '</h2>'; |
|
97 | 97 | } else { |
98 | - echo '<div id="home-page">'; |
|
98 | + echo '<div id="home-page">'; |
|
99 | 99 | } |
100 | 100 | if ($blocks['main']) { |
101 | - if ($blocks['side']) { |
|
102 | - echo '<div id="index_main_blocks">'; |
|
103 | - } else { |
|
104 | - echo '<div id="index_full_blocks">'; |
|
105 | - } |
|
106 | - foreach ($blocks['main'] as $block_id => $module_name) { |
|
107 | - if (array_key_exists($module_name, $active_blocks)) { |
|
108 | - if (Auth::isSearchEngine() || !$active_blocks[$module_name]->loadAjax()) { |
|
109 | - // Load the block directly |
|
110 | - echo $active_blocks[$module_name]->getBlock($block_id); |
|
111 | - } else { |
|
112 | - // Load the block asynchronously |
|
113 | - echo '<div id="block_', $block_id, '"><div class="loading-image"></div></div>'; |
|
114 | - $controller->addInlineJavascript( |
|
115 | - 'jQuery("#block_' . $block_id . '").load("index.php?ctype=' . $ctype . '&action=ajax&block_id=' . $block_id . '");' |
|
116 | - ); |
|
117 | - } |
|
118 | - } |
|
119 | - } |
|
120 | - echo '</div>'; |
|
101 | + if ($blocks['side']) { |
|
102 | + echo '<div id="index_main_blocks">'; |
|
103 | + } else { |
|
104 | + echo '<div id="index_full_blocks">'; |
|
105 | + } |
|
106 | + foreach ($blocks['main'] as $block_id => $module_name) { |
|
107 | + if (array_key_exists($module_name, $active_blocks)) { |
|
108 | + if (Auth::isSearchEngine() || !$active_blocks[$module_name]->loadAjax()) { |
|
109 | + // Load the block directly |
|
110 | + echo $active_blocks[$module_name]->getBlock($block_id); |
|
111 | + } else { |
|
112 | + // Load the block asynchronously |
|
113 | + echo '<div id="block_', $block_id, '"><div class="loading-image"></div></div>'; |
|
114 | + $controller->addInlineJavascript( |
|
115 | + 'jQuery("#block_' . $block_id . '").load("index.php?ctype=' . $ctype . '&action=ajax&block_id=' . $block_id . '");' |
|
116 | + ); |
|
117 | + } |
|
118 | + } |
|
119 | + } |
|
120 | + echo '</div>'; |
|
121 | 121 | } |
122 | 122 | if ($blocks['side']) { |
123 | - if ($blocks['main']) { |
|
124 | - echo '<div id="index_small_blocks">'; |
|
125 | - } else { |
|
126 | - echo '<div id="index_full_blocks">'; |
|
127 | - } |
|
128 | - foreach ($blocks['side'] as $block_id => $module_name) { |
|
129 | - if (array_key_exists($module_name, $active_blocks)) { |
|
130 | - if (Auth::isSearchEngine() || !$active_blocks[$module_name]->loadAjax()) { |
|
131 | - // Load the block directly |
|
132 | - echo $active_blocks[$module_name]->getBlock($block_id); |
|
133 | - } else { |
|
134 | - // Load the block asynchronously |
|
135 | - echo '<div id="block_', $block_id, '"><div class="loading-image"></div></div>'; |
|
136 | - $controller->addInlineJavascript( |
|
137 | - 'jQuery("#block_' . $block_id . '").load("index.php?ctype=' . $ctype . '&action=ajax&block_id=' . $block_id . '");' |
|
138 | - ); |
|
139 | - } |
|
140 | - } |
|
141 | - } |
|
142 | - echo '</div>'; |
|
123 | + if ($blocks['main']) { |
|
124 | + echo '<div id="index_small_blocks">'; |
|
125 | + } else { |
|
126 | + echo '<div id="index_full_blocks">'; |
|
127 | + } |
|
128 | + foreach ($blocks['side'] as $block_id => $module_name) { |
|
129 | + if (array_key_exists($module_name, $active_blocks)) { |
|
130 | + if (Auth::isSearchEngine() || !$active_blocks[$module_name]->loadAjax()) { |
|
131 | + // Load the block directly |
|
132 | + echo $active_blocks[$module_name]->getBlock($block_id); |
|
133 | + } else { |
|
134 | + // Load the block asynchronously |
|
135 | + echo '<div id="block_', $block_id, '"><div class="loading-image"></div></div>'; |
|
136 | + $controller->addInlineJavascript( |
|
137 | + 'jQuery("#block_' . $block_id . '").load("index.php?ctype=' . $ctype . '&action=ajax&block_id=' . $block_id . '");' |
|
138 | + ); |
|
139 | + } |
|
140 | + } |
|
141 | + } |
|
142 | + echo '</div>'; |
|
143 | 143 | } |
144 | 144 | echo '</div>'; |
@@ -32,85 +32,85 @@ |
||
32 | 32 | |
33 | 33 | $controller = new PageController; |
34 | 34 | $controller |
35 | - ->restrictAccess(Auth::isAdmin()) |
|
36 | - ->setPageTitle(I18N::translate('Module administration')); |
|
35 | + ->restrictAccess(Auth::isAdmin()) |
|
36 | + ->setPageTitle(I18N::translate('Module administration')); |
|
37 | 37 | |
38 | 38 | $modules = Module::getInstalledModules('disabled'); |
39 | 39 | $module_status = Database::prepare("SELECT module_name, status FROM `##module`")->fetchAssoc(); |
40 | 40 | |
41 | 41 | uasort($modules, function (AbstractModule $x, AbstractModule $y) { |
42 | - return I18N::strcasecmp($x->getTitle(), $y->getTitle()); |
|
42 | + return I18N::strcasecmp($x->getTitle(), $y->getTitle()); |
|
43 | 43 | }); |
44 | 44 | |
45 | 45 | if (Filter::post('action') === 'update_mods' && Filter::checkCsrf()) { |
46 | - foreach ($modules as $module) { |
|
47 | - $new_status = Filter::post('status-' . $module->getName(), '[01]'); |
|
48 | - if ($new_status !== null) { |
|
49 | - $new_status = $new_status ? 'enabled' : 'disabled'; |
|
50 | - $old_status = $module_status[$module->getName()]; |
|
51 | - if ($new_status !== $old_status) { |
|
52 | - Database::prepare("UPDATE `##module` SET status=? WHERE module_name=?")->execute(array($new_status, $module->getName())); |
|
53 | - if ($new_status === 'disabled') { |
|
54 | - FlashMessages::addMessage(I18N::translate('The module “%s” has been disabled.', $module->getTitle()), 'success'); |
|
55 | - } else { |
|
56 | - FlashMessages::addMessage(I18N::translate('The module “%s” has been enabled.', $module->getTitle()), 'success'); |
|
57 | - } |
|
58 | - } |
|
59 | - } |
|
60 | - } |
|
46 | + foreach ($modules as $module) { |
|
47 | + $new_status = Filter::post('status-' . $module->getName(), '[01]'); |
|
48 | + if ($new_status !== null) { |
|
49 | + $new_status = $new_status ? 'enabled' : 'disabled'; |
|
50 | + $old_status = $module_status[$module->getName()]; |
|
51 | + if ($new_status !== $old_status) { |
|
52 | + Database::prepare("UPDATE `##module` SET status=? WHERE module_name=?")->execute(array($new_status, $module->getName())); |
|
53 | + if ($new_status === 'disabled') { |
|
54 | + FlashMessages::addMessage(I18N::translate('The module “%s” has been disabled.', $module->getTitle()), 'success'); |
|
55 | + } else { |
|
56 | + FlashMessages::addMessage(I18N::translate('The module “%s” has been enabled.', $module->getTitle()), 'success'); |
|
57 | + } |
|
58 | + } |
|
59 | + } |
|
60 | + } |
|
61 | 61 | |
62 | - header('Location: ' . WT_BASE_URL . 'admin_modules.php'); |
|
62 | + header('Location: ' . WT_BASE_URL . 'admin_modules.php'); |
|
63 | 63 | |
64 | - return; |
|
64 | + return; |
|
65 | 65 | } |
66 | 66 | |
67 | 67 | if (Filter::post('action') === 'delete' && Filter::checkCsrf()) { |
68 | - $module_name = Filter::post('module_name'); |
|
69 | - Database::prepare( |
|
70 | - "DELETE `##block_setting`" . |
|
71 | - " FROM `##block_setting`" . |
|
72 | - " JOIN `##block` USING (block_id)" . |
|
73 | - " JOIN `##module` USING (module_name)" . |
|
74 | - " WHERE module_name=?" |
|
75 | - )->execute(array($module_name)); |
|
76 | - Database::prepare( |
|
77 | - "DELETE `##block`" . |
|
78 | - " FROM `##block`" . |
|
79 | - " JOIN `##module` USING (module_name)" . |
|
80 | - " WHERE module_name=?" |
|
81 | - )->execute(array($module_name)); |
|
82 | - Database::prepare("DELETE FROM `##module_setting` WHERE module_name=?")->execute(array($module_name)); |
|
83 | - Database::prepare("DELETE FROM `##module_privacy` WHERE module_name=?")->execute(array($module_name)); |
|
84 | - Database::prepare("DELETE FROM `##module` WHERE module_name=?")->execute(array($module_name)); |
|
68 | + $module_name = Filter::post('module_name'); |
|
69 | + Database::prepare( |
|
70 | + "DELETE `##block_setting`" . |
|
71 | + " FROM `##block_setting`" . |
|
72 | + " JOIN `##block` USING (block_id)" . |
|
73 | + " JOIN `##module` USING (module_name)" . |
|
74 | + " WHERE module_name=?" |
|
75 | + )->execute(array($module_name)); |
|
76 | + Database::prepare( |
|
77 | + "DELETE `##block`" . |
|
78 | + " FROM `##block`" . |
|
79 | + " JOIN `##module` USING (module_name)" . |
|
80 | + " WHERE module_name=?" |
|
81 | + )->execute(array($module_name)); |
|
82 | + Database::prepare("DELETE FROM `##module_setting` WHERE module_name=?")->execute(array($module_name)); |
|
83 | + Database::prepare("DELETE FROM `##module_privacy` WHERE module_name=?")->execute(array($module_name)); |
|
84 | + Database::prepare("DELETE FROM `##module` WHERE module_name=?")->execute(array($module_name)); |
|
85 | 85 | |
86 | - FlashMessages::addMessage(I18N::translate('The preferences for the module “%s” have been deleted.', $module_name), 'success'); |
|
86 | + FlashMessages::addMessage(I18N::translate('The preferences for the module “%s” have been deleted.', $module_name), 'success'); |
|
87 | 87 | |
88 | - header('Location: ' . WT_BASE_URL . 'admin_modules.php'); |
|
88 | + header('Location: ' . WT_BASE_URL . 'admin_modules.php'); |
|
89 | 89 | |
90 | - return; |
|
90 | + return; |
|
91 | 91 | } |
92 | 92 | |
93 | 93 | // The module can’t be found on disk? |
94 | 94 | // Don't delete it automatically. It may be temporarily missing, after a re-installation, etc. |
95 | 95 | foreach ($module_status as $module_name => $status) { |
96 | - if (!array_key_exists($module_name, $modules)) { |
|
97 | - $html = |
|
98 | - I18N::translate('Preferences exist for the module “%s”, but this module no longer exists.', '<span dir="ltr">' . $module_name . '</span>') . |
|
99 | - '<form method="post" class="form-inline">' . |
|
100 | - Filter::getCsrf() . |
|
101 | - '<input type="hidden" name="action" value="delete">' . |
|
102 | - '<input type="hidden" name="module_name" value="' . $module_name . '">' . |
|
103 | - '<button type="submit" class="btn btn-link">' . I18N::translate('Delete the preferences for this module.') . '</button>' . |
|
104 | - '</form>'; |
|
105 | - FlashMessages::addMessage($html, 'warning'); |
|
106 | - } |
|
96 | + if (!array_key_exists($module_name, $modules)) { |
|
97 | + $html = |
|
98 | + I18N::translate('Preferences exist for the module “%s”, but this module no longer exists.', '<span dir="ltr">' . $module_name . '</span>') . |
|
99 | + '<form method="post" class="form-inline">' . |
|
100 | + Filter::getCsrf() . |
|
101 | + '<input type="hidden" name="action" value="delete">' . |
|
102 | + '<input type="hidden" name="module_name" value="' . $module_name . '">' . |
|
103 | + '<button type="submit" class="btn btn-link">' . I18N::translate('Delete the preferences for this module.') . '</button>' . |
|
104 | + '</form>'; |
|
105 | + FlashMessages::addMessage($html, 'warning'); |
|
106 | + } |
|
107 | 107 | } |
108 | 108 | |
109 | 109 | $controller |
110 | - ->pageHeader() |
|
111 | - ->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL) |
|
112 | - ->addExternalJavascript(WT_DATATABLES_BOOTSTRAP_JS_URL) |
|
113 | - ->addInlineJavascript(' |
|
110 | + ->pageHeader() |
|
111 | + ->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL) |
|
112 | + ->addExternalJavascript(WT_DATATABLES_BOOTSTRAP_JS_URL) |
|
113 | + ->addInlineJavascript(' |
|
114 | 114 | function reindexMods(id) { |
115 | 115 | jQuery("#" + id + " input").each( |
116 | 116 | function (index, value) { |
@@ -176,9 +176,12 @@ discard block |
||
176 | 176 | <a href="<?php echo $module->getConfigLink() ?>"> |
177 | 177 | <?php echo $module->getTitle() ?> <i class="fa fa-cogs"></i> |
178 | 178 | </a> |
179 | - <?php else: ?> |
|
179 | + <?php else { |
|
180 | + : ?> |
|
180 | 181 | <?php echo $module->getTitle() ?> |
181 | - <?php endif; ?> |
|
182 | + <?php endif; |
|
183 | +} |
|
184 | +?> |
|
182 | 185 | <?php if (!in_array($module->getName(), Module::getCoreModuleNames())): ?> |
183 | 186 | <br> |
184 | 187 | <?php endif; ?> |
@@ -202,23 +205,32 @@ discard block |
||
202 | 205 | <td class="text-center text-muted hidden-xs"> |
203 | 206 | <?php if ($module instanceof ModuleMenuInterface): ?> |
204 | 207 | <i class="fa fa-list-ul" title="<?php echo I18N::translate('Menu') ?>"></i> |
205 | - <?php else: ?> |
|
208 | + <?php else { |
|
209 | + : ?> |
|
206 | 210 | - |
207 | - <?php endif; ?> |
|
211 | + <?php endif; |
|
212 | +} |
|
213 | +?> |
|
208 | 214 | </td> |
209 | 215 | <td class="text-center text-muted hidden-xs"> |
210 | 216 | <?php if ($module instanceof ModuleTabInterface): ?> |
211 | 217 | <i class="fa fa-folder" title="<?php echo I18N::translate('Tab') ?>"></i> |
212 | - <?php else: ?> |
|
218 | + <?php else { |
|
219 | + : ?> |
|
213 | 220 | - |
214 | - <?php endif; ?> |
|
221 | + <?php endif; |
|
222 | +} |
|
223 | +?> |
|
215 | 224 | </td> |
216 | 225 | <td class="text-center text-muted hidden-xs"> |
217 | 226 | <?php if ($module instanceof ModuleSidebarInterface): ?> |
218 | 227 | <i class="fa fa-th-large" title="<?php echo I18N::translate('Sidebar') ?>"></i> |
219 | - <?php else: ?> |
|
228 | + <?php else { |
|
229 | + : ?> |
|
220 | 230 | - |
221 | - <?php endif; ?> |
|
231 | + <?php endif; |
|
232 | +} |
|
233 | +?> |
|
222 | 234 | </td> |
223 | 235 | <td class="text-center text-muted hidden-xs"> |
224 | 236 | <?php if ($module instanceof ModuleBlockInterface): ?> |
@@ -228,30 +240,42 @@ discard block |
||
228 | 240 | <?php if ($module->isUserBlock()): ?> |
229 | 241 | <i class="fa fa-tree" title="<?php echo I18N::translate('Home page') ?>"></i> |
230 | 242 | <?php endif; ?> |
231 | - <?php else: ?> |
|
243 | + <?php else { |
|
244 | + : ?> |
|
232 | 245 | - |
233 | - <?php endif; ?> |
|
246 | + <?php endif; |
|
247 | +} |
|
248 | +?> |
|
234 | 249 | </td> |
235 | 250 | <td class="text-center text-muted hidden-xs"> |
236 | 251 | <?php if ($module instanceof ModuleChartInterface): ?> |
237 | 252 | <i class="fa fa-share-alt" title="<?php echo I18N::translate('Chart') ?>"></i> |
238 | - <?php else: ?> |
|
253 | + <?php else { |
|
254 | + : ?> |
|
239 | 255 | - |
240 | - <?php endif; ?> |
|
256 | + <?php endif; |
|
257 | +} |
|
258 | +?> |
|
241 | 259 | </td> |
242 | 260 | <td class="text-center text-muted hidden-xs"> |
243 | 261 | <?php if ($module instanceof ModuleReportInterface): ?> |
244 | 262 | <i class="fa fa-file" title="<?php echo I18N::translate('Report') ?>"></i> |
245 | - <?php else: ?> |
|
263 | + <?php else { |
|
264 | + : ?> |
|
246 | 265 | - |
247 | - <?php endif; ?> |
|
266 | + <?php endif; |
|
267 | +} |
|
268 | +?> |
|
248 | 269 | </td> |
249 | 270 | <td class="text-center text-muted hidden"> |
250 | 271 | <?php if ($module instanceof ModuleThemeInterface): ?> |
251 | 272 | <i class="fa fa-check" title="<?php echo I18N::translate('Theme') ?>"></i> |
252 | - <?php else: ?> |
|
273 | + <?php else { |
|
274 | + : ?> |
|
253 | 275 | - |
254 | - <?php endif; ?> |
|
276 | + <?php endif; |
|
277 | +} |
|
278 | +?> |
|
255 | 279 | </td> |
256 | 280 | </tr> |
257 | 281 | <?php endforeach; ?> |
@@ -23,45 +23,45 @@ discard block |
||
23 | 23 | |
24 | 24 | $to_delete = Filter::postArray('to_delete'); |
25 | 25 | if ($to_delete && Filter::checkCsrf()) { |
26 | - foreach ($to_delete as $path) { |
|
27 | - $is_dir = is_dir(WT_DATA_DIR . $path); |
|
28 | - if (File::delete(WT_DATA_DIR . $path)) { |
|
29 | - if ($is_dir) { |
|
30 | - FlashMessages::addMessage(I18N::translate('The folder %s has been deleted.', Filter::escapeHtml($path)), 'success'); |
|
31 | - } else { |
|
32 | - FlashMessages::addMessage(I18N::translate('The file %s has been deleted.', Filter::escapeHtml($path)), 'success'); |
|
33 | - } |
|
34 | - } else { |
|
35 | - if ($is_dir) { |
|
36 | - FlashMessages::addMessage(I18N::translate('The folder %s could not be deleted.', Filter::escapeHtml($path)), 'danger'); |
|
37 | - } else { |
|
38 | - FlashMessages::addMessage(I18N::translate('The file %s could not be deleted.', Filter::escapeHtml($path)), 'danger'); |
|
39 | - } |
|
40 | - } |
|
41 | - } |
|
42 | - |
|
43 | - header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); |
|
44 | - |
|
45 | - return; |
|
26 | + foreach ($to_delete as $path) { |
|
27 | + $is_dir = is_dir(WT_DATA_DIR . $path); |
|
28 | + if (File::delete(WT_DATA_DIR . $path)) { |
|
29 | + if ($is_dir) { |
|
30 | + FlashMessages::addMessage(I18N::translate('The folder %s has been deleted.', Filter::escapeHtml($path)), 'success'); |
|
31 | + } else { |
|
32 | + FlashMessages::addMessage(I18N::translate('The file %s has been deleted.', Filter::escapeHtml($path)), 'success'); |
|
33 | + } |
|
34 | + } else { |
|
35 | + if ($is_dir) { |
|
36 | + FlashMessages::addMessage(I18N::translate('The folder %s could not be deleted.', Filter::escapeHtml($path)), 'danger'); |
|
37 | + } else { |
|
38 | + FlashMessages::addMessage(I18N::translate('The file %s could not be deleted.', Filter::escapeHtml($path)), 'danger'); |
|
39 | + } |
|
40 | + } |
|
41 | + } |
|
42 | + |
|
43 | + header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); |
|
44 | + |
|
45 | + return; |
|
46 | 46 | } |
47 | 47 | |
48 | 48 | $controller = new PageController; |
49 | 49 | $controller |
50 | - ->restrictAccess(Auth::isAdmin()) |
|
51 | - ->setPageTitle(/* I18N: The “Data folder” is a configuration setting */ I18N::translate('Clean up data folder')) |
|
52 | - ->pageHeader(); |
|
50 | + ->restrictAccess(Auth::isAdmin()) |
|
51 | + ->setPageTitle(/* I18N: The “Data folder” is a configuration setting */ I18N::translate('Clean up data folder')) |
|
52 | + ->pageHeader(); |
|
53 | 53 | |
54 | 54 | $do_not_delete = array('index.php', 'config.ini.php', 'language'); |
55 | 55 | |
56 | 56 | // If we are storing the media in the data folder (this is the default), then don’t delete it. |
57 | 57 | foreach (Tree::getAll() as $tree) { |
58 | - $MEDIA_DIRECTORY = $tree->getPreference('MEDIA_DIRECTORY'); |
|
58 | + $MEDIA_DIRECTORY = $tree->getPreference('MEDIA_DIRECTORY'); |
|
59 | 59 | |
60 | - if (substr($MEDIA_DIRECTORY, 0, 3) != '../') { |
|
61 | - // Just need to add the first part of the path |
|
62 | - $tmp = explode('/', $MEDIA_DIRECTORY); |
|
63 | - $do_not_delete[] = $tmp[0]; |
|
64 | - } |
|
60 | + if (substr($MEDIA_DIRECTORY, 0, 3) != '../') { |
|
61 | + // Just need to add the first part of the path |
|
62 | + $tmp = explode('/', $MEDIA_DIRECTORY); |
|
63 | + $do_not_delete[] = $tmp[0]; |
|
64 | + } |
|
65 | 65 | } |
66 | 66 | |
67 | 67 | $locked_icon = '<i class="fa fa-ban text-danger"></i>'; |
@@ -69,9 +69,9 @@ discard block |
||
69 | 69 | $dir = dir(WT_DATA_DIR); |
70 | 70 | $entries = array(); |
71 | 71 | while (false !== ($entry = $dir->read())) { |
72 | - if ($entry[0] != '.') { |
|
73 | - $entries[] = $entry; |
|
74 | - } |
|
72 | + if ($entry[0] != '.') { |
|
73 | + $entries[] = $entry; |
|
74 | + } |
|
75 | 75 | } |
76 | 76 | |
77 | 77 | sort($entries); |
@@ -94,20 +94,20 @@ discard block |
||
94 | 94 | <legend class="sr-only"><?php echo $controller->getPageTitle(); ?></legend> |
95 | 95 | <ul class="fa-ul"> |
96 | 96 | <?php |
97 | - foreach ($entries as $entry) { |
|
98 | - if (in_array($entry, $do_not_delete)) { |
|
99 | - echo '<li><i class="fa-li fa fa-ban text-danger"></i>', Filter::escapeHtml($entry), '</li>'; |
|
100 | - } else { |
|
101 | - $id = 'input-' . Uuid::uuid4(); |
|
102 | - echo '<li><i class="fa-li fa fa-trash-o"></i>'; |
|
103 | - echo '<label for="', $id, '">'; |
|
104 | - echo '<input type="checkbox" id="', $id, '" name="to_delete[]" value="', Filter::escapeHtml($entry), '"> '; |
|
105 | - echo Filter::escapeHtml($entry); |
|
106 | - echo '</label></li>'; |
|
107 | - } |
|
108 | - } |
|
109 | - $dir->close(); |
|
110 | - ?> |
|
97 | + foreach ($entries as $entry) { |
|
98 | + if (in_array($entry, $do_not_delete)) { |
|
99 | + echo '<li><i class="fa-li fa fa-ban text-danger"></i>', Filter::escapeHtml($entry), '</li>'; |
|
100 | + } else { |
|
101 | + $id = 'input-' . Uuid::uuid4(); |
|
102 | + echo '<li><i class="fa-li fa fa-trash-o"></i>'; |
|
103 | + echo '<label for="', $id, '">'; |
|
104 | + echo '<input type="checkbox" id="', $id, '" name="to_delete[]" value="', Filter::escapeHtml($entry), '"> '; |
|
105 | + echo Filter::escapeHtml($entry); |
|
106 | + echo '</label></li>'; |
|
107 | + } |
|
108 | + } |
|
109 | + $dir->close(); |
|
110 | + ?> |
|
111 | 111 | </ul> |
112 | 112 | </fieldset> |
113 | 113 | <button class="btn btn-danger" type="submit"> |
@@ -34,56 +34,56 @@ |
||
34 | 34 | $changes = array(); |
35 | 35 | |
36 | 36 | if ($search && $replace) { |
37 | - $rows = Database::prepare( |
|
38 | - "SELECT i_id AS xref, i_gedcom AS gedcom" . |
|
39 | - " FROM `##individuals`" . |
|
40 | - " LEFT JOIN `##change` ON (i_id = xref AND i_file=gedcom_id AND status='pending')" . |
|
41 | - " WHERE i_file = ?" . |
|
42 | - " AND COALESCE(new_gedcom, i_gedcom) REGEXP CONCAT('\n2 PLAC ([^\n]*, )*', ?, '(\n|$)')" |
|
43 | - )->execute(array($WT_TREE->getTreeId(), preg_quote($search)))->fetchAll(); |
|
44 | - foreach ($rows as $row) { |
|
45 | - $record = Individual::getInstance($row->xref, $WT_TREE, $row->gedcom); |
|
46 | - foreach ($record->getFacts() as $fact) { |
|
47 | - $old_place = $fact->getAttribute('PLAC'); |
|
48 | - if (preg_match('/(^|, )' . preg_quote($search, '/') . '$/i', $old_place)) { |
|
49 | - $new_place = preg_replace('/(^|, )' . preg_quote($search, '/') . '$/i', '$1' . $replace, $old_place); |
|
50 | - $changes[$old_place] = $new_place; |
|
51 | - if ($confirm == 'update') { |
|
52 | - $gedcom = preg_replace('/(\n2 PLAC (?:.*, )*)' . preg_quote($search, '/') . '(\n|$)/i', '$1' . $replace . '$2', $fact->getGedcom()); |
|
53 | - $record->updateFact($fact->getFactId(), $gedcom, false); |
|
54 | - } |
|
55 | - } |
|
56 | - } |
|
57 | - } |
|
58 | - $rows = Database::prepare( |
|
59 | - "SELECT f_id AS xref, f_gedcom AS gedcom" . |
|
60 | - " FROM `##families`" . |
|
61 | - " LEFT JOIN `##change` ON (f_id = xref AND f_file=gedcom_id AND status='pending')" . |
|
62 | - " WHERE f_file = ?" . |
|
63 | - " AND COALESCE(new_gedcom, f_gedcom) REGEXP CONCAT('\n2 PLAC ([^\n]*, )*', ?, '(\n|$)')" |
|
64 | - )->execute(array($WT_TREE->getTreeId(), preg_quote($search)))->fetchAll(); |
|
65 | - foreach ($rows as $row) { |
|
66 | - $record = Family::getInstance($row->xref, $WT_TREE, $row->gedcom); |
|
67 | - foreach ($record->getFacts() as $fact) { |
|
68 | - $old_place = $fact->getAttribute('PLAC'); |
|
69 | - if (preg_match('/(^|, )' . preg_quote($search, '/') . '$/i', $old_place)) { |
|
70 | - $new_place = preg_replace('/(^|, )' . preg_quote($search, '/') . '$/i', '$1' . $replace, $old_place); |
|
71 | - $changes[$old_place] = $new_place; |
|
72 | - if ($confirm == 'update') { |
|
73 | - $gedcom = preg_replace('/(\n2 PLAC (?:.*, )*)' . preg_quote($search, '/') . '(\n|$)/i', '$1' . $replace . '$2', $fact->getGedcom()); |
|
74 | - $record->updateFact($fact->getFactId(), $gedcom, false); |
|
75 | - } |
|
76 | - } |
|
77 | - } |
|
78 | - } |
|
37 | + $rows = Database::prepare( |
|
38 | + "SELECT i_id AS xref, i_gedcom AS gedcom" . |
|
39 | + " FROM `##individuals`" . |
|
40 | + " LEFT JOIN `##change` ON (i_id = xref AND i_file=gedcom_id AND status='pending')" . |
|
41 | + " WHERE i_file = ?" . |
|
42 | + " AND COALESCE(new_gedcom, i_gedcom) REGEXP CONCAT('\n2 PLAC ([^\n]*, )*', ?, '(\n|$)')" |
|
43 | + )->execute(array($WT_TREE->getTreeId(), preg_quote($search)))->fetchAll(); |
|
44 | + foreach ($rows as $row) { |
|
45 | + $record = Individual::getInstance($row->xref, $WT_TREE, $row->gedcom); |
|
46 | + foreach ($record->getFacts() as $fact) { |
|
47 | + $old_place = $fact->getAttribute('PLAC'); |
|
48 | + if (preg_match('/(^|, )' . preg_quote($search, '/') . '$/i', $old_place)) { |
|
49 | + $new_place = preg_replace('/(^|, )' . preg_quote($search, '/') . '$/i', '$1' . $replace, $old_place); |
|
50 | + $changes[$old_place] = $new_place; |
|
51 | + if ($confirm == 'update') { |
|
52 | + $gedcom = preg_replace('/(\n2 PLAC (?:.*, )*)' . preg_quote($search, '/') . '(\n|$)/i', '$1' . $replace . '$2', $fact->getGedcom()); |
|
53 | + $record->updateFact($fact->getFactId(), $gedcom, false); |
|
54 | + } |
|
55 | + } |
|
56 | + } |
|
57 | + } |
|
58 | + $rows = Database::prepare( |
|
59 | + "SELECT f_id AS xref, f_gedcom AS gedcom" . |
|
60 | + " FROM `##families`" . |
|
61 | + " LEFT JOIN `##change` ON (f_id = xref AND f_file=gedcom_id AND status='pending')" . |
|
62 | + " WHERE f_file = ?" . |
|
63 | + " AND COALESCE(new_gedcom, f_gedcom) REGEXP CONCAT('\n2 PLAC ([^\n]*, )*', ?, '(\n|$)')" |
|
64 | + )->execute(array($WT_TREE->getTreeId(), preg_quote($search)))->fetchAll(); |
|
65 | + foreach ($rows as $row) { |
|
66 | + $record = Family::getInstance($row->xref, $WT_TREE, $row->gedcom); |
|
67 | + foreach ($record->getFacts() as $fact) { |
|
68 | + $old_place = $fact->getAttribute('PLAC'); |
|
69 | + if (preg_match('/(^|, )' . preg_quote($search, '/') . '$/i', $old_place)) { |
|
70 | + $new_place = preg_replace('/(^|, )' . preg_quote($search, '/') . '$/i', '$1' . $replace, $old_place); |
|
71 | + $changes[$old_place] = $new_place; |
|
72 | + if ($confirm == 'update') { |
|
73 | + $gedcom = preg_replace('/(\n2 PLAC (?:.*, )*)' . preg_quote($search, '/') . '(\n|$)/i', '$1' . $replace . '$2', $fact->getGedcom()); |
|
74 | + $record->updateFact($fact->getFactId(), $gedcom, false); |
|
75 | + } |
|
76 | + } |
|
77 | + } |
|
78 | + } |
|
79 | 79 | } |
80 | 80 | |
81 | 81 | $controller = new PageController; |
82 | 82 | $controller |
83 | - ->restrictAccess(Auth::isManager($WT_TREE)) |
|
84 | - ->setPageTitle(I18N::translate('Update all the place names in a family tree') . ' — ' . $WT_TREE->getTitleHtml()) |
|
85 | - ->addInlineJavascript('autocomplete();') |
|
86 | - ->pageHeader(); |
|
83 | + ->restrictAccess(Auth::isManager($WT_TREE)) |
|
84 | + ->setPageTitle(I18N::translate('Update all the place names in a family tree') . ' — ' . $WT_TREE->getTitleHtml()) |
|
85 | + ->addInlineJavascript('autocomplete();') |
|
86 | + ->pageHeader(); |
|
87 | 87 | ?> |
88 | 88 | |
89 | 89 | <ol class="breadcrumb small"> |
@@ -33,38 +33,38 @@ discard block |
||
33 | 33 | $controller = new FamilyController($record); |
34 | 34 | |
35 | 35 | if ($controller->record && $controller->record->canShow()) { |
36 | - if ($controller->record->isPendingDeletion()) { |
|
37 | - if (Auth::isModerator($controller->record->getTree())) { |
|
38 | - FlashMessages::addMessage(/* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( |
|
39 | - 'This family has been deleted. You should review the deletion and then %1$s or %2$s it.', |
|
40 | - '<a href="#" onclick="accept_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', |
|
41 | - '<a href="#" onclick="reject_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>' |
|
42 | - ) . ' ' . FunctionsPrint::helpLink('pending_changes'), 'warning'); |
|
43 | - } elseif (Auth::isEditor($controller->record->getTree())) { |
|
44 | - FlashMessages::addMessage(I18N::translate('This family has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes'), 'warning'); |
|
45 | - } |
|
46 | - } elseif ($controller->record->isPendingAddtion()) { |
|
47 | - if (Auth::isModerator($controller->record->getTree())) { |
|
48 | - FlashMessages::addMessage(/* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( |
|
49 | - 'This family has been edited. You should review the changes and then %1$s or %2$s them.', |
|
50 | - '<a href="#" onclick="accept_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', |
|
51 | - '<a href="#" onclick="reject_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' |
|
52 | - ) . ' ' . FunctionsPrint::helpLink('pending_changes'), 'warning'); |
|
53 | - } elseif (Auth::isEditor($controller->record->getTree())) { |
|
54 | - FlashMessages::addMessage(I18N::translate('This family has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes'), 'warning'); |
|
55 | - } |
|
56 | - } |
|
57 | - $controller->pageHeader(); |
|
36 | + if ($controller->record->isPendingDeletion()) { |
|
37 | + if (Auth::isModerator($controller->record->getTree())) { |
|
38 | + FlashMessages::addMessage(/* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( |
|
39 | + 'This family has been deleted. You should review the deletion and then %1$s or %2$s it.', |
|
40 | + '<a href="#" onclick="accept_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', |
|
41 | + '<a href="#" onclick="reject_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>' |
|
42 | + ) . ' ' . FunctionsPrint::helpLink('pending_changes'), 'warning'); |
|
43 | + } elseif (Auth::isEditor($controller->record->getTree())) { |
|
44 | + FlashMessages::addMessage(I18N::translate('This family has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes'), 'warning'); |
|
45 | + } |
|
46 | + } elseif ($controller->record->isPendingAddtion()) { |
|
47 | + if (Auth::isModerator($controller->record->getTree())) { |
|
48 | + FlashMessages::addMessage(/* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( |
|
49 | + 'This family has been edited. You should review the changes and then %1$s or %2$s them.', |
|
50 | + '<a href="#" onclick="accept_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', |
|
51 | + '<a href="#" onclick="reject_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' |
|
52 | + ) . ' ' . FunctionsPrint::helpLink('pending_changes'), 'warning'); |
|
53 | + } elseif (Auth::isEditor($controller->record->getTree())) { |
|
54 | + FlashMessages::addMessage(I18N::translate('This family has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes'), 'warning'); |
|
55 | + } |
|
56 | + } |
|
57 | + $controller->pageHeader(); |
|
58 | 58 | } elseif ($controller->record && $controller->record->getTree()->getPreference('SHOW_PRIVATE_RELATIONSHIPS')) { |
59 | - $controller->pageHeader(); |
|
60 | - // Continue - to display the children/parents/grandparents. |
|
61 | - // We'll check for showing the details again later |
|
59 | + $controller->pageHeader(); |
|
60 | + // Continue - to display the children/parents/grandparents. |
|
61 | + // We'll check for showing the details again later |
|
62 | 62 | } else { |
63 | - FlashMessages::addMessage(I18N::translate('This family does not exist or you do not have permission to view it.'), 'danger'); |
|
64 | - http_response_code(404); |
|
65 | - $controller->pageHeader(); |
|
63 | + FlashMessages::addMessage(I18N::translate('This family does not exist or you do not have permission to view it.'), 'danger'); |
|
64 | + http_response_code(404); |
|
65 | + $controller->pageHeader(); |
|
66 | 66 | |
67 | - return; |
|
67 | + return; |
|
68 | 68 | } |
69 | 69 | |
70 | 70 | ?> |
@@ -85,32 +85,32 @@ discard block |
||
85 | 85 | <tr> |
86 | 86 | <td colspan="2"> |
87 | 87 | <?php |
88 | - FunctionsCharts::printFamilyParents($controller->record); |
|
89 | - if (Auth::isEditor($controller->record->getTree())) { |
|
90 | - $husb = $controller->record->getHusband(); |
|
91 | - if (!$husb) { |
|
92 | - echo '<a href="#" onclick="return add_spouse_to_family(\'', $controller->record->getXref(), '\', \'HUSB\');">', I18N::translate('Add a father'), '</a><br>'; |
|
93 | - } |
|
94 | - $wife = $controller->record->getWife(); |
|
95 | - if (!$wife) { |
|
96 | - echo '<a href="#" onclick="return add_spouse_to_family(\'', $controller->record->getXref(), '\', \'WIFE\');">', I18N::translate('Add a mother'), '</a><br>'; |
|
97 | - } |
|
98 | - } |
|
99 | - ?> |
|
88 | + FunctionsCharts::printFamilyParents($controller->record); |
|
89 | + if (Auth::isEditor($controller->record->getTree())) { |
|
90 | + $husb = $controller->record->getHusband(); |
|
91 | + if (!$husb) { |
|
92 | + echo '<a href="#" onclick="return add_spouse_to_family(\'', $controller->record->getXref(), '\', \'HUSB\');">', I18N::translate('Add a father'), '</a><br>'; |
|
93 | + } |
|
94 | + $wife = $controller->record->getWife(); |
|
95 | + if (!$wife) { |
|
96 | + echo '<a href="#" onclick="return add_spouse_to_family(\'', $controller->record->getXref(), '\', \'WIFE\');">', I18N::translate('Add a mother'), '</a><br>'; |
|
97 | + } |
|
98 | + } |
|
99 | + ?> |
|
100 | 100 | </td> |
101 | 101 | </tr> |
102 | 102 | <tr> |
103 | 103 | <td colspan="2"> |
104 | 104 | <span class="subheaders"><?php echo I18N::translate('Family group information'); ?></span> |
105 | 105 | <?php |
106 | - if ($controller->record->canShow()) { |
|
107 | - echo '<table class="facts_table">'; |
|
108 | - $controller->printFamilyFacts(); |
|
109 | - echo '</table>'; |
|
110 | - } else { |
|
111 | - echo '<p>', I18N::translate('The details of this family are private.'), '</p>'; |
|
112 | - } |
|
113 | - ?> |
|
106 | + if ($controller->record->canShow()) { |
|
107 | + echo '<table class="facts_table">'; |
|
108 | + $controller->printFamilyFacts(); |
|
109 | + echo '</table>'; |
|
110 | + } else { |
|
111 | + echo '<p>', I18N::translate('The details of this family are private.'), '</p>'; |
|
112 | + } |
|
113 | + ?> |
|
114 | 114 | </td> |
115 | 115 | </tr> |
116 | 116 | </table> |
@@ -32,8 +32,8 @@ discard block |
||
32 | 32 | |
33 | 33 | $controller = new PageController; |
34 | 34 | $controller |
35 | - ->restrictAccess(Auth::isManager($WT_TREE)) |
|
36 | - ->setPageTitle(I18N::translate('Changes')); |
|
35 | + ->restrictAccess(Auth::isManager($WT_TREE)) |
|
36 | + ->setPageTitle(I18N::translate('Changes')); |
|
37 | 37 | |
38 | 38 | $earliest = Database::prepare("SELECT IFNULL(DATE(MIN(change_time)), CURDATE()) FROM `##change`")->execute(array())->fetchOne(); |
39 | 39 | $latest = Database::prepare("SELECT IFNULL(DATE(MAX(change_time)), CURDATE()) FROM `##change`")->execute(array())->fetchOne(); |
@@ -51,197 +51,197 @@ discard block |
||
51 | 51 | $search = isset($search['value']) ? $search['value'] : null; |
52 | 52 | |
53 | 53 | $statuses = array( |
54 | - 'accepted' => /* I18N: the status of an edit accepted/rejected/pending */ I18N::translate('accepted'), |
|
55 | - 'rejected' => /* I18N: the status of an edit accepted/rejected/pending */ I18N::translate('rejected'), |
|
56 | - 'pending' => /* I18N: the status of an edit accepted/rejected/pending */ I18N::translate('pending'), |
|
54 | + 'accepted' => /* I18N: the status of an edit accepted/rejected/pending */ I18N::translate('accepted'), |
|
55 | + 'rejected' => /* I18N: the status of an edit accepted/rejected/pending */ I18N::translate('rejected'), |
|
56 | + 'pending' => /* I18N: the status of an edit accepted/rejected/pending */ I18N::translate('pending'), |
|
57 | 57 | ); |
58 | 58 | |
59 | 59 | if (Auth::isAdmin()) { |
60 | - // Administrators can see all logs |
|
61 | - $gedc = Filter::get('gedc'); |
|
60 | + // Administrators can see all logs |
|
61 | + $gedc = Filter::get('gedc'); |
|
62 | 62 | } else { |
63 | - // Managers can only see logs relating to this gedcom |
|
64 | - $gedc = $WT_TREE->getName(); |
|
63 | + // Managers can only see logs relating to this gedcom |
|
64 | + $gedc = $WT_TREE->getName(); |
|
65 | 65 | } |
66 | 66 | |
67 | 67 | $sql_select = |
68 | - "SELECT SQL_CALC_FOUND_ROWS change_id, change_time, status, xref, old_gedcom, new_gedcom, IFNULL(user_name, '<none>') AS user_name, IFNULL(gedcom_name, '<none>') AS gedcom_name" . |
|
69 | - " FROM `##change`" . |
|
70 | - " LEFT JOIN `##user` USING (user_id)" . // user may be deleted |
|
71 | - " LEFT JOIN `##gedcom` USING (gedcom_id)"; // gedcom may be deleted |
|
68 | + "SELECT SQL_CALC_FOUND_ROWS change_id, change_time, status, xref, old_gedcom, new_gedcom, IFNULL(user_name, '<none>') AS user_name, IFNULL(gedcom_name, '<none>') AS gedcom_name" . |
|
69 | + " FROM `##change`" . |
|
70 | + " LEFT JOIN `##user` USING (user_id)" . // user may be deleted |
|
71 | + " LEFT JOIN `##gedcom` USING (gedcom_id)"; // gedcom may be deleted |
|
72 | 72 | |
73 | 73 | $where = " WHERE 1"; |
74 | 74 | $args = array(); |
75 | 75 | if ($search) { |
76 | - $where .= " AND (old_gedcom LIKE CONCAT('%', :search_1, '%') OR new_gedcom LIKE CONCAT('%', :search_2, '%'))"; |
|
77 | - $args['search_1'] = $search; |
|
78 | - $args['search_2'] = $search; |
|
76 | + $where .= " AND (old_gedcom LIKE CONCAT('%', :search_1, '%') OR new_gedcom LIKE CONCAT('%', :search_2, '%'))"; |
|
77 | + $args['search_1'] = $search; |
|
78 | + $args['search_2'] = $search; |
|
79 | 79 | } |
80 | 80 | if ($from) { |
81 | - $where .= " AND change_time >= :from"; |
|
82 | - $args['from'] = $from; |
|
81 | + $where .= " AND change_time >= :from"; |
|
82 | + $args['from'] = $from; |
|
83 | 83 | } |
84 | 84 | if ($to) { |
85 | - $where .= " AND change_time < TIMESTAMPADD(DAY, 1 , :to)"; // before end of the day |
|
86 | - $args['to'] = $to; |
|
85 | + $where .= " AND change_time < TIMESTAMPADD(DAY, 1 , :to)"; // before end of the day |
|
86 | + $args['to'] = $to; |
|
87 | 87 | } |
88 | 88 | if ($type) { |
89 | - $where .= " AND status = :status"; |
|
90 | - $args['status'] = $type; |
|
89 | + $where .= " AND status = :status"; |
|
90 | + $args['status'] = $type; |
|
91 | 91 | } |
92 | 92 | if ($oldged) { |
93 | - $where .= " AND old_gedcom LIKE CONCAT('%', :old_ged, '%')"; |
|
94 | - $args['old_ged'] = $oldged; |
|
93 | + $where .= " AND old_gedcom LIKE CONCAT('%', :old_ged, '%')"; |
|
94 | + $args['old_ged'] = $oldged; |
|
95 | 95 | } |
96 | 96 | if ($newged) { |
97 | - $where .= " AND new_gedcom LIKE CONCAT('%', :new_ged, '%')"; |
|
98 | - $args['new_ged'] = $newged; |
|
97 | + $where .= " AND new_gedcom LIKE CONCAT('%', :new_ged, '%')"; |
|
98 | + $args['new_ged'] = $newged; |
|
99 | 99 | } |
100 | 100 | if ($xref) { |
101 | - $where .= " AND xref = :xref"; |
|
102 | - $args['xref'] = $xref; |
|
101 | + $where .= " AND xref = :xref"; |
|
102 | + $args['xref'] = $xref; |
|
103 | 103 | } |
104 | 104 | if ($user) { |
105 | - $where .= " AND user_name LIKE CONCAT('%', :user, '%')"; |
|
106 | - $args['user'] = $user; |
|
105 | + $where .= " AND user_name LIKE CONCAT('%', :user, '%')"; |
|
106 | + $args['user'] = $user; |
|
107 | 107 | } |
108 | 108 | if ($gedc) { |
109 | - $where .= " AND gedcom_name LIKE CONCAT('%', :gedc, '%')"; |
|
110 | - $args['gedc'] = $gedc; |
|
109 | + $where .= " AND gedcom_name LIKE CONCAT('%', :gedc, '%')"; |
|
110 | + $args['gedc'] = $gedc; |
|
111 | 111 | } |
112 | 112 | |
113 | 113 | switch ($action) { |
114 | 114 | case 'delete': |
115 | - $sql_delete = |
|
116 | - "DELETE `##change` FROM `##change`" . |
|
117 | - " LEFT JOIN `##user` USING (user_id)" . // user may be deleted |
|
118 | - " LEFT JOIN `##gedcom` USING (gedcom_id)"; // gedcom may be deleted |
|
115 | + $sql_delete = |
|
116 | + "DELETE `##change` FROM `##change`" . |
|
117 | + " LEFT JOIN `##user` USING (user_id)" . // user may be deleted |
|
118 | + " LEFT JOIN `##gedcom` USING (gedcom_id)"; // gedcom may be deleted |
|
119 | 119 | |
120 | - Database::prepare($sql_delete . $where)->execute($args); |
|
121 | - break; |
|
120 | + Database::prepare($sql_delete . $where)->execute($args); |
|
121 | + break; |
|
122 | 122 | |
123 | 123 | case 'export': |
124 | - header('Content-Type: text/csv'); |
|
125 | - header('Content-Disposition: attachment; filename="webtrees-changes.csv"'); |
|
126 | - $rows = Database::prepare($sql_select . $where . ' ORDER BY change_id')->execute($args)->fetchAll(); |
|
127 | - foreach ($rows as $row) { |
|
128 | - echo |
|
129 | - '"', $row->change_time, '",', |
|
130 | - '"', $row->status, '",', |
|
131 | - '"', $row->xref, '",', |
|
132 | - '"', str_replace('"', '""', $row->old_gedcom), '",', |
|
133 | - '"', str_replace('"', '""', $row->new_gedcom), '",', |
|
134 | - '"', str_replace('"', '""', $row->user_name), '",', |
|
135 | - '"', str_replace('"', '""', $row->gedcom_name), '"', |
|
136 | - "\n"; |
|
137 | - } |
|
138 | - |
|
139 | - return; |
|
124 | + header('Content-Type: text/csv'); |
|
125 | + header('Content-Disposition: attachment; filename="webtrees-changes.csv"'); |
|
126 | + $rows = Database::prepare($sql_select . $where . ' ORDER BY change_id')->execute($args)->fetchAll(); |
|
127 | + foreach ($rows as $row) { |
|
128 | + echo |
|
129 | + '"', $row->change_time, '",', |
|
130 | + '"', $row->status, '",', |
|
131 | + '"', $row->xref, '",', |
|
132 | + '"', str_replace('"', '""', $row->old_gedcom), '",', |
|
133 | + '"', str_replace('"', '""', $row->new_gedcom), '",', |
|
134 | + '"', str_replace('"', '""', $row->user_name), '",', |
|
135 | + '"', str_replace('"', '""', $row->gedcom_name), '"', |
|
136 | + "\n"; |
|
137 | + } |
|
138 | + |
|
139 | + return; |
|
140 | 140 | case 'load_json': |
141 | - $start = Filter::getInteger('start'); |
|
142 | - $length = Filter::getInteger('length'); |
|
143 | - $order = Filter::getArray('order'); |
|
144 | - |
|
145 | - if ($order) { |
|
146 | - $order_by = " ORDER BY "; |
|
147 | - foreach ($order as $key => $value) { |
|
148 | - if ($key > 0) { |
|
149 | - $order_by .= ','; |
|
150 | - } |
|
151 | - // Datatables numbers columns 0, 1, 2 |
|
152 | - // MySQL numbers columns 1, 2, 3 |
|
153 | - switch ($value['dir']) { |
|
154 | - case 'asc': |
|
155 | - $order_by .= (1 + $value['column']) . " ASC "; |
|
156 | - break; |
|
157 | - case 'desc': |
|
158 | - $order_by .= (1 + $value['column']) . " DESC "; |
|
159 | - break; |
|
160 | - } |
|
161 | - } |
|
162 | - } else { |
|
163 | - $order_by = " ORDER BY 1 DESC"; |
|
164 | - } |
|
165 | - |
|
166 | - if ($length) { |
|
167 | - Auth::user()->setPreference('admin_site_change_page_size', $length); |
|
168 | - $limit = " LIMIT :limit OFFSET :offset"; |
|
169 | - $args['limit'] = $length; |
|
170 | - $args['offset'] = $start; |
|
171 | - } else { |
|
172 | - $limit = ""; |
|
173 | - } |
|
174 | - |
|
175 | - // This becomes a JSON list, not array, so need to fetch with numeric keys. |
|
176 | - $rows = Database::prepare($sql_select . $where . $order_by . $limit)->execute($args)->fetchAll(PDO::FETCH_OBJ); |
|
177 | - // Total filtered/unfiltered rows |
|
178 | - $recordsFiltered = (int) Database::prepare("SELECT FOUND_ROWS()")->fetchOne(); |
|
179 | - $recordsTotal = (int) Database::prepare("SELECT COUNT(*) FROM `##change`")->fetchOne(); |
|
180 | - |
|
181 | - $data = array(); |
|
182 | - $algorithm = new MyersDiff; |
|
183 | - |
|
184 | - foreach ($rows as $row) { |
|
185 | - $old_lines = preg_split('/[\n]+/', $row->old_gedcom, -1, PREG_SPLIT_NO_EMPTY); |
|
186 | - $new_lines = preg_split('/[\n]+/', $row->new_gedcom, -1, PREG_SPLIT_NO_EMPTY); |
|
187 | - |
|
188 | - $differences = $algorithm->calculate($old_lines, $new_lines); |
|
189 | - $diff_lines = array(); |
|
190 | - |
|
191 | - foreach ($differences as $difference) { |
|
192 | - switch ($difference[1]) { |
|
193 | - case MyersDiff::DELETE: |
|
194 | - $diff_lines[] = '<del>' . $difference[0] . '</del>'; |
|
195 | - break; |
|
196 | - case MyersDiff::INSERT: |
|
197 | - $diff_lines[] = '<ins>' . $difference[0] . '</ins>'; |
|
198 | - break; |
|
199 | - default: |
|
200 | - $diff_lines[] = $difference[0]; |
|
201 | - } |
|
202 | - } |
|
203 | - |
|
204 | - // Only convert valid xrefs to links |
|
205 | - $record = GedcomRecord::getInstance($row->xref, Tree::findByName($gedc)); |
|
206 | - $data[] = array( |
|
207 | - $row->change_id, |
|
208 | - $row->change_time, |
|
209 | - I18N::translate($row->status), |
|
210 | - $record ? '<a href="' . $record->getHtmlUrl() . '">' . $record->getXref() . '</a>' : $row->xref, |
|
211 | - '<div class="gedcom-data" dir="ltr">' . |
|
212 | - preg_replace_callback('/@(' . WT_REGEX_XREF . ')@/', |
|
213 | - function ($match) use ($gedc) { |
|
214 | - $record = GedcomRecord::getInstance($match[1], Tree::findByName($gedc)); |
|
215 | - |
|
216 | - return $record ? '<a href="#" onclick="return edit_raw(\'' . $match[1] . '\');">' . $match[0] . '</a>' : $match[0]; |
|
217 | - }, |
|
218 | - implode("\n", $diff_lines) |
|
219 | - ) . |
|
220 | - '</div>', |
|
221 | - $row->user_name, |
|
222 | - $row->gedcom_name, |
|
223 | - ); |
|
224 | - } |
|
225 | - |
|
226 | - header('Content-type: application/json'); |
|
227 | - // See http://www.datatables.net/usage/server-side |
|
228 | - echo json_encode(array( |
|
229 | - 'draw' => Filter::getInteger('draw'), |
|
230 | - 'recordsTotal' => $recordsTotal, |
|
231 | - 'recordsFiltered' => $recordsFiltered, |
|
232 | - 'data' => $data, |
|
233 | - )); |
|
234 | - |
|
235 | - return; |
|
141 | + $start = Filter::getInteger('start'); |
|
142 | + $length = Filter::getInteger('length'); |
|
143 | + $order = Filter::getArray('order'); |
|
144 | + |
|
145 | + if ($order) { |
|
146 | + $order_by = " ORDER BY "; |
|
147 | + foreach ($order as $key => $value) { |
|
148 | + if ($key > 0) { |
|
149 | + $order_by .= ','; |
|
150 | + } |
|
151 | + // Datatables numbers columns 0, 1, 2 |
|
152 | + // MySQL numbers columns 1, 2, 3 |
|
153 | + switch ($value['dir']) { |
|
154 | + case 'asc': |
|
155 | + $order_by .= (1 + $value['column']) . " ASC "; |
|
156 | + break; |
|
157 | + case 'desc': |
|
158 | + $order_by .= (1 + $value['column']) . " DESC "; |
|
159 | + break; |
|
160 | + } |
|
161 | + } |
|
162 | + } else { |
|
163 | + $order_by = " ORDER BY 1 DESC"; |
|
164 | + } |
|
165 | + |
|
166 | + if ($length) { |
|
167 | + Auth::user()->setPreference('admin_site_change_page_size', $length); |
|
168 | + $limit = " LIMIT :limit OFFSET :offset"; |
|
169 | + $args['limit'] = $length; |
|
170 | + $args['offset'] = $start; |
|
171 | + } else { |
|
172 | + $limit = ""; |
|
173 | + } |
|
174 | + |
|
175 | + // This becomes a JSON list, not array, so need to fetch with numeric keys. |
|
176 | + $rows = Database::prepare($sql_select . $where . $order_by . $limit)->execute($args)->fetchAll(PDO::FETCH_OBJ); |
|
177 | + // Total filtered/unfiltered rows |
|
178 | + $recordsFiltered = (int) Database::prepare("SELECT FOUND_ROWS()")->fetchOne(); |
|
179 | + $recordsTotal = (int) Database::prepare("SELECT COUNT(*) FROM `##change`")->fetchOne(); |
|
180 | + |
|
181 | + $data = array(); |
|
182 | + $algorithm = new MyersDiff; |
|
183 | + |
|
184 | + foreach ($rows as $row) { |
|
185 | + $old_lines = preg_split('/[\n]+/', $row->old_gedcom, -1, PREG_SPLIT_NO_EMPTY); |
|
186 | + $new_lines = preg_split('/[\n]+/', $row->new_gedcom, -1, PREG_SPLIT_NO_EMPTY); |
|
187 | + |
|
188 | + $differences = $algorithm->calculate($old_lines, $new_lines); |
|
189 | + $diff_lines = array(); |
|
190 | + |
|
191 | + foreach ($differences as $difference) { |
|
192 | + switch ($difference[1]) { |
|
193 | + case MyersDiff::DELETE: |
|
194 | + $diff_lines[] = '<del>' . $difference[0] . '</del>'; |
|
195 | + break; |
|
196 | + case MyersDiff::INSERT: |
|
197 | + $diff_lines[] = '<ins>' . $difference[0] . '</ins>'; |
|
198 | + break; |
|
199 | + default: |
|
200 | + $diff_lines[] = $difference[0]; |
|
201 | + } |
|
202 | + } |
|
203 | + |
|
204 | + // Only convert valid xrefs to links |
|
205 | + $record = GedcomRecord::getInstance($row->xref, Tree::findByName($gedc)); |
|
206 | + $data[] = array( |
|
207 | + $row->change_id, |
|
208 | + $row->change_time, |
|
209 | + I18N::translate($row->status), |
|
210 | + $record ? '<a href="' . $record->getHtmlUrl() . '">' . $record->getXref() . '</a>' : $row->xref, |
|
211 | + '<div class="gedcom-data" dir="ltr">' . |
|
212 | + preg_replace_callback('/@(' . WT_REGEX_XREF . ')@/', |
|
213 | + function ($match) use ($gedc) { |
|
214 | + $record = GedcomRecord::getInstance($match[1], Tree::findByName($gedc)); |
|
215 | + |
|
216 | + return $record ? '<a href="#" onclick="return edit_raw(\'' . $match[1] . '\');">' . $match[0] . '</a>' : $match[0]; |
|
217 | + }, |
|
218 | + implode("\n", $diff_lines) |
|
219 | + ) . |
|
220 | + '</div>', |
|
221 | + $row->user_name, |
|
222 | + $row->gedcom_name, |
|
223 | + ); |
|
224 | + } |
|
225 | + |
|
226 | + header('Content-type: application/json'); |
|
227 | + // See http://www.datatables.net/usage/server-side |
|
228 | + echo json_encode(array( |
|
229 | + 'draw' => Filter::getInteger('draw'), |
|
230 | + 'recordsTotal' => $recordsTotal, |
|
231 | + 'recordsFiltered' => $recordsFiltered, |
|
232 | + 'data' => $data, |
|
233 | + )); |
|
234 | + |
|
235 | + return; |
|
236 | 236 | } |
237 | 237 | |
238 | 238 | $controller |
239 | - ->pageHeader() |
|
240 | - ->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL) |
|
241 | - ->addExternalJavascript(WT_DATATABLES_BOOTSTRAP_JS_URL) |
|
242 | - ->addExternalJavascript(WT_MOMENT_JS_URL) |
|
243 | - ->addExternalJavascript(WT_BOOTSTRAP_DATETIMEPICKER_JS_URL) |
|
244 | - ->addInlineJavascript(' |
|
239 | + ->pageHeader() |
|
240 | + ->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL) |
|
241 | + ->addExternalJavascript(WT_DATATABLES_BOOTSTRAP_JS_URL) |
|
242 | + ->addExternalJavascript(WT_MOMENT_JS_URL) |
|
243 | + ->addExternalJavascript(WT_BOOTSTRAP_DATETIMEPICKER_JS_URL) |
|
244 | + ->addInlineJavascript(' |
|
245 | 245 | jQuery(".table-site-changes").dataTable( { |
246 | 246 | processing: true, |
247 | 247 | serverSide: true, |
@@ -280,7 +280,7 @@ discard block |
||
280 | 280 | |
281 | 281 | $users_array = array(); |
282 | 282 | foreach (User::all() as $tmp_user) { |
283 | - $users_array[$tmp_user->getUserName()] = $tmp_user->getUserName(); |
|
283 | + $users_array[$tmp_user->getUserName()] = $tmp_user->getUserName(); |
|
284 | 284 | } |
285 | 285 | |
286 | 286 | ?> |
@@ -151,12 +151,12 @@ discard block |
||
151 | 151 | // Datatables numbers columns 0, 1, 2 |
152 | 152 | // MySQL numbers columns 1, 2, 3 |
153 | 153 | switch ($value['dir']) { |
154 | - case 'asc': |
|
155 | - $order_by .= (1 + $value['column']) . " ASC "; |
|
156 | - break; |
|
157 | - case 'desc': |
|
158 | - $order_by .= (1 + $value['column']) . " DESC "; |
|
159 | - break; |
|
154 | + case 'asc': |
|
155 | + $order_by .= (1 + $value['column']) . " ASC "; |
|
156 | + break; |
|
157 | + case 'desc': |
|
158 | + $order_by .= (1 + $value['column']) . " DESC "; |
|
159 | + break; |
|
160 | 160 | } |
161 | 161 | } |
162 | 162 | } else { |
@@ -190,14 +190,14 @@ discard block |
||
190 | 190 | |
191 | 191 | foreach ($differences as $difference) { |
192 | 192 | switch ($difference[1]) { |
193 | - case MyersDiff::DELETE: |
|
194 | - $diff_lines[] = '<del>' . $difference[0] . '</del>'; |
|
195 | - break; |
|
196 | - case MyersDiff::INSERT: |
|
197 | - $diff_lines[] = '<ins>' . $difference[0] . '</ins>'; |
|
198 | - break; |
|
199 | - default: |
|
200 | - $diff_lines[] = $difference[0]; |
|
193 | + case MyersDiff::DELETE: |
|
194 | + $diff_lines[] = '<del>' . $difference[0] . '</del>'; |
|
195 | + break; |
|
196 | + case MyersDiff::INSERT: |
|
197 | + $diff_lines[] = '<ins>' . $difference[0] . '</ins>'; |
|
198 | + break; |
|
199 | + default: |
|
200 | + $diff_lines[] = $difference[0]; |
|
201 | 201 | } |
202 | 202 | } |
203 | 203 |
@@ -36,248 +36,248 @@ discard block |
||
36 | 36 | |
37 | 37 | // Valid values for form variables |
38 | 38 | $ALL_EDIT_OPTIONS = array( |
39 | - 'none' => /* I18N: Listbox entry; name of a role */ I18N::translate('Visitor'), |
|
40 | - 'access' => /* I18N: Listbox entry; name of a role */ I18N::translate('Member'), |
|
41 | - 'edit' => /* I18N: Listbox entry; name of a role */ I18N::translate('Editor'), |
|
42 | - 'accept' => /* I18N: Listbox entry; name of a role */ I18N::translate('Moderator'), |
|
43 | - 'admin' => /* I18N: Listbox entry; name of a role */ I18N::translate('Manager'), |
|
39 | + 'none' => /* I18N: Listbox entry; name of a role */ I18N::translate('Visitor'), |
|
40 | + 'access' => /* I18N: Listbox entry; name of a role */ I18N::translate('Member'), |
|
41 | + 'edit' => /* I18N: Listbox entry; name of a role */ I18N::translate('Editor'), |
|
42 | + 'accept' => /* I18N: Listbox entry; name of a role */ I18N::translate('Moderator'), |
|
43 | + 'admin' => /* I18N: Listbox entry; name of a role */ I18N::translate('Manager'), |
|
44 | 44 | ); |
45 | 45 | |
46 | 46 | // Form actions |
47 | 47 | switch (Filter::post('action')) { |
48 | 48 | case 'save': |
49 | - if (Filter::checkCsrf()) { |
|
50 | - $user_id = Filter::postInteger('user_id'); |
|
51 | - $user = User::find($user_id); |
|
52 | - $username = Filter::post('username'); |
|
53 | - $real_name = Filter::post('real_name'); |
|
54 | - $email = Filter::postEmail('email'); |
|
55 | - $pass1 = Filter::post('pass1', WT_REGEX_PASSWORD); |
|
56 | - $pass2 = Filter::post('pass2', WT_REGEX_PASSWORD); |
|
57 | - $theme = Filter::post('theme', implode('|', array_keys(Theme::themeNames())), ''); |
|
58 | - $language = Filter::post('language'); |
|
59 | - $timezone = Filter::post('timezone'); |
|
60 | - $contact_method = Filter::post('contact_method'); |
|
61 | - $comment = Filter::post('comment'); |
|
62 | - $auto_accept = Filter::postBool('auto_accept'); |
|
63 | - $canadmin = Filter::postBool('canadmin'); |
|
64 | - $visible_online = Filter::postBool('visible_online'); |
|
65 | - $verified = Filter::postBool('verified'); |
|
66 | - $approved = Filter::postBool('approved'); |
|
67 | - |
|
68 | - if ($user_id === 0) { |
|
69 | - // Create a new user |
|
70 | - if (User::findByUserName($username)) { |
|
71 | - FlashMessages::addMessage(I18N::translate('Duplicate username. A user with that username already exists. Please choose another username.')); |
|
72 | - } elseif (User::findByEmail($email)) { |
|
73 | - FlashMessages::addMessage(I18N::translate('Duplicate email address. A user with that email already exists.')); |
|
74 | - } elseif ($pass1 !== $pass2) { |
|
75 | - FlashMessages::addMessage(I18N::translate('The passwords do not match.')); |
|
76 | - } else { |
|
77 | - $user = User::create($username, $real_name, $email, $pass1); |
|
78 | - $user->setPreference('reg_timestamp', date('U'))->setPreference('sessiontime', '0'); |
|
79 | - Log::addAuthenticationLog('User ->' . $username . '<- created'); |
|
80 | - } |
|
81 | - } else { |
|
82 | - $user = User::find($user_id); |
|
83 | - if ($user && $username && $real_name) { |
|
84 | - $user->setEmail($email); |
|
85 | - $user->setUserName($username); |
|
86 | - $user->setRealName($real_name); |
|
87 | - if ($pass1 !== null && $pass1 === $pass2) { |
|
88 | - $user->setPassword($pass1); |
|
89 | - } |
|
90 | - } |
|
91 | - } |
|
92 | - |
|
93 | - if ($user) { |
|
94 | - // Approving for the first time? Send a confirmation email |
|
95 | - if ($approved && !$user->getPreference('verified_by_admin') && $user->getPreference('sessiontime') == 0) { |
|
96 | - I18N::init($user->getPreference('language')); |
|
97 | - Mail::systemMessage( |
|
98 | - $WT_TREE, |
|
99 | - $user, |
|
100 | - I18N::translate('Approval of account at %s', WT_BASE_URL), |
|
101 | - I18N::translate('The administrator at the webtrees site %s has approved your application for an account. You may now sign in by accessing the following link: %s', WT_BASE_URL, WT_BASE_URL) |
|
102 | - ); |
|
103 | - } |
|
104 | - |
|
105 | - $user |
|
106 | - ->setPreference('theme', $theme) |
|
107 | - ->setPreference('language', $language) |
|
108 | - ->setPreference('TIMEZONE', $timezone) |
|
109 | - ->setPreference('contactmethod', $contact_method) |
|
110 | - ->setPreference('comment', $comment) |
|
111 | - ->setPreference('auto_accept', $auto_accept ? '1' : '0') |
|
112 | - ->setPreference('visibleonline', $visible_online ? '1' : '0') |
|
113 | - ->setPreference('verified', $verified ? '1' : '0') |
|
114 | - ->setPreference('verified_by_admin', $approved ? '1' : '0'); |
|
115 | - |
|
116 | - // We cannot change our own admin status. Another admin will need to do it. |
|
117 | - if ($user->getUserId() !== Auth::id()) { |
|
118 | - $user->setPreference('canadmin', $canadmin ? '1' : '0'); |
|
119 | - } |
|
120 | - |
|
121 | - foreach (Tree::getAll() as $tree) { |
|
122 | - $tree->setUserPreference($user, 'gedcomid', Filter::post('gedcomid' . $tree->getTreeId(), WT_REGEX_XREF)); |
|
123 | - $tree->setUserPreference($user, 'canedit', Filter::post('canedit' . $tree->getTreeId(), implode('|', array_keys($ALL_EDIT_OPTIONS)))); |
|
124 | - if (Filter::post('gedcomid' . $tree->getTreeId(), WT_REGEX_XREF)) { |
|
125 | - $tree->setUserPreference($user, 'RELATIONSHIP_PATH_LENGTH', Filter::postInteger('RELATIONSHIP_PATH_LENGTH' . $tree->getTreeId(), 0, 10, 0)); |
|
126 | - } else { |
|
127 | - // Do not allow a path length to be set if the individual ID is not |
|
128 | - $tree->setUserPreference($user, 'RELATIONSHIP_PATH_LENGTH', null); |
|
129 | - } |
|
130 | - } |
|
131 | - } |
|
132 | - } |
|
133 | - |
|
134 | - header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); |
|
135 | - |
|
136 | - return; |
|
49 | + if (Filter::checkCsrf()) { |
|
50 | + $user_id = Filter::postInteger('user_id'); |
|
51 | + $user = User::find($user_id); |
|
52 | + $username = Filter::post('username'); |
|
53 | + $real_name = Filter::post('real_name'); |
|
54 | + $email = Filter::postEmail('email'); |
|
55 | + $pass1 = Filter::post('pass1', WT_REGEX_PASSWORD); |
|
56 | + $pass2 = Filter::post('pass2', WT_REGEX_PASSWORD); |
|
57 | + $theme = Filter::post('theme', implode('|', array_keys(Theme::themeNames())), ''); |
|
58 | + $language = Filter::post('language'); |
|
59 | + $timezone = Filter::post('timezone'); |
|
60 | + $contact_method = Filter::post('contact_method'); |
|
61 | + $comment = Filter::post('comment'); |
|
62 | + $auto_accept = Filter::postBool('auto_accept'); |
|
63 | + $canadmin = Filter::postBool('canadmin'); |
|
64 | + $visible_online = Filter::postBool('visible_online'); |
|
65 | + $verified = Filter::postBool('verified'); |
|
66 | + $approved = Filter::postBool('approved'); |
|
67 | + |
|
68 | + if ($user_id === 0) { |
|
69 | + // Create a new user |
|
70 | + if (User::findByUserName($username)) { |
|
71 | + FlashMessages::addMessage(I18N::translate('Duplicate username. A user with that username already exists. Please choose another username.')); |
|
72 | + } elseif (User::findByEmail($email)) { |
|
73 | + FlashMessages::addMessage(I18N::translate('Duplicate email address. A user with that email already exists.')); |
|
74 | + } elseif ($pass1 !== $pass2) { |
|
75 | + FlashMessages::addMessage(I18N::translate('The passwords do not match.')); |
|
76 | + } else { |
|
77 | + $user = User::create($username, $real_name, $email, $pass1); |
|
78 | + $user->setPreference('reg_timestamp', date('U'))->setPreference('sessiontime', '0'); |
|
79 | + Log::addAuthenticationLog('User ->' . $username . '<- created'); |
|
80 | + } |
|
81 | + } else { |
|
82 | + $user = User::find($user_id); |
|
83 | + if ($user && $username && $real_name) { |
|
84 | + $user->setEmail($email); |
|
85 | + $user->setUserName($username); |
|
86 | + $user->setRealName($real_name); |
|
87 | + if ($pass1 !== null && $pass1 === $pass2) { |
|
88 | + $user->setPassword($pass1); |
|
89 | + } |
|
90 | + } |
|
91 | + } |
|
92 | + |
|
93 | + if ($user) { |
|
94 | + // Approving for the first time? Send a confirmation email |
|
95 | + if ($approved && !$user->getPreference('verified_by_admin') && $user->getPreference('sessiontime') == 0) { |
|
96 | + I18N::init($user->getPreference('language')); |
|
97 | + Mail::systemMessage( |
|
98 | + $WT_TREE, |
|
99 | + $user, |
|
100 | + I18N::translate('Approval of account at %s', WT_BASE_URL), |
|
101 | + I18N::translate('The administrator at the webtrees site %s has approved your application for an account. You may now sign in by accessing the following link: %s', WT_BASE_URL, WT_BASE_URL) |
|
102 | + ); |
|
103 | + } |
|
104 | + |
|
105 | + $user |
|
106 | + ->setPreference('theme', $theme) |
|
107 | + ->setPreference('language', $language) |
|
108 | + ->setPreference('TIMEZONE', $timezone) |
|
109 | + ->setPreference('contactmethod', $contact_method) |
|
110 | + ->setPreference('comment', $comment) |
|
111 | + ->setPreference('auto_accept', $auto_accept ? '1' : '0') |
|
112 | + ->setPreference('visibleonline', $visible_online ? '1' : '0') |
|
113 | + ->setPreference('verified', $verified ? '1' : '0') |
|
114 | + ->setPreference('verified_by_admin', $approved ? '1' : '0'); |
|
115 | + |
|
116 | + // We cannot change our own admin status. Another admin will need to do it. |
|
117 | + if ($user->getUserId() !== Auth::id()) { |
|
118 | + $user->setPreference('canadmin', $canadmin ? '1' : '0'); |
|
119 | + } |
|
120 | + |
|
121 | + foreach (Tree::getAll() as $tree) { |
|
122 | + $tree->setUserPreference($user, 'gedcomid', Filter::post('gedcomid' . $tree->getTreeId(), WT_REGEX_XREF)); |
|
123 | + $tree->setUserPreference($user, 'canedit', Filter::post('canedit' . $tree->getTreeId(), implode('|', array_keys($ALL_EDIT_OPTIONS)))); |
|
124 | + if (Filter::post('gedcomid' . $tree->getTreeId(), WT_REGEX_XREF)) { |
|
125 | + $tree->setUserPreference($user, 'RELATIONSHIP_PATH_LENGTH', Filter::postInteger('RELATIONSHIP_PATH_LENGTH' . $tree->getTreeId(), 0, 10, 0)); |
|
126 | + } else { |
|
127 | + // Do not allow a path length to be set if the individual ID is not |
|
128 | + $tree->setUserPreference($user, 'RELATIONSHIP_PATH_LENGTH', null); |
|
129 | + } |
|
130 | + } |
|
131 | + } |
|
132 | + } |
|
133 | + |
|
134 | + header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); |
|
135 | + |
|
136 | + return; |
|
137 | 137 | } |
138 | 138 | |
139 | 139 | switch (Filter::get('action')) { |
140 | 140 | case 'load_json': |
141 | - // Generate an AJAX/JSON response for datatables to load a block of rows |
|
142 | - $search = Filter::postArray('search'); |
|
143 | - $search = $search['value']; |
|
144 | - $start = Filter::postInteger('start'); |
|
145 | - $length = Filter::postInteger('length'); |
|
146 | - $order = Filter::postArray('order'); |
|
147 | - |
|
148 | - $sql_select = |
|
149 | - "SELECT SQL_CALC_FOUND_ROWS '', u.user_id, user_name, real_name, email, us1.setting_value, us2.setting_value, NULL, us3.setting_value, NULL, us4.setting_value, us5.setting_value" . |
|
150 | - " FROM `##user` u" . |
|
151 | - " LEFT JOIN `##user_setting` us1 ON (u.user_id=us1.user_id AND us1.setting_name='language')" . |
|
152 | - " LEFT JOIN `##user_setting` us2 ON (u.user_id=us2.user_id AND us2.setting_name='reg_timestamp')" . |
|
153 | - " LEFT JOIN `##user_setting` us3 ON (u.user_id=us3.user_id AND us3.setting_name='sessiontime')" . |
|
154 | - " LEFT JOIN `##user_setting` us4 ON (u.user_id=us4.user_id AND us4.setting_name='verified')" . |
|
155 | - " LEFT JOIN `##user_setting` us5 ON (u.user_id=us5.user_id AND us5.setting_name='verified_by_admin')" . |
|
156 | - " WHERE u.user_id > 0"; |
|
157 | - |
|
158 | - $args = array(); |
|
159 | - |
|
160 | - if ($search) { |
|
161 | - $sql_select .= " AND (user_name LIKE CONCAT('%', :search_1, '%') OR real_name LIKE CONCAT('%', :search_2, '%') OR email LIKE CONCAT('%', :search_3, '%'))"; |
|
162 | - $args['search_1'] = $search; |
|
163 | - $args['search_2'] = $search; |
|
164 | - $args['search_3'] = $search; |
|
165 | - } |
|
166 | - |
|
167 | - if ($order) { |
|
168 | - $sql_select .= " ORDER BY "; |
|
169 | - foreach ($order as $key => $value) { |
|
170 | - if ($key > 0) { |
|
171 | - $sql_select .= ','; |
|
172 | - } |
|
173 | - // Datatables numbers columns 0, 1, 2 |
|
174 | - // MySQL numbers columns 1, 2, 3 |
|
175 | - switch ($value['dir']) { |
|
176 | - case 'asc': |
|
177 | - $sql_select .= (1 + $value['column']) . " ASC "; |
|
178 | - break; |
|
179 | - case 'desc': |
|
180 | - $sql_select .= (1 + $value['column']) . " DESC "; |
|
181 | - break; |
|
182 | - } |
|
183 | - } |
|
184 | - } else { |
|
185 | - $sql_select = " ORDER BY 1 ASC"; |
|
186 | - } |
|
187 | - |
|
188 | - if ($length) { |
|
189 | - Auth::user()->setPreference('admin_users_page_size', $length); |
|
190 | - $sql_select .= " LIMIT :limit OFFSET :offset"; |
|
191 | - $args['limit'] = $length; |
|
192 | - $args['offset'] = $start; |
|
193 | - } |
|
194 | - |
|
195 | - // This becomes a JSON list, not array, so need to fetch with numeric keys. |
|
196 | - $data = Database::prepare($sql_select)->execute($args)->fetchAll(PDO::FETCH_NUM); |
|
197 | - |
|
198 | - $installed_languages = array(); |
|
199 | - foreach (I18N::installedLocales() as $installed_locale) { |
|
200 | - $installed_languages[$installed_locale->languageTag()] = $installed_locale->endonym(); |
|
201 | - } |
|
202 | - |
|
203 | - // Reformat various columns for display |
|
204 | - foreach ($data as &$datum) { |
|
205 | - $user_id = $datum[1]; |
|
206 | - $user_name = $datum[2]; |
|
207 | - |
|
208 | - if ($user_id != Auth::id()) { |
|
209 | - $admin_options = '<li><a href="#" onclick="return masquerade(' . $user_id . ')"><i class="fa fa-fw fa-user"></i> ' . /* I18N: Pretend to be another user, by logging in as them */ |
|
210 | - I18N::translate('Masquerade as this user') . '</a></li>' . '<li><a href="#" onclick="delete_user(\'' . I18N::translate('Are you sure you want to delete “%s”?', Filter::escapeJs($user_name)) . '\', \'' . Filter::escapeJs($user_id) . '\');"><i class="fa fa-fw fa-trash-o"></i> ' . I18N::translate('Delete') . '</a></li>'; |
|
211 | - } else { |
|
212 | - // Do not delete ourself! |
|
213 | - $admin_options = ''; |
|
214 | - } |
|
215 | - |
|
216 | - $datum[0] = '<div class="btn-group"><button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false"><i class="fa fa-pencil"></i> <span class="caret"></span></button><ul class="dropdown-menu" role="menu"><li><a href="?action=edit&user_id=' . $user_id . '"><i class="fa fa-fw fa-pencil"></i> ' . I18N::translate('Edit') . '</a></li><li class="divider"><li><a href="index_edit.php?user_id=' . $user_id . '"><i class="fa fa-fw fa-th-large"></i> ' . I18N::translate('Change the blocks on this user’s “My page”') . '</a></li>' . $admin_options . '</ul></div>'; |
|
217 | - // $datum[1] is the user ID |
|
218 | - // $datum[3] is the real name |
|
219 | - $datum[3] = '<span dir="auto">' . Filter::escapeHtml($datum[3]) . '</span>'; |
|
220 | - // $datum[4] is the email address |
|
221 | - if ($user_id != Auth::id()) { |
|
222 | - $datum[4] = '<a href="#" onclick="return message(\'' . Filter::escapeHtml($datum[2]) . '\', \'\', \'\');">' . Filter::escapeHtml($datum[4]) . '</i></a>'; |
|
223 | - } |
|
224 | - // $datum[2] is the username |
|
225 | - $datum[2] = '<span dir="auto">' . Filter::escapeHtml($datum[2]) . '</span>'; |
|
226 | - // $datum[5] is the langauge |
|
227 | - if (array_key_exists($datum[5], $installed_languages)) { |
|
228 | - $datum[5] = $installed_languages[$datum[5]]; |
|
229 | - } |
|
230 | - // $datum[6] is the sortable registration timestamp |
|
231 | - $datum[7] = $datum[6] ? FunctionsDate::formatTimestamp($datum[6] + WT_TIMESTAMP_OFFSET) : ''; |
|
232 | - if (date("U") - $datum[6] > 604800 && !$datum[10]) { |
|
233 | - $datum[7] = '<span class="red">' . $datum[7] . '</span>'; |
|
234 | - } |
|
235 | - // $datum[8] is the sortable last-login timestamp |
|
236 | - if ($datum[8]) { |
|
237 | - $datum[9] = FunctionsDate::formatTimestamp($datum[8] + WT_TIMESTAMP_OFFSET) . '<br>' . I18N::timeAgo(WT_TIMESTAMP - $datum[8]); |
|
238 | - } else { |
|
239 | - $datum[9] = I18N::translate('Never'); |
|
240 | - } |
|
241 | - $datum[10] = $datum[10] ? I18N::translate('yes') : I18N::translate('no'); |
|
242 | - $datum[11] = $datum[11] ? I18N::translate('yes') : I18N::translate('no'); |
|
243 | - } |
|
244 | - |
|
245 | - // Total filtered/unfiltered rows |
|
246 | - $recordsFiltered = (int) Database::prepare("SELECT FOUND_ROWS()")->fetchOne(); |
|
247 | - $recordsTotal = User::count(); |
|
248 | - |
|
249 | - header('Content-type: application/json'); |
|
250 | - // See http://www.datatables.net/usage/server-side |
|
251 | - echo json_encode(array( |
|
252 | - 'draw' => Filter::getInteger('draw'), |
|
253 | - 'recordsTotal' => $recordsTotal, |
|
254 | - 'recordsFiltered' => $recordsFiltered, |
|
255 | - 'data' => $data, |
|
256 | - )); |
|
257 | - |
|
258 | - return; |
|
141 | + // Generate an AJAX/JSON response for datatables to load a block of rows |
|
142 | + $search = Filter::postArray('search'); |
|
143 | + $search = $search['value']; |
|
144 | + $start = Filter::postInteger('start'); |
|
145 | + $length = Filter::postInteger('length'); |
|
146 | + $order = Filter::postArray('order'); |
|
147 | + |
|
148 | + $sql_select = |
|
149 | + "SELECT SQL_CALC_FOUND_ROWS '', u.user_id, user_name, real_name, email, us1.setting_value, us2.setting_value, NULL, us3.setting_value, NULL, us4.setting_value, us5.setting_value" . |
|
150 | + " FROM `##user` u" . |
|
151 | + " LEFT JOIN `##user_setting` us1 ON (u.user_id=us1.user_id AND us1.setting_name='language')" . |
|
152 | + " LEFT JOIN `##user_setting` us2 ON (u.user_id=us2.user_id AND us2.setting_name='reg_timestamp')" . |
|
153 | + " LEFT JOIN `##user_setting` us3 ON (u.user_id=us3.user_id AND us3.setting_name='sessiontime')" . |
|
154 | + " LEFT JOIN `##user_setting` us4 ON (u.user_id=us4.user_id AND us4.setting_name='verified')" . |
|
155 | + " LEFT JOIN `##user_setting` us5 ON (u.user_id=us5.user_id AND us5.setting_name='verified_by_admin')" . |
|
156 | + " WHERE u.user_id > 0"; |
|
157 | + |
|
158 | + $args = array(); |
|
159 | + |
|
160 | + if ($search) { |
|
161 | + $sql_select .= " AND (user_name LIKE CONCAT('%', :search_1, '%') OR real_name LIKE CONCAT('%', :search_2, '%') OR email LIKE CONCAT('%', :search_3, '%'))"; |
|
162 | + $args['search_1'] = $search; |
|
163 | + $args['search_2'] = $search; |
|
164 | + $args['search_3'] = $search; |
|
165 | + } |
|
166 | + |
|
167 | + if ($order) { |
|
168 | + $sql_select .= " ORDER BY "; |
|
169 | + foreach ($order as $key => $value) { |
|
170 | + if ($key > 0) { |
|
171 | + $sql_select .= ','; |
|
172 | + } |
|
173 | + // Datatables numbers columns 0, 1, 2 |
|
174 | + // MySQL numbers columns 1, 2, 3 |
|
175 | + switch ($value['dir']) { |
|
176 | + case 'asc': |
|
177 | + $sql_select .= (1 + $value['column']) . " ASC "; |
|
178 | + break; |
|
179 | + case 'desc': |
|
180 | + $sql_select .= (1 + $value['column']) . " DESC "; |
|
181 | + break; |
|
182 | + } |
|
183 | + } |
|
184 | + } else { |
|
185 | + $sql_select = " ORDER BY 1 ASC"; |
|
186 | + } |
|
187 | + |
|
188 | + if ($length) { |
|
189 | + Auth::user()->setPreference('admin_users_page_size', $length); |
|
190 | + $sql_select .= " LIMIT :limit OFFSET :offset"; |
|
191 | + $args['limit'] = $length; |
|
192 | + $args['offset'] = $start; |
|
193 | + } |
|
194 | + |
|
195 | + // This becomes a JSON list, not array, so need to fetch with numeric keys. |
|
196 | + $data = Database::prepare($sql_select)->execute($args)->fetchAll(PDO::FETCH_NUM); |
|
197 | + |
|
198 | + $installed_languages = array(); |
|
199 | + foreach (I18N::installedLocales() as $installed_locale) { |
|
200 | + $installed_languages[$installed_locale->languageTag()] = $installed_locale->endonym(); |
|
201 | + } |
|
202 | + |
|
203 | + // Reformat various columns for display |
|
204 | + foreach ($data as &$datum) { |
|
205 | + $user_id = $datum[1]; |
|
206 | + $user_name = $datum[2]; |
|
207 | + |
|
208 | + if ($user_id != Auth::id()) { |
|
209 | + $admin_options = '<li><a href="#" onclick="return masquerade(' . $user_id . ')"><i class="fa fa-fw fa-user"></i> ' . /* I18N: Pretend to be another user, by logging in as them */ |
|
210 | + I18N::translate('Masquerade as this user') . '</a></li>' . '<li><a href="#" onclick="delete_user(\'' . I18N::translate('Are you sure you want to delete “%s”?', Filter::escapeJs($user_name)) . '\', \'' . Filter::escapeJs($user_id) . '\');"><i class="fa fa-fw fa-trash-o"></i> ' . I18N::translate('Delete') . '</a></li>'; |
|
211 | + } else { |
|
212 | + // Do not delete ourself! |
|
213 | + $admin_options = ''; |
|
214 | + } |
|
215 | + |
|
216 | + $datum[0] = '<div class="btn-group"><button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false"><i class="fa fa-pencil"></i> <span class="caret"></span></button><ul class="dropdown-menu" role="menu"><li><a href="?action=edit&user_id=' . $user_id . '"><i class="fa fa-fw fa-pencil"></i> ' . I18N::translate('Edit') . '</a></li><li class="divider"><li><a href="index_edit.php?user_id=' . $user_id . '"><i class="fa fa-fw fa-th-large"></i> ' . I18N::translate('Change the blocks on this user’s “My page”') . '</a></li>' . $admin_options . '</ul></div>'; |
|
217 | + // $datum[1] is the user ID |
|
218 | + // $datum[3] is the real name |
|
219 | + $datum[3] = '<span dir="auto">' . Filter::escapeHtml($datum[3]) . '</span>'; |
|
220 | + // $datum[4] is the email address |
|
221 | + if ($user_id != Auth::id()) { |
|
222 | + $datum[4] = '<a href="#" onclick="return message(\'' . Filter::escapeHtml($datum[2]) . '\', \'\', \'\');">' . Filter::escapeHtml($datum[4]) . '</i></a>'; |
|
223 | + } |
|
224 | + // $datum[2] is the username |
|
225 | + $datum[2] = '<span dir="auto">' . Filter::escapeHtml($datum[2]) . '</span>'; |
|
226 | + // $datum[5] is the langauge |
|
227 | + if (array_key_exists($datum[5], $installed_languages)) { |
|
228 | + $datum[5] = $installed_languages[$datum[5]]; |
|
229 | + } |
|
230 | + // $datum[6] is the sortable registration timestamp |
|
231 | + $datum[7] = $datum[6] ? FunctionsDate::formatTimestamp($datum[6] + WT_TIMESTAMP_OFFSET) : ''; |
|
232 | + if (date("U") - $datum[6] > 604800 && !$datum[10]) { |
|
233 | + $datum[7] = '<span class="red">' . $datum[7] . '</span>'; |
|
234 | + } |
|
235 | + // $datum[8] is the sortable last-login timestamp |
|
236 | + if ($datum[8]) { |
|
237 | + $datum[9] = FunctionsDate::formatTimestamp($datum[8] + WT_TIMESTAMP_OFFSET) . '<br>' . I18N::timeAgo(WT_TIMESTAMP - $datum[8]); |
|
238 | + } else { |
|
239 | + $datum[9] = I18N::translate('Never'); |
|
240 | + } |
|
241 | + $datum[10] = $datum[10] ? I18N::translate('yes') : I18N::translate('no'); |
|
242 | + $datum[11] = $datum[11] ? I18N::translate('yes') : I18N::translate('no'); |
|
243 | + } |
|
244 | + |
|
245 | + // Total filtered/unfiltered rows |
|
246 | + $recordsFiltered = (int) Database::prepare("SELECT FOUND_ROWS()")->fetchOne(); |
|
247 | + $recordsTotal = User::count(); |
|
248 | + |
|
249 | + header('Content-type: application/json'); |
|
250 | + // See http://www.datatables.net/usage/server-side |
|
251 | + echo json_encode(array( |
|
252 | + 'draw' => Filter::getInteger('draw'), |
|
253 | + 'recordsTotal' => $recordsTotal, |
|
254 | + 'recordsFiltered' => $recordsFiltered, |
|
255 | + 'data' => $data, |
|
256 | + )); |
|
257 | + |
|
258 | + return; |
|
259 | 259 | |
260 | 260 | case 'edit': |
261 | - $user_id = Filter::getInteger('user_id'); |
|
262 | - |
|
263 | - if ($user_id === 0) { |
|
264 | - $controller->setPageTitle(I18N::translate('Add a user')); |
|
265 | - $tmp = new \stdClass; |
|
266 | - $tmp->user_id = ''; |
|
267 | - $tmp->user_name = ''; |
|
268 | - $tmp->real_name = ''; |
|
269 | - $tmp->email = ''; |
|
270 | - $user = new User($tmp); |
|
271 | - } else { |
|
272 | - $controller->setPageTitle(I18N::translate('Edit the user')); |
|
273 | - $user = User::find($user_id); |
|
274 | - } |
|
275 | - |
|
276 | - $controller |
|
277 | - ->pageHeader() |
|
278 | - ->addExternalJavascript(WT_AUTOCOMPLETE_JS_URL) |
|
279 | - ->addInlineJavascript('autocomplete();') |
|
280 | - ->addInlineJavascript(' |
|
261 | + $user_id = Filter::getInteger('user_id'); |
|
262 | + |
|
263 | + if ($user_id === 0) { |
|
264 | + $controller->setPageTitle(I18N::translate('Add a user')); |
|
265 | + $tmp = new \stdClass; |
|
266 | + $tmp->user_id = ''; |
|
267 | + $tmp->user_name = ''; |
|
268 | + $tmp->real_name = ''; |
|
269 | + $tmp->email = ''; |
|
270 | + $user = new User($tmp); |
|
271 | + } else { |
|
272 | + $controller->setPageTitle(I18N::translate('Edit the user')); |
|
273 | + $user = User::find($user_id); |
|
274 | + } |
|
275 | + |
|
276 | + $controller |
|
277 | + ->pageHeader() |
|
278 | + ->addExternalJavascript(WT_AUTOCOMPLETE_JS_URL) |
|
279 | + ->addInlineJavascript('autocomplete();') |
|
280 | + ->addInlineJavascript(' |
|
281 | 281 | jQuery(".relpath").change(function() { |
282 | 282 | var fieldIDx = jQuery(this).attr("id"); |
283 | 283 | var idNum = fieldIDx.replace("RELATIONSHIP_PATH_LENGTH",""); |
@@ -292,7 +292,7 @@ discard block |
||
292 | 292 | } |
293 | 293 | '); |
294 | 294 | |
295 | - ?> |
|
295 | + ?> |
|
296 | 296 | <ol class="breadcrumb small"> |
297 | 297 | <li><a href="admin.php"><?php echo I18N::translate('Control panel'); ?></a></li> |
298 | 298 | <li><a href="admin_users.php"><?php echo I18N::translate('User administration'); ?></a></li> |
@@ -474,7 +474,7 @@ discard block |
||
474 | 474 | <?php echo FunctionsEdit::editFieldContact('contact_method', $user->getPreference('contactmethod')); ?> |
475 | 475 | <p class="small text-muted"> |
476 | 476 | <?php echo /* I18N: Help text for the “Preferred contact method” configuration setting */ |
477 | - I18N::translate('Site members can send each other messages. You can choose to how these messages are sent to you, or choose not receive them at all.'); ?> |
|
477 | + I18N::translate('Site members can send each other messages. You can choose to how these messages are sent to you, or choose not receive them at all.'); ?> |
|
478 | 478 | </p> |
479 | 479 | </div> |
480 | 480 | </div> |
@@ -656,15 +656,15 @@ discard block |
||
656 | 656 | </form> |
657 | 657 | <?php |
658 | 658 | |
659 | - return; |
|
659 | + return; |
|
660 | 660 | |
661 | 661 | case 'cleanup': |
662 | 662 | |
663 | - $controller |
|
664 | - ->setPageTitle(I18N::translate('Delete inactive users')) |
|
665 | - ->pageHeader(); |
|
663 | + $controller |
|
664 | + ->setPageTitle(I18N::translate('Delete inactive users')) |
|
665 | + ->pageHeader(); |
|
666 | 666 | |
667 | - ?> |
|
667 | + ?> |
|
668 | 668 | <ol class="breadcrumb small"> |
669 | 669 | <li><a href="admin.php"><?php echo I18N::translate('Control panel'); ?></a></li> |
670 | 670 | <li><a href="admin_users.php"><?php echo I18N::translate('User administration'); ?></a></li> |
@@ -675,30 +675,30 @@ discard block |
||
675 | 675 | <form method="post" action="?action=cleanup2"> |
676 | 676 | <table class="table table-bordered"> |
677 | 677 | <?php |
678 | - // Check for idle users |
|
679 | - $month = Filter::getInteger('month', 1, 12, 6); |
|
680 | - echo '<tr><th colspan="2">', I18N::translate('Number of months since the last sign-in for a user’s account to be considered inactive: '), '</th>'; |
|
681 | - echo '<td><select onchange="document.location=options[selectedIndex].value;">'; |
|
682 | - for ($i = 1; $i <= 12; $i++) { |
|
683 | - echo '<option value="admin_users.php?action=cleanup&month=' . $i . '" '; |
|
684 | - if ($i === $month) { |
|
685 | - echo 'selected'; |
|
686 | - } |
|
687 | - echo '>', $i, '</option>'; |
|
688 | - } |
|
689 | - echo '</select></td></tr>'; |
|
690 | - |
|
691 | - // Check users not logged in too long |
|
692 | - $ucnt = 0; |
|
693 | - foreach (User::all() as $user) { |
|
694 | - if ($user->getPreference('sessiontime') === '0') { |
|
695 | - $datelogin = (int) $user->getPreference('reg_timestamp'); |
|
696 | - } else { |
|
697 | - $datelogin = (int) $user->getPreference('sessiontime'); |
|
698 | - } |
|
699 | - if (mktime(0, 0, 0, (int) date('m') - $month, (int) date('d'), (int) date('Y')) > $datelogin && $user->getPreference('verified') && $user->getPreference('verified_by_admin')) { |
|
700 | - $ucnt++; |
|
701 | - ?> |
|
678 | + // Check for idle users |
|
679 | + $month = Filter::getInteger('month', 1, 12, 6); |
|
680 | + echo '<tr><th colspan="2">', I18N::translate('Number of months since the last sign-in for a user’s account to be considered inactive: '), '</th>'; |
|
681 | + echo '<td><select onchange="document.location=options[selectedIndex].value;">'; |
|
682 | + for ($i = 1; $i <= 12; $i++) { |
|
683 | + echo '<option value="admin_users.php?action=cleanup&month=' . $i . '" '; |
|
684 | + if ($i === $month) { |
|
685 | + echo 'selected'; |
|
686 | + } |
|
687 | + echo '>', $i, '</option>'; |
|
688 | + } |
|
689 | + echo '</select></td></tr>'; |
|
690 | + |
|
691 | + // Check users not logged in too long |
|
692 | + $ucnt = 0; |
|
693 | + foreach (User::all() as $user) { |
|
694 | + if ($user->getPreference('sessiontime') === '0') { |
|
695 | + $datelogin = (int) $user->getPreference('reg_timestamp'); |
|
696 | + } else { |
|
697 | + $datelogin = (int) $user->getPreference('sessiontime'); |
|
698 | + } |
|
699 | + if (mktime(0, 0, 0, (int) date('m') - $month, (int) date('d'), (int) date('Y')) > $datelogin && $user->getPreference('verified') && $user->getPreference('verified_by_admin')) { |
|
700 | + $ucnt++; |
|
701 | + ?> |
|
702 | 702 | <tr> |
703 | 703 | <td> |
704 | 704 | <a href="?action=edit&user_id=<?php echo $user->getUserId(); ?>"> |
@@ -715,14 +715,14 @@ discard block |
||
715 | 715 | </td> |
716 | 716 | </tr> |
717 | 717 | <?php |
718 | - } |
|
719 | - } |
|
720 | - |
|
721 | - // Check unverified users |
|
722 | - foreach (User::all() as $user) { |
|
723 | - if (((date('U') - (int) $user->getPreference('reg_timestamp')) > 604800) && !$user->getPreference('verified')) { |
|
724 | - $ucnt++; |
|
725 | - ?> |
|
718 | + } |
|
719 | + } |
|
720 | + |
|
721 | + // Check unverified users |
|
722 | + foreach (User::all() as $user) { |
|
723 | + if (((date('U') - (int) $user->getPreference('reg_timestamp')) > 604800) && !$user->getPreference('verified')) { |
|
724 | + $ucnt++; |
|
725 | + ?> |
|
726 | 726 | <tr> |
727 | 727 | <td> |
728 | 728 | <a href="?action=edit&user_id=<?php echo $user->getUserId(); ?>"> |
@@ -739,14 +739,14 @@ discard block |
||
739 | 739 | </td> |
740 | 740 | </tr> |
741 | 741 | <?php |
742 | - } |
|
743 | - } |
|
744 | - |
|
745 | - // Check users not verified by admin |
|
746 | - foreach (User::all() as $user) { |
|
747 | - if ($user->getUserId() !== Auth::id() && !$user->getPreference('verified_by_admin') && $user->getPreference('verified')) { |
|
748 | - $ucnt++; |
|
749 | - ?> |
|
742 | + } |
|
743 | + } |
|
744 | + |
|
745 | + // Check users not verified by admin |
|
746 | + foreach (User::all() as $user) { |
|
747 | + if ($user->getUserId() !== Auth::id() && !$user->getPreference('verified_by_admin') && $user->getPreference('verified')) { |
|
748 | + $ucnt++; |
|
749 | + ?> |
|
750 | 750 | <tr> |
751 | 751 | <td> |
752 | 752 | <a href="?action=edit&user_id=<?php echo $user->getUserId(); ?>"> |
@@ -763,9 +763,9 @@ discard block |
||
763 | 763 | </td> |
764 | 764 | </tr> |
765 | 765 | <?php |
766 | - } |
|
767 | - } |
|
768 | - ?> |
|
766 | + } |
|
767 | + } |
|
768 | + ?> |
|
769 | 769 | </table> |
770 | 770 | <p> |
771 | 771 | <?php if ($ucnt): ?> |
@@ -776,25 +776,25 @@ discard block |
||
776 | 776 | </p> |
777 | 777 | </form> |
778 | 778 | <?php |
779 | - break; |
|
779 | + break; |
|
780 | 780 | |
781 | 781 | case 'cleanup2': |
782 | - foreach (User::all() as $user) { |
|
783 | - if (Filter::post('del_' . $user->getUserId()) == '1') { |
|
784 | - Log::addAuthenticationLog('Deleted user: ' . $user->getUserName()); |
|
785 | - $user->delete(); |
|
786 | - I18N::translate('The user %s has been deleted.', Filter::escapeHtml($user->getUserName())); |
|
787 | - } |
|
788 | - } |
|
789 | - |
|
790 | - header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); |
|
791 | - break; |
|
782 | + foreach (User::all() as $user) { |
|
783 | + if (Filter::post('del_' . $user->getUserId()) == '1') { |
|
784 | + Log::addAuthenticationLog('Deleted user: ' . $user->getUserName()); |
|
785 | + $user->delete(); |
|
786 | + I18N::translate('The user %s has been deleted.', Filter::escapeHtml($user->getUserName())); |
|
787 | + } |
|
788 | + } |
|
789 | + |
|
790 | + header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); |
|
791 | + break; |
|
792 | 792 | default: |
793 | - $controller |
|
794 | - ->setPageTitle(I18N::translate('User administration')) |
|
795 | - ->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL) |
|
796 | - ->addExternalJavascript(WT_DATATABLES_BOOTSTRAP_JS_URL) |
|
797 | - ->addInlineJavascript(' |
|
793 | + $controller |
|
794 | + ->setPageTitle(I18N::translate('User administration')) |
|
795 | + ->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL) |
|
796 | + ->addExternalJavascript(WT_DATATABLES_BOOTSTRAP_JS_URL) |
|
797 | + ->addInlineJavascript(' |
|
798 | 798 | jQuery(".table-user-list").dataTable({ |
799 | 799 | ' . I18N::datatablesI18N() . ', |
800 | 800 | stateSave: true, |
@@ -828,9 +828,9 @@ discard block |
||
828 | 828 | }) |
829 | 829 | .fnFilter("' . Filter::get('filter') . '"); // View the details of a newly created user |
830 | 830 | ') |
831 | - ->pageHeader(); |
|
831 | + ->pageHeader(); |
|
832 | 832 | |
833 | - ?> |
|
833 | + ?> |
|
834 | 834 | <ol class="breadcrumb small"> |
835 | 835 | <li><a href="admin.php"><?php echo I18N::translate('Control panel'); ?></a></li> |
836 | 836 | <li class="active"><?php echo $controller->getPageTitle(); ?></li> |
@@ -858,5 +858,5 @@ discard block |
||
858 | 858 | </tbody> |
859 | 859 | </table> |
860 | 860 | <?php |
861 | - break; |
|
861 | + break; |
|
862 | 862 | } |
@@ -45,95 +45,95 @@ discard block |
||
45 | 45 | |
46 | 46 | // Form actions |
47 | 47 | switch (Filter::post('action')) { |
48 | -case 'save': |
|
49 | - if (Filter::checkCsrf()) { |
|
50 | - $user_id = Filter::postInteger('user_id'); |
|
51 | - $user = User::find($user_id); |
|
52 | - $username = Filter::post('username'); |
|
53 | - $real_name = Filter::post('real_name'); |
|
54 | - $email = Filter::postEmail('email'); |
|
55 | - $pass1 = Filter::post('pass1', WT_REGEX_PASSWORD); |
|
56 | - $pass2 = Filter::post('pass2', WT_REGEX_PASSWORD); |
|
57 | - $theme = Filter::post('theme', implode('|', array_keys(Theme::themeNames())), ''); |
|
58 | - $language = Filter::post('language'); |
|
59 | - $timezone = Filter::post('timezone'); |
|
60 | - $contact_method = Filter::post('contact_method'); |
|
61 | - $comment = Filter::post('comment'); |
|
62 | - $auto_accept = Filter::postBool('auto_accept'); |
|
63 | - $canadmin = Filter::postBool('canadmin'); |
|
64 | - $visible_online = Filter::postBool('visible_online'); |
|
65 | - $verified = Filter::postBool('verified'); |
|
66 | - $approved = Filter::postBool('approved'); |
|
67 | - |
|
68 | - if ($user_id === 0) { |
|
69 | - // Create a new user |
|
70 | - if (User::findByUserName($username)) { |
|
71 | - FlashMessages::addMessage(I18N::translate('Duplicate username. A user with that username already exists. Please choose another username.')); |
|
72 | - } elseif (User::findByEmail($email)) { |
|
73 | - FlashMessages::addMessage(I18N::translate('Duplicate email address. A user with that email already exists.')); |
|
74 | - } elseif ($pass1 !== $pass2) { |
|
75 | - FlashMessages::addMessage(I18N::translate('The passwords do not match.')); |
|
76 | - } else { |
|
77 | - $user = User::create($username, $real_name, $email, $pass1); |
|
78 | - $user->setPreference('reg_timestamp', date('U'))->setPreference('sessiontime', '0'); |
|
79 | - Log::addAuthenticationLog('User ->' . $username . '<- created'); |
|
80 | - } |
|
81 | - } else { |
|
82 | - $user = User::find($user_id); |
|
83 | - if ($user && $username && $real_name) { |
|
84 | - $user->setEmail($email); |
|
85 | - $user->setUserName($username); |
|
86 | - $user->setRealName($real_name); |
|
87 | - if ($pass1 !== null && $pass1 === $pass2) { |
|
88 | - $user->setPassword($pass1); |
|
89 | - } |
|
90 | - } |
|
91 | - } |
|
92 | - |
|
93 | - if ($user) { |
|
94 | - // Approving for the first time? Send a confirmation email |
|
95 | - if ($approved && !$user->getPreference('verified_by_admin') && $user->getPreference('sessiontime') == 0) { |
|
96 | - I18N::init($user->getPreference('language')); |
|
97 | - Mail::systemMessage( |
|
98 | - $WT_TREE, |
|
99 | - $user, |
|
100 | - I18N::translate('Approval of account at %s', WT_BASE_URL), |
|
101 | - I18N::translate('The administrator at the webtrees site %s has approved your application for an account. You may now sign in by accessing the following link: %s', WT_BASE_URL, WT_BASE_URL) |
|
102 | - ); |
|
103 | - } |
|
104 | - |
|
105 | - $user |
|
106 | - ->setPreference('theme', $theme) |
|
107 | - ->setPreference('language', $language) |
|
108 | - ->setPreference('TIMEZONE', $timezone) |
|
109 | - ->setPreference('contactmethod', $contact_method) |
|
110 | - ->setPreference('comment', $comment) |
|
111 | - ->setPreference('auto_accept', $auto_accept ? '1' : '0') |
|
112 | - ->setPreference('visibleonline', $visible_online ? '1' : '0') |
|
113 | - ->setPreference('verified', $verified ? '1' : '0') |
|
114 | - ->setPreference('verified_by_admin', $approved ? '1' : '0'); |
|
115 | - |
|
116 | - // We cannot change our own admin status. Another admin will need to do it. |
|
117 | - if ($user->getUserId() !== Auth::id()) { |
|
118 | - $user->setPreference('canadmin', $canadmin ? '1' : '0'); |
|
119 | - } |
|
120 | - |
|
121 | - foreach (Tree::getAll() as $tree) { |
|
122 | - $tree->setUserPreference($user, 'gedcomid', Filter::post('gedcomid' . $tree->getTreeId(), WT_REGEX_XREF)); |
|
123 | - $tree->setUserPreference($user, 'canedit', Filter::post('canedit' . $tree->getTreeId(), implode('|', array_keys($ALL_EDIT_OPTIONS)))); |
|
124 | - if (Filter::post('gedcomid' . $tree->getTreeId(), WT_REGEX_XREF)) { |
|
125 | - $tree->setUserPreference($user, 'RELATIONSHIP_PATH_LENGTH', Filter::postInteger('RELATIONSHIP_PATH_LENGTH' . $tree->getTreeId(), 0, 10, 0)); |
|
126 | - } else { |
|
127 | - // Do not allow a path length to be set if the individual ID is not |
|
128 | - $tree->setUserPreference($user, 'RELATIONSHIP_PATH_LENGTH', null); |
|
129 | - } |
|
130 | - } |
|
131 | - } |
|
132 | - } |
|
133 | - |
|
134 | - header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); |
|
135 | - |
|
136 | - return; |
|
48 | + case 'save': |
|
49 | + if (Filter::checkCsrf()) { |
|
50 | + $user_id = Filter::postInteger('user_id'); |
|
51 | + $user = User::find($user_id); |
|
52 | + $username = Filter::post('username'); |
|
53 | + $real_name = Filter::post('real_name'); |
|
54 | + $email = Filter::postEmail('email'); |
|
55 | + $pass1 = Filter::post('pass1', WT_REGEX_PASSWORD); |
|
56 | + $pass2 = Filter::post('pass2', WT_REGEX_PASSWORD); |
|
57 | + $theme = Filter::post('theme', implode('|', array_keys(Theme::themeNames())), ''); |
|
58 | + $language = Filter::post('language'); |
|
59 | + $timezone = Filter::post('timezone'); |
|
60 | + $contact_method = Filter::post('contact_method'); |
|
61 | + $comment = Filter::post('comment'); |
|
62 | + $auto_accept = Filter::postBool('auto_accept'); |
|
63 | + $canadmin = Filter::postBool('canadmin'); |
|
64 | + $visible_online = Filter::postBool('visible_online'); |
|
65 | + $verified = Filter::postBool('verified'); |
|
66 | + $approved = Filter::postBool('approved'); |
|
67 | + |
|
68 | + if ($user_id === 0) { |
|
69 | + // Create a new user |
|
70 | + if (User::findByUserName($username)) { |
|
71 | + FlashMessages::addMessage(I18N::translate('Duplicate username. A user with that username already exists. Please choose another username.')); |
|
72 | + } elseif (User::findByEmail($email)) { |
|
73 | + FlashMessages::addMessage(I18N::translate('Duplicate email address. A user with that email already exists.')); |
|
74 | + } elseif ($pass1 !== $pass2) { |
|
75 | + FlashMessages::addMessage(I18N::translate('The passwords do not match.')); |
|
76 | + } else { |
|
77 | + $user = User::create($username, $real_name, $email, $pass1); |
|
78 | + $user->setPreference('reg_timestamp', date('U'))->setPreference('sessiontime', '0'); |
|
79 | + Log::addAuthenticationLog('User ->' . $username . '<- created'); |
|
80 | + } |
|
81 | + } else { |
|
82 | + $user = User::find($user_id); |
|
83 | + if ($user && $username && $real_name) { |
|
84 | + $user->setEmail($email); |
|
85 | + $user->setUserName($username); |
|
86 | + $user->setRealName($real_name); |
|
87 | + if ($pass1 !== null && $pass1 === $pass2) { |
|
88 | + $user->setPassword($pass1); |
|
89 | + } |
|
90 | + } |
|
91 | + } |
|
92 | + |
|
93 | + if ($user) { |
|
94 | + // Approving for the first time? Send a confirmation email |
|
95 | + if ($approved && !$user->getPreference('verified_by_admin') && $user->getPreference('sessiontime') == 0) { |
|
96 | + I18N::init($user->getPreference('language')); |
|
97 | + Mail::systemMessage( |
|
98 | + $WT_TREE, |
|
99 | + $user, |
|
100 | + I18N::translate('Approval of account at %s', WT_BASE_URL), |
|
101 | + I18N::translate('The administrator at the webtrees site %s has approved your application for an account. You may now sign in by accessing the following link: %s', WT_BASE_URL, WT_BASE_URL) |
|
102 | + ); |
|
103 | + } |
|
104 | + |
|
105 | + $user |
|
106 | + ->setPreference('theme', $theme) |
|
107 | + ->setPreference('language', $language) |
|
108 | + ->setPreference('TIMEZONE', $timezone) |
|
109 | + ->setPreference('contactmethod', $contact_method) |
|
110 | + ->setPreference('comment', $comment) |
|
111 | + ->setPreference('auto_accept', $auto_accept ? '1' : '0') |
|
112 | + ->setPreference('visibleonline', $visible_online ? '1' : '0') |
|
113 | + ->setPreference('verified', $verified ? '1' : '0') |
|
114 | + ->setPreference('verified_by_admin', $approved ? '1' : '0'); |
|
115 | + |
|
116 | + // We cannot change our own admin status. Another admin will need to do it. |
|
117 | + if ($user->getUserId() !== Auth::id()) { |
|
118 | + $user->setPreference('canadmin', $canadmin ? '1' : '0'); |
|
119 | + } |
|
120 | + |
|
121 | + foreach (Tree::getAll() as $tree) { |
|
122 | + $tree->setUserPreference($user, 'gedcomid', Filter::post('gedcomid' . $tree->getTreeId(), WT_REGEX_XREF)); |
|
123 | + $tree->setUserPreference($user, 'canedit', Filter::post('canedit' . $tree->getTreeId(), implode('|', array_keys($ALL_EDIT_OPTIONS)))); |
|
124 | + if (Filter::post('gedcomid' . $tree->getTreeId(), WT_REGEX_XREF)) { |
|
125 | + $tree->setUserPreference($user, 'RELATIONSHIP_PATH_LENGTH', Filter::postInteger('RELATIONSHIP_PATH_LENGTH' . $tree->getTreeId(), 0, 10, 0)); |
|
126 | + } else { |
|
127 | + // Do not allow a path length to be set if the individual ID is not |
|
128 | + $tree->setUserPreference($user, 'RELATIONSHIP_PATH_LENGTH', null); |
|
129 | + } |
|
130 | + } |
|
131 | + } |
|
132 | + } |
|
133 | + |
|
134 | + header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); |
|
135 | + |
|
136 | + return; |
|
137 | 137 | } |
138 | 138 | |
139 | 139 | switch (Filter::get('action')) { |
@@ -173,12 +173,12 @@ discard block |
||
173 | 173 | // Datatables numbers columns 0, 1, 2 |
174 | 174 | // MySQL numbers columns 1, 2, 3 |
175 | 175 | switch ($value['dir']) { |
176 | - case 'asc': |
|
177 | - $sql_select .= (1 + $value['column']) . " ASC "; |
|
178 | - break; |
|
179 | - case 'desc': |
|
180 | - $sql_select .= (1 + $value['column']) . " DESC "; |
|
181 | - break; |
|
176 | + case 'asc': |
|
177 | + $sql_select .= (1 + $value['column']) . " ASC "; |
|
178 | + break; |
|
179 | + case 'desc': |
|
180 | + $sql_select .= (1 + $value['column']) . " DESC "; |
|
181 | + break; |
|
182 | 182 | } |
183 | 183 | } |
184 | 184 | } else { |
@@ -770,8 +770,11 @@ |
||
770 | 770 | <p> |
771 | 771 | <?php if ($ucnt): ?> |
772 | 772 | <input type="submit" value="<?php echo I18N::translate('delete'); ?>"> |
773 | - <?php else: ?> |
|
774 | - <?php echo I18N::translate('Nothing found to cleanup'); ?> |
|
773 | + <?php else { |
|
774 | + : ?> |
|
775 | + <?php echo I18N::translate('Nothing found to cleanup'); |
|
776 | +} |
|
777 | +?> |
|
775 | 778 | <?php endif; ?> |
776 | 779 | </p> |
777 | 780 | </form> |
@@ -23,218 +23,218 @@ discard block |
||
23 | 23 | require './includes/session.php'; |
24 | 24 | |
25 | 25 | $rules_display = array( |
26 | - 'unknown' => I18N::translate('unknown'), |
|
27 | - 'allow' => /* I18N: An access rule - allow access to the site */ I18N::translate('allow'), |
|
28 | - 'deny' => /* I18N: An access rule - deny access to the site */ I18N::translate('deny'), |
|
29 | - 'robot' => /* I18N: http://en.wikipedia.org/wiki/Web_crawler */ I18N::translate('robot'), |
|
26 | + 'unknown' => I18N::translate('unknown'), |
|
27 | + 'allow' => /* I18N: An access rule - allow access to the site */ I18N::translate('allow'), |
|
28 | + 'deny' => /* I18N: An access rule - deny access to the site */ I18N::translate('deny'), |
|
29 | + 'robot' => /* I18N: http://en.wikipedia.org/wiki/Web_crawler */ I18N::translate('robot'), |
|
30 | 30 | ); |
31 | 31 | |
32 | 32 | $rules_edit = array( |
33 | - 'unknown' => I18N::translate('unknown'), |
|
34 | - 'allow' => /* I18N: An access rule - allow access to the site */ I18N::translate('allow'), |
|
35 | - 'deny' => /* I18N: An access rule - deny access to the site */ I18N::translate('deny'), |
|
36 | - 'robot' => /* I18N: http://en.wikipedia.org/wiki/Web_crawler */ I18N::translate('robot'), |
|
33 | + 'unknown' => I18N::translate('unknown'), |
|
34 | + 'allow' => /* I18N: An access rule - allow access to the site */ I18N::translate('allow'), |
|
35 | + 'deny' => /* I18N: An access rule - deny access to the site */ I18N::translate('deny'), |
|
36 | + 'robot' => /* I18N: http://en.wikipedia.org/wiki/Web_crawler */ I18N::translate('robot'), |
|
37 | 37 | ); |
38 | 38 | |
39 | 39 | // Form actions |
40 | 40 | switch (Filter::post('action')) { |
41 | 41 | case 'save': |
42 | - if (Filter::checkCsrf()) { |
|
43 | - $site_access_rule_id = Filter::postInteger('site_access_rule_id'); |
|
44 | - $ip_address_start = Filter::post('ip_address_start', WT_REGEX_IPV4); |
|
45 | - $ip_address_end = Filter::post('ip_address_end', WT_REGEX_IPV4); |
|
46 | - $user_agent_pattern = Filter::post('user_agent_pattern'); |
|
47 | - $rule = Filter::post('rule', 'allow|deny|robot'); |
|
48 | - $comment = Filter::post('comment'); |
|
49 | - $user_agent_string = Filter::server('HTTP_USER_AGENT'); |
|
50 | - $ip_address = WT_CLIENT_IP; |
|
51 | - |
|
52 | - if ($ip_address_start !== null && $ip_address_end !== null && $user_agent_pattern !== null && $rule !== null) { |
|
53 | - // This doesn't work with named placeholders. The :user_agent_string parameter is not recognised. |
|
54 | - $oops = $rule !== 'allow' && Database::prepare( |
|
55 | - "SELECT INET_ATON(:ip_address) BETWEEN INET_ATON(:ip_address_start) AND INET_ATON(:ip_address_end)" . |
|
56 | - " AND :user_agent_string LIKE :user_agent_pattern" |
|
57 | - )->execute(array( |
|
58 | - 'ip_address' => $ip_address, |
|
59 | - 'ip_address_start' => $ip_address_start, |
|
60 | - 'ip_address_end' => $ip_address_end, |
|
61 | - 'user_agent_string' => $user_agent_string, |
|
62 | - 'user_agent_pattern' => $user_agent_pattern, |
|
63 | - ))->fetchOne(); |
|
64 | - |
|
65 | - if ($oops) { |
|
66 | - FlashMessages::addMessage(I18N::translate('You cannot create a rule which would prevent yourself from accessing the website.'), 'danger'); |
|
67 | - } elseif ($site_access_rule_id === null) { |
|
68 | - Database::prepare( |
|
69 | - "INSERT INTO `##site_access_rule` (ip_address_start, ip_address_end, user_agent_pattern, rule, comment) VALUES (INET_ATON(:ip_address_start), INET_ATON(:ip_address_end), :user_agent_pattern, :rule, :comment)" |
|
70 | - )->execute(array( |
|
71 | - 'ip_address_start' => $ip_address_start, |
|
72 | - 'ip_address_end' => $ip_address_end, |
|
73 | - 'user_agent_pattern' => $user_agent_pattern, |
|
74 | - 'rule' => $rule, |
|
75 | - 'comment' => $comment, |
|
76 | - )); |
|
77 | - FlashMessages::addMessage(I18N::translate('The website access rule has been created.'), 'success'); |
|
78 | - } else { |
|
79 | - Database::prepare( |
|
80 | - "UPDATE `##site_access_rule` SET ip_address_start = INET_ATON(:ip_address_start), ip_address_end = INET_ATON(:ip_address_end), user_agent_pattern = :user_agent_pattern, rule = :rule, comment = :comment WHERE site_access_rule_id = :site_access_rule_id" |
|
81 | - )->execute(array( |
|
82 | - 'ip_address_start' => $ip_address_start, |
|
83 | - 'ip_address_end' => $ip_address_end, |
|
84 | - 'user_agent_pattern' => $user_agent_pattern, |
|
85 | - 'rule' => $rule, |
|
86 | - 'comment' => $comment, |
|
87 | - 'site_access_rule_id' => $site_access_rule_id, |
|
88 | - )); |
|
89 | - FlashMessages::addMessage(I18N::translate('The website access rule has been updated.'), 'success'); |
|
90 | - } |
|
91 | - } |
|
92 | - } |
|
93 | - header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); |
|
94 | - |
|
95 | - return; |
|
42 | + if (Filter::checkCsrf()) { |
|
43 | + $site_access_rule_id = Filter::postInteger('site_access_rule_id'); |
|
44 | + $ip_address_start = Filter::post('ip_address_start', WT_REGEX_IPV4); |
|
45 | + $ip_address_end = Filter::post('ip_address_end', WT_REGEX_IPV4); |
|
46 | + $user_agent_pattern = Filter::post('user_agent_pattern'); |
|
47 | + $rule = Filter::post('rule', 'allow|deny|robot'); |
|
48 | + $comment = Filter::post('comment'); |
|
49 | + $user_agent_string = Filter::server('HTTP_USER_AGENT'); |
|
50 | + $ip_address = WT_CLIENT_IP; |
|
51 | + |
|
52 | + if ($ip_address_start !== null && $ip_address_end !== null && $user_agent_pattern !== null && $rule !== null) { |
|
53 | + // This doesn't work with named placeholders. The :user_agent_string parameter is not recognised. |
|
54 | + $oops = $rule !== 'allow' && Database::prepare( |
|
55 | + "SELECT INET_ATON(:ip_address) BETWEEN INET_ATON(:ip_address_start) AND INET_ATON(:ip_address_end)" . |
|
56 | + " AND :user_agent_string LIKE :user_agent_pattern" |
|
57 | + )->execute(array( |
|
58 | + 'ip_address' => $ip_address, |
|
59 | + 'ip_address_start' => $ip_address_start, |
|
60 | + 'ip_address_end' => $ip_address_end, |
|
61 | + 'user_agent_string' => $user_agent_string, |
|
62 | + 'user_agent_pattern' => $user_agent_pattern, |
|
63 | + ))->fetchOne(); |
|
64 | + |
|
65 | + if ($oops) { |
|
66 | + FlashMessages::addMessage(I18N::translate('You cannot create a rule which would prevent yourself from accessing the website.'), 'danger'); |
|
67 | + } elseif ($site_access_rule_id === null) { |
|
68 | + Database::prepare( |
|
69 | + "INSERT INTO `##site_access_rule` (ip_address_start, ip_address_end, user_agent_pattern, rule, comment) VALUES (INET_ATON(:ip_address_start), INET_ATON(:ip_address_end), :user_agent_pattern, :rule, :comment)" |
|
70 | + )->execute(array( |
|
71 | + 'ip_address_start' => $ip_address_start, |
|
72 | + 'ip_address_end' => $ip_address_end, |
|
73 | + 'user_agent_pattern' => $user_agent_pattern, |
|
74 | + 'rule' => $rule, |
|
75 | + 'comment' => $comment, |
|
76 | + )); |
|
77 | + FlashMessages::addMessage(I18N::translate('The website access rule has been created.'), 'success'); |
|
78 | + } else { |
|
79 | + Database::prepare( |
|
80 | + "UPDATE `##site_access_rule` SET ip_address_start = INET_ATON(:ip_address_start), ip_address_end = INET_ATON(:ip_address_end), user_agent_pattern = :user_agent_pattern, rule = :rule, comment = :comment WHERE site_access_rule_id = :site_access_rule_id" |
|
81 | + )->execute(array( |
|
82 | + 'ip_address_start' => $ip_address_start, |
|
83 | + 'ip_address_end' => $ip_address_end, |
|
84 | + 'user_agent_pattern' => $user_agent_pattern, |
|
85 | + 'rule' => $rule, |
|
86 | + 'comment' => $comment, |
|
87 | + 'site_access_rule_id' => $site_access_rule_id, |
|
88 | + )); |
|
89 | + FlashMessages::addMessage(I18N::translate('The website access rule has been updated.'), 'success'); |
|
90 | + } |
|
91 | + } |
|
92 | + } |
|
93 | + header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); |
|
94 | + |
|
95 | + return; |
|
96 | 96 | |
97 | 97 | case 'delete': |
98 | - if (Filter::checkCsrf()) { |
|
99 | - $site_access_rule_id = Filter::postInteger('site_access_rule_id'); |
|
100 | - Database::prepare( |
|
101 | - "DELETE FROM `##site_access_rule` WHERE site_access_rule_id = :site_access_rule_id" |
|
102 | - )->execute(array( |
|
103 | - 'site_access_rule_id' => $site_access_rule_id, |
|
104 | - )); |
|
105 | - FlashMessages::addMessage(I18N::translate('The website access rule has been deleted.'), 'success'); |
|
106 | - } |
|
107 | - header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); |
|
108 | - |
|
109 | - return; |
|
98 | + if (Filter::checkCsrf()) { |
|
99 | + $site_access_rule_id = Filter::postInteger('site_access_rule_id'); |
|
100 | + Database::prepare( |
|
101 | + "DELETE FROM `##site_access_rule` WHERE site_access_rule_id = :site_access_rule_id" |
|
102 | + )->execute(array( |
|
103 | + 'site_access_rule_id' => $site_access_rule_id, |
|
104 | + )); |
|
105 | + FlashMessages::addMessage(I18N::translate('The website access rule has been deleted.'), 'success'); |
|
106 | + } |
|
107 | + header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); |
|
108 | + |
|
109 | + return; |
|
110 | 110 | } |
111 | 111 | |
112 | 112 | // Delete any "unknown" visitors that are now "known". |
113 | 113 | // This could happen every time we create/update a rule. |
114 | 114 | Database::exec( |
115 | - "DELETE unknown" . |
|
116 | - " FROM `##site_access_rule` AS unknown" . |
|
117 | - " JOIN `##site_access_rule` AS known ON (unknown.user_agent_pattern LIKE known.user_agent_pattern)" . |
|
118 | - " WHERE unknown.rule='unknown' AND known.rule<>'unknown'" . |
|
119 | - " AND unknown.ip_address_start BETWEEN known.ip_address_start AND known.ip_address_end" |
|
115 | + "DELETE unknown" . |
|
116 | + " FROM `##site_access_rule` AS unknown" . |
|
117 | + " JOIN `##site_access_rule` AS known ON (unknown.user_agent_pattern LIKE known.user_agent_pattern)" . |
|
118 | + " WHERE unknown.rule='unknown' AND known.rule<>'unknown'" . |
|
119 | + " AND unknown.ip_address_start BETWEEN known.ip_address_start AND known.ip_address_end" |
|
120 | 120 | ); |
121 | 121 | |
122 | 122 | $controller = new PageController; |
123 | 123 | $controller |
124 | - ->restrictAccess(Auth::isAdmin()) |
|
125 | - ->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL) |
|
126 | - ->addExternalJavascript(WT_DATATABLES_BOOTSTRAP_JS_URL) |
|
127 | - ->setPageTitle(I18N::translate('Website access rules')); |
|
124 | + ->restrictAccess(Auth::isAdmin()) |
|
125 | + ->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL) |
|
126 | + ->addExternalJavascript(WT_DATATABLES_BOOTSTRAP_JS_URL) |
|
127 | + ->setPageTitle(I18N::translate('Website access rules')); |
|
128 | 128 | |
129 | 129 | $action = Filter::get('action'); |
130 | 130 | switch ($action) { |
131 | 131 | case 'load': |
132 | - // AJAX callback for datatables |
|
133 | - $search = Filter::get('search'); |
|
134 | - $search = $search['value']; |
|
135 | - $start = Filter::getInteger('start'); |
|
136 | - $length = Filter::getInteger('length'); |
|
137 | - |
|
138 | - $sql = |
|
139 | - "SELECT SQL_CALC_FOUND_ROWS" . |
|
140 | - " '', INET_NTOA(ip_address_start), ip_address_start, INET_NTOA(ip_address_end), ip_address_end, user_agent_pattern, rule, comment, site_access_rule_id" . |
|
141 | - " FROM `##site_access_rule`"; |
|
142 | - $args = array(); |
|
143 | - |
|
144 | - if ($search) { |
|
145 | - $sql .= |
|
146 | - " WHERE (INET_ATON(:search_1) BETWEEN ip_address_start AND ip_address_end" . |
|
147 | - " OR INET_NTOA(ip_address_start) LIKE CONCAT('%', :search_2, '%')" . |
|
148 | - " OR INET_NTOA(ip_address_end) LIKE CONCAT('%', :search_3, '%')" . |
|
149 | - " OR user_agent_pattern LIKE CONCAT('%', :search_4, '%')" . |
|
150 | - " OR comment LIKE CONCAT('%', :search_5, '%'))"; |
|
151 | - $args['search_1'] = Filter::escapeLike($search); |
|
152 | - $args['search_2'] = Filter::escapeLike($search); |
|
153 | - $args['search_3'] = Filter::escapeLike($search); |
|
154 | - $args['search_4'] = Filter::escapeLike($search); |
|
155 | - $args['search_5'] = Filter::escapeLike($search); |
|
156 | - } |
|
157 | - |
|
158 | - $order = Filter::getArray('order'); |
|
159 | - $sql .= ' ORDER BY'; |
|
160 | - if ($order) { |
|
161 | - foreach ($order as $key => $value) { |
|
162 | - if ($key > 0) { |
|
163 | - $sql .= ','; |
|
164 | - } |
|
165 | - // Datatables numbers columns 0, 1, 2 |
|
166 | - // MySQL numbers columns 1, 2, 3 |
|
167 | - switch ($value['dir']) { |
|
168 | - case 'asc': |
|
169 | - $sql .= " :col_" . $key . " ASC"; |
|
170 | - break; |
|
171 | - case 'desc': |
|
172 | - $sql .= " :col_" . $key . " DESC"; |
|
173 | - break; |
|
174 | - } |
|
175 | - $args['col_' . $key] = 1 + $value['column']; |
|
176 | - } |
|
177 | - } else { |
|
178 | - $sql .= ' 1 ASC'; |
|
179 | - } |
|
180 | - |
|
181 | - if ($length > 0) { |
|
182 | - $sql .= " LIMIT :length OFFSET :start"; |
|
183 | - $args['length'] = $length; |
|
184 | - $args['start'] = $start; |
|
185 | - } |
|
186 | - |
|
187 | - // This becomes a JSON list, not a JSON array, so we need numeric keys. |
|
188 | - $data = Database::prepare($sql)->execute($args)->fetchAll(PDO::FETCH_NUM); |
|
189 | - // Reformat the data for display |
|
190 | - foreach ($data as &$datum) { |
|
191 | - $site_access_rule_id = $datum[8]; |
|
192 | - |
|
193 | - $datum[0] = '<div class="btn-group"><button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false"><i class="fa fa-pencil"></i> <span class="caret"></span></button><ul class="dropdown-menu" role="menu"><li><a href="?action=edit&site_access_rule_id=' . $site_access_rule_id . '"><i class="fa fa-fw fa-pencil"></i> ' . I18N::translate('Edit') . '</a></li><li class="divider"><li><a href="#" onclick="if (confirm(\'' . I18N::translate('Are you sure you want to delete “%s”?', Filter::escapeJs($datum[5])) . '\')) delete_site_access_rule(' . $site_access_rule_id . '); return false;"><i class="fa fa-fw fa-trash-o"></i> ' . I18N::translate('Delete') . '</a></li></ul></div>'; |
|
194 | - $datum[5] = '<span dir="ltr">' . $datum[5] . '</span>'; |
|
195 | - $datum[6] = $rules_display[$datum[6]]; |
|
196 | - $datum[7] = '<span dir="auto">' . $datum[7] . '</span>'; |
|
197 | - } |
|
198 | - |
|
199 | - // Total filtered/unfiltered rows |
|
200 | - $recordsFiltered = Database::prepare("SELECT FOUND_ROWS()")->fetchOne(); |
|
201 | - $recordsTotal = Database::prepare("SELECT COUNT(*) FROM `##site_access_rule`")->fetchOne(); |
|
202 | - |
|
203 | - header('Content-type: application/json'); |
|
204 | - // See http://www.datatables.net/usage/server-side |
|
205 | - echo json_encode(array( |
|
206 | - 'draw' => Filter::getInteger('draw'), |
|
207 | - 'recordsTotal' => $recordsTotal, |
|
208 | - 'recordsFiltered' => $recordsFiltered, |
|
209 | - 'data' => $data, |
|
210 | - )); |
|
211 | - break; |
|
132 | + // AJAX callback for datatables |
|
133 | + $search = Filter::get('search'); |
|
134 | + $search = $search['value']; |
|
135 | + $start = Filter::getInteger('start'); |
|
136 | + $length = Filter::getInteger('length'); |
|
137 | + |
|
138 | + $sql = |
|
139 | + "SELECT SQL_CALC_FOUND_ROWS" . |
|
140 | + " '', INET_NTOA(ip_address_start), ip_address_start, INET_NTOA(ip_address_end), ip_address_end, user_agent_pattern, rule, comment, site_access_rule_id" . |
|
141 | + " FROM `##site_access_rule`"; |
|
142 | + $args = array(); |
|
143 | + |
|
144 | + if ($search) { |
|
145 | + $sql .= |
|
146 | + " WHERE (INET_ATON(:search_1) BETWEEN ip_address_start AND ip_address_end" . |
|
147 | + " OR INET_NTOA(ip_address_start) LIKE CONCAT('%', :search_2, '%')" . |
|
148 | + " OR INET_NTOA(ip_address_end) LIKE CONCAT('%', :search_3, '%')" . |
|
149 | + " OR user_agent_pattern LIKE CONCAT('%', :search_4, '%')" . |
|
150 | + " OR comment LIKE CONCAT('%', :search_5, '%'))"; |
|
151 | + $args['search_1'] = Filter::escapeLike($search); |
|
152 | + $args['search_2'] = Filter::escapeLike($search); |
|
153 | + $args['search_3'] = Filter::escapeLike($search); |
|
154 | + $args['search_4'] = Filter::escapeLike($search); |
|
155 | + $args['search_5'] = Filter::escapeLike($search); |
|
156 | + } |
|
157 | + |
|
158 | + $order = Filter::getArray('order'); |
|
159 | + $sql .= ' ORDER BY'; |
|
160 | + if ($order) { |
|
161 | + foreach ($order as $key => $value) { |
|
162 | + if ($key > 0) { |
|
163 | + $sql .= ','; |
|
164 | + } |
|
165 | + // Datatables numbers columns 0, 1, 2 |
|
166 | + // MySQL numbers columns 1, 2, 3 |
|
167 | + switch ($value['dir']) { |
|
168 | + case 'asc': |
|
169 | + $sql .= " :col_" . $key . " ASC"; |
|
170 | + break; |
|
171 | + case 'desc': |
|
172 | + $sql .= " :col_" . $key . " DESC"; |
|
173 | + break; |
|
174 | + } |
|
175 | + $args['col_' . $key] = 1 + $value['column']; |
|
176 | + } |
|
177 | + } else { |
|
178 | + $sql .= ' 1 ASC'; |
|
179 | + } |
|
180 | + |
|
181 | + if ($length > 0) { |
|
182 | + $sql .= " LIMIT :length OFFSET :start"; |
|
183 | + $args['length'] = $length; |
|
184 | + $args['start'] = $start; |
|
185 | + } |
|
186 | + |
|
187 | + // This becomes a JSON list, not a JSON array, so we need numeric keys. |
|
188 | + $data = Database::prepare($sql)->execute($args)->fetchAll(PDO::FETCH_NUM); |
|
189 | + // Reformat the data for display |
|
190 | + foreach ($data as &$datum) { |
|
191 | + $site_access_rule_id = $datum[8]; |
|
192 | + |
|
193 | + $datum[0] = '<div class="btn-group"><button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false"><i class="fa fa-pencil"></i> <span class="caret"></span></button><ul class="dropdown-menu" role="menu"><li><a href="?action=edit&site_access_rule_id=' . $site_access_rule_id . '"><i class="fa fa-fw fa-pencil"></i> ' . I18N::translate('Edit') . '</a></li><li class="divider"><li><a href="#" onclick="if (confirm(\'' . I18N::translate('Are you sure you want to delete “%s”?', Filter::escapeJs($datum[5])) . '\')) delete_site_access_rule(' . $site_access_rule_id . '); return false;"><i class="fa fa-fw fa-trash-o"></i> ' . I18N::translate('Delete') . '</a></li></ul></div>'; |
|
194 | + $datum[5] = '<span dir="ltr">' . $datum[5] . '</span>'; |
|
195 | + $datum[6] = $rules_display[$datum[6]]; |
|
196 | + $datum[7] = '<span dir="auto">' . $datum[7] . '</span>'; |
|
197 | + } |
|
198 | + |
|
199 | + // Total filtered/unfiltered rows |
|
200 | + $recordsFiltered = Database::prepare("SELECT FOUND_ROWS()")->fetchOne(); |
|
201 | + $recordsTotal = Database::prepare("SELECT COUNT(*) FROM `##site_access_rule`")->fetchOne(); |
|
202 | + |
|
203 | + header('Content-type: application/json'); |
|
204 | + // See http://www.datatables.net/usage/server-side |
|
205 | + echo json_encode(array( |
|
206 | + 'draw' => Filter::getInteger('draw'), |
|
207 | + 'recordsTotal' => $recordsTotal, |
|
208 | + 'recordsFiltered' => $recordsFiltered, |
|
209 | + 'data' => $data, |
|
210 | + )); |
|
211 | + break; |
|
212 | 212 | |
213 | 213 | case 'edit': |
214 | 214 | case 'create': |
215 | - if (Filter::get('action') === 'edit') { |
|
216 | - $controller->setPageTitle(I18N::translate('Edit a website access rule')); |
|
217 | - } else { |
|
218 | - $controller->setPageTitle(I18N::translate('Create a website access rule')); |
|
219 | - } |
|
220 | - |
|
221 | - $controller->pageHeader(); |
|
222 | - |
|
223 | - $site_access_rule = Database::prepare( |
|
224 | - "SELECT site_access_rule_id, INET_NTOA(ip_address_start) AS ip_address_start, INET_NTOA(ip_address_end) AS ip_address_end, user_agent_pattern, rule, comment" . |
|
225 | - " FROM `##site_access_rule` WHERE site_access_rule_id = :site_access_rule_id" |
|
226 | - )->execute(array( |
|
227 | - 'site_access_rule_id' => Filter::getInteger('site_access_rule_id'), |
|
228 | - ))->fetchOneRow(); |
|
229 | - |
|
230 | - $site_access_rule_id = $site_access_rule ? $site_access_rule->site_access_rule_id : null; |
|
231 | - $ip_address_start = $site_access_rule ? $site_access_rule->ip_address_start : '0.0.0.0'; |
|
232 | - $ip_address_end = $site_access_rule ? $site_access_rule->ip_address_end : '255.255.255.255'; |
|
233 | - $user_agent_pattern = $site_access_rule ? $site_access_rule->user_agent_pattern : '%'; |
|
234 | - $rule = $site_access_rule ? $site_access_rule->rule : 'allow'; |
|
235 | - $comment = $site_access_rule ? $site_access_rule->comment : ''; |
|
236 | - |
|
237 | - ?> |
|
215 | + if (Filter::get('action') === 'edit') { |
|
216 | + $controller->setPageTitle(I18N::translate('Edit a website access rule')); |
|
217 | + } else { |
|
218 | + $controller->setPageTitle(I18N::translate('Create a website access rule')); |
|
219 | + } |
|
220 | + |
|
221 | + $controller->pageHeader(); |
|
222 | + |
|
223 | + $site_access_rule = Database::prepare( |
|
224 | + "SELECT site_access_rule_id, INET_NTOA(ip_address_start) AS ip_address_start, INET_NTOA(ip_address_end) AS ip_address_end, user_agent_pattern, rule, comment" . |
|
225 | + " FROM `##site_access_rule` WHERE site_access_rule_id = :site_access_rule_id" |
|
226 | + )->execute(array( |
|
227 | + 'site_access_rule_id' => Filter::getInteger('site_access_rule_id'), |
|
228 | + ))->fetchOneRow(); |
|
229 | + |
|
230 | + $site_access_rule_id = $site_access_rule ? $site_access_rule->site_access_rule_id : null; |
|
231 | + $ip_address_start = $site_access_rule ? $site_access_rule->ip_address_start : '0.0.0.0'; |
|
232 | + $ip_address_end = $site_access_rule ? $site_access_rule->ip_address_end : '255.255.255.255'; |
|
233 | + $user_agent_pattern = $site_access_rule ? $site_access_rule->user_agent_pattern : '%'; |
|
234 | + $rule = $site_access_rule ? $site_access_rule->rule : 'allow'; |
|
235 | + $comment = $site_access_rule ? $site_access_rule->comment : ''; |
|
236 | + |
|
237 | + ?> |
|
238 | 238 | <ol class="breadcrumb small"> |
239 | 239 | <li><a href="admin.php"><?php echo I18N::translate('Control panel'); ?></a></li> |
240 | 240 | <li><a href="admin_site_access.php"><?php echo I18N::translate('Website access rules'); ?></a></li> |
@@ -311,12 +311,12 @@ discard block |
||
311 | 311 | </form> |
312 | 312 | |
313 | 313 | <?php |
314 | - break; |
|
314 | + break; |
|
315 | 315 | |
316 | 316 | default: |
317 | - $controller |
|
318 | - ->pageHeader() |
|
319 | - ->addInlineJavascript(' |
|
317 | + $controller |
|
318 | + ->pageHeader() |
|
319 | + ->addInlineJavascript(' |
|
320 | 320 | jQuery.fn.dataTableExt.oSort["unicode-asc" ]=function(a,b) {return a.replace(/<[^<]*>/, "").localeCompare(b.replace(/<[^<]*>/, ""))}; |
321 | 321 | jQuery.fn.dataTableExt.oSort["unicode-desc"]=function(a,b) {return b.replace(/<[^<]*>/, "").localeCompare(a.replace(/<[^<]*>/, ""))}; |
322 | 322 | jQuery(".table-site-access-rules").dataTable({ |
@@ -340,7 +340,7 @@ discard block |
||
340 | 340 | }); |
341 | 341 | '); |
342 | 342 | |
343 | - ?> |
|
343 | + ?> |
|
344 | 344 | <ol class="breadcrumb small"> |
345 | 345 | <li><a href="admin.php"><?php echo I18N::translate('Control panel'); ?></a></li> |
346 | 346 | <li class="active"><?php echo $controller->getPageTitle(); ?></li> |
@@ -381,5 +381,5 @@ discard block |
||
381 | 381 | } |
382 | 382 | </script> |
383 | 383 | <?php |
384 | - break; |
|
384 | + break; |
|
385 | 385 | } |
@@ -38,75 +38,75 @@ discard block |
||
38 | 38 | |
39 | 39 | // Form actions |
40 | 40 | switch (Filter::post('action')) { |
41 | -case 'save': |
|
42 | - if (Filter::checkCsrf()) { |
|
43 | - $site_access_rule_id = Filter::postInteger('site_access_rule_id'); |
|
44 | - $ip_address_start = Filter::post('ip_address_start', WT_REGEX_IPV4); |
|
45 | - $ip_address_end = Filter::post('ip_address_end', WT_REGEX_IPV4); |
|
46 | - $user_agent_pattern = Filter::post('user_agent_pattern'); |
|
47 | - $rule = Filter::post('rule', 'allow|deny|robot'); |
|
48 | - $comment = Filter::post('comment'); |
|
49 | - $user_agent_string = Filter::server('HTTP_USER_AGENT'); |
|
50 | - $ip_address = WT_CLIENT_IP; |
|
51 | - |
|
52 | - if ($ip_address_start !== null && $ip_address_end !== null && $user_agent_pattern !== null && $rule !== null) { |
|
53 | - // This doesn't work with named placeholders. The :user_agent_string parameter is not recognised. |
|
54 | - $oops = $rule !== 'allow' && Database::prepare( |
|
55 | - "SELECT INET_ATON(:ip_address) BETWEEN INET_ATON(:ip_address_start) AND INET_ATON(:ip_address_end)" . |
|
56 | - " AND :user_agent_string LIKE :user_agent_pattern" |
|
57 | - )->execute(array( |
|
58 | - 'ip_address' => $ip_address, |
|
59 | - 'ip_address_start' => $ip_address_start, |
|
60 | - 'ip_address_end' => $ip_address_end, |
|
61 | - 'user_agent_string' => $user_agent_string, |
|
62 | - 'user_agent_pattern' => $user_agent_pattern, |
|
63 | - ))->fetchOne(); |
|
64 | - |
|
65 | - if ($oops) { |
|
66 | - FlashMessages::addMessage(I18N::translate('You cannot create a rule which would prevent yourself from accessing the website.'), 'danger'); |
|
67 | - } elseif ($site_access_rule_id === null) { |
|
68 | - Database::prepare( |
|
69 | - "INSERT INTO `##site_access_rule` (ip_address_start, ip_address_end, user_agent_pattern, rule, comment) VALUES (INET_ATON(:ip_address_start), INET_ATON(:ip_address_end), :user_agent_pattern, :rule, :comment)" |
|
70 | - )->execute(array( |
|
71 | - 'ip_address_start' => $ip_address_start, |
|
72 | - 'ip_address_end' => $ip_address_end, |
|
73 | - 'user_agent_pattern' => $user_agent_pattern, |
|
74 | - 'rule' => $rule, |
|
75 | - 'comment' => $comment, |
|
76 | - )); |
|
77 | - FlashMessages::addMessage(I18N::translate('The website access rule has been created.'), 'success'); |
|
78 | - } else { |
|
79 | - Database::prepare( |
|
80 | - "UPDATE `##site_access_rule` SET ip_address_start = INET_ATON(:ip_address_start), ip_address_end = INET_ATON(:ip_address_end), user_agent_pattern = :user_agent_pattern, rule = :rule, comment = :comment WHERE site_access_rule_id = :site_access_rule_id" |
|
81 | - )->execute(array( |
|
82 | - 'ip_address_start' => $ip_address_start, |
|
83 | - 'ip_address_end' => $ip_address_end, |
|
84 | - 'user_agent_pattern' => $user_agent_pattern, |
|
85 | - 'rule' => $rule, |
|
86 | - 'comment' => $comment, |
|
87 | - 'site_access_rule_id' => $site_access_rule_id, |
|
88 | - )); |
|
89 | - FlashMessages::addMessage(I18N::translate('The website access rule has been updated.'), 'success'); |
|
90 | - } |
|
91 | - } |
|
92 | - } |
|
93 | - header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); |
|
94 | - |
|
95 | - return; |
|
96 | - |
|
97 | -case 'delete': |
|
98 | - if (Filter::checkCsrf()) { |
|
99 | - $site_access_rule_id = Filter::postInteger('site_access_rule_id'); |
|
100 | - Database::prepare( |
|
101 | - "DELETE FROM `##site_access_rule` WHERE site_access_rule_id = :site_access_rule_id" |
|
102 | - )->execute(array( |
|
103 | - 'site_access_rule_id' => $site_access_rule_id, |
|
104 | - )); |
|
105 | - FlashMessages::addMessage(I18N::translate('The website access rule has been deleted.'), 'success'); |
|
106 | - } |
|
107 | - header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); |
|
108 | - |
|
109 | - return; |
|
41 | + case 'save': |
|
42 | + if (Filter::checkCsrf()) { |
|
43 | + $site_access_rule_id = Filter::postInteger('site_access_rule_id'); |
|
44 | + $ip_address_start = Filter::post('ip_address_start', WT_REGEX_IPV4); |
|
45 | + $ip_address_end = Filter::post('ip_address_end', WT_REGEX_IPV4); |
|
46 | + $user_agent_pattern = Filter::post('user_agent_pattern'); |
|
47 | + $rule = Filter::post('rule', 'allow|deny|robot'); |
|
48 | + $comment = Filter::post('comment'); |
|
49 | + $user_agent_string = Filter::server('HTTP_USER_AGENT'); |
|
50 | + $ip_address = WT_CLIENT_IP; |
|
51 | + |
|
52 | + if ($ip_address_start !== null && $ip_address_end !== null && $user_agent_pattern !== null && $rule !== null) { |
|
53 | + // This doesn't work with named placeholders. The :user_agent_string parameter is not recognised. |
|
54 | + $oops = $rule !== 'allow' && Database::prepare( |
|
55 | + "SELECT INET_ATON(:ip_address) BETWEEN INET_ATON(:ip_address_start) AND INET_ATON(:ip_address_end)" . |
|
56 | + " AND :user_agent_string LIKE :user_agent_pattern" |
|
57 | + )->execute(array( |
|
58 | + 'ip_address' => $ip_address, |
|
59 | + 'ip_address_start' => $ip_address_start, |
|
60 | + 'ip_address_end' => $ip_address_end, |
|
61 | + 'user_agent_string' => $user_agent_string, |
|
62 | + 'user_agent_pattern' => $user_agent_pattern, |
|
63 | + ))->fetchOne(); |
|
64 | + |
|
65 | + if ($oops) { |
|
66 | + FlashMessages::addMessage(I18N::translate('You cannot create a rule which would prevent yourself from accessing the website.'), 'danger'); |
|
67 | + } elseif ($site_access_rule_id === null) { |
|
68 | + Database::prepare( |
|
69 | + "INSERT INTO `##site_access_rule` (ip_address_start, ip_address_end, user_agent_pattern, rule, comment) VALUES (INET_ATON(:ip_address_start), INET_ATON(:ip_address_end), :user_agent_pattern, :rule, :comment)" |
|
70 | + )->execute(array( |
|
71 | + 'ip_address_start' => $ip_address_start, |
|
72 | + 'ip_address_end' => $ip_address_end, |
|
73 | + 'user_agent_pattern' => $user_agent_pattern, |
|
74 | + 'rule' => $rule, |
|
75 | + 'comment' => $comment, |
|
76 | + )); |
|
77 | + FlashMessages::addMessage(I18N::translate('The website access rule has been created.'), 'success'); |
|
78 | + } else { |
|
79 | + Database::prepare( |
|
80 | + "UPDATE `##site_access_rule` SET ip_address_start = INET_ATON(:ip_address_start), ip_address_end = INET_ATON(:ip_address_end), user_agent_pattern = :user_agent_pattern, rule = :rule, comment = :comment WHERE site_access_rule_id = :site_access_rule_id" |
|
81 | + )->execute(array( |
|
82 | + 'ip_address_start' => $ip_address_start, |
|
83 | + 'ip_address_end' => $ip_address_end, |
|
84 | + 'user_agent_pattern' => $user_agent_pattern, |
|
85 | + 'rule' => $rule, |
|
86 | + 'comment' => $comment, |
|
87 | + 'site_access_rule_id' => $site_access_rule_id, |
|
88 | + )); |
|
89 | + FlashMessages::addMessage(I18N::translate('The website access rule has been updated.'), 'success'); |
|
90 | + } |
|
91 | + } |
|
92 | + } |
|
93 | + header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); |
|
94 | + |
|
95 | + return; |
|
96 | + |
|
97 | + case 'delete': |
|
98 | + if (Filter::checkCsrf()) { |
|
99 | + $site_access_rule_id = Filter::postInteger('site_access_rule_id'); |
|
100 | + Database::prepare( |
|
101 | + "DELETE FROM `##site_access_rule` WHERE site_access_rule_id = :site_access_rule_id" |
|
102 | + )->execute(array( |
|
103 | + 'site_access_rule_id' => $site_access_rule_id, |
|
104 | + )); |
|
105 | + FlashMessages::addMessage(I18N::translate('The website access rule has been deleted.'), 'success'); |
|
106 | + } |
|
107 | + header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); |
|
108 | + |
|
109 | + return; |
|
110 | 110 | } |
111 | 111 | |
112 | 112 | // Delete any "unknown" visitors that are now "known". |
@@ -128,50 +128,50 @@ discard block |
||
128 | 128 | |
129 | 129 | $action = Filter::get('action'); |
130 | 130 | switch ($action) { |
131 | -case 'load': |
|
132 | - // AJAX callback for datatables |
|
133 | - $search = Filter::get('search'); |
|
134 | - $search = $search['value']; |
|
135 | - $start = Filter::getInteger('start'); |
|
136 | - $length = Filter::getInteger('length'); |
|
137 | - |
|
138 | - $sql = |
|
139 | - "SELECT SQL_CALC_FOUND_ROWS" . |
|
140 | - " '', INET_NTOA(ip_address_start), ip_address_start, INET_NTOA(ip_address_end), ip_address_end, user_agent_pattern, rule, comment, site_access_rule_id" . |
|
141 | - " FROM `##site_access_rule`"; |
|
142 | - $args = array(); |
|
143 | - |
|
144 | - if ($search) { |
|
145 | - $sql .= |
|
146 | - " WHERE (INET_ATON(:search_1) BETWEEN ip_address_start AND ip_address_end" . |
|
147 | - " OR INET_NTOA(ip_address_start) LIKE CONCAT('%', :search_2, '%')" . |
|
148 | - " OR INET_NTOA(ip_address_end) LIKE CONCAT('%', :search_3, '%')" . |
|
149 | - " OR user_agent_pattern LIKE CONCAT('%', :search_4, '%')" . |
|
150 | - " OR comment LIKE CONCAT('%', :search_5, '%'))"; |
|
151 | - $args['search_1'] = Filter::escapeLike($search); |
|
152 | - $args['search_2'] = Filter::escapeLike($search); |
|
153 | - $args['search_3'] = Filter::escapeLike($search); |
|
154 | - $args['search_4'] = Filter::escapeLike($search); |
|
155 | - $args['search_5'] = Filter::escapeLike($search); |
|
156 | - } |
|
157 | - |
|
158 | - $order = Filter::getArray('order'); |
|
159 | - $sql .= ' ORDER BY'; |
|
160 | - if ($order) { |
|
161 | - foreach ($order as $key => $value) { |
|
162 | - if ($key > 0) { |
|
163 | - $sql .= ','; |
|
164 | - } |
|
165 | - // Datatables numbers columns 0, 1, 2 |
|
166 | - // MySQL numbers columns 1, 2, 3 |
|
167 | - switch ($value['dir']) { |
|
168 | - case 'asc': |
|
169 | - $sql .= " :col_" . $key . " ASC"; |
|
170 | - break; |
|
171 | - case 'desc': |
|
172 | - $sql .= " :col_" . $key . " DESC"; |
|
173 | - break; |
|
174 | - } |
|
131 | + case 'load': |
|
132 | + // AJAX callback for datatables |
|
133 | + $search = Filter::get('search'); |
|
134 | + $search = $search['value']; |
|
135 | + $start = Filter::getInteger('start'); |
|
136 | + $length = Filter::getInteger('length'); |
|
137 | + |
|
138 | + $sql = |
|
139 | + "SELECT SQL_CALC_FOUND_ROWS" . |
|
140 | + " '', INET_NTOA(ip_address_start), ip_address_start, INET_NTOA(ip_address_end), ip_address_end, user_agent_pattern, rule, comment, site_access_rule_id" . |
|
141 | + " FROM `##site_access_rule`"; |
|
142 | + $args = array(); |
|
143 | + |
|
144 | + if ($search) { |
|
145 | + $sql .= |
|
146 | + " WHERE (INET_ATON(:search_1) BETWEEN ip_address_start AND ip_address_end" . |
|
147 | + " OR INET_NTOA(ip_address_start) LIKE CONCAT('%', :search_2, '%')" . |
|
148 | + " OR INET_NTOA(ip_address_end) LIKE CONCAT('%', :search_3, '%')" . |
|
149 | + " OR user_agent_pattern LIKE CONCAT('%', :search_4, '%')" . |
|
150 | + " OR comment LIKE CONCAT('%', :search_5, '%'))"; |
|
151 | + $args['search_1'] = Filter::escapeLike($search); |
|
152 | + $args['search_2'] = Filter::escapeLike($search); |
|
153 | + $args['search_3'] = Filter::escapeLike($search); |
|
154 | + $args['search_4'] = Filter::escapeLike($search); |
|
155 | + $args['search_5'] = Filter::escapeLike($search); |
|
156 | + } |
|
157 | + |
|
158 | + $order = Filter::getArray('order'); |
|
159 | + $sql .= ' ORDER BY'; |
|
160 | + if ($order) { |
|
161 | + foreach ($order as $key => $value) { |
|
162 | + if ($key > 0) { |
|
163 | + $sql .= ','; |
|
164 | + } |
|
165 | + // Datatables numbers columns 0, 1, 2 |
|
166 | + // MySQL numbers columns 1, 2, 3 |
|
167 | + switch ($value['dir']) { |
|
168 | + case 'asc': |
|
169 | + $sql .= " :col_" . $key . " ASC"; |
|
170 | + break; |
|
171 | + case 'desc': |
|
172 | + $sql .= " :col_" . $key . " DESC"; |
|
173 | + break; |
|
174 | + } |
|
175 | 175 | $args['col_' . $key] = 1 + $value['column']; |
176 | 176 | } |
177 | 177 | } else { |
@@ -210,31 +210,31 @@ discard block |
||
210 | 210 | )); |
211 | 211 | break; |
212 | 212 | |
213 | -case 'edit': |
|
214 | -case 'create': |
|
215 | - if (Filter::get('action') === 'edit') { |
|
216 | - $controller->setPageTitle(I18N::translate('Edit a website access rule')); |
|
217 | - } else { |
|
218 | - $controller->setPageTitle(I18N::translate('Create a website access rule')); |
|
219 | - } |
|
220 | - |
|
221 | - $controller->pageHeader(); |
|
222 | - |
|
223 | - $site_access_rule = Database::prepare( |
|
224 | - "SELECT site_access_rule_id, INET_NTOA(ip_address_start) AS ip_address_start, INET_NTOA(ip_address_end) AS ip_address_end, user_agent_pattern, rule, comment" . |
|
225 | - " FROM `##site_access_rule` WHERE site_access_rule_id = :site_access_rule_id" |
|
226 | - )->execute(array( |
|
227 | - 'site_access_rule_id' => Filter::getInteger('site_access_rule_id'), |
|
228 | - ))->fetchOneRow(); |
|
229 | - |
|
230 | - $site_access_rule_id = $site_access_rule ? $site_access_rule->site_access_rule_id : null; |
|
231 | - $ip_address_start = $site_access_rule ? $site_access_rule->ip_address_start : '0.0.0.0'; |
|
232 | - $ip_address_end = $site_access_rule ? $site_access_rule->ip_address_end : '255.255.255.255'; |
|
233 | - $user_agent_pattern = $site_access_rule ? $site_access_rule->user_agent_pattern : '%'; |
|
234 | - $rule = $site_access_rule ? $site_access_rule->rule : 'allow'; |
|
235 | - $comment = $site_access_rule ? $site_access_rule->comment : ''; |
|
236 | - |
|
237 | - ?> |
|
213 | + case 'edit': |
|
214 | + case 'create': |
|
215 | + if (Filter::get('action') === 'edit') { |
|
216 | + $controller->setPageTitle(I18N::translate('Edit a website access rule')); |
|
217 | + } else { |
|
218 | + $controller->setPageTitle(I18N::translate('Create a website access rule')); |
|
219 | + } |
|
220 | + |
|
221 | + $controller->pageHeader(); |
|
222 | + |
|
223 | + $site_access_rule = Database::prepare( |
|
224 | + "SELECT site_access_rule_id, INET_NTOA(ip_address_start) AS ip_address_start, INET_NTOA(ip_address_end) AS ip_address_end, user_agent_pattern, rule, comment" . |
|
225 | + " FROM `##site_access_rule` WHERE site_access_rule_id = :site_access_rule_id" |
|
226 | + )->execute(array( |
|
227 | + 'site_access_rule_id' => Filter::getInteger('site_access_rule_id'), |
|
228 | + ))->fetchOneRow(); |
|
229 | + |
|
230 | + $site_access_rule_id = $site_access_rule ? $site_access_rule->site_access_rule_id : null; |
|
231 | + $ip_address_start = $site_access_rule ? $site_access_rule->ip_address_start : '0.0.0.0'; |
|
232 | + $ip_address_end = $site_access_rule ? $site_access_rule->ip_address_end : '255.255.255.255'; |
|
233 | + $user_agent_pattern = $site_access_rule ? $site_access_rule->user_agent_pattern : '%'; |
|
234 | + $rule = $site_access_rule ? $site_access_rule->rule : 'allow'; |
|
235 | + $comment = $site_access_rule ? $site_access_rule->comment : ''; |
|
236 | + |
|
237 | + ?> |
|
238 | 238 | <ol class="breadcrumb small"> |
239 | 239 | <li><a href="admin.php"><?php echo I18N::translate('Control panel'); ?></a></li> |
240 | 240 | <li><a href="admin_site_access.php"><?php echo I18N::translate('Website access rules'); ?></a></li> |
@@ -311,12 +311,12 @@ discard block |
||
311 | 311 | </form> |
312 | 312 | |
313 | 313 | <?php |
314 | - break; |
|
314 | + break; |
|
315 | 315 | |
316 | -default: |
|
317 | - $controller |
|
318 | - ->pageHeader() |
|
319 | - ->addInlineJavascript(' |
|
316 | + default: |
|
317 | + $controller |
|
318 | + ->pageHeader() |
|
319 | + ->addInlineJavascript(' |
|
320 | 320 | jQuery.fn.dataTableExt.oSort["unicode-asc" ]=function(a,b) {return a.replace(/<[^<]*>/, "").localeCompare(b.replace(/<[^<]*>/, ""))}; |
321 | 321 | jQuery.fn.dataTableExt.oSort["unicode-desc"]=function(a,b) {return b.replace(/<[^<]*>/, "").localeCompare(a.replace(/<[^<]*>/, ""))}; |
322 | 322 | jQuery(".table-site-access-rules").dataTable({ |
@@ -340,7 +340,7 @@ discard block |
||
340 | 340 | }); |
341 | 341 | '); |
342 | 342 | |
343 | - ?> |
|
343 | + ?> |
|
344 | 344 | <ol class="breadcrumb small"> |
345 | 345 | <li><a href="admin.php"><?php echo I18N::translate('Control panel'); ?></a></li> |
346 | 346 | <li class="active"><?php echo $controller->getPageTitle(); ?></li> |
@@ -381,5 +381,5 @@ discard block |
||
381 | 381 | } |
382 | 382 | </script> |
383 | 383 | <?php |
384 | - break; |
|
384 | + break; |
|
385 | 385 | } |