Passed
Push — patch_1-1-9 ( b5af31...33104f )
by Spuds
01:09 queued 26s
created

action_basicSettings_display()   B

Complexity

Conditions 6
Paths 15

Size

Total Lines 60
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 30
nc 15
nop 0
dl 0
loc 60
rs 8.8177
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Manage features and options administration page.
5
 *
6
 * @name      ElkArte Forum
7
 * @copyright ElkArte Forum contributors
8
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause
9
 *
10
 * This file contains code covered by:
11
 * copyright:	2011 Simple Machines (http://www.simplemachines.org)
12
 * license:		BSD, See included LICENSE.TXT for terms and conditions.
13
 *
14
 * @version 1.1.9
15
 *
16
 */
17
18
/**
19
 * Manage features and options administration page.
20
 *
21
 * This controller handles the pages which allow the admin
22
 * to see and change the basic feature settings of their site.
23
 */
24
class ManageFeatures_Controller extends Action_Controller
25
{
26
	/**
27
	 * Pre Dispatch, called before other methods.
28
	 */
29
	public function pre_dispatch()
30
	{
31
		// We need this in few places so it's easier to have it loaded here
32
		require_once(SUBSDIR . '/ManageFeatures.subs.php');
33
	}
34
35
	/**
36
	 * This function passes control through to the relevant tab.
37
	 *
38
	 * @event integrate_sa_modify_features Use to add new Configuration tabs
39
	 * @see Action_Controller::action_index()
40
	 * @uses Help, ManageSettings languages
41
	 * @uses sub_template show_settings
42
	 */
43
	public function action_index()
44
	{
45
		global $context, $txt, $settings, $scripturl;
46
47
		// Often Helpful
48
		loadLanguage('Help');
49
		loadLanguage('ManageSettings');
50
		loadLanguage('Mentions');
51
52
		// All the actions we know about
53
		$subActions = array(
54
			'basic' => array(
55
				'controller' => $this,
56
				'function' => 'action_basicSettings_display',
57
				'permission' => 'admin_forum'
58
			),
59
			'layout' => array(
60
				'controller' => $this,
61
				'function' => 'action_layoutSettings_display',
62
				'permission' => 'admin_forum'
63
			),
64
			'karma' => array(
65
				'controller' => $this,
66
				'function' => 'action_karmaSettings_display',
67
				'enabled' => in_array('k', $context['admin_features']),
68
				'permission' => 'admin_forum'
69
			),
70
			'pmsettings' => array(
71
				'controller' => $this,
72
				'function' => 'action_pmsettings',
73
				'permission' => 'admin_forum'
74
			),
75
			'likes' => array(
76
				'controller' => $this,
77
				'function' => 'action_likesSettings_display',
78
				'enabled' => in_array('l', $context['admin_features']),
79
				'permission' => 'admin_forum'
80
			),
81
			'mention' => array(
82
				'controller' => $this,
83
				'function' => 'action_notificationsSettings_display',
84
				'permission' => 'admin_forum'
85
			),
86
			'sig' => array(
87
				'controller' => $this,
88
				'function' => 'action_signatureSettings_display',
89
				'permission' => 'admin_forum'
90
			),
91
			'profile' => array(
92
				'controller' => $this,
93
				'function' => 'action_profile',
94
				'enabled' => in_array('cp', $context['admin_features']),
95
				'permission' => 'admin_forum'
96
			),
97
			'profileedit' => array(
98
				'controller' => $this,
99
				'function' => 'action_profileedit',
100
				'permission' => 'admin_forum'
101
			),
102
		);
103
104
		// Set up the action control
105
		$action = new Action('modify_features');
106
107
		// Load up all the tabs...
108
		$context[$context['admin_menu_name']]['tab_data'] = array(
109
			'title' => $txt['modSettings_title'],
110
			'help' => 'featuresettings',
111
			'description' => sprintf($txt['modSettings_desc'], $scripturl . '?action=admin;area=theme;sa=list;th=' . $settings['theme_id'] . ';' . $context['session_id'] . '=' . $context['session_var']),
112
			'tabs' => array(
113
				'basic' => array(
114
				),
115
				'layout' => array(
116
				),
117
				'pmsettings' => array(
118
				),
119
				'karma' => array(
120
				),
121
				'likes' => array(
122
				),
123
				'mention' => array(
124
					'description' => $txt['mentions_settings_desc'],
125
				),
126
				'sig' => array(
127
					'description' => $txt['signature_settings_desc'],
128
				),
129
				'profile' => array(
130
					'description' => $txt['custom_profile_desc'],
131
				),
132
			),
133
		);
134
135
		// By default do the basic settings, call integrate_sa_modify_features
136
		$subAction = $action->initialize($subActions, 'basic');
137
138
		// Some final pieces for the template
139
		$context['sub_template'] = 'show_settings';
140
		$context['sub_action'] = $subAction;
141
		$context['page_title'] = $txt['modSettings_title'];
142
143
		// Call the right function for this sub-action.
144
		$action->dispatch($subAction);
145
	}
146
147
	/**
148
	 * Config array for changing the basic forum settings
149
	 *
150
	 * - Accessed from ?action=admin;area=featuresettings;sa=basic;
151
	 *
152
	 * @event integrate_save_basic_settings
153
	 */
154
	public function action_basicSettings_display()
155
	{
156
		global $txt, $scripturl, $context;
157
158
		// Initialize the form
159
		$settingsForm = new Settings_Form(Settings_Form::DB_ADAPTER);
160
161
		// Initialize it with our settings
162
		$settingsForm->setConfigVars($this->_basicSettings());
163
164
		// Saving?
165
		if (isset($this->_req->query->save))
166
		{
167
			checkSession();
168
169
			// Prevent absurd boundaries here - make it a day tops.
170
			if (isset($this->_req->post->lastActive))
171
				$this->_req->post->lastActive = min((int) $this->_req->post->lastActive, 1440);
172
173
			call_integration_hook('integrate_save_basic_settings');
174
175
			// Microdata needs to enable its integration
176
			if (!empty($this->_req->getPost('metadata_enabled')))
177
			{
178
				Hooks::instance()->enableIntegration('Metadata_Integrate');
179
			}
180
			else
181
			{
182
				Hooks::instance()->disableIntegration('Metadata_Integrate');
183
			}
184
185
			$settingsForm->setConfigValues((array) $this->_req->post);
186
			$settingsForm->save();
187
188
			writeLog();
189
			redirectexit('action=admin;area=featuresettings;sa=basic');
190
		}
191
192
		if (isset($this->_req->post->cleanhives))
193
		{
194
			$clean_hives_result = theme()->cleanHives();
195
196
			Template_Layers::instance()->removeAll();
197
			loadTemplate('Json');
198
			addJavascriptVar(array('txt_invalid_response' => $txt['ajax_bad_response']), true);
199
			$context['sub_template'] = 'send_json';
200
			$context['json_data'] = array(
201
				'success' => $clean_hives_result,
202
				'response' => $clean_hives_result ? $txt['clean_hives_sucess'] : $txt['clean_hives_failed']
203
			);
204
			return;
205
		}
206
207
		$context['post_url'] = $scripturl . '?action=admin;area=featuresettings;save;sa=basic';
208
		$context['settings_title'] = $txt['mods_cat_features'];
209
210
		// Show / hide custom jquery fields as required
211
		addInlineJavascript('showhideJqueryOptions();', true);
212
213
		$settingsForm->prepare();
214
	}
215
216
	/**
217
	 * Allows modifying the global layout settings in the forum
218
	 *
219
	 * - Accessed through ?action=admin;area=featuresettings;sa=layout;
220
	 *
221
	 * @event integrate_save_layout_settings
222
	 */
223
	public function action_layoutSettings_display()
224
	{
225
		global $txt, $scripturl, $context, $modSettings;
226
227
		// Initialize the form
228
		$settingsForm = new Settings_Form(Settings_Form::DB_ADAPTER);
229
230
		// Initialize it with our settings
231
		$settingsForm->setConfigVars($this->_layoutSettings());
232
233
		// Saving?
234
		if (isset($this->_req->query->save))
235
		{
236
			// Setting a custom frontpage, set the hook to the FrontpageInterface of the controller
237
			if (!empty($this->_req->post->front_page))
238
			{
239
				// Addons may have left this blank
240
				$modSettings['front_page'] = empty($modSettings['front_page']) ? 'MessageIndex_Controller' : $modSettings['front_page'];
241
242
				$front_page = (string) $this->_req->post->front_page;
243
				if (
244
					class_exists($modSettings['front_page'])
245
					&& in_array('validateFrontPageOptions', get_class_methods($modSettings['front_page']))
246
					&& !$front_page::validateFrontPageOptions($this->_req->post)
247
				) {
248
					$this->_req->post->front_page = '';
249
				}
250
			}
251
252
			checkSession();
253
254
			call_integration_hook('integrate_save_layout_settings');
255
256
			$settingsForm->setConfigValues((array) $this->_req->post);
257
			$settingsForm->save();
258
			writeLog();
259
260
			redirectexit('action=admin;area=featuresettings;sa=layout');
261
		}
262
263
		$context['post_url'] = $scripturl . '?action=admin;area=featuresettings;save;sa=layout';
264
		$context['settings_title'] = $txt['mods_cat_layout'];
265
266
		$settingsForm->prepare();
267
	}
268
269
	/**
270
	 * Display configuration settings page for karma settings.
271
	 *
272
	 * - Accessed from ?action=admin;area=featuresettings;sa=karma;
273
	 *
274
	 * @event integrate_save_karma_settings
275
	 */
276
	public function action_karmaSettings_display()
277
	{
278
		global $txt, $scripturl, $context;
279
280
		// Initialize the form
281
		$settingsForm = new Settings_Form(Settings_Form::DB_ADAPTER);
282
283
		// Initialize it with our settings
284
		$settingsForm->setConfigVars($this->_karmaSettings());
285
286
		// Saving?
287
		if (isset($this->_req->query->save))
288
		{
289
			checkSession();
290
291
			call_integration_hook('integrate_save_karma_settings');
292
293
			$settingsForm->setConfigValues((array) $this->_req->post);
294
			$settingsForm->save();
295
			redirectexit('action=admin;area=featuresettings;sa=karma');
296
		}
297
298
		$context['post_url'] = $scripturl . '?action=admin;area=featuresettings;save;sa=karma';
299
		$context['settings_title'] = $txt['karma'];
300
301
		$settingsForm->prepare();
302
	}
303
304
	/**
305
	 * Display configuration settings page for likes settings.
306
	 *
307
	 * - Accessed from ?action=admin;area=featuresettings;sa=likes;
308
	 *
309
	 * @event integrate_save_likes_settings
310
	 */
311
	public function action_likesSettings_display()
312
	{
313
		global $txt, $scripturl, $context;
314
315
		// Initialize the form
316
		$settingsForm = new Settings_Form(Settings_Form::DB_ADAPTER);
317
318
		// Initialize it with our settings
319
		$settingsForm->setConfigVars($this->_likesSettings());
320
321
		// Saving?
322
		if (isset($this->_req->query->save))
323
		{
324
			checkSession();
325
326
			call_integration_hook('integrate_save_likes_settings');
327
328
			$settingsForm->setConfigValues((array) $this->_req->post);
329
			$settingsForm->save();
330
			redirectexit('action=admin;area=featuresettings;sa=likes');
331
		}
332
333
		$context['post_url'] = $scripturl . '?action=admin;area=featuresettings;save;sa=likes';
334
		$context['settings_title'] = $txt['likes'];
335
336
		$settingsForm->prepare();
337
	}
338
339
	/**
340
	 * Initializes the mentions settings admin page.
341
	 *
342
	 * - Accessed from ?action=admin;area=featuresettings;sa=mention;
343
	 *
344
	 * @event integrate_save_modify_mention_settings
345
	 */
346
	public function action_notificationsSettings_display()
347
	{
348
		global $txt, $context, $scripturl, $modSettings;
349
350
		loadLanguage('Mentions');
351
352
		// Instantiate the form
353
		$settingsForm = new Settings_Form(Settings_Form::DB_ADAPTER);
354
355
		// Initialize it with our settings
356
		$settingsForm->setConfigVars($this->_notificationsSettings());
357
358
		// Some context stuff
359
		$context['page_title'] = $txt['mentions_settings'];
360
		$context['sub_template'] = 'show_settings';
361
362
		// Saving the settings?
363
		if (isset($this->_req->query->save))
364
		{
365
			checkSession();
366
367
			call_integration_hook('integrate_save_modify_mention_settings');
368
369
			if (!empty($this->_req->post->mentions_enabled))
370
			{
371
				enableModules('mentions', array('post', 'display'));
372
			}
373
			else
374
			{
375
				disableModules('mentions', array('post', 'display'));
376
			}
377
378
			if (empty($this->_req->post->notifications))
379
			{
380
				$notification_methods = serialize(array());
381
			}
382
			else
383
			{
384
				$notification_methods = serialize($this->_req->post->notifications);
385
			}
386
387
			require_once(SUBSDIR . '/Mentions.subs.php');
388
			$enabled_mentions = array();
389
			$current_settings = unserialize($modSettings['notification_methods']);
390
391
			// Fist hide what was visible
392
			$modules_toggle = array('enable' => array(), 'disable' => array());
393
			foreach ($current_settings as $type => $val)
394
			{
395
				if (!isset($this->_req->post->notifications[$type]))
396
				{
397
					toggleMentionsVisibility($type, false);
398
					$modules_toggle['disable'][] = $type;
399
				}
400
			}
401
402
			// Then make visible what was hidden, but only if there is anything
403
			if (!empty($this->_req->post->notifications))
404
			{
405
				foreach ($this->_req->post->notifications as $type => $val)
406
				{
407
					if (!isset($current_settings[$type]))
408
					{
409
						toggleMentionsVisibility($type, true);
410
						$modules_toggle['enable'][] = $type;
411
					}
412
				}
413
414
				$enabled_mentions = array_keys($this->_req->post->notifications);
415
			}
416
417
			// Let's just keep it active, there are too many reasons it should be.
418
			require_once(SUBSDIR . '/ScheduledTasks.subs.php');
419
			toggleTaskStatusByName('user_access_mentions', true);
420
421
			// Disable or enable modules as needed
422
			foreach ($modules_toggle as $action => $toggles)
423
			{
424
				if (!empty($toggles))
425
				{
426
					// The modules associated with the notification (mentionmem, likes, etc) area
427
					$modules = getMentionsModules($toggles);
428
429
					// The action will either be enable to disable
430
					$function = $action . 'Modules';
431
432
					// Something like enableModule('mentions', array('post', 'display');
433
					foreach ($modules as $key => $val)
434
						$function($key, $val);
435
				}
436
			}
437
438
			updateSettings(array('enabled_mentions' => implode(',', array_unique($enabled_mentions)), 'notification_methods' => $notification_methods));
439
			$settingsForm->setConfigValues((array) $this->_req->post);
440
			$settingsForm->save();
441
			redirectexit('action=admin;area=featuresettings;sa=mention');
442
		}
443
444
		// Prepare the settings for display
445
		$context['post_url'] = $scripturl . '?action=admin;area=featuresettings;save;sa=mention';
446
		$settingsForm->prepare();
447
	}
448
449
	/**
450
	 * Display configuration settings for signatures on forum.
451
	 *
452
	 * - Accessed from ?action=admin;area=featuresettings;sa=sig;
453
	 *
454
	 * @event integrate_save_signature_settings
455
	 */
456
	public function action_signatureSettings_display()
457
	{
458
		global $context, $txt, $modSettings, $sig_start, $scripturl;
459
460
		// Initialize the form
461
		$settingsForm = new Settings_Form(Settings_Form::DB_ADAPTER);
462
463
		// Initialize it with our settings
464
		$settingsForm->setConfigVars($this->_signatureSettings());
465
466
		// Setup the template.
467
		$context['page_title'] = $txt['signature_settings'];
468
		$context['sub_template'] = 'show_settings';
469
470
		// Disable the max smileys option if we don't allow smileys at all!
471
		addInlineJavascript('
472
			document.getElementById(\'signature_max_smileys\').disabled = !document.getElementById(\'signature_allow_smileys\').checked;', true);
473
474
		// Load all the signature settings.
475
		list ($sig_limits, $sig_bbc) = explode(':', $modSettings['signature_settings']);
476
		$sig_limits = explode(',', $sig_limits);
477
		$disabledTags = !empty($sig_bbc) ? explode(',', $sig_bbc) : array();
478
479
		// @todo temporary since it does not work, and seriously why would you do this?
480
		$disabledTags[] = 'footnote';
481
482
		// Applying to ALL signatures?!!
483
		if (isset($this->_req->query->apply))
484
		{
485
			// Security!
486
			checkSession('get');
487
488
			$sig_start = time();
489
490
			// This is horrid - but I suppose some people will want the option to do it.
491
			$applied_sigs = $this->_req->getQuery('step', 'intval', 0);
492
			updateAllSignatures($applied_sigs);
493
494
			$settings_applied = true;
495
		}
496
497
		$context['signature_settings'] = array(
498
			'enable' => isset($sig_limits[0]) ? $sig_limits[0] : 0,
499
			'max_length' => isset($sig_limits[1]) ? $sig_limits[1] : 0,
500
			'max_lines' => isset($sig_limits[2]) ? $sig_limits[2] : 0,
501
			'max_images' => isset($sig_limits[3]) ? $sig_limits[3] : 0,
502
			'allow_smileys' => isset($sig_limits[4]) && $sig_limits[4] == -1 ? 0 : 1,
503
			'max_smileys' => isset($sig_limits[4]) && $sig_limits[4] != -1 ? $sig_limits[4] : 0,
504
			'max_image_width' => isset($sig_limits[5]) ? $sig_limits[5] : 0,
505
			'max_image_height' => isset($sig_limits[6]) ? $sig_limits[6] : 0,
506
			'max_font_size' => isset($sig_limits[7]) ? $sig_limits[7] : 0,
507
			'repetition_guests' => isset($sig_limits[8]) ? $sig_limits[8] : 0,
508
			'repetition_members' => isset($sig_limits[9]) ? $sig_limits[9] : 0,
509
		);
510
511
		// Temporarily make each setting a modSetting!
512
		foreach ($context['signature_settings'] as $key => $value)
513
			$modSettings['signature_' . $key] = $value;
514
515
		// Make sure we check the right tags!
516
		$modSettings['bbc_disabled_signature_bbc'] = $disabledTags;
517
518
		// Saving?
519
		if (isset($this->_req->query->save))
520
		{
521
			checkSession();
522
523
			// Clean up the tag stuff!
524
			$codes = \BBC\ParserWrapper::instance()->getCodes();
525
			$bbcTags = $codes->getTags();
526
527
			if (!isset($this->_req->post->signature_bbc_enabledTags))
528
				$this->_req->post->signature_bbc_enabledTags = array();
529
			elseif (!is_array($this->_req->post->signature_bbc_enabledTags))
530
				$this->_req->post->signature_bbc_enabledTags = array($this->_req->post->signature_bbc_enabledTags);
531
532
			$sig_limits = array();
533
			foreach ($context['signature_settings'] as $key => $value)
534
			{
535
				if ($key == 'allow_smileys')
536
					continue;
537
				elseif ($key == 'max_smileys' && empty($this->_req->post->signature_allow_smileys))
538
					$sig_limits[] = -1;
539
				else
540
				{
541
					$current_key = $this->_req->getPost('signature_' . $key, 'intval');
542
					$sig_limits[] = !empty($current_key) ? max(1, $current_key) : 0;
543
				}
544
			}
545
546
			call_integration_hook('integrate_save_signature_settings', array(&$sig_limits, &$bbcTags));
547
548
			$this->_req->post->signature_settings = implode(',', $sig_limits) . ':' . implode(',', array_diff($bbcTags, $this->_req->post->signature_bbc_enabledTags));
549
550
			// Even though we have practically no settings let's keep the convention going!
551
			$save_vars = array();
552
			$save_vars[] = array('text', 'signature_settings');
553
554
			$settingsForm->setConfigVars($save_vars);
555
			$settingsForm->setConfigValues((array) $this->_req->post);
556
			$settingsForm->save();
557
			redirectexit('action=admin;area=featuresettings;sa=sig');
558
		}
559
560
		$context['post_url'] = $scripturl . '?action=admin;area=featuresettings;save;sa=sig';
561
		$context['settings_title'] = $txt['signature_settings'];
562
		$context['settings_message'] = !empty($settings_applied) ? $txt['signature_settings_applied'] : sprintf($txt['signature_settings_warning'], $scripturl . '?action=admin;area=featuresettings;sa=sig;apply;' . $context['session_var'] . '=' . $context['session_id']);
563
564
		$settingsForm->prepare();
565
	}
566
567
	/**
568
	 * Show all the custom profile fields available to the user.
569
	 *
570
	 * - Allows for drag/drop sorting of custom profile fields
571
	 * - Accessed with ?action=admin;area=featuresettings;sa=profile
572
	 *
573
	 * @uses sub template show_custom_profile
574
	 */
575
	public function action_profile()
576
	{
577
		global $txt, $scripturl, $context;
578
579
		loadTemplate('ManageFeatures');
580
		$context['page_title'] = $txt['custom_profile_title'];
581
		$context['sub_template'] = 'show_custom_profile';
582
583
		// What about standard fields they can tweak?
584
		$standard_fields = array('website', 'posts', 'warning_status', 'date_registered', 'action');
585
586
		// What fields can't you put on the registration page?
587
		$context['fields_no_registration'] = array('posts', 'warning_status', 'date_registered', 'action');
588
589
		// Are we saving any standard field changes?
590
		if (isset($this->_req->post->save))
591
		{
592
			checkSession();
593
			validateToken('admin-scp');
594
595
			$changes = array();
596
597
			// Do the active ones first.
598
			$disable_fields = array_flip($standard_fields);
599
			if (!empty($this->_req->post->active))
600
			{
601
				foreach ($this->_req->post->active as $value)
602
				{
603
					if (isset($disable_fields[$value]))
604
					{
605
						unset($disable_fields[$value]);
606
					}
607
				}
608
			}
609
610
			// What we have left!
611
			$changes['disabled_profile_fields'] = empty($disable_fields) ? '' : implode(',', array_keys($disable_fields));
612
613
			// Things we want to show on registration?
614
			$reg_fields = array();
615
			if (!empty($this->_req->post->reg))
616
			{
617
				foreach ($this->_req->post->reg as $value)
618
				{
619
					if (in_array($value, $standard_fields) && !isset($disable_fields[$value]))
620
						$reg_fields[] = $value;
621
				}
622
			}
623
624
			// What we have left!
625
			$changes['registration_fields'] = empty($reg_fields) ? '' : implode(',', $reg_fields);
626
627
			if (!empty($changes))
628
				updateSettings($changes);
629
		}
630
631
		createToken('admin-scp');
632
633
		// Create a listing for all our standard fields
634
		$listOptions = array(
635
			'id' => 'standard_profile_fields',
636
			'title' => $txt['standard_profile_title'],
637
			'base_href' => $scripturl . '?action=admin;area=featuresettings;sa=profile',
638
			'get_items' => array(
639
				'function' => 'list_getProfileFields',
640
				'params' => array(
641
					true,
642
				),
643
			),
644
			'columns' => array(
645
				'field' => array(
646
					'header' => array(
647
						'value' => $txt['standard_profile_field'],
648
					),
649
					'data' => array(
650
						'db' => 'label',
651
						'style' => 'width: 60%;',
652
					),
653
				),
654
				'active' => array(
655
					'header' => array(
656
						'value' => $txt['custom_edit_active'],
657
						'class' => 'centertext',
658
					),
659
					'data' => array(
660
						'function' => function ($rowData) {
661
							$isChecked = $rowData['disabled'] ? '' : ' checked="checked"';
662
							$onClickHandler = $rowData['can_show_register'] ? sprintf('onclick="document.getElementById(\'reg_%1$s\').disabled = !this.checked;"', $rowData['id']) : '';
663
							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);
664
						},
665
						'style' => 'width: 20%;',
666
						'class' => 'centertext',
667
					),
668
				),
669
				'show_on_registration' => array(
670
					'header' => array(
671
						'value' => $txt['custom_edit_registration'],
672
						'class' => 'centertext',
673
					),
674
					'data' => array(
675
						'function' => function ($rowData) {
676
							$isChecked = $rowData['on_register'] && !$rowData['disabled'] ? ' checked="checked"' : '';
677
							$isDisabled = $rowData['can_show_register'] ? '' : ' disabled="disabled"';
678
							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);
679
						},
680
						'style' => 'width: 20%;',
681
						'class' => 'centertext',
682
					),
683
				),
684
			),
685
			'form' => array(
686
				'href' => $scripturl . '?action=admin;area=featuresettings;sa=profile',
687
				'name' => 'standardProfileFields',
688
				'token' => 'admin-scp',
689
			),
690
			'additional_rows' => array(
691
				array(
692
					'position' => 'below_table_data',
693
					'value' => '<input type="submit" name="save" value="' . $txt['save'] . '" class="right_submit" />',
694
				),
695
			),
696
		);
697
		createList($listOptions);
698
699
		// And now we do the same for all of our custom ones
700
		$token = createToken('admin-sort');
701
		$listOptions = array(
702
			'id' => 'custom_profile_fields',
703
			'title' => $txt['custom_profile_title'],
704
			'base_href' => $scripturl . '?action=admin;area=featuresettings;sa=profile',
705
			'default_sort_col' => 'vieworder',
706
			'no_items_label' => $txt['custom_profile_none'],
707
			'items_per_page' => 25,
708
			'sortable' => true,
709
			'get_items' => array(
710
				'function' => 'list_getProfileFields',
711
				'params' => array(
712
					false,
713
				),
714
			),
715
			'get_count' => array(
716
				'function' => 'list_getProfileFieldSize',
717
			),
718
			'columns' => array(
719
				'vieworder' => array(
720
					'header' => array(
721
						'value' => '',
722
						'class' => 'hide',
723
					),
724
					'data' => array(
725
						'db' => 'vieworder',
726
						'class' => 'hide',
727
					),
728
					'sort' => array(
729
						'default' => 'vieworder',
730
					),
731
				),
732
				'field_name' => array(
733
					'header' => array(
734
						'value' => $txt['custom_profile_fieldname'],
735
					),
736
					'data' => array(
737
						'function' => function ($rowData) {
738
							global $scripturl;
739
740
							return sprintf('<a href="%1$s?action=admin;area=featuresettings;sa=profileedit;fid=%2$d">%3$s</a><div class="smalltext">%4$s</div>', $scripturl, $rowData['id_field'], $rowData['field_name'], $rowData['field_desc']);
741
						},
742
						'style' => 'width: 65%;',
743
					),
744
					'sort' => array(
745
						'default' => 'field_name',
746
						'reverse' => 'field_name DESC',
747
					),
748
				),
749
				'field_type' => array(
750
					'header' => array(
751
						'value' => $txt['custom_profile_fieldtype'],
752
					),
753
					'data' => array(
754
						'function' => function ($rowData) {
755
							global $txt;
756
757
							$textKey = sprintf('custom_profile_type_%1$s', $rowData['field_type']);
758
							return isset($txt[$textKey]) ? $txt[$textKey] : $textKey;
759
						},
760
						'style' => 'width: 10%;',
761
					),
762
					'sort' => array(
763
						'default' => 'field_type',
764
						'reverse' => 'field_type DESC',
765
					),
766
				),
767
				'cust' => array(
768
					'header' => array(
769
						'value' => $txt['custom_profile_active'],
770
						'class' => 'centertext',
771
					),
772
					'data' => array(
773
						'function' => function ($rowData) {
774
							$isChecked = $rowData['active'] ? ' checked="checked"' : '';
775
							return sprintf('<input type="checkbox" name="cust[]" id="cust_%1$s" value="%1$s" class="input_check"%2$s />', $rowData['id_field'], $isChecked);
776
						},
777
						'style' => 'width: 8%;',
778
						'class' => 'centertext',
779
					),
780
					'sort' => array(
781
						'default' => 'active DESC',
782
						'reverse' => 'active',
783
					),
784
				),
785
				'placement' => array(
786
					'header' => array(
787
						'value' => $txt['custom_profile_placement'],
788
					),
789
					'data' => array(
790
						'function' => function ($rowData) {
791
							global $txt;
792
							$placement = 'custom_profile_placement_';
793
794
							switch ((int) $rowData['placement'])
795
							{
796
								case 0:
797
									$placement .= 'standard';
798
									break;
799
								case 1:
800
									$placement .= 'withicons';
801
									break;
802
								case 2:
803
									$placement .= 'abovesignature';
804
									break;
805
								case 3:
806
									$placement .= 'aboveicons';
807
									break;
808
							}
809
810
							return $txt[$placement];
811
						},
812
						'style' => 'width: 5%;',
813
					),
814
					'sort' => array(
815
						'default' => 'placement DESC',
816
						'reverse' => 'placement',
817
					),
818
				),
819
				'show_on_registration' => array(
820
					'data' => array(
821
						'sprintf' => array(
822
							'format' => '<a href="' . $scripturl . '?action=admin;area=featuresettings;sa=profileedit;fid=%1$s">' . $txt['modify'] . '</a>',
823
							'params' => array(
824
								'id_field' => false,
825
							),
826
						),
827
						'style' => 'width: 5%;',
828
					),
829
				),
830
			),
831
			'form' => array(
832
				'href' => $scripturl . '?action=admin;area=featuresettings;sa=profileedit',
833
				'name' => 'customProfileFields',
834
				'token' => 'admin-scp',
835
			),
836
			'additional_rows' => array(
837
				array(
838
					'class' => 'submitbutton',
839
					'position' => 'below_table_data',
840
					'value' => '<input type="submit" name="onoff" value="' . $txt['save'] . '" class="right_submit" />
841
					<input type="submit" name="new" value="' . $txt['custom_profile_make_new'] . '" class="right_submit" />',
842
				),
843
				array(
844
					'position' => 'top_of_list',
845
					'value' => '<p class="infobox">' . $txt['custom_profile_sort'] . '</p>',
846
				),
847
			),
848
			'javascript' => '
849
				$().elkSortable({
850
					sa: "profileorder",
851
					error: "' . $txt['admin_order_error'] . '",
852
					title: "' . $txt['admin_order_title'] . '",
853
					placeholder: "ui-state-highlight",
854
					href: "?action=admin;area=featuresettings;sa=profile",
855
					token: {token_var: "' . $token['admin-sort_token_var'] . '", token_id: "' . $token['admin-sort_token'] . '"}
856
				});
857
			',
858
		);
859
860
		createList($listOptions);
861
	}
862
863
	/**
864
	 * Edit some profile fields?
865
	 *
866
	 * - Accessed with ?action=admin;area=featuresettings;sa=profileedit
867
	 *
868
	 * @uses sub template edit_profile_field
869
	 */
870
	public function action_profileedit()
871
	{
872
		global $txt, $scripturl, $context;
873
874
		loadTemplate('ManageFeatures');
875
876
		// Sort out the context!
877
		$context['fid'] = $this->_req->getQuery('fid', 'intval', 0);
878
		$context[$context['admin_menu_name']]['current_subsection'] = 'profile';
879
		$context['page_title'] = $context['fid'] ? $txt['custom_edit_title'] : $txt['custom_add_title'];
880
		$context['sub_template'] = 'edit_profile_field';
881
882
		// Any errors messages to show?
883
		if (isset($this->_req->query->msg))
884
		{
885
			loadLanguage('Errors');
886
887
			if (isset($txt['custom_option_' . $this->_req->query->msg]))
888
				$context['custom_option__error'] = $txt['custom_option_' . $this->_req->query->msg];
889
		}
890
891
		// Load the profile language for section names.
892
		loadLanguage('Profile');
893
894
		// Load up the profile field, if one was supplied
895
		if ($context['fid'])
896
		{
897
			$context['field'] = getProfileField($context['fid']);
898
		}
899
900
		// Setup the default values as needed.
901
		if (empty($context['field']))
902
		{
903
			$context['field'] = array(
904
				'name' => '',
905
				'colname' => '???',
906
				'desc' => '',
907
				'profile_area' => 'forumprofile',
908
				'reg' => false,
909
				'display' => false,
910
				'memberlist' => false,
911
				'type' => 'text',
912
				'max_length' => 255,
913
				'rows' => 4,
914
				'cols' => 30,
915
				'bbc' => false,
916
				'default_check' => false,
917
				'default_select' => '',
918
				'default_value' => '',
919
				'options' => array('', '', ''),
920
				'active' => true,
921
				'private' => false,
922
				'can_search' => false,
923
				'mask' => 'nohtml',
924
				'regex' => '',
925
				'enclose' => '',
926
				'placement' => 0,
927
			);
928
		}
929
930
		// All the javascript for this page... everything else is in admin.js
931
		addJavascriptVar(array('startOptID' => count($context['field']['options'])));
932
		addInlineJavascript('updateInputBoxes();', true);
933
934
		// Are we toggling which ones are active?
935
		if (isset($this->_req->post->onoff))
936
		{
937
			checkSession();
938
			validateToken('admin-scp');
939
940
			// Enable and disable custom fields as required.
941
			$enabled = array(0);
942
			if(isset($this->_req->post->cust) && is_array($this->_req->post->cust)) {
943
				foreach ($this->_req->post->cust as $id)
944
					$enabled[] = (int) $id;
945
			}
946
947
			updateRenamedProfileStatus($enabled);
948
		}
949
		// Are we saving?
950
		elseif (isset($this->_req->post->save))
951
		{
952
			checkSession();
953
			validateToken('admin-ecp');
954
955
			// Everyone needs a name - even the (bracket) unknown...
956
			if (trim($this->_req->post->field_name) == '')
957
				redirectexit($scripturl . '?action=admin;area=featuresettings;sa=profileedit;fid=' . $this->_req->query->fid . ';msg=need_name');
958
959
			// Regex you say?  Do a very basic test to see if the pattern is valid
960
			if (!empty($this->_req->post->regex) && @preg_match($this->_req->post->regex, 'dummy') === false)
961
				redirectexit($scripturl . '?action=admin;area=featuresettings;sa=profileedit;fid=' . $this->_req->query->fid . ';msg=regex_error');
962
963
			$this->_req->post->field_name = $this->_req->getPost('field_name', 'Util::htmlspecialchars');
964
			$this->_req->post->field_desc = $this->_req->getPost('field_desc', 'Util::htmlspecialchars');
965
966
			$rows = isset($this->_req->post->rows) ? (int) $this->_req->post->rows : 4;
967
			$cols = isset($this->_req->post->cols) ? (int) $this->_req->post->cols : 30;
968
969
			// Checkboxes...
970
			$show_reg = $this->_req->getPost('reg', 'intval', 0);
971
			$show_display = isset($this->_req->post->display) ? 1 : 0;
972
			$show_memberlist = isset($this->_req->post->memberlist) ? 1 : 0;
973
			$bbc = isset($this->_req->post->bbc) ? 1 : 0;
974
			$show_profile = $this->_req->post->profile_area;
975
			$active = isset($this->_req->post->active) ? 1 : 0;
976
			$private = $this->_req->getPost('private', 'intval', 0);
977
			$can_search = isset($this->_req->post->can_search) ? 1 : 0;
978
979
			// Some masking stuff...
980
			$mask = $this->_req->getPost('mask', 'strval', '');
981
			if ($mask == 'regex' && isset($this->_req->post->regex))
982
				$mask .= $this->_req->post->regex;
983
984
			$field_length = $this->_req->getPost('max_length', 'intval', 255);
985
			$enclose = $this->_req->getPost('enclose', 'strval', '');
986
			$placement = $this->_req->getPost('placement', 'intval', 0);
987
988
			// Select options?
989
			$field_options = '';
990
			$newOptions = array();
991
992
			// Set default
993
			$default = '';
994
995
			switch ($this->_req->post->field_type)
996
			{
997
				case 'check':
998
					$default = isset($this->_req->post->default_check) ? 1 : '';
999
					break;
1000
				case 'select':
1001
				case 'radio':
1002
					if (!empty($this->_req->post->select_option))
1003
					{
1004
						foreach ($this->_req->post->select_option as $k => $v)
1005
						{
1006
							// Clean, clean, clean...
1007
							$v = Util::htmlspecialchars($v);
1008
							$v = strtr($v, array(',' => ''));
1009
1010
							// Nada, zip, etc...
1011
							if (trim($v) == '')
1012
								continue;
1013
1014
							// Otherwise, save it boy.
1015
							$field_options .= $v . ',';
1016
1017
							// This is just for working out what happened with old options...
1018
							$newOptions[$k] = $v;
1019
1020
							// Is it default?
1021
							if (isset($this->_req->post->default_select) && $this->_req->post->default_select == $k)
1022
							{
1023
								$default = $v;
1024
							}
1025
						}
1026
1027
						if (isset($_POST['default_select']) && $_POST['default_select'] == 'no_default')
1028
							$default = 'no_default';
1029
1030
						$field_options = substr($field_options, 0, -1);
1031
					}
1032
					break;
1033
				default:
1034
					$default = isset($this->_req->post->default_value) ? $this->_req->post->default_value : '';
1035
			}
1036
1037
			// Text area by default has dimensions
1038
//			if ($this->_req->post->field_type == 'textarea')
1039
//				$default = (int) $this->_req->post->rows . ',' . (int) $this->_req->post->cols;
1040
1041
			// Come up with the unique name?
1042
			if (empty($context['fid']))
1043
			{
1044
				$colname = Util::substr(strtr($this->_req->post->field_name, array(' ' => '')), 0, 6);
1045
				preg_match('~([\w\d_-]+)~', $colname, $matches);
1046
1047
				// If there is nothing to the name, then let's start our own - for foreign languages etc.
1048
				if (isset($matches[1]))
1049
					$colname = $initial_colname = 'cust_' . strtolower($matches[1]);
1050
				else
1051
					$colname = $initial_colname = 'cust_' . mt_rand(1, 999999);
1052
1053
				$unique = ensureUniqueProfileField($colname, $initial_colname);
1054
1055
				// Still not a unique column name? Leave it up to the user, then.
1056
				if (!$unique)
1057
					throw new Elk_Exception('custom_option_not_unique');
1058
1059
				// And create a new field
1060
				$new_field = array(
1061
					'col_name' => $colname,
1062
					'field_name' => $this->_req->post->field_name,
1063
					'field_desc' => $this->_req->post->field_desc,
1064
					'field_type' => $this->_req->post->field_type,
1065
					'field_length' => $field_length,
1066
					'field_options' => $field_options,
1067
					'show_reg' => $show_reg,
1068
					'show_display' => $show_display,
1069
					'show_memberlist' => $show_memberlist,
1070
					'show_profile' => $show_profile,
1071
					'private' => $private,
1072
					'active' => $active,
1073
					'default_value' => $default,
1074
					'rows' => $rows,
1075
					'cols' => $cols,
1076
					'can_search' => $can_search,
1077
					'bbc' => $bbc,
1078
					'mask' => $mask,
1079
					'enclose' => $enclose,
1080
					'placement' => $placement,
1081
					'vieworder' => list_getProfileFieldSize() + 1,
1082
				);
1083
				addProfileField($new_field);
1084
			}
1085
			// Work out what to do with the user data otherwise...
1086
			else
1087
			{
1088
				// Anything going to check or select is pointless keeping - as is anything coming from check!
1089
				if (($this->_req->post->field_type == 'check' && $context['field']['type'] != 'check')
1090
					|| (($this->_req->post->field_type == 'select' || $this->_req->post->field_type == 'radio') && $context['field']['type'] != 'select' && $context['field']['type'] != 'radio')
1091
					|| ($context['field']['type'] == 'check' && $this->_req->post->field_type != 'check'))
1092
				{
1093
					deleteProfileFieldUserData($context['field']['colname']);
1094
				}
1095
				// Otherwise - if the select is edited may need to adjust!
1096
				elseif ($this->_req->post->field_type == 'select' || $this->_req->post->field_type == 'radio')
1097
				{
1098
					$optionChanges = array();
1099
					$takenKeys = array();
1100
1101
					// Work out what's changed!
1102
					foreach ($context['field']['options'] as $k => $option)
1103
					{
1104
						if (trim($option) == '')
1105
							continue;
1106
1107
						// Still exists?
1108
						if (in_array($option, $newOptions))
1109
						{
1110
							$takenKeys[] = $k;
1111
							continue;
1112
						}
1113
					}
1114
1115
					// Finally - have we renamed it - or is it really gone?
1116
					foreach ($optionChanges as $k => $option)
1117
					{
1118
						// Just been renamed?
1119
						if (!in_array($k, $takenKeys) && !empty($newOptions[$k]))
1120
							updateRenamedProfileField($k, $newOptions, $context['field']['colname'], $option);
1121
					}
1122
				}
1123
				// @todo Maybe we should adjust based on new text length limits?
1124
1125
				// And finally update an existing field
1126
				$field_data = array(
1127
					'field_length' => $field_length,
1128
					'show_reg' => $show_reg,
1129
					'show_display' => $show_display,
1130
					'show_memberlist' => $show_memberlist,
1131
					'private' => $private,
1132
					'active' => $active,
1133
					'can_search' => $can_search,
1134
					'bbc' => $bbc,
1135
					'current_field' => $context['fid'],
1136
					'field_name' => $this->_req->post->field_name,
1137
					'field_desc' => $this->_req->post->field_desc,
1138
					'field_type' => $this->_req->post->field_type,
1139
					'field_options' => $field_options,
1140
					'show_profile' => $show_profile,
1141
					'default_value' => $default,
1142
					'mask' => $mask,
1143
					'enclose' => $enclose,
1144
					'placement' => $placement,
1145
					'rows' => $rows,
1146
					'cols' => $cols,
1147
				);
1148
1149
				updateProfileField($field_data);
1150
1151
				// Just clean up any old selects - these are a pain!
1152
				if (($this->_req->post->field_type == 'select' || $this->_req->post->field_type == 'radio') && !empty($newOptions))
1153
					deleteOldProfileFieldSelects($newOptions, $context['field']['colname']);
1154
			}
1155
		}
1156
		// Deleting?
1157
		elseif (isset($this->_req->post->delete) && $context['field']['colname'])
1158
		{
1159
			checkSession();
1160
			validateToken('admin-ecp');
1161
1162
			// Delete the old data first, then the field.
1163
			deleteProfileFieldUserData($context['field']['colname']);
1164
			deleteProfileField($context['fid']);
1165
		}
1166
1167
		// Rebuild display cache etc.
1168
		if (isset($this->_req->post->delete) || isset($this->_req->post->save) || isset($this->_req->post->onoff))
1169
		{
1170
			checkSession();
1171
1172
			// Update the display cache
1173
			updateDisplayCache();
1174
			redirectexit('action=admin;area=featuresettings;sa=profile');
1175
		}
1176
1177
		createToken('admin-ecp');
1178
	}
1179
1180
	/**
1181
	 * Editing personal messages settings
1182
	 *
1183
	 * - Accessed with ?action=admin;area=featuresettings;sa=pmsettings
1184
	 *
1185
	 * @event integrate_save_pmsettings_settings
1186
	 */
1187
	public function action_pmsettings()
1188
	{
1189
		global $txt, $scripturl, $context;
1190
1191
		// Initialize the form
1192
		$settingsForm = new Settings_Form(Settings_Form::DB_ADAPTER);
1193
1194
		// Initialize it with our settings
1195
		$settingsForm->setConfigVars($this->_pmSettings());
1196
1197
		require_once(SUBSDIR . '/PersonalMessage.subs.php');
1198
		loadLanguage('ManageMembers');
1199
1200
		$context['pm_limits'] = loadPMLimits();
1201
1202
		// Saving?
1203
		if (isset($this->_req->query->save))
1204
		{
1205
			checkSession();
1206
1207
			require_once(SUBSDIR . '/Membergroups.subs.php');
1208
			foreach ($context['pm_limits'] as $group_id => $group)
1209
			{
1210
				if (isset($this->_req->post->group[$group_id]) && $this->_req->post->group[$group_id] != $group['max_messages'])
1211
					updateMembergroupProperties(array('current_group' => $group_id, 'max_messages' => $this->_req->post->group[$group_id]));
1212
			}
1213
1214
			call_integration_hook('integrate_save_pmsettings_settings');
1215
1216
			$settingsForm->setConfigValues((array) $this->_req->post);
1217
			$settingsForm->save();
1218
			redirectexit('action=admin;area=featuresettings;sa=pmsettings');
1219
		}
1220
1221
		$context['post_url'] = $scripturl . '?action=admin;area=featuresettings;save;sa=pmsettings';
1222
		$context['settings_title'] = $txt['personal_messages'];
1223
1224
		$settingsForm->prepare();
1225
	}
1226
1227
	/**
1228
	 * Return basic feature settings.
1229
	 *
1230
	 * @event integrate_modify_basic_settings Adds to General features and Options
1231
	 */
1232
	private function _basicSettings()
1233
	{
1234
		global $txt;
1235
1236
		$config_vars = array(
1237
				// Basic stuff, titles, permissions...
1238
				array('check', 'allow_guestAccess'),
1239
				array('check', 'enable_buddylist'),
1240
				array('check', 'allow_editDisplayName'),
1241
				array('check', 'allow_hideOnline'),
1242
				array('check', 'titlesEnable'),
1243
			'',
1244
				// Javascript and CSS options
1245
				array('select', 'jquery_source', array('auto' => $txt['jquery_auto'], 'local' => $txt['jquery_local'], 'cdn' => $txt['jquery_cdn'])),
1246
				array('check', 'jquery_default', 'onchange' => 'showhideJqueryOptions();'),
1247
				array('text', 'jquery_version', 'postinput' => $txt['jquery_custom_after']),
1248
				array('check', 'jqueryui_default', 'onchange' => 'showhideJqueryOptions();'),
1249
				array('text', 'jqueryui_version', 'postinput' => $txt['jqueryui_custom_after']),
1250
				array('check', 'minify_css_js', 'postinput' => '<a href="#" id="clean_hives" class="linkbutton">' . $txt['clean_hives'] . '</a>'),
1251
			'',
1252
				// Number formatting, timezones.
1253
				array('text', 'time_format'),
1254
				array('float', 'time_offset', 'subtext' => $txt['setting_time_offset_note'], 6, 'postinput' => $txt['hours']),
1255
				'default_timezone' => array('select', 'default_timezone', array()),
1256
			'',
1257
				// Who's online?
1258
				array('check', 'who_enabled'),
1259
				array('int', 'lastActive', 6, 'postinput' => $txt['minutes']),
1260
			'',
1261
				// Statistics.
1262
				array('check', 'trackStats'),
1263
				array('check', 'hitStats'),
1264
			'',
1265
				// Option-ish things... miscellaneous sorta.
1266
				array('check', 'metadata_enabled'),
1267
				array('check', 'allow_disableAnnounce'),
1268
				array('check', 'disallow_sendBody'),
1269
				array('select', 'enable_contactform', array('disabled' => $txt['contact_form_disabled'], 'registration' => $txt['contact_form_registration'], 'menu' => $txt['contact_form_menu'])),
1270
		);
1271
1272
		// Get all the time zones.
1273
		$all_zones = timezone_identifiers_list();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $all_zones is correct as timezone_identifiers_list() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
1274
		if ($all_zones === false)
1275
			unset($config_vars['default_timezone']);
1276
		else
1277
		{
1278
			// Make sure we set the value to the same as the printed value.
1279
			foreach ($all_zones as $zone)
0 ignored issues
show
Bug introduced by
The expression $all_zones of type void is not traversable.
Loading history...
1280
				$config_vars['default_timezone'][2][$zone] = $zone;
1281
		}
1282
1283
		call_integration_hook('integrate_modify_basic_settings', array(&$config_vars));
1284
1285
		return $config_vars;
1286
	}
1287
1288
	/**
1289
	 * Public method to return the basic settings, used for admin search
1290
	 */
1291
	public function basicSettings_search()
1292
	{
1293
		return $this->_basicSettings();
1294
	}
1295
1296
	/**
1297
	 * Return layout settings.
1298
	 *
1299
	 * @event integrate_modify_layout_settings Adds options to Configuration->Layout
1300
	 */
1301
	private function _layoutSettings()
1302
	{
1303
		global $txt;
1304
1305
		$config_vars = array_merge(getFrontPageControllers(), array(
1306
			'',
1307
				// Pagination stuff.
1308
				array('check', 'compactTopicPagesEnable'),
1309
				array('int', 'compactTopicPagesContiguous', 'subtext' => str_replace(' ', '&nbsp;', '"3" ' . $txt['to_display'] . ': <strong>1 ... 4 [5] 6 ... 9</strong>') . '<br />' . str_replace(' ', '&nbsp;', '"5" ' . $txt['to_display'] . ': <strong>1 ... 3 4 [5] 6 7 ... 9</strong>')),
1310
				array('int', 'defaultMaxMembers'),
1311
				array('check', 'displayMemberNames'),
1312
			'',
1313
				// Stuff that just is everywhere - today, search, online, etc.
1314
				array('select', 'todayMod', array($txt['today_disabled'], $txt['today_only'], $txt['yesterday_today'], $txt['relative_time'])),
1315
				array('check', 'onlineEnable'),
1316
				array('check', 'enableVBStyleLogin'),
1317
			'',
1318
				// Automagic image resizing.
1319
				array('int', 'max_image_width', 'subtext' => $txt['zero_for_no_limit']),
1320
				array('int', 'max_image_height', 'subtext' => $txt['zero_for_no_limit']),
1321
			'',
1322
				// This is like debugging sorta.
1323
				array('check', 'timeLoadPageEnable'),
1324
		));
1325
1326
		call_integration_hook('integrate_modify_layout_settings', array(&$config_vars));
1327
1328
		return $config_vars;
1329
	}
1330
1331
	/**
1332
	 * Public method to return the layout settings, used for admin search
1333
	 */
1334
	public function layoutSettings_search()
1335
	{
1336
		return $this->_layoutSettings();
1337
	}
1338
1339
	/**
1340
	 * Return karma settings.
1341
	 *
1342
	 * @event integrate_modify_karma_settings Adds to Configuration->Karma
1343
	 */
1344
	private function _karmaSettings()
1345
	{
1346
		global $txt;
1347
1348
		$config_vars = array(
1349
				// Karma - On or off?
1350
				array('select', 'karmaMode', explode('|', $txt['karma_options'])),
1351
			'',
1352
				// Who can do it.... and who is restricted by time limits?
1353
				array('int', 'karmaMinPosts', 6, 'postinput' => $txt['manageposts_posts']),
1354
				array('float', 'karmaWaitTime', 6, 'postinput' => $txt['hours']),
1355
				array('check', 'karmaTimeRestrictAdmins'),
1356
				array('check', 'karmaDisableSmite'),
1357
			'',
1358
				// What does it look like?  [smite]?
1359
				array('text', 'karmaLabel'),
1360
				array('text', 'karmaApplaudLabel', 'mask' => 'nohtml'),
1361
				array('text', 'karmaSmiteLabel', 'mask' => 'nohtml'),
1362
		);
1363
1364
		call_integration_hook('integrate_modify_karma_settings', array(&$config_vars));
1365
1366
		return $config_vars;
1367
	}
1368
1369
	/**
1370
	 * Public method to return the karma settings, used for admin search
1371
	 */
1372
	public function karmaSettings_search()
1373
	{
1374
		return $this->_karmaSettings();
1375
	}
1376
1377
	/**
1378
	 * Return likes settings.
1379
	 *
1380
	 * @event integrate_modify_likes_settings Adds to Configuration->Likes
1381
	 */
1382
	private function _likesSettings()
1383
	{
1384
		global $txt;
1385
1386
		$config_vars = array(
1387
				// Likes - On or off?
1388
				array('check', 'likes_enabled'),
1389
			'',
1390
				// Who can do it.... and who is restricted by count limits?
1391
				array('int', 'likeMinPosts', 6, 'postinput' => $txt['manageposts_posts']),
1392
				array('int', 'likeWaitTime', 6, 'postinput' => $txt['minutes']),
1393
				array('int', 'likeWaitCount', 6),
1394
				array('check', 'likeRestrictAdmins'),
1395
				array('check', 'likeAllowSelf'),
1396
			'',
1397
				array('int', 'likeDisplayLimit', 6)
1398
		);
1399
1400
		call_integration_hook('integrate_modify_likes_settings', array(&$config_vars));
1401
1402
		return $config_vars;
1403
	}
1404
1405
	/**
1406
	 * Public method to return the likes settings, used for admin search
1407
	 */
1408
	public function likesSettings_search()
1409
	{
1410
		return $this->_likesSettings();
1411
	}
1412
1413
	/**
1414
	 * Return mentions settings.
1415
	 *
1416
	 * @event integrate_modify_mention_settings Adds to Configuration->Mentions
1417
	 */
1418
	private function _notificationsSettings()
1419
	{
1420
		global $txt, $modSettings;
1421
1422
		loadLanguage('Profile');
1423
		loadLanguage('UserNotifications');
1424
1425
		// The mentions settings
1426
		$config_vars = array(
1427
			array('title', 'mentions_settings'),
1428
			array('check', 'mentions_enabled'),
1429
		);
1430
1431
		$notification_methods = Notifications::instance()->getNotifiers();
1432
		list($notification_types, $frequency) = getNotificationTypes();
1433
		$current_settings = unserialize($modSettings['notification_methods']);
1434
1435
		foreach ($notification_types as $title)
1436
		{
1437
			$config_vars[] = array('title', 'setting_' . $title);
1438
1439
			foreach ($notification_methods as $key => $method)
1440
			{
1441
				// If the method is available in this area, show the option
1442
				if (in_array($method, $frequency[$title]))
1443
				{
1444
					if ($method === 'notification')
1445
					{
1446
						$text_label = $txt['setting_notify_enable_this'];
1447
					}
1448
					else
1449
					{
1450
						$text_label = $txt['notify_' . $method];
1451
					}
1452
1453
					$config_vars[] = array('check', 'notifications[' . $title . '][' . $method . ']', 'text_label' => $text_label);
1454
					$modSettings['notifications[' . $title . '][' . $method . ']'] = !empty($current_settings[$title][$method]);
1455
				}
1456
			}
1457
		}
1458
1459
		call_integration_hook('integrate_modify_mention_settings', array(&$config_vars));
1460
1461
		return $config_vars;
1462
	}
1463
1464
	/**
1465
	 * Public method to return the mention settings, used for admin search
1466
	 */
1467
	public function mentionSettings_search()
1468
	{
1469
		return $this->_notificationsSettings();
1470
	}
1471
1472
	/**
1473
	 * Return signature settings.
1474
	 *
1475
	 * - Used in admin center search and settings form
1476
	 *
1477
	 * @event integrate_modify_signature_settings Adds options to Signature Settings
1478
	 */
1479
	private function _signatureSettings()
1480
	{
1481
		global $txt;
1482
1483
		$config_vars = array(
1484
				// Are signatures even enabled?
1485
				array('check', 'signature_enable'),
1486
			'',
1487
				// Tweaking settings!
1488
				array('int', 'signature_max_length', 'subtext' => $txt['zero_for_no_limit']),
1489
				array('int', 'signature_max_lines', 'subtext' => $txt['zero_for_no_limit']),
1490
				array('int', 'signature_max_font_size', 'subtext' => $txt['zero_for_no_limit']),
1491
				array('check', 'signature_allow_smileys', 'onclick' => 'document.getElementById(\'signature_max_smileys\').disabled = !this.checked;'),
1492
				array('int', 'signature_max_smileys', 'subtext' => $txt['zero_for_no_limit']),
1493
				array('select', 'signature_repetition_guests',
1494
					array(
1495
						$txt['signature_always'],
1496
						$txt['signature_onlyfirst'],
1497
						$txt['signature_never'],
1498
					),
1499
				),
1500
				array('select', 'signature_repetition_members',
1501
					array(
1502
						$txt['signature_always'],
1503
						$txt['signature_onlyfirst'],
1504
						$txt['signature_never'],
1505
					),
1506
				),
1507
			'',
1508
				// Image settings.
1509
				array('int', 'signature_max_images', 'subtext' => $txt['signature_max_images_note']),
1510
				array('int', 'signature_max_image_width', 'subtext' => $txt['zero_for_no_limit']),
1511
				array('int', 'signature_max_image_height', 'subtext' => $txt['zero_for_no_limit']),
1512
			'',
1513
				array('bbc', 'signature_bbc'),
1514
		);
1515
1516
		call_integration_hook('integrate_modify_signature_settings', array(&$config_vars));
1517
1518
		return $config_vars;
1519
	}
1520
1521
	/**
1522
	 * Public method to return the signature settings, used for admin search
1523
	 */
1524
	public function signatureSettings_search()
1525
	{
1526
		return $this->_signatureSettings();
1527
	}
1528
1529
	/**
1530
	 * Return pm settings.
1531
	 *
1532
	 * - Used in admin center search and settings form
1533
	 *
1534
	 * @event integrate_modify_pmsettings_settings Adds / Modifies PM Settings
1535
	 */
1536
	private function _pmSettings()
1537
	{
1538
		global $txt;
1539
1540
		$config_vars = array(
1541
			// Reporting of personal messages?
1542
			array('check', 'enableReportPM'),
1543
			// Inline permissions.
1544
			array('permissions', 'pm_send'),
1545
			// PM Settings
1546
			array('title', 'antispam_PM'),
1547
				'pm1' => array('int', 'max_pm_recipients', 'postinput' => $txt['max_pm_recipients_note']),
1548
				'pm2' => array('int', 'pm_posts_verification', 'postinput' => $txt['pm_posts_verification_note']),
1549
				'pm3' => array('int', 'pm_posts_per_hour', 'postinput' => $txt['pm_posts_per_hour_note']),
1550
			array('title', 'membergroups_max_messages'),
1551
				array('desc', 'membergroups_max_messages_desc'),
1552
				array('callback', 'pm_limits'),
1553
		);
1554
1555
		call_integration_hook('integrate_modify_pmsettings_settings', array(&$config_vars));
1556
1557
		return $config_vars;
1558
	}
1559
}
1560
1561
/**
1562
 * Just pause the signature applying thing.
1563
 *
1564
 * @todo Move to subs file
1565
 * @todo Merge with other pause functions?
1566
 *    pausePermsSave(), pauseAttachmentMaintenance(), pauseRepairProcess()
1567
 *
1568
 * @param int $applied_sigs
1569
 * @throws Elk_Exception
1570
 */
1571
function pauseSignatureApplySettings($applied_sigs)
1572
{
1573
	global $context, $txt, $sig_start;
1574
1575
	// Try get more time...
1576
	detectServer()->setTimeLimit(600);
1577
1578
	// Have we exhausted all the time we allowed?
1579
	if (time() - array_sum(explode(' ', $sig_start)) < 3)
1580
		return;
1581
1582
	$context['continue_get_data'] = '?action=admin;area=featuresettings;sa=sig;apply;step=' . $applied_sigs . ';' . $context['session_var'] . '=' . $context['session_id'];
1583
	$context['page_title'] = $txt['not_done_title'];
1584
	$context['continue_post_data'] = '';
1585
	$context['continue_countdown'] = '2';
1586
	$context['sub_template'] = 'not_done';
1587
1588
	// Specific stuff to not break this template!
1589
	$context[$context['admin_menu_name']]['current_subsection'] = 'sig';
1590
1591
	// Get the right percent.
1592
	$context['continue_percent'] = round(($applied_sigs / $context['max_member']) * 100);
1593
1594
	// Never more than 100%!
1595
	$context['continue_percent'] = min($context['continue_percent'], 100);
1596
1597
	obExit();
1598
}
1599