Issues (1686)

themes/default/Packages.template.php (3 issues)

1
<?php
2
3
/**
4
 * @package   ElkArte Forum
5
 * @copyright ElkArte Forum contributors
6
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file)
7
 *
8
 * This file contains code covered by:
9
 * copyright: 2011 Simple Machines (http://www.simplemachines.org)
10
 *
11
 * @version 2.0 dev
12
 *
13
 */
14
15
/**
16
 * Shows the screen for the package install / uninstall
17
 * Displays license, readme, and test results
18
 */
19
function template_view_package()
20
{
21
	global $context, $settings, $txt, $scripturl;
22
23
	echo '
24
	<div id="admincenter">
25
		<h2 class="category_header">', $txt[($context['uninstalling'] ? 'un' : '') . 'install_mod'], '</h2>
26
		<div class="information">';
27
28
	if ($context['is_installed'])
29
	{
30
		echo '
31
			<strong>', $txt['package_installed_warning1'], '</strong><br />
32
			<br />
33
			', $txt['package_installed_warning2'], '<br />
34
			<br />';
35
	}
36
37
	echo $txt['package_installed_warning3'], '
38
		</div>';
39
40
	// Do errors exist in the install? If so light them up like a Christmas tree.
41
	if ($context['has_failure'])
42
	{
43
		echo '
44
		<div class="errorbox">
45
			', sprintf($txt['package_will_fail_title'], $txt['package_' . ($context['uninstalling'] ? 'uninstall' : 'install')]), '<br />
46
			', sprintf($txt['package_will_fail_warning'], $txt['package_' . ($context['uninstalling'] ? 'uninstall' : 'install')]),
47
		empty($context['failure_details']) ? '' : '<br /><br /><strong>' . $context['failure_details'] . '</strong>', '
48
		</div>';
49
	}
50
51
	// Display the package readme if one exists
52
	if (isset($context['package_readme']))
53
	{
54
		echo '
55
			<h2 class="category_header">', $txt['package_' . ($context['uninstalling'] ? 'un' : '') . 'install_readme'], '</h2>
56
			<div class="content">
57
				', $context['package_readme'], '
58
				<span class="floatright">', $txt['package_available_readme_language'], '
59
					<select name="readme_language" id="readme_language" onchange="if (this.options[this.selectedIndex].value) window.location.href = elk_prepareScriptUrl(elk_scripturl + \'', '?action=admin;area=packages;sa=', $context['uninstalling'] ? 'uninstall' : 'install', ';package=', $context['filename'], ';readme=\' + this.options[this.selectedIndex].value + \';license=\' + get_selected(\'license_language\'));">';
60
61
		foreach ($context['readmes'] as $a => $b)
62
		{
63
			echo '
64
						<option value="', $b, '"', $a === 'selected' ? ' selected="selected"' : '', '>', $b === 'default' ? $txt['package_readme_default'] : ucfirst($b), '</option>';
65
		}
66
67
		echo '
68
					</select>
69
				</span>
70
			</div>
71
			<br />';
72
	}
73
74
	// Did they specify a license to display?
75
	if (isset($context['package_license']))
76
	{
77
		echo '
78
			<h2 class="category_header">', $txt['package_install_license'], '</h2>
79
			<div class="content">
80
				', $context['package_license'], '
81
				<span class="floatright">', $txt['package_available_license_language'], '
82
					<select name="license_language" id="license_language" onchange="if (this.options[this.selectedIndex].value) window.location.href = elk_prepareScriptUrl(elk_scripturl + \'', '?action=admin;area=packages;sa=install', ';package=', $context['filename'], ';license=\' + this.options[this.selectedIndex].value + \';readme=\' + get_selected(\'readme_language\'));">';
83
84
		foreach ($context['licenses'] as $a => $b)
85
		{
86
			echo '
87
						<option value="', $b, '"', $a === 'selected' ? ' selected="selected"' : '', '>', $b === 'default' ? $txt['package_license_default'] : ucfirst($b), '</option>';
88
		}
89
90
		echo '
91
					</select>
92
				</span>
93
			</div>
94
			<br />';
95
	}
96
97
	if (!empty($context['post_url']))
98
	{
99
		echo '
100
		<form action="', $context['post_url'], '" onsubmit="submitonce(this);" method="post" accept-charset="UTF-8">';
101
	}
102
103
	echo '
104
			<h2 class="category_header">
105
				', $context['uninstalling'] ? $txt['package_uninstall_actions'] : $txt['package_install_actions'], ' &quot;', $context['package_name'], '&quot;
106
			</h2>';
107
108
	// Are there data changes to be removed?
109
	if ($context['uninstalling'] && !empty($context['database_changes']))
110
	{
111
		echo '
112
			<div class="content">
113
				<label for="do_db_changes"><input type="checkbox" name="do_db_changes" id="do_db_changes" />', $txt['package_db_uninstall'], '</label> [<a href="#" onclick="return swap_database_changes();">', $txt['package_db_uninstall_details'], '</a>]
114
				<div id="db_changes_div">
115
					', $txt['package_db_uninstall_actions'], ':
116
					<ul>';
117
118
		foreach ($context['database_changes'] as $change)
119
		{
120
			echo '
121
						<li>', $change, '</li>';
122
		}
123
124
		echo '
125
					</ul>
126
				</div>
127
			</div>';
128
	}
129
130
	echo '
131
			<div class="information">';
132
133
	if (empty($context['actions']) && empty($context['database_changes']))
134
	{
135
		echo '
136
				<br />
137
				<div class="errorbox">
138
					', $txt['corrupt_compatible'], '
139
				</div>
140
			</div>';
141
	}
142
	else
143
	{
144
		echo '
145
					', $txt['perform_actions'], '
146
			</div>
147
			<table class="table_grid">
148
			<thead>
149
				<tr class="table_head">
150
					<th scope="col" style="width: 20px;"></th>
151
					<th scope="col" style="width: 30px;"></th>
152
					<th scope="col" class="lefttext">', $txt['package_install_type'], '</th>
153
					<th scope="col" class="lefttext grid50">', $txt['package_install_action'], '</th>
154
					<th scope="col" class="lefttext grid20">', $txt['package_install_desc'], '</th>
155
				</tr>
156
			</thead>
157
			<tbody>';
158
159
		$i = 1;
160
		$action_num = 1;
161
		$js_operations = array();
162
		foreach ($context['actions'] as $packageaction)
163
		{
164
			// Did we pass or fail?  Need to know for later on.
165
			$js_operations[$action_num] = $packageaction['failed'] ?? 0;
166
167
			echo '
168
				<tr>
169
					<td>', isset($packageaction['operations']) ? '<img id="operation_img_' . $action_num . '" src="' . $settings['images_url'] . '/selected_open.png" alt="*" class="hide" />' : '', '</td>
170
					<td>', $i++, '.</td>
171
					<td>', $packageaction['type'], '</td>
172
					<td>', $packageaction['action'], '</td>
173
					<td>', $packageaction['description'], '</td>
174
				</tr>';
175
176
			// Is there water on the knee? Operation!
177
			if (isset($packageaction['operations']))
178
			{
179
				echo '
180
				<tr id="operation_', $action_num, '">
181
					<td colspan="5" class="standard_row">
182
						<table class="table_grid">';
183
184
				// Show the operations.
185
				$operation_num = 1;
186
				foreach ($packageaction['operations'] as $operation)
187
				{
188
					// Determine the position text.
189
					$operation_text = $operation['position'] == 'replace' ? 'operation_replace' : ($operation['position'] == 'before' ? 'operation_after' : 'operation_before');
190
191
					echo '
192
							<tr>
193
								<td class="hide"></td>
194
								<td class="grid4 smalltext">
195
									<a href="' . $scripturl . '?action=admin;area=packages;sa=showoperations;operation_key=', $operation['operation_key'], ';package=', $context['filename'], ';filename=', $operation['filename'], (empty($context['uninstalling']) ? '' : ';reverse'), '" onclick="return reqWin(this.href, 680, 400, false);">
196
										<i class="icon i-view"></i>
197
									</a>
198
								</td>
199
								<td class="grid4 smalltext">', $operation_num, '.</td>
200
								<td class="smalltext">', $txt[$operation_text], '</td>
201
								<td class="smalltext grid50">', $operation['action'], '</td>
202
								<td class="smalltext grid20">', $operation['description'], empty($operation['ignore_failure']) ? '' : ' (' . $txt['operation_ignore'] . ')', '</td>
203
							</tr>';
204
205
					$operation_num++;
206
				}
207
208
				echo '
209
						</table>
210
					</td>
211
				</tr>';
212
213
				// Increase it.
214
				$action_num++;
215
			}
216
		}
217
218
		echo '
219
			</tbody>
220
			</table>
221
			';
222
223
		// What if we have custom themes we can install into? List them too!
224
		if (!empty($context['theme_actions']))
225
		{
226
			echo '
227
			<br />
228
			<h2 class="category_header">
229
				', $context['uninstalling'] ? $txt['package_other_themes_uninstall'] : $txt['package_other_themes'], '
230
			</h2>
231
			<div id="custom_changes">
232
				<div class="information">
233
					', $txt['package_other_themes_desc'], '
234
				</div>
235
				<table class="table_grid">';
236
237
			// Loop through each theme and display it's name, and then it's details.
238
			foreach ($context['theme_actions'] as $id => $theme)
239
			{
240
				// Pass?
241
				$js_operations[$action_num] = !empty($theme['has_failure']);
242
243
				echo '
244
					<tr class="secondary_header">
245
						<td></td>
246
						<td class="centertext">';
247
248
				if (!empty($context['themes_locked']))
249
				{
250
					echo '
251
							<input type="hidden" name="custom_theme[]" value="', $id, '" />';
252
				}
253
254
				echo '
255
							<input type="checkbox" name="custom_theme[]" id="custom_theme_', $id, '" value="', $id, '" onclick="', (empty($theme['has_failure']) ? '' : 'if (this.form.custom_theme_' . $id . ".checked && !confirm('" . $txt['package_theme_failure_warning'] . "')) return false;"), "invertAll(this, this.form, 'dummy_theme_", $id, '\', true);" ', empty($context['themes_locked']) ? '' : 'disabled="disabled" checked="checked"', '/>
256
						</td>
257
						<td colspan="3">
258
							', $theme['name'], '
259
						</td>
260
					</tr>';
261
262
				foreach ($theme['actions'] as $action)
263
				{
264
					echo '
265
					<tr>
266
						<td>', isset($packageaction['operations']) ? '<img id="operation_img_' . $action_num . '" src="' . $settings['images_url'] . '/selected_open.png" alt="*" class="hide" />' : '', '</td>
267
						<td class="centertext" style="width: 30px;">
268
							<input type="checkbox" name="theme_changes[]" value="', empty($action['value']) ? '' : $action['value'], '" id="dummy_theme_', $id, '" ', (empty($action['not_mod']) ? 'disabled="disabled"' : ''), ' ', empty($context['themes_locked']) ? '' : 'checked="checked"', '/>
269
						</td>
270
						<td>', $action['type'], '</td>
271
						<td class="grid50">', $action['action'], '</td>
272
						<td class="grid20"><strong>', $action['description'], '</strong></td>
273
					</tr>';
274
275
					// Is there water on the knee? Operation!
276
					if (isset($action['operations']))
277
					{
278
						echo '
279
					<tr id="operation_', $action_num, '">
280
						<td colspan="5" class="standard_row">
281
							<table class="table_grid">';
282
283
						$operation_num = 1;
284
						foreach ($action['operations'] as $operation)
285
						{
286
							// Determine the position text.
287
							$operation_text = $operation['position'] === 'replace' ? 'operation_replace' : ($operation['position'] === 'before' ? 'operation_after' : 'operation_before');
288
289
							echo '
290
								<tr>
291
									<td class="hide"></td>
292
									<td class="grid4 smalltext">
293
										<a href="' . $scripturl . '?action=admin;area=packages;sa=showoperations;operation_key=', $operation['operation_key'], ';package=', $context['filename'], ';filename=', $operation['filename'], (empty($context['uninstalling']) ? '' : ';reverse'), '" onclick="return reqWin(this.href, 600, 400, false);">
294
											<i class="icon i-view"></i>
295
										</a>
296
									</td>
297
									<td class="grid4 smalltext">', $operation_num, '.</td>
298
									<td class="smalltext">', $txt[$operation_text], '</td>
299
									<td class="smalltext grid50">', $operation['action'], '</td>
300
									<td class="smalltext grid20">', $operation['description'], empty($operation['ignore_failure']) ? '' : ' (' . $txt['operation_ignore'] . ')', '</td>
301
								</tr>';
302
							$operation_num++;
303
						}
304
305
						echo '
306
							</table>
307
						</td>
308
					</tr>';
309
310
						// Increase it.
311
						$action_num++;
312
					}
313
				}
314
			}
315
316
			echo '
317
				</table>
318
			</div>';
319
		}
320
	}
321
322
	// Are we effectively ready to install?
323
	if (!$context['ftp_needed'] && (!empty($context['actions']) || !empty($context['database_changes'])))
324
	{
325
		echo '
326
			<div class="submitbutton">
327
				<input type="submit" value="', $context['uninstalling'] ? $txt['package_uninstall_now'] : $txt['package_install_now'], '" onclick="return ', empty($context['has_failure']) ? 'submitThisOnce(this)' : "(submitThisOnce(this) &amp;&amp; confirm('" . ($context['uninstalling'] ? $txt['package_will_fail_popup_uninstall'] : $txt['package_will_fail_popup']) . "'))", ';" />
328
			</div>';
329
	}
330
	// If we need ftp information then demand it!
331
	elseif ($context['ftp_needed'])
332
	{
333
		echo '
334
			<h2 class="category_header hdicon i-warning">', $txt['package_ftp_necessary'], '</h2>
335
336
			<div>
337
				', template_control_chmod(), '
0 ignored issues
show
Are you sure template_control_chmod() of type false|null can be used in echo? ( Ignorable by Annotation )

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

337
				', /** @scrutinizer ignore-type */ template_control_chmod(), '
Loading history...
338
			</div>';
339
	}
340
341
	if (!empty($context['post_url']))
342
	{
343
		echo '
344
			<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />', (isset($context['form_sequence_number']) && !$context['ftp_needed']) ? '
345
			<input type="hidden" name="seqnum" value="' . $context['form_sequence_number'] . '" />' : '', '
346
		</form>';
347
	}
348
349
	echo '
350
	</div>';
351
352
	// Toggle options.
353
	echo '
354
	<script>
355
		var aOperationElements = [];';
356
357
	// Operations.
358
	foreach ($js_operations as $key => $operation)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $js_operations does not seem to be defined for all execution paths leading up to this point.
Loading history...
359
	{
360
		echo '
361
			aOperationElements[', $key, '] = new elk_Toggle({
362
				bToggleEnabled: true,
363
				bCurrentlyCollapsed: ', $operation ? 'false' : 'true', ',
364
				aSwappableContainers: [
365
					\'operation_', $key, '\'
366
				],
367
				aSwapImages: [
368
					{
369
						sId: \'operation_img_', $key, '\',
370
						srcExpanded: elk_images_url + \'/selected_open.png\',
371
						altExpanded: ', JavaScriptEscape($txt['hide']), ',
372
						srcCollapsed: elk_images_url + \'/selected.png\',
373
						altCollapsed: ', JavaScriptEscape($txt['show']), ',
374
					}
375
				]
376
			});';
377
	}
378
379
	echo '
380
	</script>';
381
382
	// Get the currently selected item from a select list
383
	echo '
384
	<script>
385
	function get_selected(id)
386
	{
387
		var aSelected = document.getElementById(id);
388
		for (var i = 0; i < aSelected.options.length; i++)
389
		{
390
			if (aSelected.options[i].selected == true)
391
				return aSelected.options[i].value;
392
		}
393
		return aSelected.options[0];
394
	}
395
	</script>';
396
397
	// And a bit more for database changes.
398
	if (!$context['uninstalling'])
399
	{
400
		return;
401
	}
402
403
	if (empty($context['database_changes']))
404
	{
405
		return;
406
	}
407
408
	echo '
409
	<script>
410
		var database_changes_area = document.getElementById(\'db_changes_div\'),
411
			db_vis = false;
412
413
		database_changes_area.style.display = "none";
414
	</script>';
415
}
416
417
/**
418
 * Show after the package has been installed, redirects / permissions
419
 */
420
function template_extract_package()
421
{
422
	global $context, $txt, $scripturl;
423
424
	// Override any redirect if we have to show the permissions changed dialog
425
	if (function_exists('template_show_list') && !empty($context['restore_file_permissions']['rows']))
426
	{
427
		$context['redirect_url'] = '';
428
	}
429
430
	if (!empty($context['redirect_url']))
431
	{
432
		echo '
433
	<script>
434
		setTimeout(function() {doRedirect();}, ', $context['redirect_timeout'], ');
435
436
		function doRedirect()
437
		{
438
			window.location = "', $context['redirect_url'], '";
439
		}
440
	</script>';
441
	}
442
443
	echo '
444
	<div id="admincenter">';
445
446
	if (empty($context['redirect_url']))
447
	{
448
		echo '
449
			<h2 class="category_header">', ($context['uninstalling'] ? $txt['uninstall'] : $txt['extracting']), '</h2>', ($context['uninstalling'] ? '' : '<div class="information">' . $txt['package_installed_extract'] . '</div>');
450
	}
451
	else
452
	{
453
		echo '
454
			<h2 class="category_header">', $txt['package_installed_redirecting'], '</h2>';
455
	}
456
457
	echo '
458
		<div class="generic_list_wrapper">
459
			<div class="content">';
460
461
	// If we are going to redirect we have a slightly different agenda.
462
	if (!empty($context['redirect_url']))
463
	{
464
		echo '
465
				', $context['redirect_text'], '<br /><br />
466
				<a href="', $context['redirect_url'], '">', $txt['package_installed_redirect_go_now'], '</a> | <a href="', $scripturl, '?action=admin;area=packages;sa=browse">', $txt['package_installed_redirect_cancel'], '</a>';
467
	}
468
	elseif ($context['uninstalling'])
469
	{
470
		echo '
471
				', $txt['package_uninstall_done'];
472
	}
473
	elseif ($context['install_finished'])
474
	{
475
		if ($context['extract_type'] == 'avatar')
476
		{
477
			echo '
478
				', $txt['avatars_extracted'];
479
		}
480
		elseif ($context['extract_type'] == 'language')
481
		{
482
			echo '
483
				', $txt['language_extracted'];
484
		}
485
		else
486
		{
487
			echo '
488
				', $txt['package_installed_done'];
489
		}
490
	}
491
	else
492
	{
493
		echo '
494
				', $txt['corrupt_compatible'];
495
	}
496
497
	echo '
498
			</div>
499
		</div>';
500
501
	// Show the "restore permissions" screen?
502
	if (function_exists('template_show_list') && !empty($context['restore_file_permissions']['rows']))
503
	{
504
		echo '<br />';
505
		template_show_list('restore_file_permissions');
506
	}
507
508
	echo '
509
	</div>';
510
}
511
512
/**
513
 * List the files in an addon package
514
 */
515
function template_list()
516
{
517
	global $context, $txt, $scripturl;
518
519
	echo '
520
	<div id="admincenter">
521
		<h2 class="category_header">', $txt['list_file'], '</h2>
522
		<h2 class="category_header">', $txt['files_archive'], ' ', $context['filename'], ':</h2>
523
		<div class="content">
524
			<ol>';
525
526
	foreach ($context['files'] as $fileinfo)
527
	{
528
		echo '
529
				<li><a href="', $scripturl, '?action=admin;area=packages;sa=examine;package=', $context['filename'], ';file=', $fileinfo['filename'], '" title="', $txt['view'], '">', $fileinfo['filename'], '</a> (', $fileinfo['formatted_size'], ')</li>';
530
	}
531
532
	echo '
533
			</ol>
534
			<br />
535
			<a class="linkbutton floatright" href="', $scripturl, '?action=admin;area=packages">', $txt['back'], '</a>
536
		</div>
537
	</div>';
538
}
539
540
/**
541
 * Used to view an individual file from the package
542
 */
543
function template_examine()
544
{
545
	global $context, $txt, $scripturl;
546
547
	echo '
548
	<div id="admincenter">
549
		<h2 class="category_header">', $txt['package_examine_file'], ' : ', $context['package'], '</h2>
550
		<h3 class="category_header">', $txt['package_file_contents'], ' ', $context['filename'], ':</h3>
551
		<div class="content largetext">
552
			<code><pre class="file_content prettyprint">', $context['filedata'], '</pre></code>
553
			<a href="', $scripturl, '?action=admin;area=packages;sa=list;package=', $context['package'], '" class="linkbutton floatright">', $txt['list_files'], '</a>
554
		</div>
555
	</div>';
556
}
557
558
/**
559
 * Show the listing of addons on the system, installed, uninstalled, etc.
560
 */
561
function template_browse()
562
{
563
	global $context, $txt;
564
565
	echo '
566
	<div id="admincenter">';
567
568
	$adds_available = false;
569
	foreach ($context['package_types'] as $type)
570
	{
571
		if (!empty($context['available_' . $type]))
572
		{
573
			template_show_list('packages_lists_' . $type);
574
			$adds_available = true;
575
		}
576
	}
577
578
	if (!$adds_available)
579
	{
580
		echo '
581
		<div class="infobox">', $context['sub_action'] === 'browse' ? $txt['no_packages'] : $txt['no_adds_installed'], '</div>';
582
	}
583
584
	echo '
585
	</div>';
586
}
587
588
/**
589
 * Show the install options
590
 */
591
function template_install_options()
592
{
593
	global $context, $txt, $scripturl;
594
595
	echo '
596
	<div id="admincenter">
597
		<h2 class="category_header">', $txt['package_install_options'], '</h2>
598
		<div class="description">
599
			', $txt['package_install_options_ftp_why'], '
600
		</div>
601
		<form id="admin_form_wrapper" action="', $scripturl, '?action=admin;area=packages;sa=options" method="post" accept-charset="UTF-8">
602
			<div class="content">
603
			<dl class="settings">
604
				<dt>
605
					<label for="pack_server">', $txt['package_install_options_ftp_server'], ':</label>
606
				</dt>
607
				<dd>
608
					<input type="text" name="pack_server" id="pack_server" value="', $context['package_ftp_server'], '" size="30" class="input_text" />
609
				</dd>
610
				<dt>
611
					<label for="pack_port">', $txt['package_install_options_ftp_port'], ':</label>
612
				</dt>
613
				<dd>
614
					<input type="text" name="pack_port" id="pack_port" size="3" value="', $context['package_ftp_port'], '" class="input_text" />
615
				</dd>
616
				<dt>
617
					<label for="pack_user">', $txt['package_install_options_ftp_user'], ':</label>
618
				</dt>
619
				<dd>
620
					<input type="text" name="pack_user" id="pack_user" value="', $context['package_ftp_username'], '" size="30" class="input_text" />
621
				</dd>
622
			</dl>
623
			<hr />
624
			<dl class="settings">
625
				<dt>
626
					<label for="package_make_backups">', $txt['package_install_options_make_backups'], '</label>
627
				</dt>
628
				<dd>
629
					<input type="checkbox" name="package_make_backups" id="package_make_backups" value="1" class="input_check"', $context['package_make_backups'] ? ' checked="checked"' : '', ' />
630
				</dd>
631
				<dt>
632
					<label for="package_make_full_backups">', $txt['package_install_options_make_full_backups'], '</label>
633
				</dt>
634
				<dd>
635
					<input type="checkbox" name="package_make_full_backups" id="package_make_full_backups" value="1" class="input_check"', $context['package_make_full_backups'] ? ' checked="checked"' : '', ' />
636
				</dd>
637
			</dl>
638
			<div class="submitbutton">
639
				<input type="submit" name="save" value="', $txt['save'], '" />
640
				<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
641
			</div>
642
			</div>
643
		</form>
644
	</div>';
645
}
646
647
/**
648
 * Sometimes you have to set file permissions and hope for the best outcome
649
 */
650
function template_control_chmod()
651
{
652
	global $context, $txt;
653
654
	// Nothing to do? Brilliant!
655
	if (empty($context['package_ftp']))
656
	{
657
		return false;
658
	}
659
660
	// Asked to show the list of files/Directories we need access to in order to change
661
	if (empty($context['package_ftp']['form_elements_only']))
662
	{
663
		echo '
664
				', sprintf($txt['package_ftp_why'], "document.getElementById('need_writable_list').style.display = ''; return false;"), '<br />
665
				<div id="need_writable_list" class="smalltext">
666
					', $txt['package_ftp_why_file_list'], '
667
					<ul class="bbc_list">';
668
669
		if (!empty($context['notwritable_files']))
670
		{
671
			foreach ($context['notwritable_files'] as $file)
672
			{
673
				echo '
674
						<li>', $file, '</li>';
675
			}
676
		}
677
678
		echo '
679
					</ul>
680
				</div>';
681
	}
682
683
	echo '
684
				<div id="ftp_error_div" class="errorbox', empty($context['package_ftp']['error']) ? ' hide"' : '"', '>
685
					<span id="ftp_error_message">', empty($context['package_ftp']['error']) ? '' : $context['package_ftp']['error'], '</span>
686
				</div>';
687
688
	if (!empty($context['package_ftp']['destination']))
689
	{
690
		echo '
691
				<form action="', $context['package_ftp']['destination'], '" method="post" accept-charset="UTF-8">';
692
	}
693
694
	echo '
695
					<fieldset>
696
					<dl class="settings">
697
						<dt>
698
							<label for="ftp_server">', $txt['package_ftp_server'], ':</label>
699
						</dt>
700
						<dd>
701
							<input type="text" size="30" name="ftp_server" id="ftp_server" value="', $context['package_ftp']['server'], '" class="input_text" />
702
							<label for="ftp_port">', $txt['package_ftp_port'], ':&nbsp;</label> <input type="text" size="3" name="ftp_port" id="ftp_port" value="', $context['package_ftp']['port'], '" class="input_text" />
703
						</dd>
704
						<dt>
705
							<label for="ftp_username">', $txt['package_ftp_username'], ':</label>
706
						</dt>
707
						<dd>
708
							<input type="text" size="50" name="ftp_username" id="ftp_username" value="', $context['package_ftp']['username'], '" class="input_text" />
709
						</dd>
710
						<dt>
711
							<label for="ftp_password">', $txt['package_ftp_password'], ':</label>
712
						</dt>
713
						<dd>
714
							<input type="password" size="50" name="ftp_password" id="ftp_password" class="input_password" />
715
						</dd>
716
						<dt>
717
							<label for="ftp_path">', $txt['package_ftp_path'], ':</label>
718
						</dt>
719
						<dd>
720
							<input type="text" size="50" name="ftp_path" id="ftp_path" value="', $context['package_ftp']['path'], '" class="input_text" />
721
						</dd>
722
					</dl>
723
					</fieldset>';
724
725
	if (empty($context['package_ftp']['form_elements_only']))
726
	{
727
		echo '
728
					<div class="submitbutton">
729
						<span id="test_ftp_placeholder_full"></span>
730
						<input type="submit" value="', $txt['package_proceed'], '" class="right_submit" />
731
					</div>';
732
	}
733
734
	if (!empty($context['package_ftp']['destination']))
735
	{
736
		echo '
737
					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
738
				</form>';
739
	}
740
741
	// Hide the details of the list.
742
	if (empty($context['package_ftp']['form_elements_only']))
743
	{
744
		echo '
745
		<script>
746
			document.getElementById(\'need_writable_list\').style.display = \'none\';
747
		</script>';
748
	}
749
750
	// Set up to generate the FTP test button.
751
	echo '
752
	<script>
753
		var generatedButton = false,
754
			package_ftp_test = "', $txt['package_ftp_test'], '",
755
			package_ftp_test_connection = "', $txt['package_ftp_test_connection'], '",
756
			package_ftp_test_failed = "', addcslashes($txt['package_ftp_test_failed'], "'"), '";
757
	</script>';
758
759
	// Make sure the button gets generated last.
760
	// Prevent browsers from auto completing the FTP password
761
	theme()->addInlineJavascript('
762
		disableAutoComplete();
763
		generateFTPTest();', true);
764
}
765
766
/**
767
 * Show the ftp permissions panel when needed
768
 */
769
function template_ftp_required()
770
{
771
	global $txt;
772
773
	echo '
774
		<fieldset>
775
			<legend>
776
				', $txt['package_ftp_necessary'], '
777
			</legend>
778
			<div class="ftp_details">
779
				', template_control_chmod(), '
0 ignored issues
show
Are you sure template_control_chmod() of type false|null can be used in echo? ( Ignorable by Annotation )

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

779
				', /** @scrutinizer ignore-type */ template_control_chmod(), '
Loading history...
780
			</div>
781
		</fieldset>';
782
}
783
784
/**
785
 * Used to view a specific edit to a file as the xml defines
786
 */
787
function template_view_operations()
788
{
789
	global $context, $txt, $settings;
790
791
	echo '<!DOCTYPE html>
792
<html ', $context['right_to_left'] ? 'dir="rtl"' : '', '>
793
	<head>
794
		<title>', $txt['operation_title'], '</title>
795
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
796
		<link rel="stylesheet" href="', $settings['theme_url'], '/css/admin.css', CACHE_STALE, '" />
797
		<link rel="stylesheet" href="', $settings['theme_url'], '/css/', $context['theme_variant_url'], 'index', $context['theme_variant'], '.css', CACHE_STALE, '" />
798
		<script src="', $settings['default_theme_url'], '/scripts/script.js', CACHE_STALE, '"></script>
799
		<script src="', $settings['default_theme_url'], '/scripts/theme.js', CACHE_STALE, '"></script>
800
	</head>
801
	<body>
802
		<div class="content">
803
			', $context['operations']['search'], '
804
			<br />
805
				', $context['operations']['replace'], '
806
		</div>
807
	</body>
808
</html>';
809
}
810