ManageSearchEngines::action_editspiders()   B
last analyzed

Complexity

Conditions 6
Paths 8

Size

Total Lines 54
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
cc 6
eloc 27
c 0
b 0
f 0
nc 8
nop 0
dl 0
loc 54
ccs 0
cts 24
cp 0
crap 42
rs 8.8657

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
 * This file contains all the screens that relate to search engines.
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 ElkArte\AbstractController;
20
use ElkArte\Action;
21
use ElkArte\Cache\Cache;
22
use ElkArte\Languages\Txt;
23
use ElkArte\SettingsForm\SettingsForm;
24
25
/**
26
 * ManageSearchEngines admin controller. This class handles all search engines
27
 * pages in admin panel, forwards to display and allows to change options.
28
 *
29
 * @package SearchEngines
30
 */
31
class ManageSearchEngines extends AbstractController
32
{
33
	/**
34
	 * Entry point for this section.
35
	 *
36
	 * @event integrate_sa_manage_search_engines add additonal search engine actions
37
	 * @see AbstractController::action_index()
38
	 */
39
	public function action_index()
40
	{
41
		global $context, $txt;
42
43
		Txt::load('Search');
44
		theme()->getTemplates()->load('ManageSearch');
45
46
		$subActions = array(
47
			'editspiders' => array($this, 'action_editspiders', 'permission' => 'admin_forum'),
48
			'logs' => array($this, 'action_logs', 'permission' => 'admin_forum'),
49
			'settings' => array($this, 'action_engineSettings_display', 'permission' => 'admin_forum'),
50
			'spiders' => array($this, 'action_spiders', 'permission' => 'admin_forum'),
51
			'stats' => array($this, 'action_stats', 'permission' => 'admin_forum'),
52
		);
53
54
		// Control
55
		$action = new Action('manage_search_engines');
56
57
		// Ensure we have a valid subaction. call integrate_sa_manage_search_engines
58
		$subAction = $action->initialize($subActions, 'stats');
59
60
		// Some contextual data for the template.
61
		$context['sub_action'] = $subAction;
62
		$context['page_title'] = $txt['search_engines'];
63
64
		// Some more tab data.
65
		$context[$context['admin_menu_name']]['object']->prepareTabData([
66
			'title' => 'search_engines',
67
			'description' => 'search_engines_description',
68
		]);
69
70
		// Call the right function for this sub-action.
71
		$action->dispatch($subAction);
72
	}
73
74
	/**
75
	 * This is the admin settings page for search engines.
76
	 *
77
	 * @event integrate_save_search_engine_settings
78
	 */
79
	public function action_engineSettings_display()
80
	{
81
		global $context, $txt;
82
83
		// Initialize the form
84
		$settingsForm = new SettingsForm(SettingsForm::DB_ADAPTER);
85
86
		// Initialize it with our settings
87
		$config_vars = $this->_settings();
88
		$settingsForm->setConfigVars($config_vars);
89
90
		// Set up a message.
91
		$context['settings_message'] = sprintf($txt['spider_settings_desc'], getUrl('admin', ['action' => 'admin', 'area' => 'logs', 'sa' => 'pruning', '{session_data}']));
92
93
		// Make sure it's valid - note that regular members are given id_group = 1 which is reversed in Load.php - no admins here!
94
		if (isset($this->_req->post->spider_group) && !isset($config_vars['spider_group'][2][$this->_req->post->spider_group]))
95
		{
96
			$this->_req->post->spider_group = 0;
97
		}
98
99
		// Setup the template.
100
		$context['page_title'] = $txt['settings'];
101
		$context['sub_template'] = 'show_settings';
102
103
		// Are we saving them - are we??
104
		if (isset($this->_req->query->save))
105
		{
106
			// security checks
107
			checkSession();
108
109
			// notify the interested addons or integrations
110
			call_integration_hook('integrate_save_search_engine_settings');
111
112
			// save the results!
113
			$settingsForm->setConfigValues((array) $this->_req->post);
114
			$settingsForm->save();
115
116
			// make sure to rebuild the cache with updated results
117
			recacheSpiderNames();
118
119
			// We're done with this.
120
			redirectexit('action=admin;area=sengines;sa=settings');
121
		}
122
123
		// Set up some details for the template.
124
		$context['post_url'] = getUrl('admin', ['action' => 'admin', 'area' => 'sengines', 'save', 'sa' => 'settings']);
125
		$context['settings_title'] = $txt['settings'];
126
127
		// Do some javascript.
128
		$javascript_function = '
129
			function disableFields()
130
			{
131
				disabledState = document.getElementById(\'spider_mode\').value == 0;';
132
133
		foreach ($config_vars as $variable)
134
		{
135
			if ($variable[1] !== 'spider_mode')
136
			{
137
				$javascript_function .= '
138
				if (document.getElementById(\'' . $variable[1] . '\'))
139
					document.getElementById(\'' . $variable[1] . "').disabled = disabledState;";
140
			}
141
		}
142
143
		$javascript_function .= '
144
			}
145
			disableFields();';
146
147
		theme()->addInlineJavascript($javascript_function, true);
148
149
		// Prepare the settings...
150
		$settingsForm->prepare();
151
	}
152
153
	/**
154
	 * Return configuration settings for search engines
155
	 *
156
	 * @event integrate_modify_search_engine_settings
157 2
	 */
158
	private function _settings()
159 2
	{
160
		global $txt;
161
162
		$config_vars = array(
163 2
			// How much detail?
164 2
			array('select', 'spider_mode', 'subtext' => $txt['spider_mode_note'], array($txt['spider_mode_off'], $txt['spider_mode_standard'], $txt['spider_mode_high'], $txt['spider_mode_vhigh']), 'onchange' => 'disableFields();'),
165 2
			'spider_group' => array('select', 'spider_group', 'subtext' => $txt['spider_group_note'], array($txt['spider_group_none'])),
166
			array('check', 'spider_no_guest', 'subtext' => $txt['spider_no_guest_note']),
167
			array('select', 'show_spider_online', array($txt['show_spider_online_no'], $txt['show_spider_online_summary'], $txt['show_spider_online_detail'], $txt['show_spider_online_detail_admin'])),
168 2
		);
169 2
170
		require_once(SUBSDIR . '/SearchEngines.subs.php');
171 2
		require_once(SUBSDIR . '/Membergroups.subs.php');
172 2
173
		$groups = getBasicMembergroupData(array('globalmod', 'postgroups', 'protected', 'member'));
174
		foreach ($groups as $row)
175 2
		{
176
			// Unfortunately, regular members have to be 1 because 0 is for disabled.
177 2
			if ($row['id'] == 0)
178
			{
179
				$config_vars['spider_group'][2][1] = $row['name'];
180
			}
181 2
			else
182
			{
183
				$config_vars['spider_group'][2][$row['id']] = $row['name'];
184
			}
185
		}
186 2
187
		// Notify the integration that we're preparing to mess up with search engine settings...
188 2
		call_integration_hook('integrate_modify_search_engine_settings', array(&$config_vars));
189
190
		return $config_vars;
191
	}
192
193
	/**
194 2
	 * Return the search engine settings for use in admin search
195
	 */
196 2
	public function settings_search()
197
	{
198
		return $this->_settings();
199
	}
200
201
	/**
202
	 * View a list of all the spiders we know about.
203
	 *
204
	 * @event integrate_list_spider_list
205
	 */
206
	public function action_spiders()
207
	{
208
		global $context, $txt;
209
210
		// We'll need to do hard work here.
211
		require_once(SUBSDIR . '/SearchEngines.subs.php');
212
213
		if (!isset($_SESSION['spider_stat']) || $_SESSION['spider_stat'] < time() - 60)
214
		{
215
			consolidateSpiderStats();
216
			$_SESSION['spider_stat'] = time();
217
		}
218
219
		// Are we adding a new one?
220
		if (!empty($this->_req->post->addSpider))
221
		{
222
			$this->action_editspiders();
223
			return;
224
		}
225
226
		// User pressed the 'remove selection button'.
227
		if (!empty($this->_req->post->removeSpiders) && !empty($this->_req->post->remove) && is_array($this->_req->post->remove))
228
		{
229
			checkSession();
230
			validateToken('admin-ser');
231
232
			// Make sure every entry is a proper integer.
233
			$toRemove = array_map('intval', $this->_req->post->remove);
234
235
			// Delete them all!
236
			removeSpiders($toRemove);
237
			Cache::instance()->remove('spider_search');
238
			recacheSpiderNames();
239
		}
240
241
		// Get the last seen's.
242
		$context['spider_last_seen'] = spidersLastSeen();
243
244
		// Token for the ride
245
		createToken('admin-ser');
246
247
		// Build the list
248
		$listOptions = array(
249
			'id' => 'spider_list',
250
			'title' => $txt['spiders'],
251
			'items_per_page' => 20,
252
			'base_href' => getUrl('admin', ['action' => 'admin', 'area' => 'sengines', 'sa' => 'spiders']),
253
			'default_sort_col' => 'name',
254
			'get_items' => array(
255
				'function' => 'getSpiders',
256
			),
257
			'get_count' => array(
258
				'function' => 'getNumSpiders',
259
				'file' => SUBSDIR . '/SearchEngines.subs.php',
260
			),
261
			'no_items_label' => $txt['spiders_no_entries'],
262
			'columns' => array(
263
				'name' => array(
264
					'header' => array(
265
						'value' => $txt['spider_name'],
266
					),
267
					'data' => array(
268
						'function' => static fn($rowData) => sprintf('<a href=' . getUrl('admin', ['action' => 'admin', 'area' => 'sengines', 'sa' => 'editspiders', 'sid' => $rowData['id_spider']]) . '">%1$s</a>', htmlspecialchars($rowData['spider_name'], ENT_COMPAT, 'UTF-8')),
269
					),
270
					'sort' => array(
271
						'default' => 'spider_name',
272
						'reverse' => 'spider_name DESC',
273
					),
274
				),
275
				'last_seen' => array(
276
					'header' => array(
277
						'value' => $txt['spider_last_seen'],
278
					),
279
					'data' => array(
280
						'function' => static function ($rowData) {
281
							global $context, $txt;
282
283
							return isset($context['spider_last_seen'][$rowData['id_spider']]) ? standardTime($context['spider_last_seen'][$rowData['id_spider']]) : $txt['spider_last_never'];
284
						},
285
					),
286
				),
287
				'user_agent' => array(
288
					'header' => array(
289
						'value' => $txt['spider_agent'],
290
					),
291
					'data' => array(
292
						'db_htmlsafe' => 'user_agent',
293
					),
294
					'sort' => array(
295
						'default' => 'user_agent',
296
						'reverse' => 'user_agent DESC',
297
					),
298
				),
299
				'ip_info' => array(
300
					'header' => array(
301
						'value' => $txt['spider_ip_info'],
302
					),
303
					'data' => array(
304
						'db_htmlsafe' => 'ip_info',
305
						'class' => 'smalltext',
306
					),
307
					'sort' => array(
308
						'default' => 'ip_info',
309
						'reverse' => 'ip_info DESC',
310
					),
311
				),
312
				'check' => array(
313
					'header' => array(
314
						'value' => '<input type="checkbox" onclick="invertAll(this, this.form);" class="input_check" />',
315
						'class' => 'centertext',
316
					),
317
					'data' => array(
318
						'sprintf' => array(
319
							'format' => '<input type="checkbox" name="remove[]" value="%1$d" class="input_check" />',
320
							'params' => array(
321
								'id_spider' => false,
322
							),
323
						),
324
						'class' => 'centertext',
325
					),
326
				),
327
			),
328
			'form' => array(
329
				'href' => getUrl('admin', ['action' => 'admin', 'area' => 'sengines', 'sa' => 'spiders']),
330
				'token' => 'admin-ser',
331
			),
332
			'additional_rows' => array(
333
				array(
334
					'class' => 'submitbutton',
335
					'position' => 'bottom_of_list',
336
					'value' => '
337
						<input type="submit" name="removeSpiders" value="' . $txt['spiders_remove_selected'] . '" onclick="return confirm(\'' . $txt['spider_remove_selected_confirm'] . '\');" />
338
						<input type="submit" name="addSpider" value="' . $txt['spiders_add'] . '" class="right_submit" />
339
					',
340
				),
341
			),
342
		);
343
344
		createList($listOptions);
345
346
		$context['sub_template'] = 'show_list';
347
		$context['default_list'] = 'spider_list';
348
	}
349
350
	/**
351
	 * Here we can add, and edit, spider info!
352
	 */
353
	public function action_editspiders()
354
	{
355
		global $context, $txt;
356
357
		// Some standard stuff.
358
		$context['id_spider'] = $this->_req->getQuery('sid', 'intval', 0);
359
		$context['page_title'] = $context['id_spider'] ? $txt['spiders_edit'] : $txt['spiders_add'];
360
		$context['sub_template'] = 'spider_edit';
361
		require_once(SUBSDIR . '/SearchEngines.subs.php');
362
363
		// Are we saving?
364
		if (!empty($this->_req->post->save))
365
		{
366
			checkSession();
367
			validateToken('admin-ses');
368
369
			// Check the IP range is valid.
370
			$ips = array();
371
			$ip_sets = explode(',', $this->_req->post->spider_ip);
372
			foreach ($ip_sets as $set)
373
			{
374
				$test = ip2range(trim($set));
375
				if (!empty($test))
376
				{
377
					$ips[] = $set;
378
				}
379
			}
380
381
			$ips = implode(',', $ips);
382
383
			// Goes in as it is...
384
			updateSpider($context['id_spider'], $this->_req->post->spider_name, $this->_req->post->spider_agent, $ips);
385
386
			Cache::instance()->remove('spider_search');
387
			recacheSpiderNames();
388
389
			redirectexit('action=admin;area=sengines;sa=spiders');
390
		}
391
392
		// The default is new.
393
		$context['spider'] = array(
394
			'id' => 0,
395
			'name' => '',
396
			'agent' => '',
397
			'ip_info' => '',
398
		);
399
400
		// An edit?
401
		if ($context['id_spider'])
402
		{
403
			$context['spider'] = getSpiderDetails($context['id_spider']);
404
		}
405
406
		createToken('admin-ses');
407
	}
408
409
	/**
410
	 * See what spiders have been up to.
411
	 *
412
	 * @event integrate_list_spider_logs
413
	 */
414
	public function action_logs()
415
	{
416
		global $context, $txt, $modSettings;
417
418
		// Load the template and language just incase.
419
		Txt::load('Search');
420
		theme()->getTemplates()->load('ManageSearch');
421
422
		// Did they want to delete some or all entries?
423
		if ((!empty($this->_req->post->delete_entries) && isset($this->_req->post->older)) || !empty($this->_req->post->removeAll))
424
		{
425
			checkSession();
426
			validateToken('admin-sl');
427
428
			$since = $this->_req->getPost('older', 'intval', 0);
429
			$deleteTime = time() - ($since * 24 * 60 * 60);
430
431
			// Delete the entries.
432
			require_once(SUBSDIR . '/SearchEngines.subs.php');
433
			removeSpiderOldLogs($deleteTime);
434
		}
435
436
		// Build out the spider log list
437
		$listOptions = array(
438
			'id' => 'spider_logs',
439
			'items_per_page' => 20,
440
			'title' => $txt['spider_logs'],
441
			'no_items_label' => $txt['spider_logs_empty'],
442
			'base_href' => $context['admin_area'] === 'sengines' ? getUrl('admin', ['action' => 'admin', 'area' => 'sengines', 'sa' => 'logs']) : getUrl('admin', ['action' => 'admin', 'area' => 'logs', 'sa' => 'spiderlog']),
443
			'default_sort_col' => 'log_time',
444
			'get_items' => array(
445
				'function' => 'getSpiderLogs',
446
			),
447
			'get_count' => array(
448
				'function' => 'getNumSpiderLogs',
449
				'file' => SUBSDIR . '/SearchEngines.subs.php',
450
			),
451
			'columns' => array(
452
				'name' => array(
453
					'header' => array(
454
						'value' => $txt['spider'],
455
					),
456
					'data' => array(
457
						'db' => 'spider_name',
458
					),
459
					'sort' => array(
460
						'default' => 's.spider_name',
461
						'reverse' => 's.spider_name DESC',
462
					),
463
				),
464
				'log_time' => array(
465
					'header' => array(
466
						'value' => $txt['spider_time'],
467
					),
468
					'data' => array(
469
						'function' => static fn($rowData) => standardTime($rowData['log_time']),
470
					),
471
					'sort' => array(
472
						'default' => 'sl.id_hit DESC',
473
						'reverse' => 'sl.id_hit',
474
					),
475
				),
476
				'viewing' => array(
477
					'header' => array(
478
						'value' => $txt['spider_viewing'],
479
					),
480
					'data' => array(
481
						'db' => 'url',
482
					),
483
				),
484
			),
485
			'form' => array(
486
				'token' => 'admin-sl',
487
				'href' => getUrl('admin', ['action' => 'admin', 'area' => 'sengines', 'sa' => 'logs']),
488
			),
489
			'additional_rows' => array(
490
				array(
491
					'position' => 'after_title',
492
					'value' => $txt['spider_logs_info'],
493
				),
494
				array(
495
					'position' => 'below_table_data',
496
					'value' => '<input type="submit" name="removeAll" value="' . $txt['spider_log_empty_log'] . '" onclick="return confirm(\'' . $txt['spider_log_empty_log_confirm'] . '\');" class="right_submit" />',
497
				),
498
			),
499
		);
500
501
		createToken('admin-sl');
502
		createList($listOptions);
503
504
		// Now determine the actions of the URLs.
505
		if (!empty($context['spider_logs']['rows']))
506
		{
507
			$urls = array();
508
509
			// Grab the current /url.
510
			foreach ($context['spider_logs']['rows'] as $k => $row)
511
			{
512
				// Feature disabled?
513
				if (empty($row['data']['viewing']['value']) && isset($modSettings['spider_mode']) && $modSettings['spider_mode'] < 3)
514
				{
515
					$context['spider_logs']['rows'][$k]['data']['viewing']['value'] = '<em>' . $txt['spider_disabled'] . '</em>';
516
				}
517
				else
518
				{
519
					$urls[$k] = array($row['data']['viewing']['value'], -1);
520
				}
521
			}
522
523
			// Now stick in the new URLs.
524
			require_once(SUBSDIR . '/Who.subs.php');
525
			$urls = determineActions($urls, 'whospider_');
526
			foreach ($urls as $k => $new_url)
527
			{
528
				$context['spider_logs']['rows'][$k]['data']['viewing']['value'] = $new_url;
529
			}
530
		}
531
532
		$context['page_title'] = $txt['spider_logs'];
533
		$context['sub_template'] = 'show_spider_logs';
534
	}
535
536
	/**
537
	 * Show the spider statistics.
538
	 *
539
	 * @event integrate_list_spider_stat_list
540
	 */
541
	public function action_stats()
542
	{
543
		global $context, $txt;
544
545
		// We'll need to do hard work here.
546
		require_once(SUBSDIR . '/SearchEngines.subs.php');
547
548
		// Force an update of the stats every 60 seconds.
549
		if (!isset($_SESSION['spider_stat']) || $_SESSION['spider_stat'] < time() - 60)
550
		{
551
			consolidateSpiderStats();
552
			$_SESSION['spider_stat'] = time();
553
		}
554
555
		// Are we cleaning up some old stats?
556
		if (!empty($this->_req->post->delete_entries) && isset($this->_req->post->older))
557
		{
558
			checkSession();
559
			validateToken('admin-ss');
560
561
			$deleteTime = time() - (((int) $this->_req->post->older) * 24 * 60 * 60);
562
563
			// Delete the entries.
564
			removeSpiderOldStats($deleteTime);
565
		}
566
567
		// Prepare the dates for the drop down.
568
		$date_choices = spidersStatsDates();
569
		$max_date = array_key_last($date_choices);
570
571
		// What are we currently viewing?
572
		$current_date = isset($this->_req->post->new_date, $date_choices[$this->_req->post->new_date]) ? $this->_req->post->new_date : $max_date;
573
574
		// Prepare the HTML.
575
		$date_select = '
576
			' . $txt['spider_stats_select_month'] . ':
577
			<select name="new_date" onchange="document.spider_stat_list.submit();">';
578
579
		if (empty($date_choices))
580
		{
581
			$date_select .= '
582
				<option></option>';
583
		}
584
		else
585
		{
586
			foreach ($date_choices as $id => $text)
587
			{
588
				$date_select .= '
589
				<option value="' . $id . '"' . ($current_date == $id ? ' selected="selected"' : '') . '>' . $text . '</option>';
590
			}
591
		}
592
593
		$date_select .= '
594
			</select>
595
			<noscript>
596
				<input type="submit" name="go" value="' . $txt['go'] . '" class="right_submit" />
597
			</noscript>';
598
599
		// If we manually jumped to a date work out the offset.
600
		if (isset($this->_req->post->new_date))
601
		{
602
			$date_query = sprintf('%04d-%02d-01', substr($current_date, 0, 4), substr($current_date, 4));
0 ignored issues
show
Bug introduced by
It seems like $current_date can also be of type null; however, parameter $string of substr() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

602
			$date_query = sprintf('%04d-%02d-01', substr(/** @scrutinizer ignore-type */ $current_date, 0, 4), substr($current_date, 4));
Loading history...
603
604
			$_REQUEST['start'] = getNumSpiderStats($date_query);
0 ignored issues
show
Bug introduced by
$date_query of type string is incompatible with the type integer|null expected by parameter $time of getNumSpiderStats(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

604
			$_REQUEST['start'] = getNumSpiderStats(/** @scrutinizer ignore-type */ $date_query);
Loading history...
605
		}
606
607
		$listOptions = array(
608
			'id' => 'spider_stat_list',
609
			'title' => $txt['spider'] . ' ' . $txt['spider_stats'],
610
			'items_per_page' => 20,
611
			'base_href' => getUrl('admin', ['action' => 'admin', 'area' => 'sengines', 'sa' => 'stats']),
612
			'default_sort_col' => 'stat_date',
613
			'get_items' => array(
614
				'function' => 'getSpiderStats',
615
			),
616
			'get_count' => array(
617
				'function' => 'getNumSpiderStats',
618
				'file' => SUBSDIR . '/SearchEngines.subs.php',
619
			),
620
			'no_items_label' => $txt['spider_stats_no_entries'],
621
			'columns' => array(
622
				'stat_date' => array(
623
					'header' => array(
624
						'value' => $txt['date'],
625
					),
626
					'data' => array(
627
						'db' => 'stat_date',
628
					),
629
					'sort' => array(
630
						'default' => 'stat_date',
631
						'reverse' => 'stat_date DESC',
632
					),
633
				),
634
				'name' => array(
635
					'header' => array(
636
						'value' => $txt['spider_name'],
637
					),
638
					'data' => array(
639
						'db' => 'spider_name',
640
					),
641
					'sort' => array(
642
						'default' => 's.spider_name',
643
						'reverse' => 's.spider_name DESC',
644
					),
645
				),
646
				'page_hits' => array(
647
					'header' => array(
648
						'value' => $txt['spider_stats_page_hits'],
649
					),
650
					'data' => array(
651
						'db' => 'page_hits',
652
					),
653
					'sort' => array(
654
						'default' => 'ss.page_hits',
655
						'reverse' => 'ss.page_hits DESC',
656
					),
657
				),
658
			),
659
			'form' => array(
660
				'href' => getUrl('admin', ['action' => 'admin', 'area' => 'sengines', 'sa' => 'stats']),
661
				'name' => 'spider_stat_list',
662
			),
663
			'additional_rows' => array(
664
				array(
665
					'position' => 'below_table_data',
666
					'value' => $date_select,
667
					'style' => 'text-align: right;',
668
				),
669
			),
670
		);
671
672
		createToken('admin-ss');
673
674
		createList($listOptions);
675
676
		$context['sub_template'] = 'show_spider_stats';
677
	}
678
}
679