1 | <?php |
||
2 | |||
3 | /** |
||
4 | * Manage features and options administration page. |
||
5 | * |
||
6 | * @package ElkArte Forum |
||
7 | * @copyright ElkArte Forum contributors |
||
8 | * @license BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file) |
||
9 | * |
||
10 | * This file contains code covered by: |
||
11 | * copyright: 2011 Simple Machines (http://www.simplemachines.org) |
||
12 | * |
||
13 | * @version 2.0 dev |
||
14 | * |
||
15 | */ |
||
16 | |||
17 | namespace ElkArte\AdminController; |
||
18 | |||
19 | use BBC\ParserWrapper; |
||
20 | use DateTimeZone; |
||
21 | use ElkArte\AbstractController; |
||
22 | use ElkArte\Action; |
||
23 | use ElkArte\Exceptions\Exception; |
||
24 | use ElkArte\Helper\DataValidator; |
||
25 | use ElkArte\Helper\Util; |
||
26 | use ElkArte\Hooks; |
||
27 | use ElkArte\Languages\Txt; |
||
28 | use ElkArte\Mentions\MentionType\AbstractNotificationMessage; |
||
29 | use ElkArte\MetadataIntegrate; |
||
30 | use ElkArte\Notifications\Notifications; |
||
31 | use ElkArte\SettingsForm\SettingsForm; |
||
32 | |||
33 | /** |
||
34 | * Manage features and options administration page. |
||
35 | * |
||
36 | * This controller handles the pages which allow the admin |
||
37 | * to see and change the basic feature settings of their site. |
||
38 | 2 | */ |
|
39 | class ManageFeatures extends AbstractController |
||
40 | { |
||
41 | 2 | /** |
|
42 | 2 | * Pre Dispatch, called before other methods. |
|
43 | */ |
||
44 | public function pre_dispatch() |
||
45 | { |
||
46 | // We need this in few places so it's easier to have it loaded here |
||
47 | require_once(SUBSDIR . '/ManageFeatures.subs.php'); |
||
48 | } |
||
49 | |||
50 | /** |
||
51 | * This function passes control through to the relevant tab. |
||
52 | * |
||
53 | * @event integrate_sa_modify_features Use to add new Configuration tabs |
||
54 | * @see AbstractController::action_index() |
||
55 | * @uses Help, ManageSettings languages |
||
56 | * @uses sub_template show_settings |
||
57 | */ |
||
58 | public function action_index() |
||
59 | { |
||
60 | global $context, $txt, $settings; |
||
61 | |||
62 | // Often Helpful |
||
63 | Txt::load('Help+ManageSettings+Mentions'); |
||
64 | |||
65 | // All the actions we know about. These must exist in loadMenu() of the admin controller. |
||
66 | $subActions = array( |
||
67 | 'basic' => array( |
||
68 | 'controller' => $this, |
||
69 | 'function' => 'action_basicSettings_display', |
||
70 | 'permission' => 'admin_forum' |
||
71 | ), |
||
72 | 'layout' => array( |
||
73 | 'controller' => $this, |
||
74 | 'function' => 'action_layoutSettings_display', |
||
75 | 'permission' => 'admin_forum' |
||
76 | ), |
||
77 | 'pwa' => array( |
||
78 | 'controller' => $this, |
||
79 | 'function' => 'action_pwaSettings_display', |
||
80 | 'enabled' => true, |
||
81 | 'permission' => 'admin_forum' |
||
82 | ), |
||
83 | 'karma' => array( |
||
84 | 'controller' => $this, |
||
85 | 'function' => 'action_karmaSettings_display', |
||
86 | 'enabled' => featureEnabled('k'), |
||
87 | 'permission' => 'admin_forum' |
||
88 | ), |
||
89 | 'pmsettings' => array( |
||
90 | 'controller' => $this, |
||
91 | 'function' => 'action_pmsettings', |
||
92 | 'permission' => 'admin_forum' |
||
93 | ), |
||
94 | 'likes' => array( |
||
95 | 'controller' => $this, |
||
96 | 'function' => 'action_likesSettings_display', |
||
97 | 'enabled' => featureEnabled('l'), |
||
98 | 'permission' => 'admin_forum' |
||
99 | ), |
||
100 | 'mention' => array( |
||
101 | 'controller' => $this, |
||
102 | 'function' => 'action_notificationsSettings_display', |
||
103 | 'permission' => 'admin_forum' |
||
104 | ), |
||
105 | 'sig' => array( |
||
106 | 'controller' => $this, |
||
107 | 'function' => 'action_signatureSettings_display', |
||
108 | 'permission' => 'admin_forum' |
||
109 | ), |
||
110 | 'profile' => array( |
||
111 | 'controller' => $this, |
||
112 | 'function' => 'action_profile', |
||
113 | 'enabled' => featureEnabled('cp'), |
||
114 | 'permission' => 'admin_forum' |
||
115 | ), |
||
116 | 'profileedit' => array( |
||
117 | 'controller' => $this, |
||
118 | 'function' => 'action_profileedit', |
||
119 | 'permission' => 'admin_forum' |
||
120 | ), |
||
121 | ); |
||
122 | |||
123 | // Set up the action control |
||
124 | $action = new Action('modify_features'); |
||
125 | |||
126 | // By default, do the basic settings, call integrate_sa_modify_features |
||
127 | $subAction = $action->initialize($subActions, 'basic'); |
||
128 | |||
129 | // Some final pieces for the template |
||
130 | $context['sub_template'] = 'show_settings'; |
||
131 | $context['sub_action'] = $subAction; |
||
132 | $context['page_title'] = $txt['modSettings_title']; |
||
133 | |||
134 | // Load up all the tabs... |
||
135 | $context[$context['admin_menu_name']]['object']->prepareTabData([ |
||
136 | 'title' => 'modSettings_title', |
||
137 | 'help' => 'featuresettings', |
||
138 | 'description' => sprintf($txt['modSettings_desc'], getUrl('admin', ['action' => 'admin', 'area' => 'theme', 'sa' => 'list', 'th' => $settings['theme_id'], '{session_data}'])), |
||
139 | // All valid $subActions will be added, here you just specify any special tab data |
||
140 | 'tabs' => [ |
||
141 | 'mention' => [ |
||
142 | 'description' => $txt['mentions_settings_desc'], |
||
143 | ], |
||
144 | 'sig' => [ |
||
145 | 'description' => $txt['signature_settings_desc'], |
||
146 | ], |
||
147 | 'profile' => [ |
||
148 | 'description' => $txt['custom_profile_desc'], |
||
149 | ], |
||
150 | 'pwa' => [ |
||
151 | 'description' => $txt['pwa_settings_desc'], |
||
152 | ], |
||
153 | ], |
||
154 | ]); |
||
155 | |||
156 | // Call the right function for this sub-action. |
||
157 | $action->dispatch($subAction); |
||
158 | } |
||
159 | |||
160 | /** |
||
161 | * Config array for changing the basic forum settings |
||
162 | * |
||
163 | * - Accessed from ?action=admin;area=featuresettings;sa=basic; |
||
164 | * |
||
165 | * @event integrate_save_basic_settings |
||
166 | */ |
||
167 | public function action_basicSettings_display() |
||
168 | { |
||
169 | global $txt, $context, $modSettings; |
||
170 | |||
171 | // Initialize the form |
||
172 | $settingsForm = new SettingsForm(SettingsForm::DB_ADAPTER); |
||
173 | |||
174 | // Initialize it with our settings |
||
175 | $settingsForm->setConfigVars($this->_basicSettings()); |
||
176 | |||
177 | theme()->addJavascriptVar(['txt_invalid_response' => $txt['ajax_bad_response']], true); |
||
178 | |||
179 | // Saving? |
||
180 | if (isset($this->_req->query->save)) |
||
181 | { |
||
182 | checkSession(); |
||
183 | |||
184 | // Prevent absurd boundaries here - make it a day tops. |
||
185 | if (isset($this->_req->post->lastActive)) |
||
186 | { |
||
187 | $this->_req->post->lastActive = min((int) $this->_req->post->lastActive, 1440); |
||
188 | } |
||
189 | |||
190 | call_integration_hook('integrate_save_basic_settings'); |
||
191 | |||
192 | // Microdata needs to enable its integration |
||
193 | if ($this->_req->isSet('metadata_enabled')) |
||
194 | { |
||
195 | Hooks::instance()->enableIntegration(MetadataIntegrate::class); |
||
196 | } |
||
197 | else |
||
198 | { |
||
199 | Hooks::instance()->disableIntegration(MetadataIntegrate::class); |
||
200 | } |
||
201 | |||
202 | // If they have changed Hive settings, lets clear them to avoid issues |
||
203 | if (empty($modSettings['minify_css_js']) !== empty($this->_req->post->minify_css_js)) |
||
204 | { |
||
205 | theme()->cleanHives(); |
||
206 | } |
||
207 | |||
208 | $settingsForm->setConfigValues((array) $this->_req->post); |
||
209 | $settingsForm->save(); |
||
210 | |||
211 | writeLog(); |
||
212 | redirectexit('action=admin;area=featuresettings;sa=basic'); |
||
213 | } |
||
214 | |||
215 | if (isset($this->_req->post->cleanhives) && $this->getApi() === 'json') |
||
216 | { |
||
217 | $clean_hives_result = theme()->cleanHives(); |
||
218 | 2 | ||
219 | setJsonTemplate(); |
||
220 | 2 | $context['json_data'] = array( |
|
221 | 'success' => $clean_hives_result, |
||
222 | 'response' => $clean_hives_result ? $txt['clean_hives_sucess'] : $txt['clean_hives_failed'] |
||
223 | ); |
||
224 | 2 | ||
225 | return; |
||
226 | } |
||
227 | |||
228 | $context['post_url'] = getUrl('admin', ['action' => 'admin', 'area' => 'featuresettings', 'sa' => 'basic', 'save']); |
||
229 | 2 | $context['settings_title'] = $txt['mods_cat_features']; |
|
230 | |||
231 | 2 | $settingsForm->prepare(); |
|
232 | } |
||
233 | 2 | ||
234 | /** |
||
235 | 2 | * Return basic feature settings. |
|
236 | 2 | * |
|
237 | 2 | * @event integrate_modify_basic_settings Adds to General features and Options |
|
238 | */ |
||
239 | private function _basicSettings() |
||
240 | 2 | { |
|
241 | global $txt; |
||
242 | 2 | ||
243 | $config_vars = array( |
||
244 | // Basic stuff, titles, permissions... |
||
245 | 2 | array('check', 'allow_guestAccess'), |
|
246 | 2 | array('check', 'enable_buddylist'), |
|
247 | array('check', 'allow_editDisplayName'), |
||
248 | array('check', 'allow_hideOnline'), |
||
249 | array('check', 'titlesEnable'), |
||
250 | 2 | '', |
|
251 | // Javascript and CSS options |
||
252 | array('select', 'jquery_source', array('auto' => $txt['jquery_auto'], 'local' => $txt['jquery_local'], 'cdn' => $txt['jquery_cdn'])), |
||
253 | array('check', 'minify_css_js', 'postinput' => '<a href="#" id="clean_hives" class="linkbutton">' . $txt['clean_hives'] . '</a>'), |
||
254 | 2 | '', |
|
255 | // Number formatting, timezones. |
||
256 | array('text', 'time_format'), |
||
257 | array('float', 'time_offset', 'subtext' => $txt['setting_time_offset_note'], 6, 'postinput' => $txt['hours']), |
||
258 | 2 | 'default_timezone' => array('select', 'default_timezone', array()), |
|
259 | 2 | '', |
|
260 | // Who's online? |
||
261 | array('check', 'who_enabled'), |
||
262 | array('int', 'lastActive', 6, 'postinput' => $txt['minutes']), |
||
263 | '', |
||
264 | // Statistics. |
||
265 | array('check', 'trackStats'), |
||
266 | 2 | array('check', 'hitStats'), |
|
267 | '', |
||
268 | 2 | // Option-ish things... miscellaneous sorta. |
|
269 | array('check', 'metadata_enabled'), |
||
270 | array('check', 'allow_disableAnnounce'), |
||
271 | array('check', 'disallow_sendBody'), |
||
272 | 2 | array('select', 'enable_contactform', array('disabled' => $txt['contact_form_disabled'], 'registration' => $txt['contact_form_registration'], 'menu' => $txt['contact_form_menu'])), |
|
273 | ); |
||
274 | 2 | ||
275 | // Get all the time zones. |
||
276 | $all_zones = DateTimeZone::listIdentifiers(); |
||
277 | if (empty($all_zones)) |
||
278 | { |
||
279 | unset($config_vars['default_timezone']); |
||
280 | } |
||
281 | else |
||
282 | { |
||
283 | // Make sure we set the value to the same as the printed value. |
||
284 | foreach ($all_zones as $zone) |
||
285 | { |
||
286 | $config_vars['default_timezone'][2][$zone] = $zone; |
||
287 | } |
||
288 | } |
||
289 | |||
290 | theme()->addInlineJavascript(' |
||
291 | document.getElementById("clean_hives").addEventListener("click", function(event) {return cleanHives(event);});', ['defer' => true]); |
||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||
292 | |||
293 | call_integration_hook('integrate_modify_basic_settings', array(&$config_vars)); |
||
294 | |||
295 | return $config_vars; |
||
296 | } |
||
297 | |||
298 | /** |
||
299 | * Allows modifying the global layout settings in the forum |
||
300 | * |
||
301 | * - Accessed through ?action=admin;area=featuresettings;sa=layout; |
||
302 | * |
||
303 | * @event integrate_save_layout_settings |
||
304 | */ |
||
305 | public function action_layoutSettings_display() |
||
306 | { |
||
307 | global $txt, $context, $modSettings; |
||
308 | |||
309 | // Initialize the form |
||
310 | $settingsForm = new SettingsForm(SettingsForm::DB_ADAPTER); |
||
311 | |||
312 | // Initialize it with our settings |
||
313 | $settingsForm->setConfigVars($this->_layoutSettings()); |
||
314 | |||
315 | // Saving? |
||
316 | if (isset($this->_req->query->save)) |
||
317 | { |
||
318 | // Setting a custom frontpage, set the hook to the FrontpageInterface of the controller |
||
319 | if (!empty($this->_req->post->front_page)) |
||
320 | { |
||
321 | // Addons may have left this blank |
||
322 | $modSettings['front_page'] = empty($modSettings['front_page']) ? 'MessageIndex_Controller' : $modSettings['front_page']; |
||
323 | |||
324 | $front_page = (string) $this->_req->post->front_page; |
||
325 | if ( |
||
326 | class_exists($modSettings['front_page']) |
||
327 | && in_array('validateFrontPageOptions', get_class_methods($modSettings['front_page'])) |
||
328 | && !$front_page::validateFrontPageOptions($this->_req->post) |
||
329 | ) |
||
330 | 2 | { |
|
331 | $this->_req->post->front_page = ''; |
||
332 | 2 | } |
|
333 | } |
||
334 | 2 | ||
335 | 2 | checkSession(); |
|
336 | |||
337 | call_integration_hook('integrate_save_layout_settings'); |
||
338 | 2 | ||
339 | $settingsForm->setConfigValues((array) $this->_req->post); |
||
340 | $settingsForm->save(); |
||
341 | 2 | writeLog(); |
|
342 | |||
343 | 2 | redirectexit('action=admin;area=featuresettings;sa=layout'); |
|
344 | } |
||
345 | |||
346 | 2 | $context['post_url'] = getUrl('admin', ['action' => 'admin', 'area' => 'featuresettings', 'sa' => 'layout', 'save']); |
|
347 | $context['settings_title'] = $txt['mods_cat_layout']; |
||
348 | 2 | ||
349 | 2 | $settingsForm->prepare(); |
|
350 | 2 | } |
|
351 | |||
352 | /** |
||
353 | * Return layout settings. |
||
354 | * |
||
355 | 2 | * @event integrate_modify_layout_settings Adds options to Configuration->Layout |
|
356 | */ |
||
357 | 2 | private function _layoutSettings() |
|
358 | { |
||
359 | global $txt; |
||
360 | |||
361 | $config_vars = array_merge(getFrontPageControllers(), array( |
||
362 | '', |
||
363 | // Pagination stuff. |
||
364 | array('check', 'compactTopicPagesEnable'), |
||
365 | array('int', 'compactTopicPagesContiguous', 'subtext' => str_replace(' ', ' ', '"3" ' . $txt['to_display'] . ': <strong>1 ... 4 [5] 6 ... 9</strong>') . '<br />' . str_replace(' ', ' ', '"5" ' . $txt['to_display'] . ': <strong>1 ... 3 4 [5] 6 7 ... 9</strong>')), |
||
366 | array('int', 'defaultMaxMembers'), |
||
367 | array('check', 'displayMemberNames'), |
||
368 | '', |
||
369 | // Stuff that just is everywhere - today, search, online, etc. |
||
370 | array('select', 'todayMod', array($txt['today_disabled'], $txt['today_only'], $txt['yesterday_today'], $txt['relative_time'])), |
||
371 | array('check', 'onlineEnable'), |
||
372 | array('check', 'enableVBStyleLogin'), |
||
373 | '', |
||
374 | // Automagic image resizing. |
||
375 | array('int', 'max_image_width', 'subtext' => $txt['zero_for_no_limit']), |
||
376 | array('int', 'max_image_height', 'subtext' => $txt['zero_for_no_limit']), |
||
377 | '', |
||
378 | // This is like debugging sorta. |
||
379 | array('check', 'timeLoadPageEnable'), |
||
380 | )); |
||
381 | |||
382 | call_integration_hook('integrate_modify_layout_settings', array(&$config_vars)); |
||
383 | |||
384 | return $config_vars; |
||
385 | } |
||
386 | |||
387 | /** |
||
388 | * Display configuration settings page for progressive web application settings. |
||
389 | * |
||
390 | * - Accessed from ?action=admin;area=featuresettings;sa=pwa; |
||
391 | * |
||
392 | * @event integrate_save_pwa_settings |
||
393 | */ |
||
394 | public function action_pwaSettings_display() |
||
395 | { |
||
396 | global $txt, $context; |
||
397 | |||
398 | // Initialize the form |
||
399 | $settingsForm = new SettingsForm(SettingsForm::DB_ADAPTER); |
||
400 | 2 | ||
401 | // Initialize it with our settings |
||
402 | 2 | $settingsForm->setConfigVars($this->_pwaSettings()); |
|
403 | |||
404 | // Saving, lots of checks then |
||
405 | if (isset($this->_req->query->save)) |
||
406 | 2 | { |
|
407 | 2 | checkSession(); |
|
408 | |||
409 | 2 | call_integration_hook('integrate_save_pwa_settings'); |
|
410 | 2 | ||
411 | // Don't allow it to be enabled if we don't have SSL |
||
412 | $canUse = detectServer()->supportsSSL(); |
||
413 | 2 | if (!$canUse) |
|
414 | { |
||
415 | $this->_req->post->pwa_enabled = 0; |
||
416 | } |
||
417 | |||
418 | // And you must enable this if PWA is enabled |
||
419 | if ($this->_req->getPost('pwa_enabled', 'intval') === 1) |
||
420 | 2 | { |
|
421 | $this->_req->post->pwa_manifest_enabled = 1; |
||
422 | 2 | } |
|
423 | |||
424 | $validator = new DataValidator(); |
||
425 | $validation_rules = [ |
||
426 | 'pwa_theme_color' => 'valid_color', |
||
427 | 'pwa_background_color' => 'valid_color', |
||
428 | 'pwa_short_name' => 'max_length[12]' |
||
429 | ]; |
||
430 | |||
431 | // Only check the rest if they entered something. |
||
432 | $valid_urls = ['pwa_small_icon', 'pwa_large_icon', 'favicon_icon', 'apple_touch_icon']; |
||
433 | foreach ($valid_urls as $url) |
||
434 | { |
||
435 | if ($this->_req->getPost($url, 'trim') !== '') |
||
436 | { |
||
437 | $validation_rules[$url] = 'valid_url'; |
||
438 | } |
||
439 | } |
||
440 | $validator->validation_rules($validation_rules); |
||
441 | |||
442 | if (!$validator->validate($this->_req->post)) |
||
443 | { |
||
444 | // Some input error, lets tell them what is wrong |
||
445 | $context['error_type'] = 'minor'; |
||
446 | $context['settings_message'] = []; |
||
447 | foreach ($validator->validation_errors() as $error) |
||
448 | { |
||
449 | $context['settings_message'][] = $error; |
||
450 | } |
||
451 | } |
||
452 | else |
||
453 | { |
||
454 | $settingsForm->setConfigValues((array) $this->_req->post); |
||
455 | $settingsForm->save(); |
||
456 | redirectexit('action=admin;area=featuresettings;sa=pwa'); |
||
457 | } |
||
458 | } |
||
459 | |||
460 | $context['post_url'] = getUrl('admin', ['action' => 'admin', 'area' => 'featuresettings', 'sa' => 'pwa', 'save']); |
||
461 | $context['settings_title'] = $txt['pwa_settings']; |
||
462 | theme()->addInlineJavascript(' |
||
463 | pwaPreview("pwa_small_icon"); |
||
464 | pwaPreview("pwa_large_icon"); |
||
465 | 2 | pwaPreview("favicon_icon"); |
|
466 | pwaPreview("apple_touch_icon");', true); |
||
467 | 2 | ||
468 | $settingsForm->prepare(); |
||
469 | } |
||
470 | |||
471 | 2 | /** |
|
472 | 2 | * Return PWA settings. |
|
473 | * |
||
474 | 2 | * @event integrate_modify_karma_settings Adds to Configuration->Pwa |
|
475 | 2 | */ |
|
476 | private function _pwaSettings() |
||
477 | { |
||
478 | global $txt; |
||
479 | 2 | ||
480 | // PWA requires SSL |
||
481 | $canUse = detectServer()->supportsSSL(); |
||
482 | |||
483 | 2 | $config_vars = array( |
|
484 | // PWA - On or off? |
||
485 | 2 | array('check', 'pwa_enabled', 'disabled' => !$canUse, 'invalid' => !$canUse, 'postinput' => !$canUse ? $txt['pwa_disabled'] : ''), |
|
486 | '', |
||
487 | array('check', 'pwa_manifest_enabled', 'helptext' => $txt['pwa_manifest_enabled_desc']), |
||
488 | array('text', 'pwa_short_name', 12, 'mask' => 'nohtml', 'helptext' => $txt['pwa_short_name_desc'], 'maxlength' => 12), |
||
489 | array('color', 'pwa_theme_color', 'helptext' => $txt['pwa_theme_color_desc']), |
||
490 | array('color', 'pwa_background_color', 'helptext' => $txt['pwa_background_color_desc']), |
||
491 | '', |
||
492 | array('url', 'pwa_small_icon', 'size' => 40, 'helptext' => $txt['pwa_small_icon_desc'], 'onchange' => "pwaPreview('pwa_small_icon');"), |
||
493 | array('url', 'pwa_large_icon', 'size' => 40, 'helptext' => $txt['pwa_large_icon_desc'], 'onchange' => "pwaPreview('pwa_large_icon');"), |
||
494 | array('title', 'other_icons_title'), |
||
495 | array('url', 'favicon_icon', 'size' => 40, 'helptext' => $txt['favicon_icon_desc'], 'onchange' => "pwaPreview('favicon_icon');"), |
||
496 | array('url', 'apple_touch_icon', 'size' => 40, 'helptext' => $txt['apple_touch_icon_desc'], 'onchange' => "pwaPreview('apple_touch_icon');"), |
||
497 | ); |
||
498 | |||
499 | call_integration_hook('integrate_modify_pwa_settings', array(&$config_vars)); |
||
500 | |||
501 | return $config_vars; |
||
502 | } |
||
503 | |||
504 | /** |
||
505 | * Display configuration settings page for karma settings. |
||
506 | * |
||
507 | * - Accessed from ?action=admin;area=featuresettings;sa=karma; |
||
508 | * |
||
509 | * @event integrate_save_karma_settings |
||
510 | */ |
||
511 | public function action_karmaSettings_display() |
||
512 | { |
||
513 | global $txt, $context; |
||
514 | |||
515 | // Initialize the form |
||
516 | $settingsForm = new SettingsForm(SettingsForm::DB_ADAPTER); |
||
517 | |||
518 | // Initialize it with our settings |
||
519 | $settingsForm->setConfigVars($this->_karmaSettings()); |
||
520 | |||
521 | // Saving? |
||
522 | if (isset($this->_req->query->save)) |
||
523 | { |
||
524 | checkSession(); |
||
525 | |||
526 | call_integration_hook('integrate_save_karma_settings'); |
||
527 | |||
528 | $settingsForm->setConfigValues((array) $this->_req->post); |
||
529 | $settingsForm->save(); |
||
530 | redirectexit('action=admin;area=featuresettings;sa=karma'); |
||
531 | } |
||
532 | |||
533 | $context['post_url'] = getUrl('admin', ['action' => 'admin', 'area' => 'featuresettings', 'sa' => 'karma', 'save']); |
||
534 | $context['settings_title'] = $txt['karma']; |
||
535 | |||
536 | $settingsForm->prepare(); |
||
537 | } |
||
538 | |||
539 | /** |
||
540 | * Return karma settings. |
||
541 | * |
||
542 | * @event integrate_modify_karma_settings Adds to Configuration->Karma |
||
543 | */ |
||
544 | private function _karmaSettings() |
||
545 | { |
||
546 | global $txt; |
||
547 | |||
548 | $config_vars = array( |
||
549 | // Karma - On or off? |
||
550 | array('select', 'karmaMode', explode('|', $txt['karma_options'])), |
||
551 | '', |
||
552 | // Who can do it.... and who is restricted by time limits? |
||
553 | array('int', 'karmaMinPosts', 6, 'postinput' => $txt['manageposts_posts']), |
||
554 | array('float', 'karmaWaitTime', 6, 'postinput' => $txt['hours']), |
||
555 | array('check', 'karmaTimeRestrictAdmins'), |
||
556 | array('check', 'karmaDisableSmite'), |
||
557 | '', |
||
558 | // What does it look like? [smite]? |
||
559 | array('text', 'karmaLabel'), |
||
560 | array('text', 'karmaApplaudLabel', 'mask' => 'nohtml'), |
||
561 | array('text', 'karmaSmiteLabel', 'mask' => 'nohtml'), |
||
562 | ); |
||
563 | |||
564 | call_integration_hook('integrate_modify_karma_settings', array(&$config_vars)); |
||
565 | |||
566 | return $config_vars; |
||
567 | } |
||
568 | |||
569 | /** |
||
570 | * Display configuration settings page for likes settings. |
||
571 | * |
||
572 | * - Accessed from ?action=admin;area=featuresettings;sa=likes; |
||
573 | * |
||
574 | * @event integrate_save_likes_settings |
||
575 | */ |
||
576 | public function action_likesSettings_display() |
||
577 | { |
||
578 | global $txt, $context; |
||
579 | |||
580 | // Initialize the form |
||
581 | $settingsForm = new SettingsForm(SettingsForm::DB_ADAPTER); |
||
582 | |||
583 | // Initialize it with our settings |
||
584 | $settingsForm->setConfigVars($this->_likesSettings()); |
||
585 | |||
586 | // Saving? |
||
587 | if (isset($this->_req->query->save)) |
||
588 | { |
||
589 | checkSession(); |
||
590 | |||
591 | call_integration_hook('integrate_save_likes_settings'); |
||
592 | |||
593 | $settingsForm->setConfigValues((array) $this->_req->post); |
||
594 | $settingsForm->save(); |
||
595 | redirectexit('action=admin;area=featuresettings;sa=likes'); |
||
596 | } |
||
597 | |||
598 | $context['post_url'] = getUrl('admin', ['action' => 'admin', 'area' => 'featuresettings', 'sa' => 'likes', 'save']); |
||
599 | $context['settings_title'] = $txt['likes']; |
||
600 | |||
601 | $settingsForm->prepare(); |
||
602 | } |
||
603 | |||
604 | /** |
||
605 | 2 | * Return likes settings. |
|
606 | * |
||
607 | 2 | * @event integrate_modify_likes_settings Adds to Configuration->Likes |
|
608 | */ |
||
609 | 2 | private function _likesSettings() |
|
610 | 2 | { |
|
611 | global $txt; |
||
612 | |||
613 | $config_vars = array( |
||
614 | 2 | // Likes - On or off? |
|
615 | array('check', 'likes_enabled'), |
||
616 | '', |
||
617 | // Who can do it.... and who is restricted by count limits? |
||
618 | 2 | array('int', 'likeMinPosts', 6, 'postinput' => $txt['manageposts_posts']), |
|
619 | 2 | array('int', 'likeWaitTime', 6, 'postinput' => $txt['minutes']), |
|
620 | 2 | array('int', 'likeWaitCount', 6), |
|
621 | array('check', 'likeRestrictAdmins'), |
||
622 | 2 | array('check', 'likeAllowSelf'), |
|
623 | array('check', 'useLikesNotViews'), |
||
624 | '', |
||
625 | array('int', 'likeDisplayLimit', 6) |
||
626 | ); |
||
627 | |||
628 | call_integration_hook('integrate_modify_likes_settings', array(&$config_vars)); |
||
629 | |||
630 | return $config_vars; |
||
631 | } |
||
632 | |||
633 | /** |
||
634 | * Initializes the mentions settings admin page. |
||
635 | 2 | * |
|
636 | * - Accessed from ?action=admin;area=featuresettings;sa=mention; |
||
637 | 2 | * |
|
638 | * @event integrate_save_modify_mention_settings |
||
639 | */ |
||
640 | public function action_notificationsSettings_display() |
||
641 | { |
||
642 | global $txt, $context, $modSettings; |
||
643 | |||
644 | Txt::load('Mentions'); |
||
645 | |||
646 | // Instantiate the form |
||
647 | $settingsForm = new SettingsForm(SettingsForm::DB_ADAPTER); |
||
648 | |||
649 | // Initialize it with our settings |
||
650 | $settingsForm->setConfigVars($this->_notificationsSettings()); |
||
651 | |||
652 | // Some context stuff |
||
653 | $context['page_title'] = $txt['mentions_settings']; |
||
654 | $context['sub_template'] = 'show_settings'; |
||
655 | |||
656 | // Saving the settings? |
||
657 | if (isset($this->_req->query->save)) |
||
658 | { |
||
659 | checkSession(); |
||
660 | |||
661 | call_integration_hook('integrate_save_modify_mention_settings'); |
||
662 | |||
663 | if (!empty($this->_req->post->mentions_enabled)) |
||
664 | { |
||
665 | enableModules('mentions', array('post', 'display')); |
||
666 | } |
||
667 | else |
||
668 | { |
||
669 | disableModules('mentions', array('post', 'display')); |
||
670 | } |
||
671 | |||
672 | if (!empty($modSettings['hidden_notification_methods'])) |
||
673 | { |
||
674 | foreach ($modSettings['hidden_notification_methods'] as $class) |
||
675 | { |
||
676 | $this->_req->post->notifications[$class::getType()] = $class::getSettings(); |
||
677 | } |
||
678 | } |
||
679 | |||
680 | if (empty($this->_req->post->notifications)) |
||
681 | { |
||
682 | $notification_methods = serialize(array()); |
||
683 | } |
||
684 | else |
||
685 | { |
||
686 | $notification_methods = []; |
||
687 | foreach ($this->_req->post->notifications as $type => $notification) |
||
688 | { |
||
689 | if (!empty($notification['enable'])) |
||
690 | { |
||
691 | $defaults = $notification['default'] ?? []; |
||
692 | unset($notification['enable'], $notification['default']); |
||
693 | foreach ($notification as $k => $v) |
||
694 | { |
||
695 | $notification[$k] = in_array($k, $defaults) ? Notifications::DEFAULT_LEVEL : $v; |
||
696 | } |
||
697 | |||
698 | $notification_methods[$type] = $notification; |
||
699 | } |
||
700 | } |
||
701 | |||
702 | $notification_methods = serialize($notification_methods); |
||
703 | } |
||
704 | |||
705 | require_once(SUBSDIR . '/Mentions.subs.php'); |
||
706 | $enabled_mentions = array(); |
||
707 | $current_settings = Util::unserialize($modSettings['notification_methods']); |
||
708 | |||
709 | // Fist hide what was visible |
||
710 | $modules_toggle = array('enable' => array(), 'disable' => array()); |
||
711 | foreach ($current_settings as $type => $val) |
||
712 | { |
||
713 | if (!isset($this->_req->post->notifications[$type])) |
||
714 | { |
||
715 | toggleMentionsVisibility($type, false); |
||
716 | $modules_toggle['disable'][] = $type; |
||
717 | } |
||
718 | } |
||
719 | |||
720 | // Then make visible what was hidden, but only if there is anything |
||
721 | if (!empty($this->_req->post->notifications)) |
||
722 | { |
||
723 | foreach ($this->_req->post->notifications as $type => $val) |
||
724 | { |
||
725 | if (!isset($current_settings[$type])) |
||
726 | { |
||
727 | toggleMentionsVisibility($type, true); |
||
728 | $modules_toggle['enable'][] = $type; |
||
729 | } |
||
730 | } |
||
731 | |||
732 | $enabled_mentions = array_keys($this->_req->post->notifications); |
||
733 | } |
||
734 | |||
735 | // Let's just keep it active, there are too many reasons it should be. |
||
736 | require_once(SUBSDIR . '/ScheduledTasks.subs.php'); |
||
737 | toggleTaskStatusByName('user_access_mentions', true); |
||
738 | |||
739 | // Disable or enable modules as needed |
||
740 | foreach ($modules_toggle as $action => $toggles) |
||
741 | { |
||
742 | if (!empty($toggles)) |
||
743 | { |
||
744 | // The modules associated with the notification (mentionmem, likes, etc) area |
||
745 | $modules = getMentionsModules($toggles); |
||
746 | |||
747 | // The action will either be enable to disable |
||
748 | $function = $action . 'Modules'; |
||
749 | |||
750 | // Something like enableModule('mentions', array('post', 'display'); |
||
751 | foreach ($modules as $key => $val) |
||
752 | { |
||
753 | $function($key, $val); |
||
754 | } |
||
755 | } |
||
756 | } |
||
757 | |||
758 | updateSettings(array('enabled_mentions' => implode(',', array_unique($enabled_mentions)), 'notification_methods' => $notification_methods)); |
||
759 | $settingsForm->setConfigValues((array) $this->_req->post); |
||
760 | $settingsForm->save(); |
||
761 | redirectexit('action=admin;area=featuresettings;sa=mention'); |
||
762 | } |
||
763 | |||
764 | // Prepare the settings for display |
||
765 | $context['post_url'] = getUrl('admin', ['action' => 'admin', 'area' => 'featuresettings', 'sa' => 'mention', 'save']); |
||
766 | $settingsForm->prepare(); |
||
767 | } |
||
768 | |||
769 | /** |
||
770 | * Return mentions settings. |
||
771 | 2 | * |
|
772 | * @event integrate_modify_mention_settings Adds to Configuration->Mentions |
||
773 | 2 | */ |
|
774 | private function _notificationsSettings() |
||
775 | { |
||
776 | global $txt, $modSettings; |
||
777 | 2 | ||
778 | 2 | Txt::load('Profile+UserNotifications'); |
|
779 | loadJavascriptFile('ext/jquery.multiselect.min.js'); |
||
780 | 2 | theme()->addInlineJavascript(' |
|
781 | 2 | $(\'.select_multiple\').multiselect({\'language_strings\': {\'Select all\': ' . JavaScriptEscape($txt['notify_select_all']) . '}}); |
|
782 | 2 | document.addEventListener("DOMContentLoaded", function() { |
|
783 | prepareNotificationOptions(); |
||
784 | 2 | });', true); |
|
785 | 2 | loadCSSFile('multiselect.css'); |
|
786 | |||
787 | 2 | // The mentions settings |
|
788 | 2 | $config_vars = array( |
|
789 | 2 | array('title', 'mentions_settings'), |
|
790 | array('check', 'mentions_enabled'), |
||
791 | ); |
||
792 | 2 | ||
793 | $notification_methods = Notifications::instance()->getNotifiers(); |
||
794 | 2 | $notification_classes = getAvailableNotifications(); |
|
795 | 2 | $current_settings = unserialize($modSettings['notification_methods'], ['allowed_classes' => false]); |
|
796 | 2 | ||
797 | foreach ($notification_classes as $class) |
||
798 | { |
||
799 | 2 | // The canUse can be set by each notifier based on conditions, default is true; |
|
800 | /* @var $class AbstractNotificationMessage */ |
||
801 | 2 | if ($class::canUse() === false) |
|
802 | 2 | { |
|
803 | 2 | continue; |
|
804 | 2 | } |
|
805 | |||
806 | if ($class::hasHiddenInterface() === true) |
||
807 | { |
||
808 | 2 | $modSettings['hidden_notification_methods'][] = $class; |
|
809 | continue; |
||
810 | 2 | } |
|
811 | |||
812 | // Set up config enable/disable setting for all notifications. |
||
813 | $title = strtolower($class::getType()); |
||
814 | $config_vars[] = array('title', 'setting_' . $title); |
||
815 | $config_vars[] = array('check', 'notifications[' . $title . '][enable]', 'text_label' => $txt['setting_notify_enable_this']); |
||
816 | $modSettings['notifications[' . $title . '][enable]'] = !empty($current_settings[$title]); |
||
817 | $default_values = []; |
||
818 | $is_default = []; |
||
819 | |||
820 | // If its enabled, show all the available ways, like email, notify, weekly ... |
||
821 | foreach (array_keys($notification_methods) as $method_name) |
||
822 | { |
||
823 | $method_name = strtolower($method_name); |
||
824 | |||
825 | // Are they excluding any, like don't let mailfail be allowed to send email ! |
||
826 | if ($class::isNotAllowed($method_name)) |
||
827 | { |
||
828 | continue; |
||
829 | } |
||
830 | |||
831 | $config_vars[] = array('check', 'notifications[' . $title . '][' . $method_name . ']', 'text_label' => $txt['notify_' . $method_name]); |
||
832 | $modSettings['notifications[' . $title . '][' . $method_name . ']'] = !empty($current_settings[$title][$method_name]); |
||
833 | $default_values[] = [$method_name, $txt['notify_' . $method_name]]; |
||
834 | if (empty($current_settings[$title][$method_name])) |
||
835 | { |
||
836 | continue; |
||
837 | } |
||
838 | |||
839 | if ((int) $current_settings[$title][$method_name] !== Notifications::DEFAULT_LEVEL) |
||
840 | { |
||
841 | continue; |
||
842 | } |
||
843 | |||
844 | $is_default[] = $method_name; |
||
845 | } |
||
846 | |||
847 | $config_vars[] = array('select', 'notifications[' . $title . '][default]', $default_values, 'text_label' => $txt['default_active'], 'multiple' => true, 'value' => $is_default); |
||
848 | $modSettings['notifications[' . $title . '][default]'] = $is_default; |
||
849 | } |
||
850 | |||
851 | call_integration_hook('integrate_modify_mention_settings', array(&$config_vars)); |
||
852 | |||
853 | return $config_vars; |
||
854 | } |
||
855 | |||
856 | /** |
||
857 | * Display configuration settings for signatures on forum. |
||
858 | * |
||
859 | * - Accessed from ?action=admin;area=featuresettings;sa=sig; |
||
860 | * |
||
861 | * @event integrate_save_signature_settings |
||
862 | */ |
||
863 | public function action_signatureSettings_display() |
||
864 | { |
||
865 | global $context, $txt, $modSettings; |
||
866 | |||
867 | // Initialize the form |
||
868 | $settingsForm = new SettingsForm(SettingsForm::DB_ADAPTER); |
||
869 | |||
870 | // Initialize it with our settings |
||
871 | $settingsForm->setConfigVars($this->_signatureSettings()); |
||
872 | |||
873 | // Setup the template. |
||
874 | $context['page_title'] = $txt['signature_settings']; |
||
875 | $context['sub_template'] = 'show_settings'; |
||
876 | |||
877 | // Disable the max smileys option if we don't allow smileys at all! |
||
878 | theme()->addInlineJavascript(' |
||
879 | document.getElementById(\'signature_max_smileys\').disabled = !document.getElementById(\'signature_allow_smileys\').checked;', true); |
||
880 | |||
881 | // Load all the signature settings. |
||
882 | [$sig_limits, $sig_bbc] = explode(':', $modSettings['signature_settings']); |
||
883 | $sig_limits = explode(',', $sig_limits); |
||
884 | $disabledTags = empty($sig_bbc) ? array() : explode(',', $sig_bbc); |
||
885 | |||
886 | // @todo temporary since it does not work, and seriously why would you do this? |
||
887 | $disabledTags[] = 'footnote'; |
||
888 | |||
889 | // Applying to ALL signatures?!! |
||
890 | if (isset($this->_req->query->apply)) |
||
891 | { |
||
892 | // Security! |
||
893 | checkSession('get'); |
||
894 | |||
895 | // This is horrid - but I suppose some people will want the option to do it. |
||
896 | $applied_sigs = $this->_req->getQuery('step', 'intval', 0); |
||
897 | updateAllSignatures($applied_sigs); |
||
898 | |||
899 | $settings_applied = true; |
||
900 | } |
||
901 | |||
902 | $context['signature_settings'] = array( |
||
903 | 'enable' => $sig_limits[0] ?? 0, |
||
904 | 'max_length' => $sig_limits[1] ?? 0, |
||
905 | 'max_lines' => $sig_limits[2] ?? 0, |
||
906 | 'max_images' => $sig_limits[3] ?? 0, |
||
907 | 'allow_smileys' => isset($sig_limits[4]) && $sig_limits[4] == -1 ? 0 : 1, |
||
908 | 'max_smileys' => isset($sig_limits[4]) && $sig_limits[4] != -1 ? $sig_limits[4] : 0, |
||
909 | 'max_image_width' => $sig_limits[5] ?? 0, |
||
910 | 'max_image_height' => $sig_limits[6] ?? 0, |
||
911 | 'max_font_size' => $sig_limits[7] ?? 0, |
||
912 | 'repetition_guests' => $sig_limits[8] ?? 0, |
||
913 | 'repetition_members' => $sig_limits[9] ?? 0, |
||
914 | ); |
||
915 | |||
916 | // Temporarily make each setting a modSetting! |
||
917 | foreach ($context['signature_settings'] as $key => $value) |
||
918 | { |
||
919 | $modSettings['signature_' . $key] = $value; |
||
920 | } |
||
921 | |||
922 | // Make sure we check the right tags! |
||
923 | $modSettings['bbc_disabled_signature_bbc'] = $disabledTags; |
||
924 | |||
925 | // Saving? |
||
926 | if (isset($this->_req->query->save)) |
||
927 | { |
||
928 | checkSession(); |
||
929 | |||
930 | // Clean up the tag stuff! |
||
931 | $codes = ParserWrapper::instance()->getCodes(); |
||
932 | $bbcTags = $codes->getTags(); |
||
933 | |||
934 | $signature_bbc_enabledTags = $this->_req->getPost('signature_bbc_enabledTags', null, []); |
||
935 | if (!is_array($signature_bbc_enabledTags)) |
||
936 | { |
||
937 | $signature_bbc_enabledTags = array($signature_bbc_enabledTags); |
||
938 | } |
||
939 | |||
940 | $this->_req->post->signature_bbc_enabledTags = $signature_bbc_enabledTags; |
||
941 | |||
942 | $sig_limits = array(); |
||
943 | foreach (array_keys($context['signature_settings']) as $key) |
||
944 | { |
||
945 | if ($key === 'allow_smileys') |
||
946 | { |
||
947 | continue; |
||
948 | } |
||
949 | if ($key === 'max_smileys' && empty($this->_req->post->signature_allow_smileys)) |
||
950 | { |
||
951 | $sig_limits[] = -1; |
||
952 | } |
||
953 | else |
||
954 | { |
||
955 | $current_key = $this->_req->getPost('signature_' . $key, 'intval'); |
||
956 | $sig_limits[] = empty($current_key) ? 0 : max(1, $current_key); |
||
957 | } |
||
958 | } |
||
959 | |||
960 | call_integration_hook('integrate_save_signature_settings', array(&$sig_limits, &$bbcTags)); |
||
961 | |||
962 | $this->_req->post->signature_settings = implode(',', $sig_limits) . ':' . implode(',', array_diff($bbcTags, $this->_req->post->signature_bbc_enabledTags)); |
||
963 | |||
964 | // Even though we have practically no settings let's keep the convention going! |
||
965 | $save_vars = array(); |
||
966 | $save_vars[] = array('text', 'signature_settings'); |
||
967 | |||
968 | $settingsForm->setConfigVars($save_vars); |
||
969 | $settingsForm->setConfigValues((array) $this->_req->post); |
||
970 | $settingsForm->save(); |
||
971 | redirectexit('action=admin;area=featuresettings;sa=sig'); |
||
972 | } |
||
973 | |||
974 | $context['post_url'] = getUrl('admin', ['action' => 'admin', 'area' => 'featuresettings', 'sa' => 'sig', 'save']); |
||
975 | $context['settings_title'] = $txt['signature_settings']; |
||
976 | $context['settings_message'] = empty($settings_applied) ? sprintf($txt['signature_settings_warning'], getUrl('admin', ['action' => 'admin', 'area' => 'featuresettings', 'sa' => 'sig', 'apply', '{session_data}'])) : $txt['signature_settings_applied']; |
||
977 | |||
978 | $settingsForm->prepare(); |
||
979 | } |
||
980 | |||
981 | /** |
||
982 | * Return signature settings. |
||
983 | * |
||
984 | * - Used in admin center search and settings form |
||
985 | * |
||
986 | * @event integrate_modify_signature_settings Adds options to Signature Settings |
||
987 | */ |
||
988 | private function _signatureSettings() |
||
989 | { |
||
990 | global $txt; |
||
991 | |||
992 | $config_vars = array( |
||
993 | // Are signatures even enabled? |
||
994 | array('check', 'signature_enable'), |
||
995 | '', |
||
996 | // Tweaking settings! |
||
997 | array('int', 'signature_max_length', 'subtext' => $txt['zero_for_no_limit']), |
||
998 | array('int', 'signature_max_lines', 'subtext' => $txt['zero_for_no_limit']), |
||
999 | array('int', 'signature_max_font_size', 'subtext' => $txt['zero_for_no_limit']), |
||
1000 | array('check', 'signature_allow_smileys', 'onclick' => "document.getElementById('signature_max_smileys').disabled = !this.checked;"), |
||
1001 | array('int', 'signature_max_smileys', 'subtext' => $txt['zero_for_no_limit']), |
||
1002 | array('select', 'signature_repetition_guests', |
||
1003 | array( |
||
1004 | $txt['signature_always'], |
||
1005 | $txt['signature_onlyfirst'], |
||
1006 | $txt['signature_never'], |
||
1007 | ), |
||
1008 | ), |
||
1009 | array('select', 'signature_repetition_members', |
||
1010 | array( |
||
1011 | $txt['signature_always'], |
||
1012 | $txt['signature_onlyfirst'], |
||
1013 | $txt['signature_never'], |
||
1014 | ), |
||
1015 | ), |
||
1016 | '', |
||
1017 | // Image settings. |
||
1018 | array('int', 'signature_max_images', 'subtext' => $txt['signature_max_images_note']), |
||
1019 | array('int', 'signature_max_image_width', 'subtext' => $txt['zero_for_no_limit']), |
||
1020 | array('int', 'signature_max_image_height', 'subtext' => $txt['zero_for_no_limit']), |
||
1021 | '', |
||
1022 | array('bbc', 'signature_bbc'), |
||
1023 | ); |
||
1024 | |||
1025 | call_integration_hook('integrate_modify_signature_settings', array(&$config_vars)); |
||
1026 | |||
1027 | return $config_vars; |
||
1028 | } |
||
1029 | |||
1030 | /** |
||
1031 | * Show all the custom profile fields available to the user. |
||
1032 | * |
||
1033 | * - Allows for drag/drop sorting of custom profile fields |
||
1034 | * - Accessed with ?action=admin;area=featuresettings;sa=profile |
||
1035 | * |
||
1036 | * @uses sub template show_custom_profile |
||
1037 | */ |
||
1038 | public function action_profile() |
||
1039 | { |
||
1040 | global $txt, $context; |
||
1041 | |||
1042 | theme()->getTemplates()->load('ManageFeatures'); |
||
1043 | $context['page_title'] = $txt['custom_profile_title']; |
||
1044 | $context['sub_template'] = 'show_custom_profile'; |
||
1045 | |||
1046 | // What about standard fields they can tweak? |
||
1047 | $standard_fields = array('website', 'posts', 'warning_status', 'date_registered', 'action'); |
||
1048 | |||
1049 | // What fields can't you put on the registration page? |
||
1050 | $context['fields_no_registration'] = array('posts', 'warning_status', 'date_registered', 'action'); |
||
1051 | |||
1052 | // Are we saving any standard field changes? |
||
1053 | if (isset($this->_req->post->save)) |
||
1054 | { |
||
1055 | checkSession(); |
||
1056 | validateToken('admin-scp'); |
||
1057 | |||
1058 | $changes = array(); |
||
1059 | |||
1060 | // Do the active ones first. |
||
1061 | $disable_fields = array_flip($standard_fields); |
||
1062 | if (!empty($this->_req->post->active)) |
||
1063 | { |
||
1064 | foreach ($this->_req->post->active as $value) |
||
1065 | { |
||
1066 | if (isset($disable_fields[$value])) |
||
1067 | { |
||
1068 | unset($disable_fields[$value]); |
||
1069 | } |
||
1070 | } |
||
1071 | } |
||
1072 | |||
1073 | // What we have left! |
||
1074 | $changes['disabled_profile_fields'] = empty($disable_fields) ? '' : implode(',', array_keys($disable_fields)); |
||
1075 | |||
1076 | // Things we want to show on registration? |
||
1077 | $reg_fields = array(); |
||
1078 | if (!empty($this->_req->post->reg)) |
||
1079 | { |
||
1080 | foreach ($this->_req->post->reg as $value) |
||
1081 | { |
||
1082 | if (!in_array($value, $standard_fields)) |
||
1083 | { |
||
1084 | continue; |
||
1085 | } |
||
1086 | |||
1087 | if (isset($disable_fields[$value])) |
||
1088 | { |
||
1089 | continue; |
||
1090 | } |
||
1091 | |||
1092 | $reg_fields[] = $value; |
||
1093 | } |
||
1094 | } |
||
1095 | |||
1096 | // What we have left! |
||
1097 | $changes['registration_fields'] = empty($reg_fields) ? '' : implode(',', $reg_fields); |
||
1098 | |||
1099 | updateSettings($changes); |
||
1100 | } |
||
1101 | |||
1102 | createToken('admin-scp'); |
||
1103 | |||
1104 | // Create a listing for all our standard fields |
||
1105 | $listOptions = array( |
||
1106 | 'id' => 'standard_profile_fields', |
||
1107 | 'title' => $txt['standard_profile_title'], |
||
1108 | 'base_href' => getUrl('admin', ['action' => 'admin', 'area' => 'featuresettings', 'sa' => 'profile']), |
||
1109 | 'get_items' => array( |
||
1110 | 'function' => 'list_getProfileFields', |
||
1111 | 'params' => array( |
||
1112 | true, |
||
1113 | ), |
||
1114 | ), |
||
1115 | 'columns' => array( |
||
1116 | 'field' => array( |
||
1117 | 'header' => array( |
||
1118 | 'value' => $txt['standard_profile_field'], |
||
1119 | ), |
||
1120 | 'data' => array( |
||
1121 | 'db' => 'label', |
||
1122 | 'style' => 'width: 60%;', |
||
1123 | ), |
||
1124 | ), |
||
1125 | 'active' => array( |
||
1126 | 'header' => array( |
||
1127 | 'value' => $txt['custom_edit_active'], |
||
1128 | 'class' => 'centertext', |
||
1129 | ), |
||
1130 | 'data' => array( |
||
1131 | 'function' => static function ($rowData) { |
||
1132 | $isChecked = $rowData['disabled'] ? '' : ' checked="checked"'; |
||
1133 | $onClickHandler = $rowData['can_show_register'] ? sprintf('onclick="document.getElementById(\'reg_%1$s\').disabled = !this.checked;"', $rowData['id']) : ''; |
||
1134 | |||
1135 | return sprintf('<input type="checkbox" name="active[]" id="active_%1$s" value="%1$s" class="input_check" %2$s %3$s />', $rowData['id'], $isChecked, $onClickHandler); |
||
1136 | }, |
||
1137 | 'style' => 'width: 20%;', |
||
1138 | 'class' => 'centertext', |
||
1139 | ), |
||
1140 | ), |
||
1141 | 'show_on_registration' => array( |
||
1142 | 'header' => array( |
||
1143 | 'value' => $txt['custom_edit_registration'], |
||
1144 | 'class' => 'centertext', |
||
1145 | ), |
||
1146 | 'data' => array( |
||
1147 | 'function' => static function ($rowData) { |
||
1148 | $isChecked = $rowData['on_register'] && !$rowData['disabled'] ? ' checked="checked"' : ''; |
||
1149 | $isDisabled = $rowData['can_show_register'] ? '' : ' disabled="disabled"'; |
||
1150 | |||
1151 | return sprintf('<input type="checkbox" name="reg[]" id="reg_%1$s" value="%1$s" class="input_check" %2$s %3$s />', $rowData['id'], $isChecked, $isDisabled); |
||
1152 | }, |
||
1153 | 'style' => 'width: 20%;', |
||
1154 | 'class' => 'centertext', |
||
1155 | ), |
||
1156 | ), |
||
1157 | ), |
||
1158 | 'form' => array( |
||
1159 | 'href' => getUrl('admin', ['action' => 'admin', 'area' => 'featuresettings', 'sa' => 'profile']), |
||
1160 | 'name' => 'standardProfileFields', |
||
1161 | 'token' => 'admin-scp', |
||
1162 | ), |
||
1163 | 'additional_rows' => array( |
||
1164 | array( |
||
1165 | 'position' => 'below_table_data', |
||
1166 | 'value' => '<input type="submit" name="save" value="' . $txt['save'] . '" class="right_submit" />', |
||
1167 | ), |
||
1168 | ), |
||
1169 | ); |
||
1170 | createList($listOptions); |
||
1171 | |||
1172 | // And now we do the same for all of our custom ones |
||
1173 | $token = createToken('admin-sort'); |
||
1174 | $listOptions = array( |
||
1175 | 'id' => 'custom_profile_fields', |
||
1176 | 'title' => $txt['custom_profile_title'], |
||
1177 | 'base_href' => getUrl('admin', ['action' => 'admin', 'area' => 'featuresettings', 'sa' => 'profile']), |
||
1178 | 'default_sort_col' => 'vieworder', |
||
1179 | 'no_items_label' => $txt['custom_profile_none'], |
||
1180 | 'items_per_page' => 25, |
||
1181 | 'sortable' => true, |
||
1182 | 'get_items' => array( |
||
1183 | 'function' => 'list_getProfileFields', |
||
1184 | 'params' => array( |
||
1185 | false, |
||
1186 | ), |
||
1187 | ), |
||
1188 | 'get_count' => array( |
||
1189 | 'function' => 'list_getProfileFieldSize', |
||
1190 | ), |
||
1191 | 'columns' => array( |
||
1192 | 'vieworder' => array( |
||
1193 | 'header' => array( |
||
1194 | 'value' => '', |
||
1195 | 'class' => 'hide', |
||
1196 | ), |
||
1197 | 'data' => array( |
||
1198 | 'db' => 'vieworder', |
||
1199 | 'class' => 'hide', |
||
1200 | ), |
||
1201 | 'sort' => array( |
||
1202 | 'default' => 'vieworder', |
||
1203 | ), |
||
1204 | ), |
||
1205 | 'field_name' => array( |
||
1206 | 'header' => array( |
||
1207 | 'value' => $txt['custom_profile_fieldname'], |
||
1208 | ), |
||
1209 | 'data' => array( |
||
1210 | 'function' => static fn($rowData) => sprintf('<a href="%1$s">%2$s</a><div class="smalltext">%3$s</div>', getUrl('admin', ['action' => 'admin', 'area' => 'featuresettings', 'sa' => 'profileedit', 'fid' => (int) $rowData['id_field']]), $rowData['field_name'], $rowData['field_desc']), |
||
1211 | 'style' => 'width: 65%;', |
||
1212 | ), |
||
1213 | 'sort' => array( |
||
1214 | 'default' => 'field_name', |
||
1215 | 'reverse' => 'field_name DESC', |
||
1216 | ), |
||
1217 | ), |
||
1218 | 'field_type' => array( |
||
1219 | 'header' => array( |
||
1220 | 'value' => $txt['custom_profile_fieldtype'], |
||
1221 | ), |
||
1222 | 'data' => array( |
||
1223 | 'function' => static function ($rowData) { |
||
1224 | global $txt; |
||
1225 | |||
1226 | $textKey = sprintf('custom_profile_type_%1$s', $rowData['field_type']); |
||
1227 | |||
1228 | return $txt[$textKey] ?? $textKey; |
||
1229 | }, |
||
1230 | 'style' => 'width: 10%;', |
||
1231 | ), |
||
1232 | 'sort' => array( |
||
1233 | 'default' => 'field_type', |
||
1234 | 'reverse' => 'field_type DESC', |
||
1235 | ), |
||
1236 | ), |
||
1237 | 'cust' => array( |
||
1238 | 'header' => array( |
||
1239 | 'value' => $txt['custom_profile_active'], |
||
1240 | 'class' => 'centertext', |
||
1241 | ), |
||
1242 | 'data' => array( |
||
1243 | 'function' => static function ($rowData) { |
||
1244 | $isChecked = $rowData['active'] === '1' ? ' checked="checked"' : ''; |
||
1245 | |||
1246 | return sprintf('<input type="checkbox" name="cust[]" id="cust_%1$s" value="%1$s" class="input_check"%2$s />', $rowData['id_field'], $isChecked); |
||
1247 | }, |
||
1248 | 'style' => 'width: 8%;', |
||
1249 | 'class' => 'centertext', |
||
1250 | ), |
||
1251 | 'sort' => array( |
||
1252 | 'default' => 'active DESC', |
||
1253 | 'reverse' => 'active', |
||
1254 | ), |
||
1255 | ), |
||
1256 | 'placement' => array( |
||
1257 | 'header' => array( |
||
1258 | 'value' => $txt['custom_profile_placement'], |
||
1259 | ), |
||
1260 | 'data' => array( |
||
1261 | 'function' => static function ($rowData) { |
||
1262 | global $txt; |
||
1263 | |||
1264 | $placement = 'custom_profile_placement_'; |
||
1265 | switch ((int) $rowData['placement']) |
||
1266 | { |
||
1267 | case 0: |
||
1268 | $placement .= 'standard'; |
||
1269 | break; |
||
1270 | case 1: |
||
1271 | $placement .= 'withicons'; |
||
1272 | break; |
||
1273 | case 2: |
||
1274 | $placement .= 'abovesignature'; |
||
1275 | break; |
||
1276 | case 3: |
||
1277 | $placement .= 'aboveicons'; |
||
1278 | break; |
||
1279 | } |
||
1280 | |||
1281 | return $txt[$placement]; |
||
1282 | }, |
||
1283 | 'style' => 'width: 5%;', |
||
1284 | ), |
||
1285 | 'sort' => array( |
||
1286 | 'default' => 'placement DESC', |
||
1287 | 'reverse' => 'placement', |
||
1288 | ), |
||
1289 | ), |
||
1290 | 'modify' => array( |
||
1291 | 'data' => array( |
||
1292 | 'sprintf' => array( |
||
1293 | 'format' => '<a href="' . getUrl('admin', ['action' => 'admin', 'area' => 'featuresettings', 'sa' => 'profileedit']) . ';fid=%1$s">' . $txt['modify'] . '</a>', |
||
1294 | 'params' => array( |
||
1295 | 'id_field' => false, |
||
1296 | ), |
||
1297 | ), |
||
1298 | 'style' => 'width: 5%;', |
||
1299 | ), |
||
1300 | ), |
||
1301 | ), |
||
1302 | 'form' => array( |
||
1303 | 'href' => getUrl('admin', ['action' => 'admin', 'area' => 'featuresettings', 'sa' => 'profileedit']), |
||
1304 | 'name' => 'customProfileFields', |
||
1305 | 'token' => 'admin-scp', |
||
1306 | ), |
||
1307 | 'additional_rows' => array( |
||
1308 | array( |
||
1309 | 'class' => 'submitbutton flow_flex_additional_row', |
||
1310 | 'position' => 'below_table_data', |
||
1311 | 'value' => ' |
||
1312 | <input type="submit" name="onoff" value="' . $txt['save'] . '" /> |
||
1313 | <input type="submit" name="new" value="' . $txt['custom_profile_make_new'] . '" />', |
||
1314 | ), |
||
1315 | array( |
||
1316 | 'position' => 'top_of_list', |
||
1317 | 'value' => '<p class="infobox">' . $txt['custom_profile_sort'] . '</p>', |
||
1318 | ), |
||
1319 | ), |
||
1320 | 'javascript' => ' |
||
1321 | $().elkSortable({ |
||
1322 | sa: "profileorder", |
||
1323 | error: "' . $txt['admin_order_error'] . '", |
||
1324 | title: "' . $txt['admin_order_title'] . '", |
||
1325 | placeholder: "ui-state-highlight", |
||
1326 | href: "?action=admin;area=featuresettings;sa=profile", |
||
1327 | token: {token_var: "' . $token['admin-sort_token_var'] . '", token_id: "' . $token['admin-sort_token'] . '"} |
||
1328 | }); |
||
1329 | ', |
||
1330 | ); |
||
1331 | |||
1332 | createList($listOptions); |
||
1333 | } |
||
1334 | |||
1335 | /** |
||
1336 | * Edit some profile fields? |
||
1337 | * |
||
1338 | * - Accessed with ?action=admin;area=featuresettings;sa=profileedit |
||
1339 | * |
||
1340 | * @uses sub template edit_profile_field |
||
1341 | */ |
||
1342 | public function action_profileedit() |
||
1343 | { |
||
1344 | global $txt, $context; |
||
1345 | |||
1346 | theme()->getTemplates()->load('ManageFeatures'); |
||
1347 | |||
1348 | // Sort out the context! |
||
1349 | $context['fid'] = $this->_req->getQuery('fid', 'intval', 0); |
||
1350 | $context[$context['admin_menu_name']]['current_subsection'] = 'profile'; |
||
1351 | $context['page_title'] = $context['fid'] ? $txt['custom_edit_title'] : $txt['custom_add_title']; |
||
1352 | $context['sub_template'] = 'edit_profile_field'; |
||
1353 | |||
1354 | // Any errors messages to show? |
||
1355 | if (isset($this->_req->query->msg)) |
||
1356 | { |
||
1357 | Txt::load('Errors'); |
||
1358 | |||
1359 | if (isset($txt['custom_option_' . $this->_req->query->msg])) |
||
1360 | { |
||
1361 | $context['custom_option__error'] = $txt['custom_option_' . $this->_req->query->msg]; |
||
1362 | } |
||
1363 | } |
||
1364 | |||
1365 | // Load the profile language for section names. |
||
1366 | Txt::load('Profile'); |
||
1367 | |||
1368 | // Load up the profile field, if one was supplied |
||
1369 | if ($context['fid']) |
||
1370 | { |
||
1371 | $context['field'] = getProfileField($context['fid']); |
||
1372 | } |
||
1373 | |||
1374 | // Setup the default values as needed. |
||
1375 | if (empty($context['field'])) |
||
1376 | { |
||
1377 | $context['field'] = array( |
||
1378 | 'name' => '', |
||
1379 | 'colname' => '???', |
||
1380 | 'desc' => '', |
||
1381 | 'profile_area' => 'forumprofile', |
||
1382 | 'reg' => false, |
||
1383 | 'display' => false, |
||
1384 | 'memberlist' => false, |
||
1385 | 'type' => 'text', |
||
1386 | 'max_length' => 255, |
||
1387 | 'rows' => 4, |
||
1388 | 'cols' => 30, |
||
1389 | 'bbc' => false, |
||
1390 | 'default_check' => false, |
||
1391 | 'default_select' => '', |
||
1392 | 'default_value' => '', |
||
1393 | 'options' => array('', '', ''), |
||
1394 | 'active' => true, |
||
1395 | 'private' => false, |
||
1396 | 'can_search' => false, |
||
1397 | 'mask' => 'nohtml', |
||
1398 | 'regex' => '', |
||
1399 | 'enclose' => '', |
||
1400 | 'placement' => 0, |
||
1401 | ); |
||
1402 | } |
||
1403 | |||
1404 | // All the javascript for this page... everything else is in admin.js |
||
1405 | theme()->addJavascriptVar(array('startOptID' => count($context['field']['options']))); |
||
1406 | theme()->addInlineJavascript('updateInputBoxes();', true); |
||
1407 | |||
1408 | // Are we toggling which ones are active? |
||
1409 | if (isset($this->_req->post->onoff)) |
||
1410 | { |
||
1411 | checkSession(); |
||
1412 | validateToken('admin-scp'); |
||
1413 | |||
1414 | // Enable and disable custom fields as required. |
||
1415 | $enabled = array(0); |
||
1416 | if (isset($this->_req->post->cust) && is_array($this->_req->post->cust)) |
||
1417 | { |
||
1418 | foreach ($this->_req->post->cust as $id) |
||
1419 | { |
||
1420 | $enabled[] = (int) $id; |
||
1421 | } |
||
1422 | } |
||
1423 | |||
1424 | updateRenamedProfileStatus($enabled); |
||
1425 | } |
||
1426 | // Are we saving? |
||
1427 | elseif (isset($this->_req->post->save)) |
||
1428 | { |
||
1429 | checkSession(); |
||
1430 | validateToken('admin-ecp'); |
||
1431 | |||
1432 | // Everyone needs a name - even the (bracket) unknown... |
||
1433 | if (trim($this->_req->post->field_name) === '') |
||
1434 | { |
||
1435 | redirectexit('action=admin;area=featuresettings;sa=profileedit;fid=' . $this->_req->query->fid . ';msg=need_name'); |
||
1436 | } |
||
1437 | |||
1438 | // Regex you say? Do a very basic test to see if the pattern is valid |
||
1439 | if (!empty($this->_req->post->regex) && @preg_match($this->_req->post->regex, 'dummy') === false) |
||
1440 | { |
||
1441 | redirectexit('action=admin;area=featuresettings;sa=profileedit;fid=' . $this->_req->query->fid . ';msg=regex_error'); |
||
1442 | } |
||
1443 | |||
1444 | $this->_req->post->field_name = $this->_req->getPost('field_name', '\\ElkArte\\Helper\\Util::htmlspecialchars'); |
||
1445 | $this->_req->post->field_desc = $this->_req->getPost('field_desc', '\\ElkArte\\Helper\\Util::htmlspecialchars'); |
||
1446 | |||
1447 | $rows = isset($this->_req->post->rows) ? (int) $this->_req->post->rows : 4; |
||
1448 | $cols = isset($this->_req->post->cols) ? (int) $this->_req->post->cols : 30; |
||
1449 | |||
1450 | // Checkboxes... |
||
1451 | $show_reg = $this->_req->getPost('reg', 'intval', 0); |
||
1452 | $show_display = isset($this->_req->post->display) ? 1 : 0; |
||
1453 | $show_memberlist = isset($this->_req->post->memberlist) ? 1 : 0; |
||
1454 | $bbc = isset($this->_req->post->bbc) ? 1 : 0; |
||
1455 | $show_profile = $this->_req->post->profile_area; |
||
1456 | $active = isset($this->_req->post->active) ? 1 : 0; |
||
1457 | $private = $this->_req->getPost('private', 'intval', 0); |
||
1458 | $can_search = isset($this->_req->post->can_search) ? 1 : 0; |
||
1459 | |||
1460 | // Some masking stuff... |
||
1461 | $mask = $this->_req->getPost('mask', 'strval', ''); |
||
1462 | if ($mask === 'regex' && isset($this->_req->post->regex)) |
||
1463 | { |
||
1464 | $mask .= $this->_req->post->regex; |
||
1465 | } |
||
1466 | |||
1467 | $field_length = $this->_req->getPost('max_length', 'intval', 255); |
||
1468 | $enclose = $this->_req->getPost('enclose', 'strval', ''); |
||
1469 | $placement = $this->_req->getPost('placement', 'intval', 0); |
||
1470 | |||
1471 | // Select options? |
||
1472 | $field_options = ''; |
||
1473 | $newOptions = array(); |
||
1474 | |||
1475 | // Set default |
||
1476 | $default = ''; |
||
1477 | |||
1478 | switch ($this->_req->post->field_type) |
||
1479 | { |
||
1480 | case 'check': |
||
1481 | $default = isset($this->_req->post->default_check) ? 1 : ''; |
||
1482 | break; |
||
1483 | case 'select': |
||
1484 | case 'radio': |
||
1485 | if (!empty($this->_req->post->select_option)) |
||
1486 | { |
||
1487 | foreach ($this->_req->post->select_option as $k => $v) |
||
1488 | { |
||
1489 | // Clean, clean, clean... |
||
1490 | $v = Util::htmlspecialchars($v); |
||
1491 | $v = strtr($v, array(',' => '')); |
||
1492 | |||
1493 | // Nada, zip, etc... |
||
1494 | if (trim($v) === '') |
||
1495 | { |
||
1496 | continue; |
||
1497 | } |
||
1498 | |||
1499 | // Otherwise, save it boy. |
||
1500 | $field_options .= $v . ','; |
||
1501 | |||
1502 | // This is just for working out what happened with old options... |
||
1503 | $newOptions[$k] = $v; |
||
1504 | |||
1505 | // Is it default? |
||
1506 | if (!isset($this->_req->post->default_select)) |
||
1507 | { |
||
1508 | continue; |
||
1509 | } |
||
1510 | |||
1511 | if ($this->_req->post->default_select != $k) |
||
1512 | { |
||
1513 | continue; |
||
1514 | } |
||
1515 | |||
1516 | $default = $v; |
||
1517 | } |
||
1518 | |||
1519 | if (isset($_POST['default_select']) && $_POST['default_select'] === 'no_default') |
||
1520 | { |
||
1521 | $default = 'no_default'; |
||
1522 | } |
||
1523 | |||
1524 | $field_options = substr($field_options, 0, -1); |
||
1525 | } |
||
1526 | |||
1527 | break; |
||
1528 | default: |
||
1529 | $default = $this->_req->post->default_value ?? ''; |
||
1530 | } |
||
1531 | |||
1532 | // Come up with the unique name? |
||
1533 | if (empty($context['fid'])) |
||
1534 | { |
||
1535 | $colname = Util::substr(strtr($this->_req->post->field_name, array(' ' => '')), 0, 6); |
||
1536 | preg_match('~([\w_-]+)~', $colname, $matches); |
||
1537 | |||
1538 | 2 | // If there is nothing to the name, then let's start our own - for foreign languages etc. |
|
1539 | if (isset($matches[1])) |
||
1540 | 2 | { |
|
1541 | $colname = 'cust_' . strtolower($matches[1]); |
||
1542 | $initial_colname = 'cust_' . strtolower($matches[1]); |
||
1543 | } |
||
1544 | else |
||
1545 | { |
||
1546 | 2 | $colname = 'cust_' . mt_rand(1, 999999); |
|
1547 | $initial_colname = 'cust_' . mt_rand(1, 999999); |
||
1548 | 2 | } |
|
1549 | |||
1550 | $unique = ensureUniqueProfileField($colname, $initial_colname); |
||
1551 | |||
1552 | // Still not a unique column name? Leave it up to the user, then. |
||
1553 | if (!$unique) |
||
1554 | 2 | { |
|
1555 | throw new Exception('custom_option_not_unique'); |
||
1556 | 2 | } |
|
1557 | |||
1558 | // And create a new field |
||
1559 | $new_field = array( |
||
1560 | 'col_name' => $colname, |
||
1561 | 'field_name' => $this->_req->post->field_name, |
||
1562 | 2 | 'field_desc' => $this->_req->post->field_desc, |
|
1563 | 'field_type' => $this->_req->post->field_type, |
||
1564 | 2 | 'field_length' => $field_length, |
|
1565 | 'field_options' => $field_options, |
||
1566 | 'show_reg' => $show_reg, |
||
1567 | 'show_display' => $show_display, |
||
1568 | 'show_memberlist' => $show_memberlist, |
||
1569 | 'show_profile' => $show_profile, |
||
1570 | 2 | 'private' => $private, |
|
1571 | 'active' => $active, |
||
1572 | 2 | 'default_value' => $default, |
|
1573 | 'rows' => $rows, |
||
1574 | 'cols' => $cols, |
||
1575 | 'can_search' => $can_search, |
||
1576 | 'bbc' => $bbc, |
||
1577 | 'mask' => $mask, |
||
1578 | 2 | 'enclose' => $enclose, |
|
1579 | 'placement' => $placement, |
||
1580 | 2 | 'vieworder' => list_getProfileFieldSize() + 1, |
|
1581 | ); |
||
1582 | addProfileField($new_field); |
||
1583 | } |
||
1584 | // Work out what to do with the user data otherwise... |
||
1585 | else |
||
1586 | { |
||
1587 | // Anything going to check or select is pointless keeping - as is anything coming from check! |
||
1588 | if (($this->_req->post->field_type === 'check' && $context['field']['type'] !== 'check') |
||
1589 | || (($this->_req->post->field_type === 'select' || $this->_req->post->field_type === 'radio') && $context['field']['type'] !== 'select' && $context['field']['type'] !== 'radio') |
||
1590 | || ($context['field']['type'] === 'check' && $this->_req->post->field_type !== 'check')) |
||
1591 | { |
||
1592 | deleteProfileFieldUserData($context['field']['colname']); |
||
1593 | } |
||
1594 | // Otherwise - if the select is edited may need to adjust! |
||
1595 | elseif ($this->_req->post->field_type === 'select' || $this->_req->post->field_type === 'radio') |
||
1596 | { |
||
1597 | $optionChanges = $context['field']['options']; |
||
1598 | $takenKeys = array(); |
||
1599 | |||
1600 | // Work out what's changed! |
||
1601 | foreach ($optionChanges as $k => $option) |
||
1602 | { |
||
1603 | if (trim($option) === '') |
||
1604 | { |
||
1605 | continue; |
||
1606 | } |
||
1607 | |||
1608 | // Still exists? |
||
1609 | if (in_array($option, $newOptions)) |
||
1610 | { |
||
1611 | $takenKeys[] = $k; |
||
1612 | } |
||
1613 | } |
||
1614 | |||
1615 | // Finally - have we renamed it - or is it really gone? |
||
1616 | foreach ($optionChanges as $k => $option) |
||
1617 | { |
||
1618 | // Just been renamed? |
||
1619 | if (in_array($k, $takenKeys)) |
||
1620 | { |
||
1621 | continue; |
||
1622 | } |
||
1623 | |||
1624 | if (empty($newOptions[$k])) |
||
1625 | { |
||
1626 | continue; |
||
1627 | } |
||
1628 | |||
1629 | updateRenamedProfileField($k, $newOptions, $context['field']['colname'], $option); |
||
1630 | } |
||
1631 | } |
||
1632 | |||
1633 | // @todo Maybe we should adjust based on new text length limits? |
||
1634 | |||
1635 | // And finally update an existing field |
||
1636 | $field_data = array( |
||
1637 | 'field_length' => $field_length, |
||
1638 | 'show_reg' => $show_reg, |
||
1639 | 'show_display' => $show_display, |
||
1640 | 'show_memberlist' => $show_memberlist, |
||
1641 | 'private' => $private, |
||
1642 | 'active' => $active, |
||
1643 | 'can_search' => $can_search, |
||
1644 | 'bbc' => $bbc, |
||
1645 | 'current_field' => $context['fid'], |
||
1646 | 'field_name' => $this->_req->post->field_name, |
||
1647 | 'field_desc' => $this->_req->post->field_desc, |
||
1648 | 'field_type' => $this->_req->post->field_type, |
||
1649 | 'field_options' => $field_options, |
||
1650 | 'show_profile' => $show_profile, |
||
1651 | 'default_value' => $default, |
||
1652 | 'mask' => $mask, |
||
1653 | 'enclose' => $enclose, |
||
1654 | 'placement' => $placement, |
||
1655 | 'rows' => $rows, |
||
1656 | 'cols' => $cols, |
||
1657 | ); |
||
1658 | |||
1659 | updateProfileField($field_data); |
||
1660 | |||
1661 | // Just clean up any old selects - these are a pain! |
||
1662 | if (($this->_req->post->field_type == 'select' || $this->_req->post->field_type == 'radio') && !empty($newOptions)) |
||
1663 | { |
||
1664 | deleteOldProfileFieldSelects($newOptions, $context['field']['colname']); |
||
1665 | } |
||
1666 | } |
||
1667 | } |
||
1668 | // Deleting? |
||
1669 | elseif (isset($this->_req->post->delete) && $context['field']['colname']) |
||
1670 | { |
||
1671 | checkSession(); |
||
1672 | validateToken('admin-ecp'); |
||
1673 | |||
1674 | // Delete the old data first, then the field. |
||
1675 | deleteProfileFieldUserData($context['field']['colname']); |
||
1676 | deleteProfileField($context['fid']); |
||
1677 | } |
||
1678 | |||
1679 | // Rebuild display cache etc. |
||
1680 | if (isset($this->_req->post->delete) || isset($this->_req->post->save) || isset($this->_req->post->onoff)) |
||
1681 | { |
||
1682 | checkSession(); |
||
1683 | |||
1684 | // Update the display cache |
||
1685 | updateDisplayCache(); |
||
1686 | redirectexit('action=admin;area=featuresettings;sa=profile'); |
||
1687 | } |
||
1688 | |||
1689 | createToken('admin-ecp'); |
||
1690 | } |
||
1691 | |||
1692 | /** |
||
1693 | * Editing personal messages settings |
||
1694 | * |
||
1695 | * - Accessed with ?action=admin;area=featuresettings;sa=pmsettings |
||
1696 | * |
||
1697 | * @event integrate_save_pmsettings_settings |
||
1698 | */ |
||
1699 | public function action_pmsettings() |
||
1700 | { |
||
1701 | global $txt, $context; |
||
1702 | |||
1703 | // Initialize the form |
||
1704 | $settingsForm = new SettingsForm(SettingsForm::DB_ADAPTER); |
||
1705 | |||
1706 | // Initialize it with our settings |
||
1707 | $settingsForm->setConfigVars($this->_pmSettings()); |
||
1708 | |||
1709 | require_once(SUBSDIR . '/PersonalMessage.subs.php'); |
||
1710 | Txt::load('ManageMembers'); |
||
1711 | |||
1712 | $context['pm_limits'] = loadPMLimits(); |
||
1713 | |||
1714 | // Saving? |
||
1715 | if (isset($this->_req->query->save)) |
||
1716 | { |
||
1717 | checkSession(); |
||
1718 | |||
1719 | require_once(SUBSDIR . '/Membergroups.subs.php'); |
||
1720 | foreach ($context['pm_limits'] as $group_id => $group) |
||
1721 | { |
||
1722 | if (!isset($this->_req->post->group[$group_id])) |
||
1723 | { |
||
1724 | continue; |
||
1725 | } |
||
1726 | |||
1727 | if ($this->_req->post->group[$group_id] == $group['max_messages']) |
||
1728 | { |
||
1729 | continue; |
||
1730 | } |
||
1731 | |||
1732 | updateMembergroupProperties(array('current_group' => $group_id, 'max_messages' => $this->_req->post->group[$group_id])); |
||
1733 | } |
||
1734 | |||
1735 | call_integration_hook('integrate_save_pmsettings_settings'); |
||
1736 | |||
1737 | $settingsForm->setConfigValues((array) $this->_req->post); |
||
1738 | $settingsForm->save(); |
||
1739 | redirectexit('action=admin;area=featuresettings;sa=pmsettings'); |
||
1740 | } |
||
1741 | |||
1742 | $context['post_url'] = getUrl('admin', ['action' => 'admin', 'area' => 'featuresettings', 'sa' => 'pmsettings', 'save']); |
||
1743 | $context['settings_title'] = $txt['personal_messages']; |
||
1744 | |||
1745 | $settingsForm->prepare(); |
||
1746 | } |
||
1747 | |||
1748 | /** |
||
1749 | * Return pm settings. |
||
1750 | * |
||
1751 | * - Used in admin center search and settings form |
||
1752 | * |
||
1753 | * @event integrate_modify_pmsettings_settings Adds / Modifies PM Settings |
||
1754 | */ |
||
1755 | private function _pmSettings() |
||
1756 | { |
||
1757 | global $txt; |
||
1758 | |||
1759 | $config_vars = array( |
||
1760 | // Reporting of personal messages? |
||
1761 | array('check', 'enableReportPM'), |
||
1762 | // Inline permissions. |
||
1763 | array('permissions', 'pm_send'), |
||
1764 | // PM Settings |
||
1765 | array('title', 'antispam_PM'), |
||
1766 | 'pm1' => array('int', 'max_pm_recipients', 'postinput' => $txt['max_pm_recipients_note']), |
||
1767 | 'pm2' => array('int', 'pm_posts_verification', 'postinput' => $txt['pm_posts_verification_note']), |
||
1768 | 'pm3' => array('int', 'pm_posts_per_hour', 'postinput' => $txt['pm_posts_per_hour_note']), |
||
1769 | array('title', 'membergroups_max_messages'), |
||
1770 | array('desc', 'membergroups_max_messages_desc'), |
||
1771 | array('callback', 'pm_limits'), |
||
1772 | ); |
||
1773 | |||
1774 | call_integration_hook('integrate_modify_pmsettings_settings', array(&$config_vars)); |
||
1775 | |||
1776 | return $config_vars; |
||
1777 | } |
||
1778 | |||
1779 | /** |
||
1780 | * Public method to return the basic settings, used for admin search |
||
1781 | */ |
||
1782 | public function basicSettings_search() |
||
1783 | { |
||
1784 | return $this->_basicSettings(); |
||
1785 | } |
||
1786 | |||
1787 | /** |
||
1788 | * Public method to return the layout settings, used for admin search |
||
1789 | */ |
||
1790 | public function layoutSettings_search() |
||
1791 | { |
||
1792 | return $this->_layoutSettings(); |
||
1793 | } |
||
1794 | |||
1795 | /** |
||
1796 | * Public method to return the karma settings, used for admin search |
||
1797 | */ |
||
1798 | public function karmaSettings_search() |
||
1799 | { |
||
1800 | global $modSettings; |
||
1801 | |||
1802 | // Karma - On or off? |
||
1803 | if (empty($modSettings['karmaMode'])) |
||
1804 | { |
||
1805 | return ['check', 'dummy_karma']; |
||
1806 | } |
||
1807 | |||
1808 | return $this->_karmaSettings(); |
||
1809 | } |
||
1810 | |||
1811 | /** |
||
1812 | * Public method to return the likes settings, used for admin search |
||
1813 | */ |
||
1814 | public function likesSettings_search() |
||
1815 | { |
||
1816 | global $modSettings; |
||
1817 | |||
1818 | // Likes - On or off? |
||
1819 | if (empty($modSettings['enable_likes'])) |
||
1820 | { |
||
1821 | return ['check', 'dummy_likes']; |
||
1822 | } |
||
1823 | |||
1824 | return $this->_likesSettings(); |
||
1825 | } |
||
1826 | |||
1827 | /** |
||
1828 | * Public method to return the mention settings, used for admin search |
||
1829 | */ |
||
1830 | public function mentionSettings_search() |
||
1831 | { |
||
1832 | return $this->_notificationsSettings(); |
||
1833 | } |
||
1834 | |||
1835 | /** |
||
1836 | * Public method to return the signature settings, used for admin search |
||
1837 | */ |
||
1838 | public function signatureSettings_search() |
||
1839 | { |
||
1840 | return $this->_signatureSettings(); |
||
1841 | } |
||
1842 | |||
1843 | /** |
||
1844 | * Public method to return the PM settings, used for admin search |
||
1845 | */ |
||
1846 | public function pmSettings_search() |
||
1847 | { |
||
1848 | return $this->_pmSettings(); |
||
1849 | } |
||
1850 | } |
||
1851 |