<?php
/*
 * Copyright (c) 2024, Tribal Limited
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Zenario, Tribal Limited nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL TRIBAL LTD BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
if (!defined('NOT_ACCESSED_DIRECTLY')) exit('This file may not be directly accessed');

class zenario_common_features__admin_boxes__site_settings extends ze\moduleBaseClass {

	public function fillAdminBox($path, $settingGroup, &$box, &$fields, &$values) {
		if (is_array($box['tabs'] ?? false)) {
			foreach ($box['tabs'] as $tabName => &$tab) {
				if (!empty($tab['fields'])
				 && is_array($tab['fields'])) {
					foreach ($tab['fields'] as $fieldId => &$field) {
						if (!empty($field['site_setting']['name'])) {
						
							$settingOpts = $field['site_setting'];
							$setting = $settingOpts['name'];
							$isSecret = !empty($settingOpts['secret']);
							
							if ($perm = ze\ring::chopPrefix('perm.', $setting)) {
								$field['value'] = ze\user::permSetting($perm);
							
							} elseif ($isSecret) {
								$field['value'] = ze::secretSetting($setting);
							
							} else {
								$field['value'] = ze::setting($setting);
							}
							
							if (!empty($settingOpts['encrypt']) && \ze\pde::init()) {
								$field['encrypted'] = true;
							}
							
							
							if ($setting == 'default_template_family') {
								$field['values'] = [$field['value'] => $field['value']];
					
							} elseif ($setting == 'admin_domain' || $setting == 'primary_domain') {
								$field['value'] = ($field['value'] ?: 'none');
							}
							
							if ($isSecret && ($field['type'] ?? '') == 'password') {
								$field['onmouseover'] = ($field['onmouseover'] ?? ''). ' this.type = "text";';
								$field['onmouseout'] = ($field['onmouseout'] ?? ''). ' this.type = "password";';
								$field['css_class'] = ($field['css_class'] ?? ''). ' zenario_secret_password';
								$field['pre_field_html'] = ($field['pre_field_html'] ?? ''). '<span
									class="zenario_secret_password_wrap'. (!empty($field['readonly']) || !empty($field['disabled'])? ' zenario_secret_password_wrap_readonly' : ''). '"
									onclick="zenarioAB.get(\''. ze\escape::js($fieldId). '\').focus();"
								>';
								$field['post_field_html'] = '</span>'. ($field['post_field_html'] ?? '');
							}
						}
					}
				}
				
				if ($tabName == 'google_maps') {
					ze\lang::applyMergeFields($fields['google_maps/google_maps_api_key']['note_below'], ['cms_url' => ze\link::host()]);
					$serverPublicIP = gethostbyname(ze\link::host());
					ze\lang::applyMergeFields($fields['google_maps/alternative_google_maps_api_key']['note_below'], ['server_IP_address' => $serverPublicIP]);
				}
			}
		}
		
		if (isset($fields['admin_login/zenario_logo'])) {
			$senarioLogo = \ze\link::absolute(). 'zenario/admin/images/zenario-logo-diamond.svg';
			$logoWidth = 50;
			$logoHeight = 38;
			$fields['admin_login/zenario_logo']['snippet']['html'] = '<img src="' . htmlspecialchars($senarioLogo) . '" width="' . (int) $logoWidth . '" height="' . (int) $logoHeight . '">';
		}
		
		if (isset($fields['admin_login/site_disabled_title'])) {
			$values['admin_login/site_disabled_title'] = ze::setting('site_disabled_title');
			$values['admin_login/site_disabled_message'] = ze::setting('site_disabled_message');
		}

		if (isset($fields['admin_domain/admin_domain_is_public'])) {
			$fields['admin_domain/admin_domain_is_public']['value'] = !ze\link::adminDomainIsPrivate();
		}

		if (isset($fields['email/email_address_system'])) {
			$fields['email/email_address_system']['value'] = EMAIL_ADDRESS_GLOBAL_SUPPORT;
		}

		if (isset($fields['filesizes/apache_max_filesize'])) {
			$fields['filesizes/apache_max_filesize']['value'] = ze\file::fileSizeConvert(ze\dbAdm::apacheMaxFilesize());
		}
		if (isset($fields['filesizes/max_allowed_packet'])) {
			$fields['filesizes/max_allowed_packet']['value'] = '?';
	
			if ($result = @ze\sql::select("SHOW VARIABLES LIKE 'max_allowed_packet'")) {
				$settings = [];
				if ($row = ze\sql::fetchRow($result)) {
					$fields['filesizes/max_allowed_packet']['value'] = ze\file::fileSizeConvert($row[1]);
				}
			}
		}

		if (isset($fields['default_language/default_language'])) {
			ze\contentAdm::getLanguageSelectListOptions($fields['default_language/default_language']);
		}

		if (isset($fields['urls/mod_rewrite_suffix'])) {
			$fields['urls/mod_rewrite_suffix']['values'] = ['.htm' => '.htm', '.html' => '.html'];
	
			//Hide/show different options and notes, depending on whether language specific domains are
			//used, and whether every language has a language specific URL
			if (ze\lang::count() > 1) {
		
				$langSpecificDomainsUsed = ze\row::exists('languages', ['domain' => ['!' => '']]);
				$langSpecificDomainsNotUsed = ze\row::exists('languages', ['domain' => '']);
		
				if ($langSpecificDomainsUsed) {
					if ($langSpecificDomainsNotUsed) {
						$fields['urls/note_d']['hidden'] = true;
					} else {
						$fields['urls/translations_hide_language_code']['hidden'] =
						$fields['urls/note_a']['hidden'] =
						$fields['urls/note_b']['hidden'] =
						$fields['urls/note_c']['hidden'] = true;
					}
				} else {
					$fields['urls/note_c']['hidden'] =
					$fields['urls/note_d']['hidden'] = true;
				}
			} else {
				$fields['urls/note_c']['hidden'] =
				$fields['urls/note_d']['hidden'] = true;
			}
		}

		if (isset($fields['dates/vis_date_format_short'])) {
			ze\miscAdm::formatDateFormatSelectList($fields['dates/vis_date_format_short'], true);
			ze\miscAdm::formatDateFormatSelectList($fields['dates/vis_date_format_med']);
			ze\miscAdm::formatDateFormatSelectList($fields['dates/vis_date_format_long']);
			ze\miscAdm::formatDateFormatSelectList($fields['dates/vis_date_format_datepicker'], true, true);
			ze\miscAdm::formatDateFormatSelectList($fields['dates/organizer_date_format'], true, true);
		}

		foreach ([
			'admin_domain' => 'Use [[domain]] as the admin domain; redirect all administrators to [[domain]]',
			'primary_domain' => 'Use [[domain]] as the primary domain (redirect all traffic to [[domain]])'
		] as $domainSetting => $phrase) {
			if (isset($box['tabs'][$domainSetting]['fields'][$domainSetting])) {
				if (ze::setting($domainSetting)) {
					$box['tabs'][$domainSetting]['fields'][$domainSetting]['values'][ze::setting($domainSetting)] =
						['ord' => 2, 'label' => ze\admin::phrase($phrase, ['domain' => ze::setting($domainSetting)])];
				}
				if ($_SERVER['HTTP_HOST'] != ze::setting($domainSetting)) {
					$box['tabs'][$domainSetting]['fields'][$domainSetting]['values'][$_SERVER['HTTP_HOST']] =
						['ord' => 3, 'label' => ze\admin::phrase($phrase, ['domain' => $_SERVER['HTTP_HOST']])];
				}
			}
		}
		
		$path = 'zenario/has_database_changed_and_is_cache_out_of_date.php';
		$post = true;
		if (isset($fields['primary_domain/new']) && !(ze\curl::checkEnabled() && ($thisDomainCheck = ze\curl::fetch(ze\link::absolute(). $path, $post)))) {
			unset($fields['primary_domain/new']['note_below']);
		}
		if (isset($fields['cookie_free_domain/cookie_free_domain']) && !(ze\curl::checkEnabled() && ($thisDomainCheck = ze\curl::fetch(ze\link::absolute(). $path, $post)))) {
			unset($fields['cookie_free_domain/cookie_free_domain']['note_below']);
		}

		//Check whether compression is enabled on the server
		
		
		if (isset($fields['speed/compress_web_pages'])) {
			if (function_exists('apache_get_modules') && in_array('mod_deflate', apache_get_modules())) {
				$values['speed/compress_web_pages'] = 1;
				$fields['speed/compress_web_pages']['readonly'] = true;
				$fields['speed/compress_web_pages']['note_below'] .=
					'<br/>'.
					ze\admin::phrase('Compression is enabled on this server (<code>mod_deflate</code> is enabled in Apache).');
			
			} else
			if (extension_loaded('zlib')
			 && ze\server::checkFunctionEnabled('ini_get')
			 && ze\ring::engToBoolean(ini_get('zlib.output_compression'))
			) {
				$values['speed/compress_web_pages'] = 1;
				$fields['speed/compress_web_pages']['readonly'] = true;
				$fields['speed/compress_web_pages']['note_below'] .=
					'<br/>'.
					ze\admin::phrase('Compression is enabled on this server (<code>zlib.output_compression</code> is set in your <code>php.ini</code> and/or <code>.htaccess</code> file).');
			
			} else {
				$values['speed/compress_web_pages'] = '';
				$fields['speed/compress_web_pages']['readonly'] = true;
				$fields['speed/compress_web_pages']['note_below'] .=
					'<br/>'.
					ze\admin::phrase('Compression is not enabled on this server. To enable, do one of the following: <br/> &nbsp; &bull; Enable <code>mod_deflate</code> in Apache<br/> &nbsp; &bull; Enable <code>zlib.output_compression</code> in your <code>php.ini</code><br/> &nbsp; &bull; Enable <code>zlib.output_compression</code> in your <code>.htaccess</code> file');
			}
		}
		
		if (isset($fields['speed/have_query_cache'])) {
			if ($result = @ze\sql::select("SHOW VARIABLES LIKE '%query_cache%'")) {
				$settings = [];
				while ($row = ze\sql::fetchRow($result)) {
					$settings[$row[0]] = $row[1];
				}
		
				if (!$fields['speed/query_cache_size']['hidden'] = !(
					$fields['speed/have_query_cache']['value'] =
					$fields['speed/have_query_cache']['current_value'] =
						ze\ring::engToBoolean($settings['have_query_cache'] ?? false) && ze\ring::engToBoolean($settings['query_cache_type'] ?? false)
				)) {
					$fields['speed/query_cache_size']['value'] =
					$fields['speed/query_cache_size']['current_value'] = ze\lang::formatFilesizeNicely((int) ($settings['query_cache_size'] ?? false), $precision = 1, $adminMode = true);
				}
	
			} else {
				$fields['speed/have_query_cache']['post_field_html'] = ' '. ze\admin::phrase('(Could not check)');
				$fields['speed/query_cache_size']['hidden'] = true;
			}
		}

		if (isset($fields['test/test_send_email_address'])) {
			$adminDetails = ze\admin::details(ze\admin::id());
			$fields['test/test_send_email_address']['value'] = $adminDetails['admin_email'];
		}

		//Working copy images store a number for enabled. But the UI is a checkbox for enabled, and then a number if enabled.
		//Convert the format when displaying the fields
		if (isset($fields['image_sizes/custom_thumbnail_1'])) {
			if (ze::setting('custom_thumbnail_1_width')) {
				$fields['image_sizes/custom_thumbnail_1']['value'] = 1;
			} else {
				$fields['image_sizes/custom_thumbnail_1']['value'] = '';
				$fields['image_sizes/custom_thumbnail_1_width']['value'] =
				$fields['image_sizes/custom_thumbnail_1_height']['value'] = 300;
			}
		}
		if (isset($fields['image_sizes/custom_thumbnail_2'])) {
			if (ze::setting('custom_thumbnail_2_width')) {
				$fields['image_sizes/custom_thumbnail_2']['value'] = 1;
			} else {
				$fields['image_sizes/custom_thumbnail_2']['value'] = '';
				$fields['image_sizes/custom_thumbnail_2_width']['value'] =
				$fields['image_sizes/custom_thumbnail_2_height']['value'] = 200;
			}
		}
		if (isset($fields['image_resizing/thumbnail_threshold'])) {
			if (!$values['image_resizing/thumbnail_threshold']) {
				$values['image_resizing/thumbnail_threshold'] = 66;
			}
		}

		if (isset($fields['security/enable_two_factor_authentication_for_admin_logins'])) {
			
			if (ze\ring::engToBoolean(ze\site::description('enable_two_factor_authentication_for_admin_logins'))) {
				$values['security/enable_two_factor_authentication_for_admin_logins'] = 1;
				$values['security/apply_two_factor_authentication_by_ip'] = ze\site::description('apply_two_factor_authentication_by_ip');
				$values['security/two_factor_authentication_timeout'] = ze\site::description('two_factor_authentication_timeout');
			}
		}

		if (isset($fields['styles/email_style_formats'])) {
	
			$yaml = ['email_style_formats' => ze\site::description('email_style_formats')];
	
			if (empty($yaml['email_style_formats'])) {
				$yaml['email_style_formats'] = [];
			}
	
			$values['email_style_formats'] = Spyc::YAMLDump($yaml, 4);
		}

		//On multisite sites, don't allow local Admins to change the directory paths
		if (ze\db::hasGlobal() && !($_SESSION['admin_global_id'] ?? false)) {
			foreach (['backup_dir', 'docstore_dir'] as $dir) {
				if (isset($box['tabs'][$dir]['edit_mode'])) {
					$box['tabs'][$dir]['edit_mode']['enabled'] = false;
				}
			}
		}

		//Hack to stop a buggy error message from appearing if the admin never opens the second tab on the branding FAB,
		//as the _was_hidden_before property was never set by the JavaScript on the client side.
		//Fix this problem by setting the _was_hidden_before property for the field.
		if (isset($fields['og/organizer_favicon'])) {
			if ($values['og/organizer_favicon'] != 'custom') {
				$fields['og/custom_organizer_favicon']['_was_hidden_before'] = true;
			}
		}
		
		//Add editor options to Standard Email Template editor
		$styleFormats = ze\site::description('email_style_formats');
		if (!empty($styleFormats)) {
			//If custom email styles exist, load them and add them to the toolbar.
			//Please note: by default, the full featured editor DOES NOT have the styles dropdown.
			
			$fields['template/standard_email_template']['editor_options']['style_formats'] = $styleFormats;
		}
		
		if ($settingGroup == 'data_protection') {
			//Show a warning if the scheduled task for deleting content is not running.
			if (!ze\module::inc('zenario_scheduled_task_manager') 
				|| !zenario_scheduled_task_manager::checkScheduledTaskRunning('jobDataProtectionCleanup')
			) {
				$box['tabs']['data_protection']['notices']['scheduled_task_not_running']['show'] = true;
			} else {
				$box['tabs']['data_protection']['notices']['scheduled_task_running']['show'] = true;
			}
			
			//Fill the backups tab
			if (file_exists($dirpath = ze::setting('backup_dir'))) {
				$backupsCount = 0;
				foreach (scandir($dirpath) as $i => $file) {
					if (is_file($dirpath. '/'. $file) && substr($file, 0, 1) != '.') {
						$backupsCount++;
					}
				}
				$fields['backup/manual_backups']['snippet']['html'] .= '<p>' . ze\admin::nPhrase('There is 1 manual backup.', 'There are [[count]] manual backups.', $backupsCount) . '</p>';
			} else {
				$fields['backup/manual_backups']['snippet']['html'] .= '<p>' . ze\admin::phrase('The backups directory "[[path]]" could not be found.', ['path' => $dirpath]) . '</p>';
			}
			$link = ze\link::absolute() . 'organizer.php#zenario__administration/panels/backups';
			$fields['backup/manual_backups']['snippet']['html'] .= '<p><a target="_blank" href="'.$link.'">Go to backups panel</a></p>';
			
			if (($path = ze::setting('automated_backup_log_path')) 
				&& is_file($path) 
				&& is_readable($path) 
				&& ($backup = ze\welcome::lastAutomatedBackup())
			) {
				$fields['backup/automated_backups']['snippet']['html'] .= '<p>' . ze\admin::phrase(
					'The database "[[DBNAME]]" was last backed up on [[date]] on the server "[[server]]"	.', 
					[
						'DBNAME' => DBNAME, 
						'date' => ze\admin::formatDate($backup[0]), 
						'server' => $backup[1]
					]
				) . '</p>';
			} else {
				$fields['backup/automated_backups']['snippet']['html'] = '<p>' . ze\admin::phrase('None found.') . '</p>';
			}
			
		} elseif ($settingGroup == 'dirs') {
            		$warnings = ze\welcome::getBackupWarningsWithoutHtmlLinks();
            		if (!empty($warnings) && isset($warnings['show_warning'])) {
                		if (isset($warnings['snippet']['html'])) {
                    			$box['tabs']['automated_backups']['notices']['show_warning_message']['message']= $warnings['snippet']['html'];
                		}
            		} else {
                		$box['tabs']['automated_backups']['notices']['show_warning_message']['show'] = false;
			}
			$values['restore_policy/allow_restore'] = RESTORE_POLICY;
		}
		$link = ze\link::absolute() . '/organizer.php#zenario__administration/panels/site_settings//data_protection~.site_settings~tdata_protection~k{"id"%3A"data_protection"}';
		$fields['email/data_protection_link']['snippet']['html'] = ze\admin::phrase('See the <a target="_blank" href="[[link]]">data protection</a> panel for settings on how long to store sent email logs.', ['link' => htmlspecialchars($link)]);
		
		if ($box['setting_group'] == 'email' && !ze\module::isRunning('zenario_newsletter')) {
			$box['title'] = 'Editing email settings';
		}
		
		if ($settingGroup == 'cookies') {
			if (ze::setting('captcha_status_and_version') == 'enabled_v2' && ze::setting('google_recaptcha_site_key') && ze::setting('google_recaptcha_secret_key')) {
				$fields['recaptcha_policy/recaptcha_info']['hidden'] = true;
				$fields['recaptcha_policy/recaptcha_warning']['hidden'] = false;
			}
			
			if (!$values['cookies/cookie_image_canvas']) {
				$fields['cookies/cookie_image_canvas']['value'] = 'fixed_width_and_height';
			}
			
			if (!$values['cookies/cookie_image_width']) {
				$fields['cookies/cookie_image_width']['value'] = 275;
			}
			
			if (!$values['cookies/cookie_image_height']) {
				$fields['cookies/cookie_image_height']['value'] = 60;
			}
			
			if (!$values['cookies/popup_cookie_type_switches_initial_state']) {
				$fields['cookies/popup_cookie_type_switches_initial_state']['value'] = 'off';
			}
			
			//Re-apply the default values if needed
			if (!$fields['cookies/cookie_box1_01_implied_msg']['value']) {
				$fields['cookies/cookie_box1_01_implied_msg']['value'] = ze\admin::phrase("This site uses cookies, and places cookies on your computer to provide you with the best experience. If you continue to use this site, we will assume that you consent to this. Please see our privacy policy for more information.");
			}
			
			if (!$fields['cookies/cookie_box1_02_continue_btn']['value']) {
				$fields['cookies/cookie_box1_02_continue_btn']['value'] = ze\admin::phrase("Continue");
			}
			
			if (!$fields['cookies/cookie_box1_03_cookie_consent_msg']['value']) {
				$fields['cookies/cookie_box1_03_cookie_consent_msg']['value'] = ze\admin::phrase("This site would like to place cookies on your computer. These are designed to improve your experience and provide personalised content. You can accept all cookies, or find out more and accept only certain types.");
			}
			
			if (!$fields['cookies/cookie_box1_04_manage_btn']['value']) {
				$fields['cookies/cookie_box1_04_manage_btn']['value'] = ze\admin::phrase("Manage cookies");
			}
			
			if (!$fields['cookies/cookie_box1_05_accept_btn']['value']) {
				$fields['cookies/cookie_box1_05_accept_btn']['value'] = ze\admin::phrase("Accept all");
			}
			
			if (!$fields['cookies/cookie_box2_01_intro_msg']['value']) {
				$fields['cookies/cookie_box2_01_intro_msg']['value'] = ze\admin::phrase("<h2>Cookie settings</h2><p>This site uses cookies, which are small text files, to improve your experience and show you personalised content. You can accept all cookies, or manage them by type.</p><p>You can find out more on our privacy page.</p>");
			}
			
			if (!$fields['cookies/cookie_image_canvas']['value']) {
				$fields['cookies/cookie_image_canvas']['value'] = "fixed_width_and_height";
			}
			
			if (!$fields['cookies/cookie_image_width']['value']) {
				$fields['cookies/cookie_image_width']['value'] = 275;
			}
			
			if (!$fields['cookies/cookie_image_height']['value']) {
				$fields['cookies/cookie_image_height']['value'] = 60;
			}
			
			if (!$fields['cookies/cookie_box2_02_accept_all_btn']['value']) {
				$fields['cookies/cookie_box2_02_accept_all_btn']['value'] = ze\admin::phrase("Accept all");
			}
			
			if (!$fields['cookies/cookie_box2_11_save_preferences_btn']['value']) {
				$fields['cookies/cookie_box2_11_save_preferences_btn']['value'] = ze\admin::phrase("Save preferences");
			}
			
			if (!$fields['cookies/popup_cookie_type_switches_initial_state']['value']) {
				$fields['cookies/popup_cookie_type_switches_initial_state']['value'] = "off";
			}
		}

		if ($settingGroup == 'head_and_foot' && !ze\priv::check('_PRIV_EDIT_SITEWIDE')) {
			$box['tabs']['head']['edit_mode']['enabled'] =
			$box['tabs']['body']['edit_mode']['enabled'] =
			$box['tabs']['foot']['edit_mode']['enabled'] =
			$box['tabs']['cookie_content']['edit_mode']['enabled'] = false;
		}
		
		
		if ($settingGroup == 'aws_s3_and_vector_data_processing') {
			
			if (!class_exists('Aws\\S3\\S3Client')) {
				$values['awss3_file_downloads/enable_aws_support'] = '';
				$fields['awss3_file_downloads/enable_aws_support']['disabled'] = true;
				
				$awsPackageDocumentationHref = 'https://zenar.io/download-page/advanced-installation/installing-aws-s3-support';
				$linkStart = '<a href="' . $awsPackageDocumentationHref . '" target="_blank">';
				$linkEnd = '</a>';
				$fields['awss3_file_downloads/enable_aws_support']['note_below'] = ze\admin::phrase(
					'To use this feature, please [[link_start]]install the AWS library[[link_end]].',
					['link_start' => $linkStart, 'link_end' => $linkEnd]
				);
			}
			
			
			//Check the scheduled task is running
			if (ze\module::inc('zenario_scheduled_task_manager')) {
			
				if (!ze::setting('jobs_enabled')
				 || !ze\row::get('jobs', 'enabled', ['job_name' => 'jobFetchDocumentExtract', 'module_class_name' => 'zenario_common_features'])) {
					
					$link = 'href="'. htmlspecialchars(ze\link::absolute(). 'organizer.php#zenario__administration/panels/zenario_scheduled_task_manager__scheduled_tasks'). '" target="_blank"';
					$fields['awss3_file_downloads/textract_description']['notices_below'] = [[
						'type' => 'warning',
						'message' => ze\admin::phrase('Document extracts are not available. The Scheduled Task Manager is installed but the document extract task (jobFetchDocumentExtract) is not enabled. <a [[link]]>Click for more info.</a>', ['link' => $link]),
						'html' => true
					]];
				}
		
			} else {
				$scheduledTaskManagerModuleId = ze\module::id('zenario_scheduled_task_manager');
				$link = 'href="'. htmlspecialchars(ze\link::absolute(). 'organizer.php#zenario__modules/panels/modules//'. (int) $scheduledTaskManagerModuleId. '~-scheduled_task_manager'). '" target="_blank"';
				$fields['awss3_file_downloads/textract_description']['notices_below'] = [[
					'type' => 'warning',
					'message' => ze\admin::phrase('Document extracts are not available. To enable them, please install the Scheduled Task Manager module. <a [[link]]>See available modules.</a>', ['link' => $link]),
					'html' => true
				]];
			}
		}
	}

	public function formatAdminBox($path, $settingGroup, &$box, &$fields, &$values, $changes) {
		
		if (isset($fields['errors/show_notices'])) {
			$fields['errors/show_notices']['value'] =
			$fields['errors/show_notices']['current_value'] = (error_reporting() & E_NOTICE) == E_NOTICE;
		}

		if (isset($fields['errors/show_strict'])) {
			$fields['errors/show_strict']['value'] =
			$fields['errors/show_strict']['current_value'] = (error_reporting() & E_STRICT) == E_STRICT;
		}

		if (isset($fields['errors/show_all'])) {
			$fields['errors/show_all']['value'] =
			$fields['errors/show_all']['current_value'] = ((error_reporting() | E_NOTICE | E_STRICT) & (E_ALL | E_NOTICE | E_STRICT)) == (E_ALL | E_NOTICE | E_STRICT);
		}

		if (isset($fields['cookie_domain/cookie_domain'])) {
			$fields['cookie_domain/cookie_domain']['value'] =
			$fields['cookie_domain/cookie_domain']['current_value'] = COOKIE_DOMAIN;
		}

		if (isset($fields['cookie_timeouts/cookie_timeout'])) {
			$fields['cookie_timeouts/cookie_timeout']['value'] =
			$fields['cookie_timeouts/cookie_timeout']['current_value'] = ze\phraseAdm::seconds(COOKIE_TIMEOUT);
		}
		
		if ($settingGroup == 'cookies') {
			$hidden = $values['cookies/cookie_require_consent'] != 'explicit' || !$values['cookies/cookie_show_image'] || !$values['cookies/cookie_image'];
			$this->showHideImageOptions($fields, $values, 'cookies', $hidden, 'cookie_image_');
		}

		if (isset($fields['mysql/debug_use_strict_mode']) && defined('DEBUG_USE_STRICT_MODE')) {
			$fields['mysql/debug_use_strict_mode']['value'] =
			$fields['mysql/debug_use_strict_mode']['current_value'] = DEBUG_USE_STRICT_MODE;
		}

		if (isset($fields['mysql/debug_send_email']) && defined('DEBUG_SEND_EMAIL')) {
			$fields['mysql/debug_send_email']['value'] =
			$fields['mysql/debug_send_email']['current_value'] = DEBUG_SEND_EMAIL;
		}

		if (isset($fields['mysql/email_address_global_support']) && defined('EMAIL_ADDRESS_GLOBAL_SUPPORT')) {
			$fields['mysql/email_address_global_support']['value'] =
			$fields['mysql/email_address_global_support']['current_value'] = EMAIL_ADDRESS_GLOBAL_SUPPORT;
		}

		if (isset($fields['dates/vis_date_format_short'])) {
			$fields['dates/vis_date_format_short__preview']['current_value'] =
				ze\admin::formatDate(ze\date::now(), $values['dates/vis_date_format_short'], true);
	
			$fields['dates/vis_date_format_med__preview']['current_value'] =
				ze\admin::formatDate(ze\date::now(), $values['dates/vis_date_format_med'], true);
	
			$fields['dates/vis_date_format_long__preview']['current_value'] =
				ze\admin::formatDate(ze\date::now(), $values['dates/vis_date_format_long'], true);
		}

		if (isset($fields['urls/mod_rewrite_enabled']) && $values['urls/mod_rewrite_enabled']) {
			$fields['urls/friendly_urls_disabled_warning']['hidden'] = true;
			$fields['sitemap/sitemap_enabled']['hidden'] = false;
			$fields['sitemap/sitemap_disabled_warning']['hidden'] = true;
			if (isset($fields['sitemap/sitemap_url'])) {
				if (!$fields['sitemap/sitemap_url']['hidden'] = !$values['sitemap/sitemap_enabled']) {
					if (ze::setting('mod_rewrite_enabled')) {
						$fields['sitemap/sitemap_url']['value'] =
						$fields['sitemap/sitemap_url']['current_value'] = ze\link::protocol() . ze\link::primaryDomain(). SUBDIRECTORY. 'sitemap.xml';
					} else {
						$fields['sitemap/sitemap_url']['value'] =
						$fields['sitemap/sitemap_url']['current_value'] = ze\link::protocol() . ze\link::primaryDomain(). SUBDIRECTORY. DIRECTORY_INDEX_FILENAME. '?method_call=showSitemap';
					}
				}
			}
		} elseif (isset($fields['urls/mod_rewrite_enabled']) && !$values['urls/mod_rewrite_enabled']) {
			$fields['urls/friendly_urls_disabled_warning']['hidden'] = false;
			$fields['sitemap/sitemap_enabled']['hidden'] = true;
			$fields['sitemap/sitemap_url']['hidden'] = true;
			$values['sitemap/sitemap_url'] = false;
			$fields['sitemap/sitemap_disabled_warning']['hidden'] = false;
		}
		
		if (isset($box['tabs']['caching'])) {
			
			ze\cache::cleanDirs();
			if (is_writable(CMS_ROOT. 'public/images')
			 && is_writable(CMS_ROOT. 'private/images')) {
				$values['caching/cache_images'] = 1;
				$fields['caching/cache_images']['note_below'] =
					ze\admin::phrase('The <code>public/images/</code> and <code>private/images/</code> directories are writable, Zenario will create cached copies of images and thumbnails in these directories.');
				$box['tabs']['caching']['notices']['img_dir_writable']['show'] = true;
				$box['tabs']['caching']['notices']['img_dir_not_writable']['show'] = false;
			} else {
				$values['caching/cache_images'] = '';
				$fields['caching/cache_images']['note_below'] =
					ze\admin::phrase('The <code>public/images/</code> and <code>private/images/</code> directories are not writable, images and thumbnails will not be cached.');
			}
	
			if (isset($box['tabs']['clear_cache']) && ze\priv::check('_PRIV_EDIT_SITE_SETTING')) {
				//Manually clear the cache
				if (!empty($box['tabs']['clear_cache']['fields']['clear_cache']['pressed'])) {
					
					ze\skinAdm::clearCache();
	
					$box['tabs']['clear_cache']['notices']['notice']['show'] = true;
				} else {
					$box['tabs']['clear_cache']['notices']['notice']['show'] = false;
				}
			}
		}
		
		if (isset($box['tabs']['antivirus'])) {
			$box['tabs']['antivirus']['notices']['error']['show'] =
			$box['tabs']['antivirus']['notices']['daemon']['show'] =
			$box['tabs']['antivirus']['notices']['success']['show'] = false;
			
			
			$output = [];
			$returnValue = 0;
			
			if (!empty($box['tabs']['antivirus']['fields']['test']['pressed'])) {
				
				$programPath = ze\server::programPathForExec($values['antivirus/clamscan_tool_path'], 'clamdscan', true);
				
				
				
				$output = [];
				$returnValue = 3;
				
				if ($programPath) {
					$version = exec(escapeshellarg($programPath) .' --version', $output, $returnValue);
					
					if (strpos($version, 'ClamAV') !== false) {
						$filepath = CMS_ROOT. ze::moduleDir('zenario_common_features', 'fun/test_files/test.pdf');
						//$filepath = tempnam(sys_get_temp_dir(), 'testscan');
						//file_put_contents($filepath, 'Hello world!');
						//@chmod($filepath, 0644);
						
						exec(escapeshellarg($programPath) . ' --quiet ' . escapeshellarg($filepath), $output, $returnValue);
						
						//@chmod($filepath, 0600);					
					}
				}
				
				if ($returnValue == 0) {
					$box['tabs']['antivirus']['notices']['success']['show'] = true;
				
				} elseif ($returnValue == 2) {
					$box['tabs']['antivirus']['notices']['daemon']['show'] = true;
				
				} else {
					$box['tabs']['antivirus']['notices']['error']['show'] = true;
				}
			}
		}

		if (isset($box['tabs']['antiword'])) {
			$box['tabs']['antiword']['notices']['error']['show'] =
			$box['tabs']['antiword']['notices']['success']['show'] = false;
	
			if (!empty($fields['antiword/test']['pressed'])) {
				$extract = '';
				ze\site::setSetting('antiword_path', $values['antiword/antiword_path'], $updateDB = false);
		
				if ((ze\file::plainTextExtract(ze::moduleDir('zenario_common_features', 'fun/test_files/test.doc'), $extract))
				 && ($extract == 'Test')) {
					$box['tabs']['antiword']['notices']['success']['show'] = true;
				} else {
					$box['tabs']['antiword']['notices']['error']['show'] = true;
				}
			}
		}

		if (isset($box['tabs']['pdftotext'])) {
			$box['tabs']['pdftotext']['notices']['error']['show'] =
			$box['tabs']['pdftotext']['notices']['success']['show'] = false;
	
			if (!empty($fields['pdftotext/test']['pressed'])) {
				$extract = '';
				ze\site::setSetting('pdftotext_path', $values['pdftotext/pdftotext_path'], $updateDB = false);
		
				if ((ze\file::plainTextExtract(ze::moduleDir('zenario_common_features', 'fun/test_files/test.pdf'), $extract))
				 && (trim($extract, "\0\t..\r ") == 'Test')) {
					$box['tabs']['pdftotext']['notices']['success']['show'] = true;
				} else {
					$box['tabs']['pdftotext']['notices']['error']['show'] = true;
				}
			}
		}

		if (isset($box['tabs']['ghostscript'])) {
			$box['tabs']['ghostscript']['notices']['error']['show'] =
			$box['tabs']['ghostscript']['notices']['success']['show'] = false;

			if (!empty($fields['ghostscript/test']['pressed'])) {
				$extract = '';
				ze\site::setSetting('ghostscript_path', $values['ghostscript/ghostscript_path'], $updateDB = false);

				if (ze\file::createPdfFirstPageScreenshotPng(ze::moduleDir('zenario_common_features', 'fun/test_files/test.pdf'))) {
					$box['tabs']['ghostscript']['notices']['success']['show'] = true;
				} else {
					$box['tabs']['ghostscript']['notices']['error']['show'] = true;
				}
			}
		}

		if (isset($box['tabs']['mysql'])) {
			$box['tabs']['mysql']['notices']['error']['show'] =
			$box['tabs']['mysql']['notices']['success']['show'] = false;

			if (!empty($fields['mysql/test']['pressed'])) {
				ze\site::setSetting('mysql_path', $values['mysql/mysql_path'], $updateDB = false);
				
				if (ze\dbAdm::testMySQL(false)) {
					$box['tabs']['mysql']['notices']['success']['show'] = true;
				} else {
					$box['tabs']['mysql']['notices']['error']['show'] = true;
				}
			}
			
			$box['tabs']['mysql']['notices']['error2']['show'] =
			$box['tabs']['mysql']['notices']['success2']['show'] = false;

			if (!empty($fields['mysql/test2']['pressed'])) {
				ze\site::setSetting('mysqldump_path', $values['mysql/mysqldump_path'], $updateDB = false);
				
				if (ze\dbAdm::testMySQL(true)) {
					$box['tabs']['mysql']['notices']['success2']['show'] = true;
				} else {
					$box['tabs']['mysql']['notices']['error2']['show'] = true;
				}
			}
			
			$box['tabs']['mysql']['notices']['error3']['show'] =
			$box['tabs']['mysql']['notices']['success3']['show'] = false;
			
			if (!empty($fields['mysql/test3']['pressed'])) {
				if (ze\dbAdm::testMySQLTimezoneHandling()) {
					$box['tabs']['mysql']['notices']['success3']['show'] = true;
				} else {
					$box['tabs']['mysql']['notices']['error3']['show'] = true;
				}
			}
			
			if ($settingGroup == 'external_programs') {
				foreach ([
					'advpng' => 'png',
					'jpegoptim' => 'jpeg',
					'jpegtran' => 'jpeg',
					'optipng' => 'png',
					'pngcrush' => 'png',
					'pngquant' => 'png'
				] as $program => $tab) {
					$box['tabs'][$tab]['notices']['error_'. $program]['show'] =
					$box['tabs'][$tab]['notices']['success_'. $program]['show'] = false;
					if (!empty($fields[$tab. '/test_'. $program]['pressed'])) {
				
						if (ze\server::programPathForExec($values[$tab. '/'. $program. '_path'], $program, true)) {
							$box['tabs'][$tab]['notices']['success_'. $program]['show'] = true;
						} else {
							$box['tabs'][$tab]['notices']['error_'. $program]['show'] = true;
						}
					}
				}
			}
		}
		
		if (isset($box['tabs']['wkhtmltopdf'])) {
			$box['tabs']['wkhtmltopdf']['notices']['error']['show'] =
			$box['tabs']['wkhtmltopdf']['notices']['success']['show'] = false;

			if ($values['wkhtmltopdf/wkhtmltopdf_path'] && $values['wkhtmltopdf/wkhtmltopdf_path'] == 'PATH') {
				$fields['wkhtmltopdf/wkhtmltopdf_path']['note_below'] = ze\admin::phrase('Warning: If you use this program in a scheduled task, it may not be found because the PATH environment variable may be different when called via cron.');
			} else {
				unset($fields['wkhtmltopdf/wkhtmltopdf_path']['note_below']);
			}
			
			if (!empty($box['tabs']['wkhtmltopdf']['fields']['test']['pressed'])) {
				if (($programPath = ze\server::programPathForExec($values['wkhtmltopdf/wkhtmltopdf_path'], 'wkhtmltopdf'))
				 && ($rv = exec(escapeshellarg($programPath) .' --version'))) {
					$box['tabs']['wkhtmltopdf']['notices']['success']['show'] = true;
				} else {
					$box['tabs']['wkhtmltopdf']['notices']['error']['show'] = true;
				}
			}
		}
		
		if (isset($fields['automated_backups/test'])
		 && $values['automated_backups/check_automated_backups']
		 && (!isset($fields['automated_backups/test']['note_below'])
		  || !empty($fields['automated_backups/test']['pressed']))) {
			
			$fields['automated_backups/test']['note_below'] = '';
			
			
			
			if (($automated_backup_log_path = $values['automated_backups/automated_backup_log_path'])
			 && (is_file($automated_backup_log_path))
			 && (is_readable($automated_backup_log_path))) {
				
				$timestamp = ze\welcome::lastAutomatedBackupTimestamp($automated_backup_log_path);
				
				if (!$timestamp) {
					$mrg = [
						'DBNAME' => DBNAME,
						'path' => $automated_backup_log_path
					];
					$fields['automated_backups/test']['note_below'] = htmlspecialchars(
						ze\admin::phrase('The database "[[DBNAME]]" was not listed in [[path]]', $mrg)
					);
			
				} else {
					$mrg = [
						'DBNAME' => DBNAME,
						'datetime' => ze\admin::formatDateTime($timestamp, false, true)
					];
					$fields['automated_backups/test']['note_below'] = htmlspecialchars(
						ze\admin::phrase('The database "[[DBNAME]]" was last backed up on [[datetime]]', $mrg)
					);
				}
			}
		}
		
		if (isset($fields['template/standard_email_template'])) {
			//Try and ensure that we use absolute URLs where possible
			ze\contentAdm::addAbsURLsToAdminBoxField($fields['template/standard_email_template']);
		}

		if (isset($fields['test/test_send_button'])) {
	
			$box['tabs']['test']['notices']['test_send_error']['show'] = false;
			$box['tabs']['test']['notices']['test_send_sucesses']['show'] = false;
			
			$mrg = ['absCMSDirURL' => ze\link::absolute()];
			$values['test/test_send_message'] = ze\admin::phrase('<p>Your email appears to be working.</p><p>This is a test email sent by an administrator at [[absCMSDirURL]].</p>', $mrg);
			$values['test/test_send_from_address'] = $values['email/email_address_from'];
			$values['test/test_send_subject'] = ze\admin::phrase('A test email from [[absCMSDirURL]]', $mrg);
	
			if (ze\ray::engToBooleanArray($fields['test/test_send_button'], 'pressed') && ze\priv::check('_PRIV_EDIT_SITE_SETTING')) {
				$box['tabs']['test']['notices']['test_send']['show'] = true;
		
				$error = '';
				$success = '';
				if (!$email = trim($values['test/test_send_email_address'])) {
					$error = ze\admin::phrase('Please enter an email address.');
		
				} elseif (!ze\ring::validateEmailAddress($email)) {
					$error = ze\admin::phrase('"[[email]]" is not a valid email address.', ['email' => $email]);
		
				} else {
					//Temporarily switch the site settings to the current values
					$settingVals = [];
					$settings = [
						'email_address_from' => 'email',
						'base64_encode_emails' => 'smtp',
						'smtp_host' => 'smtp',
						'smtp_port' => 'smtp',
						'smtp_security' => 'smtp',
						'smtp_specify_server' => 'smtp',
						'smtp_use_auth' => 'smtp',
						'smtp_username' => 'smtp'
					];
					foreach($settings as $name => $onTab) {
						$settingVals[$name] = ze::setting($name);
						ze\site::setSetting($name, $values[$onTab. '/'. $name], $updateDB = false);
					}
					
					$secretSettingVals = [];
					$settings = [
						'smtp_password' => 'smtp'
					];
					foreach($settings as $name => $onTab) {
						$secretSettingVals[$name] = ze::secretSetting($name);
						ze\site::setSecretSetting($name, $values[$onTab. '/'. $name], $updateDB = false);
					}
			
					try {
						$subject = $values['test/test_send_subject'];
						$body = $values['test/test_send_message'];
						$addressToOverriddenBy = false;
						
						if ($values['test/test_send_format'] == "standard_email_template") {
							ze\module::inc('zenario_email_template_manager');
							zenario_email_template_manager::putBodyInTemplate($body);
						}
						
						$result = ze\server::sendEmailAdvancedAndShowErrorMessages(
							$subject, $body,
							$email,
							$addressToOverriddenBy,
							$nameTo = false,
							$addressFrom = false,
							$nameFrom = false,
							$attachments = false,
							$attachmentFilenameMappings = false,
							$precedence = false,
							$isHTML = true, 
							$exceptions = true);
				
						if ($result && !ze::isError($result)) {
							$success = ze\admin::phrase('Test email sent to "[[email]]".', ['email' => $email]);
						} else {
							$error = ze\admin::phrase('An email could not be sent to "[[email]]".', ['email' => $email]);
						}
					} catch (Exception $e) {
						$error = $e->getMessage();
					}
			
					//Switch the site settings back
					foreach($settingVals as $name => $value) {
						ze\site::setSetting($name, $value, $updateDB = false);
					}
					foreach($secretSettingVals as $name => $value) {
						ze\site::setSecretSetting($name, $value, $updateDB = false);
					}
				}
		
				if ($error) {
					$box['tabs']['test']['notices']['test_send_error']['show'] = true;
					$box['tabs']['test']['notices']['test_send_error']['message'] = $error;
				}
				if ($success) {
					$box['tabs']['test']['notices']['test_send_sucesses']['show'] = true;
					$box['tabs']['test']['notices']['test_send_sucesses']['message'] = $success;
				}
			}
		}
		
		//Set the default template values for the two buttons below the textarea for editing the robots.txt file.
		//Note: This is done in formatAdminBox() and not fillAdminBox() as one of the default values changes depending
		//on the settings chosen in the sitemap tab!
		if ($settingGroup == 'search_engine_optimisation') {
			$defaultConfig = self::setRobotsTxtToDefaultConfig($values['sitemap/sitemap_enabled'], $values['sitemap/sitemap_url']);
			$blockAll = self::setRobotsTxtToBlockAll();
			
			if (!empty($fields['robots_txt/default_config']['pressed'])) {
				unset($fields['robots_txt/default_config']['pressed']);
				
				$fields['robots_txt/default_config']['disabled'] = true;
				$values['robots_txt/robots_txt_file_contents'] = $defaultConfig;
			} else {
				$fields['robots_txt/default_config']['disabled'] = false;
			}
			
			if (!empty($fields['robots_txt/block_all']['pressed'])) {
				unset($fields['robots_txt/block_all']['pressed']);
				
				$fields['robots_txt/block_all']['disabled'] = true;
				$values['robots_txt/robots_txt_file_contents'] = $blockAll;
			} else {
				$fields['robots_txt/block_all']['disabled'] = false;
			}
			
			$fields['robots_txt/robots_config_info_message__blocks_all']['hidden'] = true;
			$fields['robots_txt/robots_config_info_message__default_config']['hidden'] = true;
			
			if ($values['robots_txt/robots_txt_file_contents'] == $blockAll) {
				$fields['robots_txt/robots_config_info_message__blocks_all']['hidden'] = false;
			} elseif ($values['robots_txt/robots_txt_file_contents'] == $defaultConfig) {
				$fields['robots_txt/robots_config_info_message__default_config']['hidden'] = false;
			}
			
			$robotxTxtReferencesSitemap = false;
			if (strpos($values['robots_txt/robots_txt_file_contents'], 'Sitemap:') !== false) {
				$robotxTxtReferencesSitemap = true;
			}
			$box['tabs']['robots_txt']['notices']['robots_txt_refers_to_disabled_sitemap']['show'] = $robotxTxtReferencesSitemap && !$values['sitemap/sitemap_enabled'];
			$box['tabs']['robots_txt']['notices']['robots_txt_does_not_include_sitemap']['show'] = !$robotxTxtReferencesSitemap && $values['sitemap/sitemap_enabled'];
    	}
	}


	public function validateAdminBox($path, $settingGroup, &$box, &$fields, &$values, $changes, $saving) {
		if (isset($fields['admin_domain/admin_domain'])) {
			if ($values['admin_domain/admin_domain'] != 'none'
			 && $values['admin_domain/admin_domain'] != $_SERVER['HTTP_HOST']
			 && $values['admin_domain/admin_domain'] != ze::setting('admin_domain')) {
				$box['tabs']['admin_domain']['errors'][] = ze\admin::phrase('Please select a domain name.');
			}
		}
		
		if (isset($fields['favicon/favicon']) && $values['favicon/favicon']) {
			$mimeType = $mimeType = $mimeType = '';
			
			if (is_numeric($values['favicon/favicon']) && ($file = ze\row::get('files', true, $values['favicon/favicon']))) {
				$imageWidth = $file['width'];
				$imageHeight = $file['height'];
				$mimeType = $file['mime_type'];
			//Add new uploads into the pool.
			} elseif ($filepath = ze\file::getPathOfUploadInCacheDir($values['favicon/favicon'])) {
				$imageSize = getimagesize($filepath);
				
				$imageWidth = $imageSize[0];
				$imageHeight = $imageSize[1];
				$mimeType = $imageSize['mime'];
			}
			
			if (ze\file::isImageOrSVG($mimeType) && ($imageWidth > 512 || $imageHeight > 512)) {
				$fields['favicon/favicon']['error'] = ze\admin::phrase('The favicon dimensions may not exceed 512 x 512 px.');
			}
		}

		$path = 'zenario/has_database_changed_and_is_cache_out_of_date.php';
		$post = true;
		if (isset($fields['primary_domain/primary_domain'])) {
			if ($values['primary_domain/primary_domain'] == 'new') {
				if ($values['primary_domain/new']) {
					if ($thisDomainCheck = ze\curl::fetch(ze\link::absolute(). $path, $post)) {
						if ($specifiedDomainCheck = ze\curl::fetch(($cookieFreeDomain = ze\link::protocol(). $values['primary_domain/new']. SUBDIRECTORY). $path, $post)) {
							if ($thisDomainCheck == $specifiedDomainCheck) {
								//Success, looks correct
							} else {
								$box['tabs']['primary_domain']['errors'][] = ze\admin::phrase('We tried to check "[[domain]]", but it does not point to this site. Please check your domain and try again.', ['domain' => $cookieFreeDomain]);
							}
						} else {
							$box['tabs']['primary_domain']['errors'][] = ze\admin::phrase('We tried to check "[[domain]]", but it does not point to this site. Please check your domain and try again.', ['domain' => $cookieFreeDomain]);
						}
					}
				} else {
					$box['tabs']['primary_domain']['errors'][] = ze\admin::phrase('Please enter a primary domain.');
				}
			}
		}

		if (isset($fields['cookie_free_domain/cookie_free_domain'])) {
			if ($values['cookie_free_domain/use_cookie_free_domain']) {
				if ($values['cookie_free_domain/cookie_free_domain']) {
					if ($values['cookie_free_domain/cookie_free_domain'] != ze\link::adminDomain()
					 && $values['cookie_free_domain/cookie_free_domain'] != ze\link::primaryDomain()) {
						if ($thisDomainCheck = ze\curl::fetch(ze\link::absolute(). $path, $post)) {
							if ($specifiedDomainCheck = ze\curl::fetch(($cookieFreeDomain = ze\link::protocol(). $values['cookie_free_domain/cookie_free_domain']. SUBDIRECTORY). $path, $post)) {
								if ($thisDomainCheck == $specifiedDomainCheck) {
									//Success, looks correct
								} else {
									$box['tabs']['cookie_free_domain']['errors'][] = ze\admin::phrase('We tried to check "[[domain]]", but it does not point to this site. Please check your domain and try again.', ['domain' => $cookieFreeDomain]);
								}
							} else {
								$box['tabs']['cookie_free_domain']['errors'][] = ze\admin::phrase('We tried to check "[[domain]]", but it does not point to this site. Please check your domain and try again.', ['domain' => $cookieFreeDomain]);
							}
						}
					} else {
						$box['tabs']['cookie_free_domain']['errors'][] = ze\admin::phrase('The cookie-free domain must be a different domain to the primary domain.');
					}
				} else {
					$box['tabs']['cookie_free_domain']['errors'][] = ze\admin::phrase('Please enter a cookie-free domain.');
				}
			}
		}

		if (isset($fields['image_resizing/jpeg_quality_limit'])) {
			if (!$values['image_resizing/jpeg_quality_limit']) {
				$box['tabs']['image_sizes']['errors'][] = ze\admin::phrase('Please enter a JPEG quality.');
	
			} elseif (!is_numeric($values['image_resizing/jpeg_quality_limit'])) {
				$box['tabs']['image_sizes']['errors'][] = ze\admin::phrase('The JPEG quality must be a number.');
	
			} else
			if ((int) $values['image_resizing/jpeg_quality_limit'] < 80
			 || (int) $values['image_resizing/jpeg_quality_limit'] > 100) {
				$box['tabs']['image_sizes']['errors'][] = ze\admin::phrase('The JPEG quality must be a number between 80 and 100.');
			}
		}
		
		if (
			isset($values['filesizes/content_max_filesize'])
			&& $values['filesizes/content_max_filesize']
			&& ze\file::fileSizeBasedOnUnit($values['filesizes/content_max_filesize'], $values['filesizes/content_max_filesize_unit']) > ze\dbAdm::apacheMaxFilesize()
		) {
			$box['tabs']['filesizes']['errors'][] = ze\admin::phrase(
				'The Zenario maximum uploadable file size value should not exceed the server maximum uploadable file size ([[apacheMaxFilesize]]).',
				['apacheMaxFilesize' => $fields['filesizes/apache_max_filesize']['value']]
			);
		}
		
		if (!empty($values['smtp/smtp_specify_server'])) {
			if (empty($values['smtp/smtp_host'])) {
				$box['tabs']['smtp']['errors'][] = ze\admin::phrase('Please enter the SMTP server name.');
			}
			if (empty($values['smtp/smtp_port'])) {
				$box['tabs']['smtp']['errors'][] = ze\admin::phrase('Please enter the SMTP port number.');
			}
	
			if (!empty($values['smtp/smtp_use_auth'])) {
				if (empty($values['smtp/smtp_username'])) {
					$box['tabs']['smtp']['errors'][] = ze\admin::phrase('Please enter the SMTP account username.');
				}
				if (empty($values['smtp/smtp_password'])) {
					$box['tabs']['smtp']['errors'][] = ze\admin::phrase('Please enter the SMTP account password.');
				}
			}
		}

		if (isset($box['tabs']['automated_backups']['fields']['check_automated_backups'])
		 && ze\ring::engToBoolean($box['tabs']['automated_backups']['edit_mode']['on'] ?? false)
		 && $values['automated_backups/check_automated_backups']) {
			if (!$values['automated_backups/automated_backup_log_path']) {
				//Allow no path to be entered; this is actually the default state.
				//This will cause a warning on the diagnostics screen.
				//$box['tabs']['automated_backups']['errors'][] = ze\admin::phrase('Please enter a file path.');
	
			} elseif (!is_file($values['automated_backups/automated_backup_log_path'])) {
				$box['tabs']['automated_backups']['errors'][] = ze\admin::phrase('This file does not exist.');
	
			} elseif (!is_readable($values['automated_backups/automated_backup_log_path'])) {
				$box['tabs']['automated_backups']['errors'][] = ze\admin::phrase('This file is not readable.');
	
			} elseif (false !== ze\ring::chopPrefix(realpath(CMS_ROOT), realpath($values['automated_backups/automated_backup_log_path']))) {
				$box['tabs']['automated_backups']['errors'][] = ze\admin::phrase('Zenario is installed in this directory. Please choose a different path.');
			}
		}

		foreach (['backup_dir', 'docstore_dir'] as $dir) {
			if ($saving
			 && isset($box['tabs'][$dir]['fields'][$dir])
			 && ze\ring::engToBoolean($box['tabs'][$dir]['edit_mode']['on'] ?? false)) {
				if (!$values[$dir. '/'. $dir]) {
					$box['tabs'][$dir]['errors'][] = ze\admin::phrase('Please enter a directory.');
		
				} elseif (!is_dir($values[$dir. '/'. $dir])) {
					$box['tabs'][$dir]['errors'][] = ze\admin::phrase('This directory does not exist.');
		
				} elseif (false !== ze\ring::chopPrefix(realpath(CMS_ROOT), realpath($values[$dir. '/'. $dir]))) {
					$box['tabs'][$dir]['errors'][] = ze\admin::phrase('Zenario is installed in this directory. Please choose a different directory.');
		
				} else {
					//Strip any trailing slashes off of a directory path
					$box['tabs'][$dir]['fields'][$dir]['current_value'] = preg_replace('/[\\\\\\/]+$/', '', $box['tabs'][$dir]['fields'][$dir]['current_value']);
				}
			}
		}

		if (isset($values['webp_images/webp_quality']) && !ctype_digit($values['webp_images/webp_quality'])) {
			$fields['webp_images/webp_quality']['error'] = ze\admin::phrase('The value must be an integer.');
		}

		if ($settingGroup == 'logos_and_branding') {
			if (!$values['admin_login/site_disabled_title']) {
				$box['tabs']['admin_login']['errors'][] =
					ze\admin::phrase('Please enter a browser title.');
			}
			if (!$values['admin_login/site_disabled_message']) {
				$box['tabs']['admin_login']['errors'][] =
					ze\admin::phrase('Please enter a message.');
			}
		}
		
		if ($settingGroup == 'cookies') {
			if ($values['cookies/cookie_show_image'] && $values['cookies/cookie_image']) {
				if (ze::in($values['cookies/cookie_image_canvas'], 'fixed_width', 'fixed_width_and_height') && is_numeric($values['cookies/cookie_image_width']) && $values['cookies/cookie_image_width'] > 275) {
					$fields['cookies/cookie_image_width']['error'] = ze\admin::phrase('The width cannot be greater than 275 px.');
				}
				
				if (ze::in($values['cookies/cookie_image_canvas'], 'fixed_height', 'fixed_width_and_height') && is_numeric($values['cookies/cookie_image_height']) && $values['cookies/cookie_image_height'] > 60) {
					$fields['cookies/cookie_image_height']['error'] = ze\admin::phrase('The height cannot be greater than 60 px.');
				}
			}
		}
		
		if ($settingGroup == 'search_engine_optimisation') {
			$fields['robots_txt/robots_txt_file_contents_required_lines_description']['hidden'] = true;
			
			if ($values['robots_txt/robots_txt_file_contents']) {
				$rules = [];
				foreach (explode("\n", $values['robots_txt/robots_txt_file_contents']) as $line) {
					$parts = explode(':', $line, 2);
					if (!empty($parts[1])) {
						$command = trim(strtolower($parts[0]));
						$param = trim($parts[1]);
						
						if (!isset($rules[$command])) {
							$rules[$command] = [];
						}
						
						$rules[$command][$param] = true;
					}
				}
				
				//Make sure that the line:
				
				//User-agent: *
				
				//and EITHER the line:

				//Disallow: /
				
				//OR all of the following lines (in any order):
				
				//Disallow: /cache/
				//Disallow: /private/
				//Disallow: /zenario/admin/
				//Disallow: /zenario/api/
				//Disallow: /zenario/frameworks/
				//Disallow: /zenario/includes/
				//Disallow: /zenario_custom/
				//Disallow: /zenario/cookie_message.php
				
				//... are present in the textarea.
				
				$robotstxtContentsAreValid = false;
				if (isset($rules['user-agent']['*'])) {
					//This is valid so far
					$robotstxtContentsAreValid = true;
				}
				
				if ($robotstxtContentsAreValid) {
					//If this is valid so far, continue with the rest of the validation.
					//Otherwise display an error.
					if (isset($rules['disallow']['/'])) {
						//Valid file
						$robotstxtContentsAreValid = true;
					} else {
						$linesToLookFor = [
							'/cache/',
							'/private/',
							'/zenario/admin/',
							'/zenario/api/',
							'/zenario/frameworks/',
							'/zenario/includes/',
							'/zenario_custom/',
							'/zenario/cookie_message.php'
						];
					
						$allLinesArePresent = true;
						foreach ($linesToLookFor as $lineToLookFor) {
							if (!isset($rules['disallow'][$lineToLookFor])) {
								$allLinesArePresent = false;
								break;
							}
						}
					
						$robotstxtContentsAreValid = $allLinesArePresent;
					}
				}
				
				if (!$robotstxtContentsAreValid) {
					$fields['robots_txt/robots_txt_file_contents']['error'] = ze\admin::phrase('Please check the note below and make sure the required lines are present in the robots.txt file contents.');
					$fields['robots_txt/robots_txt_file_contents_required_lines_description']['hidden'] = false;
				}
			}
		}
		
		
		if ($settingGroup == 'aws_s3_and_vector_data_processing') {
			
			if (class_exists('Aws\\S3\\S3Client')
			 && $values['awss3_file_downloads/enable_aws_support']
			 && $values['awss3_file_downloads/enable_aws_textract']) {
				
				$awsS3Region = $values['awss3_file_downloads/aws_s3_region'];
				$awsS3KeyId = $values['awss3_file_downloads/aws_s3_key_id'];
				$awsS3SecretKey = $values['awss3_file_downloads/aws_s3_secret_key'];
				$awsS3Bucket = $values['awss3_file_downloads/aws_textract_temporary_storage_bucket'];
		
				if ($awsS3Region && $awsS3KeyId && $awsS3SecretKey && $awsS3Bucket) {
					$bucket = ltrim($awsS3Bucket, 'arn:aws:s3:::');
					$s3 = new Aws\S3\S3Client([
						'region'  => $awsS3Region,
						'version' => 'latest',
						'credentials' => [
							'key'    => $awsS3KeyId,
							'secret' => $awsS3SecretKey,
						]
					]);

					// Send a PutObject request and get the result object.
					$bucketResponse = $s3->doesBucketExist($bucket);
					if (!$bucketResponse) {
						$box['tabs']['awss3_file_downloads']['errors']['aws'] = ze\admin::phrase('Connection failed! Please check your credentials.');
					}
				}
			}
		}
	}
	
	
	public function saveAdminBox($path, $settingGroup, &$box, &$fields, &$values, $changes) {
		if (!ze\priv::check('_PRIV_EDIT_SITE_SETTING')) {
			exit;
		}

		if ($settingGroup == 'head_and_foot' && !ze\priv::check('_PRIV_EDIT_SITEWIDE')) {
			exit;
		}

		if (isset($fields['template/standard_email_template'])) {
			//Try and ensure that we use absolute URLs where possible
			ze\contentAdm::addAbsURLsToAdminBoxField($fields['template/standard_email_template']);
		}

		$changesToFiles = false;

		//Loop through each field that would be in the Admin Box, and has the <site_setting> tag set
		foreach ($box['tabs'] as $tabName => &$tab) {
	
			$recreateCustomThumbnailTwos = $recreateCustomThumbnailOnes = false;
			$jpegOnly = true;
	
			if (is_array($tab)
			 && !empty($tab['fields'])
			 && is_array($tab['fields'])
			 && ze\ring::engToBoolean($tab['edit_mode']['on'] ?? false)) {
				
				foreach ($tab['fields'] as $fieldName => &$field) {
					if (!empty($field['site_setting']['name'])
					 && empty($field['readonly'])
					 && empty($field['read_only'])) {
						
						$settingOpts = $field['site_setting'];
						$setting = $settingOpts['name'];
						$isSecret = !empty($settingOpts['secret']);
						
						//Get the value of the setting. Hidden fields should count as being empty
						if (ze\ring::engToBoolean($field['hidden'] ?? false)
						 || ze\ring::engToBoolean($field['_was_hidden_before'] ?? false)) {
							$value = '';
						} else {
							$value = ze\ray::value($values, $tabName. '/'. $fieldName);
						}
				
						//Setting the primary or admin domain to "none" should count as being empty
						if ($setting == 'admin_domain' || $setting == 'primary_domain') {
							if ($value == 'none') {
								$value = '';
							} elseif ($value == 'new') {
								$value = $values['primary_domain/new'];
							}
						}
				
						//On multisite sites, don't allow local Admins to change the directory paths
						if (ze::in($setting, 'backup_dir', 'docstore_dir') && ze\db::hasGlobal() && !($_SESSION['admin_global_id'] ?? false)) {
							continue;
						}
						
						//Run a HTML sanitiser on any HTML fields when we save them
						if ('editor' == ($field['type'] ?? '')) {
							$value = ze\ring::sanitiseWYSIWYGEditorHTML($value, true, $settingOpts['advanced_inline_styles'] ?? false);
						}
				
						//Working copy images store a number for enabled. But the UI is a checkbox for enabled, and then a number if enabled.
						//Convert the format back when saving
						if (($setting == 'custom_thumbnail_1_width' && empty($values['image_sizes/custom_thumbnail_1']))
						 || ($setting == 'custom_thumbnail_1_height' && empty($values['image_sizes/custom_thumbnail_1']))
						 || ($setting == 'custom_thumbnail_2_width' && empty($values['image_sizes/custom_thumbnail_1']) && empty($values['image_sizes/custom_thumbnail_2']))
						 || ($setting == 'custom_thumbnail_2_height' && empty($values['image_sizes/custom_thumbnail_1']) && empty($values['image_sizes/custom_thumbnail_2']))) {
							$value = '';
						}
				
						//Handle file pickers
						if (!empty($field['upload'])) {
							//If a file ID from the database has been selected, check if it's a file
							//from the site settings pool, and copy it into the pool if it's not.
							if (is_numeric($value)) {
								$value = ze\file::copyInDatabase('site_setting', $value);
							
							//Add new uploads into the pool.
							} elseif ($filepath = ze\file::getPathOfUploadInCacheDir($value)) {
								$oldPathCodename = $value;
								$value = ze\file::addToDatabase('site_setting', $filepath);
								
								$field['current_value'] = 
								$values[$tabName. '/'. $fieldName] = $value;
								
								if (!isset($field['upload']['uploaded_ids'])) {
									$field['upload']['uploaded_ids'] = [];
								}
								$field['upload']['uploaded_ids'][$oldPathCodename] = $value;
							}
							$changesToFiles = true;
						}
				
						if ($perm = ze\ring::chopPrefix('perm.', $setting)) {
							$settingChanged = $value != ze\user::permSetting($perm);
							
							if ($settingChanged) {
								ze\row::set('user_perm_settings', ['value' => $value], $perm);
							}
						
						} else {
							if ($isSecret) {
								$settingChanged = $value != ze::secretSetting($setting);
							} else {
								$settingChanged = $value != ze::setting($setting);
							}
				
							if ($settingChanged) {
								ze\site::setSetting($setting, $value,
									true, ze\ring::engToBoolean($settingOpts['encrypt'] ?? false),
									true, ze\ring::engToBoolean($settingOpts['secret'] ?? false));
							
								//Handle changing the default language of the site
								if ($setting == 'default_language') {
									ze::$defaultLang = $value;
								
									//Update the special pages, creating new ones if needed
									ze\contentAdm::addNeededSpecialPages();
						
									//Resync every content equivalence, trying to make sure that the pages for the new default language are used as the base
									$sql = "
										SELECT DISTINCT equiv_id, type
										FROM ". DB_PREFIX. "content_items
										WHERE status NOT IN ('trashed','deleted')";
									$equivResult = ze\sql::select($sql);
									while ($equiv = ze\sql::fetchAssoc($equivResult)) {
										ze\contentAdm::resyncEquivalence($equiv['equiv_id'], $equiv['type']);
									}
					
								} elseif ($setting == 'custom_thumbnail_1_width' || $setting == 'custom_thumbnail_1_height') {
									$recreateCustomThumbnailOnes = true;
									$jpegOnly = false;
					
								} elseif ($setting == 'custom_thumbnail_2_width' || $setting == 'custom_thumbnail_2_height') {
									$recreateCustomThumbnailTwos = true;
									$jpegOnly = false;
								} elseif ($setting == 'standard_email_template') {
									$files = [];
									$htmlChanged = false;
									ze\contentAdm::syncInlineFileLinks($files, $value, $htmlChanged);
									$key = ['foreign_key_to' => 'standard_email_template', 'foreign_key_id' => 1, 'foreign_key_char' => ''];
									ze\contentAdm::syncInlineFiles($files, $key, $keepOldImagesThatAreNotInUse = false);
								}
							}
						}
					}
				}
			}
	
			if ($recreateCustomThumbnailOnes || $recreateCustomThumbnailTwos) {
				ze\contentAdm::rerenderWorkingCopyImages($recreateCustomThumbnailOnes, $recreateCustomThumbnailTwos, true, $jpegOnly);
			}
		}

		if ($settingGroup == 'logos_and_branding') {
			ze\site::setSetting('site_disabled_title', $values['admin_login/site_disabled_title']);
			ze\site::setSetting('site_disabled_message', ze\ring::sanitiseWYSIWYGEditorHTML($values['admin_login/site_disabled_message'], true));
		}
		
		//In Zenario 9.4, a new setting for User Forms max attachment size was introduced.
		//It can follow the global setting or be different.
		//In case it's different, make sure that after changing the setting in this admin box,
		//the Forms one is not suddenly larger. Set it to use the global file size.
		//
		//Also the settings for max user image file upload size, and max location image size, were changed to work like the global setting
		//(text field + unit selector). Replicate the same logic for it.
		if ($settingGroup == 'files_and_images' && isset($values['filesizes/content_max_filesize']) && $values['filesizes/content_max_filesize']) {
			$maxFileSize = ze\file::fileSizeBasedOnUnit($values['filesizes/content_max_filesize'], $values['filesizes/content_max_filesize_unit']);
			
			if (ze::setting('zenario_user_forms_max_attachment_file_size_override')) {
				$maxUserFormsFileSize = ze\file::fileSizeBasedOnUnit(ze::setting('zenario_user_forms_content_max_filesize'), ze::setting('zenario_user_forms_content_max_filesize_unit'));
				if ($maxUserFormsFileSize > $maxFileSize) {
					ze\site::setSetting('zenario_user_forms_content_max_filesize', '');
					ze\site::setSetting('zenario_user_forms_content_max_filesize_unit', '');
					ze\site::setSetting('zenario_user_forms_max_attachment_file_size_override', false);
				}
			}
			
			if (ze::setting('max_user_image_filesize_override')) {
				$maxUserImageileSize = ze\file::fileSizeBasedOnUnit(ze::setting('max_user_image_filesize'), ze::setting('max_user_image_filesize_unit'));
				if ($maxUserImageileSize > $maxFileSize) {
					ze\site::setSetting('max_user_image_filesize', '');
					ze\site::setSetting('max_user_image_filesize_unit', '');
					ze\site::setSetting('max_user_image_filesize_override', false);
				}
			}
			
			if (ze::setting('max_location_image_filesize_override')) {
				$maxLocationImageileSize = ze\file::fileSizeBasedOnUnit(ze::setting('max_location_image_filesize'), ze::setting('max_location_image_filesize_unit'));
				if ($maxLocationImageileSize > $maxFileSize) {
					ze\site::setSetting('max_location_image_filesize', '');
					ze\site::setSetting('max_location_image_filesize_unit', '');
					ze\site::setSetting('max_location_image_filesize_override', false);
				}
			}
		}
	}
	
	
	
	protected function loadPhrase($keepHTML, $code) {
		
		$text = ze\row::get('visitor_phrases',
			'local_text',
			['module_class_name' => 'zenario_common_features', 'language_id' => ze::$defaultLang, 'code' => $code]
		);
		
		if (!$keepHTML) {
			$text = html_entity_decode($text, ENT_QUOTES | ENT_HTML5);
		}
		
		return $text;
	}
	
	protected function savePhrase($isHTML, $code, $text) {
		
		if (!$isHTML) {
			$text = htmlspecialchars($text);
		}
		
		ze\row::set('visitor_phrases', 
			['local_text' => $text],
			['module_class_name' => 'zenario_common_features', 'language_id' => ze::$defaultLang, 'code' => $code]
		);
	}
	
	protected function setRobotsTxtToBlockAll() {
		return
'User-agent: *
Disallow: /';
	}
	
	protected function setRobotsTxtToDefaultConfig($siteMapEnabled, $siteMapUrl) {
		$defaultValue = '';
		
		$defaultConfigFilePath = CMS_ROOT . 'zenario/includes/test_files/default_robots.txt';
		$file = fopen($defaultConfigFilePath, 'r');
		if ($file) {
			while ($line = fgets($file)) {
				$defaultValue .= $line;
			}
		}
		
		fclose($file);
		
		//Also include the sitemap if in use
		if ($siteMapEnabled) {
			$defaultValue .= 'Sitemap: ' . $siteMapUrl;
		}
		
		return trim($defaultValue);
	}
}
