@@ -33,136 +33,136 @@ discard block |
||
33 | 33 | |
34 | 34 | $controller = new PageController; |
35 | 35 | $controller |
36 | - ->restrictAccess(Auth::isManager($WT_TREE)) |
|
37 | - ->setPageTitle(I18N::translate('Upload media files')); |
|
36 | + ->restrictAccess(Auth::isManager($WT_TREE)) |
|
37 | + ->setPageTitle(I18N::translate('Upload media files')); |
|
38 | 38 | |
39 | 39 | $action = Filter::post('action'); |
40 | 40 | |
41 | 41 | if ($action == "upload") { |
42 | - for ($i = 1; $i < 6; $i++) { |
|
43 | - if (!empty($_FILES['mediafile' . $i]["name"]) || !empty($_FILES['thumbnail' . $i]["name"])) { |
|
44 | - $folder = Filter::post('folder' . $i); |
|
42 | + for ($i = 1; $i < 6; $i++) { |
|
43 | + if (!empty($_FILES['mediafile' . $i]["name"]) || !empty($_FILES['thumbnail' . $i]["name"])) { |
|
44 | + $folder = Filter::post('folder' . $i); |
|
45 | 45 | |
46 | - // Validate the media folder |
|
47 | - $folderName = str_replace('\\', '/', $folder); |
|
48 | - $folderName = trim($folderName, '/'); |
|
49 | - if ($folderName == '.') { |
|
50 | - $folderName = ''; |
|
51 | - } |
|
52 | - if ($folderName) { |
|
53 | - $folderName .= '/'; |
|
54 | - // Not allowed to use “../” |
|
55 | - if (strpos('/' . $folderName, '/../') !== false) { |
|
56 | - FlashMessages::addMessage('Folder names are not allowed to include “../”'); |
|
57 | - break; |
|
58 | - } |
|
59 | - } |
|
46 | + // Validate the media folder |
|
47 | + $folderName = str_replace('\\', '/', $folder); |
|
48 | + $folderName = trim($folderName, '/'); |
|
49 | + if ($folderName == '.') { |
|
50 | + $folderName = ''; |
|
51 | + } |
|
52 | + if ($folderName) { |
|
53 | + $folderName .= '/'; |
|
54 | + // Not allowed to use “../” |
|
55 | + if (strpos('/' . $folderName, '/../') !== false) { |
|
56 | + FlashMessages::addMessage('Folder names are not allowed to include “../”'); |
|
57 | + break; |
|
58 | + } |
|
59 | + } |
|
60 | 60 | |
61 | - // Make sure the media folder exists |
|
62 | - if (!is_dir(WT_DATA_DIR . $MEDIA_DIRECTORY)) { |
|
63 | - if (File::mkdir(WT_DATA_DIR . $MEDIA_DIRECTORY)) { |
|
64 | - FlashMessages::addMessage(I18N::translate('The folder %s has been created.', Html::filename(WT_DATA_DIR . $MEDIA_DIRECTORY))); |
|
65 | - } else { |
|
66 | - FlashMessages::addMessage(I18N::translate('The folder %s does not exist, and it could not be created.', Html::filename(WT_DATA_DIR . $MEDIA_DIRECTORY)), 'danger'); |
|
67 | - break; |
|
68 | - } |
|
69 | - } |
|
61 | + // Make sure the media folder exists |
|
62 | + if (!is_dir(WT_DATA_DIR . $MEDIA_DIRECTORY)) { |
|
63 | + if (File::mkdir(WT_DATA_DIR . $MEDIA_DIRECTORY)) { |
|
64 | + FlashMessages::addMessage(I18N::translate('The folder %s has been created.', Html::filename(WT_DATA_DIR . $MEDIA_DIRECTORY))); |
|
65 | + } else { |
|
66 | + FlashMessages::addMessage(I18N::translate('The folder %s does not exist, and it could not be created.', Html::filename(WT_DATA_DIR . $MEDIA_DIRECTORY)), 'danger'); |
|
67 | + break; |
|
68 | + } |
|
69 | + } |
|
70 | 70 | |
71 | - // Managers can create new media paths (subfolders). Users must use existing folders. |
|
72 | - if ($folderName && !is_dir(WT_DATA_DIR . $MEDIA_DIRECTORY . $folderName)) { |
|
73 | - if (Auth::isManager($WT_TREE)) { |
|
74 | - if (File::mkdir(WT_DATA_DIR . $MEDIA_DIRECTORY . $folderName)) { |
|
75 | - FlashMessages::addMessage(I18N::translate('The folder %s has been created.', Html::filename(WT_DATA_DIR . $MEDIA_DIRECTORY . $folderName))); |
|
76 | - } else { |
|
77 | - FlashMessages::addMessage(I18N::translate('The folder %s does not exist, and it could not be created.', Html::filename(WT_DATA_DIR . $MEDIA_DIRECTORY . $folderName)), 'danger'); |
|
78 | - break; |
|
79 | - } |
|
80 | - } else { |
|
81 | - // Regular users should not have seen this option - so no need for an error message. |
|
82 | - break; |
|
83 | - } |
|
84 | - } |
|
71 | + // Managers can create new media paths (subfolders). Users must use existing folders. |
|
72 | + if ($folderName && !is_dir(WT_DATA_DIR . $MEDIA_DIRECTORY . $folderName)) { |
|
73 | + if (Auth::isManager($WT_TREE)) { |
|
74 | + if (File::mkdir(WT_DATA_DIR . $MEDIA_DIRECTORY . $folderName)) { |
|
75 | + FlashMessages::addMessage(I18N::translate('The folder %s has been created.', Html::filename(WT_DATA_DIR . $MEDIA_DIRECTORY . $folderName))); |
|
76 | + } else { |
|
77 | + FlashMessages::addMessage(I18N::translate('The folder %s does not exist, and it could not be created.', Html::filename(WT_DATA_DIR . $MEDIA_DIRECTORY . $folderName)), 'danger'); |
|
78 | + break; |
|
79 | + } |
|
80 | + } else { |
|
81 | + // Regular users should not have seen this option - so no need for an error message. |
|
82 | + break; |
|
83 | + } |
|
84 | + } |
|
85 | 85 | |
86 | - // The media folder exists. Now create a thumbnail folder to match it. |
|
87 | - if (!is_dir(WT_DATA_DIR . $MEDIA_DIRECTORY . 'thumbs/' . $folderName)) { |
|
88 | - if (!File::mkdir(WT_DATA_DIR . $MEDIA_DIRECTORY . 'thumbs/' . $folderName)) { |
|
89 | - FlashMessages::addMessage(I18N::translate('The folder %s does not exist, and it could not be created.', Html::filename(WT_DATA_DIR . $MEDIA_DIRECTORY . 'thumbs/' . $folderName))); |
|
90 | - break; |
|
91 | - } |
|
92 | - } |
|
86 | + // The media folder exists. Now create a thumbnail folder to match it. |
|
87 | + if (!is_dir(WT_DATA_DIR . $MEDIA_DIRECTORY . 'thumbs/' . $folderName)) { |
|
88 | + if (!File::mkdir(WT_DATA_DIR . $MEDIA_DIRECTORY . 'thumbs/' . $folderName)) { |
|
89 | + FlashMessages::addMessage(I18N::translate('The folder %s does not exist, and it could not be created.', Html::filename(WT_DATA_DIR . $MEDIA_DIRECTORY . 'thumbs/' . $folderName))); |
|
90 | + break; |
|
91 | + } |
|
92 | + } |
|
93 | 93 | |
94 | - // A thumbnail file with no main image? |
|
95 | - if (!empty($_FILES['thumbnail' . $i]['name']) && empty($_FILES['mediafile' . $i]['name'])) { |
|
96 | - // Assume the user used the wrong field, and treat this as a main image |
|
97 | - $_FILES['mediafile' . $i] = $_FILES['thumbnail' . $i]; |
|
98 | - unset($_FILES['thumbnail' . $i]); |
|
99 | - } |
|
94 | + // A thumbnail file with no main image? |
|
95 | + if (!empty($_FILES['thumbnail' . $i]['name']) && empty($_FILES['mediafile' . $i]['name'])) { |
|
96 | + // Assume the user used the wrong field, and treat this as a main image |
|
97 | + $_FILES['mediafile' . $i] = $_FILES['thumbnail' . $i]; |
|
98 | + unset($_FILES['thumbnail' . $i]); |
|
99 | + } |
|
100 | 100 | |
101 | - // Thumbnail files must contain images. |
|
102 | - if (!empty($_FILES['thumbnail' . $i]['name']) && !preg_match('/^image\/(png|gif|jpeg)/', $_FILES['thumbnail' . $i]['type'])) { |
|
103 | - FlashMessages::addMessage(I18N::translate('Thumbnail files must contain images.')); |
|
104 | - break; |
|
105 | - } |
|
101 | + // Thumbnail files must contain images. |
|
102 | + if (!empty($_FILES['thumbnail' . $i]['name']) && !preg_match('/^image\/(png|gif|jpeg)/', $_FILES['thumbnail' . $i]['type'])) { |
|
103 | + FlashMessages::addMessage(I18N::translate('Thumbnail files must contain images.')); |
|
104 | + break; |
|
105 | + } |
|
106 | 106 | |
107 | - // User-specified filename? |
|
108 | - $filename = Filter::post('filename' . $i); |
|
109 | - // Use the name of the uploaded file? |
|
110 | - if (!$filename && !empty($_FILES['mediafile' . $i]['name'])) { |
|
111 | - $filename = $_FILES['mediafile' . $i]['name']; |
|
112 | - } |
|
107 | + // User-specified filename? |
|
108 | + $filename = Filter::post('filename' . $i); |
|
109 | + // Use the name of the uploaded file? |
|
110 | + if (!$filename && !empty($_FILES['mediafile' . $i]['name'])) { |
|
111 | + $filename = $_FILES['mediafile' . $i]['name']; |
|
112 | + } |
|
113 | 113 | |
114 | - // Validate the media path and filename |
|
115 | - if (preg_match('/([\/\\\\<>])/', $filename, $match)) { |
|
116 | - // Local media files cannot contain certain special characters |
|
117 | - FlashMessages::addMessage(I18N::translate('Filenames are not allowed to contain the character “%s”.', $match[1])); |
|
118 | - $filename = ''; |
|
119 | - break; |
|
120 | - } elseif (preg_match('/(\.(php|pl|cgi|bash|sh|bat|exe|com|htm|html|shtml))$/i', $filename, $match)) { |
|
121 | - // Do not allow obvious script files. |
|
122 | - FlashMessages::addMessage(I18N::translate('Filenames are not allowed to have the extension “%s”.', $match[1])); |
|
123 | - $filename = ''; |
|
124 | - break; |
|
125 | - } elseif (!$filename) { |
|
126 | - FlashMessages::addMessage(I18N::translate('No media file was provided.')); |
|
127 | - break; |
|
128 | - } else { |
|
129 | - $fileName = $filename; |
|
130 | - } |
|
114 | + // Validate the media path and filename |
|
115 | + if (preg_match('/([\/\\\\<>])/', $filename, $match)) { |
|
116 | + // Local media files cannot contain certain special characters |
|
117 | + FlashMessages::addMessage(I18N::translate('Filenames are not allowed to contain the character “%s”.', $match[1])); |
|
118 | + $filename = ''; |
|
119 | + break; |
|
120 | + } elseif (preg_match('/(\.(php|pl|cgi|bash|sh|bat|exe|com|htm|html|shtml))$/i', $filename, $match)) { |
|
121 | + // Do not allow obvious script files. |
|
122 | + FlashMessages::addMessage(I18N::translate('Filenames are not allowed to have the extension “%s”.', $match[1])); |
|
123 | + $filename = ''; |
|
124 | + break; |
|
125 | + } elseif (!$filename) { |
|
126 | + FlashMessages::addMessage(I18N::translate('No media file was provided.')); |
|
127 | + break; |
|
128 | + } else { |
|
129 | + $fileName = $filename; |
|
130 | + } |
|
131 | 131 | |
132 | - // Now copy the file to the correct location. |
|
133 | - if (!empty($_FILES['mediafile' . $i]['name'])) { |
|
134 | - $serverFileName = WT_DATA_DIR . $MEDIA_DIRECTORY . $folderName . $fileName; |
|
135 | - if (file_exists($serverFileName)) { |
|
136 | - FlashMessages::addMessage(I18N::translate('The file %s already exists. Use another filename.', $folderName . $fileName)); |
|
137 | - $filename = ''; |
|
138 | - break; |
|
139 | - } |
|
140 | - if (move_uploaded_file($_FILES['mediafile' . $i]['tmp_name'], $serverFileName)) { |
|
141 | - FlashMessages::addMessage(I18N::translate('The file %s has been uploaded.', Html::filename($serverFileName))); |
|
142 | - Log::addMediaLog('Media file ' . $serverFileName . ' uploaded'); |
|
143 | - } else { |
|
144 | - FlashMessages::addMessage( |
|
145 | - I18N::translate('There was an error uploading your file.') . |
|
146 | - '<br>' . |
|
147 | - Functions::fileUploadErrorText($_FILES['mediafile' . $i]['error']) |
|
148 | - ); |
|
149 | - $filename = ''; |
|
150 | - break; |
|
151 | - } |
|
132 | + // Now copy the file to the correct location. |
|
133 | + if (!empty($_FILES['mediafile' . $i]['name'])) { |
|
134 | + $serverFileName = WT_DATA_DIR . $MEDIA_DIRECTORY . $folderName . $fileName; |
|
135 | + if (file_exists($serverFileName)) { |
|
136 | + FlashMessages::addMessage(I18N::translate('The file %s already exists. Use another filename.', $folderName . $fileName)); |
|
137 | + $filename = ''; |
|
138 | + break; |
|
139 | + } |
|
140 | + if (move_uploaded_file($_FILES['mediafile' . $i]['tmp_name'], $serverFileName)) { |
|
141 | + FlashMessages::addMessage(I18N::translate('The file %s has been uploaded.', Html::filename($serverFileName))); |
|
142 | + Log::addMediaLog('Media file ' . $serverFileName . ' uploaded'); |
|
143 | + } else { |
|
144 | + FlashMessages::addMessage( |
|
145 | + I18N::translate('There was an error uploading your file.') . |
|
146 | + '<br>' . |
|
147 | + Functions::fileUploadErrorText($_FILES['mediafile' . $i]['error']) |
|
148 | + ); |
|
149 | + $filename = ''; |
|
150 | + break; |
|
151 | + } |
|
152 | 152 | |
153 | - // Now copy the (optional thumbnail) |
|
154 | - if (!empty($_FILES['thumbnail' . $i]['name']) && preg_match('/^image\/(png|gif|jpeg)/', $_FILES['thumbnail' . $i]['type'], $match)) { |
|
155 | - $extension = $match[1]; |
|
156 | - $thumbFile = preg_replace('/\.[a-z0-9]{3,5}$/', '.' . $extension, $fileName); |
|
157 | - $serverFileName = WT_DATA_DIR . $MEDIA_DIRECTORY . 'thumbs/' . $folderName . $thumbFile; |
|
158 | - if (move_uploaded_file($_FILES['thumbnail' . $i]['tmp_name'], $serverFileName)) { |
|
159 | - FlashMessages::addMessage(I18N::translate('The file %s has been uploaded.', Html::filename($serverFileName))); |
|
160 | - Log::addMediaLog('Thumbnail file ' . $serverFileName . ' uploaded'); |
|
161 | - } |
|
162 | - } |
|
163 | - } |
|
164 | - } |
|
165 | - } |
|
153 | + // Now copy the (optional thumbnail) |
|
154 | + if (!empty($_FILES['thumbnail' . $i]['name']) && preg_match('/^image\/(png|gif|jpeg)/', $_FILES['thumbnail' . $i]['type'], $match)) { |
|
155 | + $extension = $match[1]; |
|
156 | + $thumbFile = preg_replace('/\.[a-z0-9]{3,5}$/', '.' . $extension, $fileName); |
|
157 | + $serverFileName = WT_DATA_DIR . $MEDIA_DIRECTORY . 'thumbs/' . $folderName . $thumbFile; |
|
158 | + if (move_uploaded_file($_FILES['thumbnail' . $i]['tmp_name'], $serverFileName)) { |
|
159 | + FlashMessages::addMessage(I18N::translate('The file %s has been uploaded.', Html::filename($serverFileName))); |
|
160 | + Log::addMediaLog('Thumbnail file ' . $serverFileName . ' uploaded'); |
|
161 | + } |
|
162 | + } |
|
163 | + } |
|
164 | + } |
|
165 | + } |
|
166 | 166 | } |
167 | 167 | |
168 | 168 | $controller->pageHeader(); |
@@ -172,7 +172,7 @@ discard block |
||
172 | 172 | // Determine file size limit |
173 | 173 | $filesize = ini_get('upload_max_filesize'); |
174 | 174 | if (empty($filesize)) { |
175 | - $filesize = "2M"; |
|
175 | + $filesize = "2M"; |
|
176 | 176 | } |
177 | 177 | |
178 | 178 | ?> |
@@ -196,68 +196,68 @@ discard block |
||
196 | 196 | |
197 | 197 | // Print 5 forms for uploading images |
198 | 198 | for ($i = 1; $i < 6; $i++) { |
199 | - echo '<table class="upload_media">'; |
|
200 | - echo '<tr><th>', I18N::translate('Media file'), ' ', $i, '</th></tr>'; |
|
201 | - echo '<tr><td>'; |
|
202 | - echo I18N::translate('Media file to upload'); |
|
203 | - echo '</td>'; |
|
204 | - echo '<td>'; |
|
205 | - echo '<input name="mediafile', $i, '" type="file" size="40">'; |
|
206 | - echo '</td></tr>'; |
|
207 | - echo '<tr><td>'; |
|
208 | - echo I18N::translate('Thumbnail to upload'); |
|
209 | - echo '</td>'; |
|
210 | - echo '<td>'; |
|
211 | - echo '<input name="thumbnail', $i, '" type="file" size="40">'; |
|
212 | - if ($i === 1) { |
|
213 | - echo '<p class="small text-muted">', I18N::translate('Choose the thumbnail image that you want to upload. Although thumbnails can be generated automatically for images, you may wish to generate your own thumbnail, especially for other media types. For example, you can provide a still image from a video, or a photograph of the individual who made an audio recording.'), '</p>'; |
|
214 | - } |
|
215 | - echo '</td></tr>'; |
|
199 | + echo '<table class="upload_media">'; |
|
200 | + echo '<tr><th>', I18N::translate('Media file'), ' ', $i, '</th></tr>'; |
|
201 | + echo '<tr><td>'; |
|
202 | + echo I18N::translate('Media file to upload'); |
|
203 | + echo '</td>'; |
|
204 | + echo '<td>'; |
|
205 | + echo '<input name="mediafile', $i, '" type="file" size="40">'; |
|
206 | + echo '</td></tr>'; |
|
207 | + echo '<tr><td>'; |
|
208 | + echo I18N::translate('Thumbnail to upload'); |
|
209 | + echo '</td>'; |
|
210 | + echo '<td>'; |
|
211 | + echo '<input name="thumbnail', $i, '" type="file" size="40">'; |
|
212 | + if ($i === 1) { |
|
213 | + echo '<p class="small text-muted">', I18N::translate('Choose the thumbnail image that you want to upload. Although thumbnails can be generated automatically for images, you may wish to generate your own thumbnail, especially for other media types. For example, you can provide a still image from a video, or a photograph of the individual who made an audio recording.'), '</p>'; |
|
214 | + } |
|
215 | + echo '</td></tr>'; |
|
216 | 216 | |
217 | - if (Auth::isManager($WT_TREE)) { |
|
218 | - echo '<tr><td>'; |
|
219 | - echo I18N::translate('Filename on server'); |
|
220 | - echo '</td>'; |
|
221 | - echo '<td>'; |
|
222 | - echo '<input name="filename', $i, '" type="text" size="40">'; |
|
223 | - if ($i == 1) { |
|
224 | - echo '<p class="small text-muted">', I18N::translate('Do not change to keep original filename.'), "</p>"; |
|
225 | - echo '<p class="small text-muted">', I18N::translate('The media file you are uploading can be, and probably should be, named differently on the server than it is on your local computer. This is so because often the local filename has meaning to you but is much less meaningful to others visiting this website. Consider also the possibility that you and someone else both try to upload different files called “granny.jpg“.<br><br>In this field, you specify the new name of the file you are uploading. The name you enter here will also be used to name the thumbnail, which can be uploaded separately or generated automatically. You do not need to enter the filename extension (jpg, gif, pdf, doc, etc.)<br><br>Leave this field blank to keep the original name of the file you have uploaded from your local computer.'), '</p>'; |
|
226 | - } |
|
227 | - echo '</td></tr>'; |
|
228 | - } else { |
|
229 | - echo '<tr style="display:none;"><td><input type="hidden" name="filename', $i, '" value=""></td></tr>'; |
|
230 | - } |
|
217 | + if (Auth::isManager($WT_TREE)) { |
|
218 | + echo '<tr><td>'; |
|
219 | + echo I18N::translate('Filename on server'); |
|
220 | + echo '</td>'; |
|
221 | + echo '<td>'; |
|
222 | + echo '<input name="filename', $i, '" type="text" size="40">'; |
|
223 | + if ($i == 1) { |
|
224 | + echo '<p class="small text-muted">', I18N::translate('Do not change to keep original filename.'), "</p>"; |
|
225 | + echo '<p class="small text-muted">', I18N::translate('The media file you are uploading can be, and probably should be, named differently on the server than it is on your local computer. This is so because often the local filename has meaning to you but is much less meaningful to others visiting this website. Consider also the possibility that you and someone else both try to upload different files called “granny.jpg“.<br><br>In this field, you specify the new name of the file you are uploading. The name you enter here will also be used to name the thumbnail, which can be uploaded separately or generated automatically. You do not need to enter the filename extension (jpg, gif, pdf, doc, etc.)<br><br>Leave this field blank to keep the original name of the file you have uploaded from your local computer.'), '</p>'; |
|
226 | + } |
|
227 | + echo '</td></tr>'; |
|
228 | + } else { |
|
229 | + echo '<tr style="display:none;"><td><input type="hidden" name="filename', $i, '" value=""></td></tr>'; |
|
230 | + } |
|
231 | 231 | |
232 | - if (Auth::isManager($WT_TREE)) { |
|
233 | - echo '<tr><td>'; |
|
234 | - echo I18N::translate('Folder name on server'); |
|
235 | - echo '</td>'; |
|
236 | - echo '<td>'; |
|
232 | + if (Auth::isManager($WT_TREE)) { |
|
233 | + echo '<tr><td>'; |
|
234 | + echo I18N::translate('Folder name on server'); |
|
235 | + echo '</td>'; |
|
236 | + echo '<td>'; |
|
237 | 237 | |
238 | - echo '<select name="folder_list', $i, '" onchange="document.uploadmedia.folder', $i, '.value=this.options[this.selectedIndex].value;">'; |
|
239 | - echo '<option'; |
|
240 | - echo ' value="/"> ', I18N::translate('<select>'), ' </option>'; |
|
241 | - if (Auth::isAdmin()) { |
|
242 | - echo '<option value="other" disabled>', I18N::translate('Other folder… please type in'), "</option>"; |
|
243 | - } |
|
244 | - foreach ($mediaFolders as $f) { |
|
245 | - echo '<option value="', Filter::escapeHtml($f), '">', Filter::escapeHtml($f), "</option>"; |
|
246 | - } |
|
247 | - echo "</select>"; |
|
248 | - if (Auth::isAdmin()) { |
|
249 | - echo '<br><input name="folder', $i, '" type="text" size="40" value="">'; |
|
250 | - } else { |
|
251 | - echo '<input name="folder', $i, '" type="hidden" value="">'; |
|
252 | - } |
|
253 | - if ($i === 1) { |
|
254 | - echo '<p class="small text-muted">', I18N::translate('If you have a large number of media files, you can organize them into folders and subfolders.'), '</p>'; |
|
255 | - } |
|
256 | - echo '</td></tr>'; |
|
257 | - } else { |
|
258 | - echo '<tr style="display:none;"><td><input name="folder', $i, '" type="hidden" value=""></td></tr>'; |
|
259 | - } |
|
260 | - echo '</table>'; |
|
238 | + echo '<select name="folder_list', $i, '" onchange="document.uploadmedia.folder', $i, '.value=this.options[this.selectedIndex].value;">'; |
|
239 | + echo '<option'; |
|
240 | + echo ' value="/"> ', I18N::translate('<select>'), ' </option>'; |
|
241 | + if (Auth::isAdmin()) { |
|
242 | + echo '<option value="other" disabled>', I18N::translate('Other folder… please type in'), "</option>"; |
|
243 | + } |
|
244 | + foreach ($mediaFolders as $f) { |
|
245 | + echo '<option value="', Filter::escapeHtml($f), '">', Filter::escapeHtml($f), "</option>"; |
|
246 | + } |
|
247 | + echo "</select>"; |
|
248 | + if (Auth::isAdmin()) { |
|
249 | + echo '<br><input name="folder', $i, '" type="text" size="40" value="">'; |
|
250 | + } else { |
|
251 | + echo '<input name="folder', $i, '" type="hidden" value="">'; |
|
252 | + } |
|
253 | + if ($i === 1) { |
|
254 | + echo '<p class="small text-muted">', I18N::translate('If you have a large number of media files, you can organize them into folders and subfolders.'), '</p>'; |
|
255 | + } |
|
256 | + echo '</td></tr>'; |
|
257 | + } else { |
|
258 | + echo '<tr style="display:none;"><td><input name="folder', $i, '" type="hidden" value=""></td></tr>'; |
|
259 | + } |
|
260 | + echo '</table>'; |
|
261 | 261 | } |
262 | 262 | // Print the Submit button for uploading the media |
263 | 263 | echo '<input type="submit" value="', /* I18N: A button label. */ I18N::translate('upload'), '">'; |
@@ -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) { |
@@ -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 | ?> |
@@ -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 | } |