<?php
/*
 * Copyright (c) 2026, 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['file_storage/apache_max_filesize'])) {
			$fields['file_storage/apache_max_filesize']['value'] = ze\file::fileSizeConvert(ze\dbAdm::apacheMaxFilesize());
		}
		if (isset($fields['file_storage/max_allowed_packet'])) {
			$fields['file_storage/max_allowed_packet']['value'] = '?';
	
			if ($result = @ze\sql::select("SHOW VARIABLES LIKE 'max_allowed_packet'")) {
				$settings = [];
				if ($row = ze\sql::fetchRow($result)) {
					$fields['file_storage/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\file::formatSizeUnits((int) ($settings['query_cache_size'] ?? false), $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)) {
			if (isset($box['tabs']['backup_dir']['edit_mode'])) {
				$box['tabs'][$dir]['edit_mode']['enabled'] = false;
			}
			
			if (isset($box['tabs']['file_storage'])) {
				$box['tabs']['file_storage']['fields']['docstore_dir']['readonly'] = true;
			}
		}

		//Hack to stop a buggy error message from appearing if the admin never opens the second tab on the branding FAB,
		//as the _cms_hidden property was never set by the JavaScript on the client side.
		//Fix this problem by setting the _cms_hidden property for the field.
		if (isset($fields['og/organizer_favicon'])) {
			if ($values['og/organizer_favicon'] != 'custom') {
				$fields['og/custom_organizer_favicon']['_cms_hidden'] = 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>';
			}
			
			
			//Show the number of sent emails currently stored
			$count = ze\row::count('email_template_sending_log');
			$note = ze\admin::nPhrase('1 record currently stored.', '[[count]] records currently stored.', $count);
			
			if ($count) {
				$min = ze\row::min('email_template_sending_log', 'sent_datetime');
				$note .= ' ' . ze\admin::phrase('Oldest record from [[date]].', ['date' => ze\admin::formatDateTime($min, '_MEDIUM')]);
			}
			
			$link = ze\link::absolute() . 'organizer.php#zenario__email_template_manager/panels/email_log';
			$note .= ' ' . '<a target="_blank" href="' . $link . '">View</a>';
			$fields['data_protection/period_to_delete_the_email_template_sending_log_headers']['note_below'] = $note;
			
			//Show the number of items in the error log
			$count = ze\row::count('error_404_log');
			$note = ze\admin::nPhrase('1 record currently stored.', '[[count]] records currently stored.', $count);
			
			if ($count) {
				$min = ze\row::min('error_404_log', 'logged');
				$note .= ' ' . ze\admin::phrase('Oldest record from [[date]].', ['date' => ze\admin::formatDateTime($min, '_MEDIUM')]);
			}
			
			$link = ze\link::absolute() . 'organizer.php#zenario__administration/panels/error_log';
			$note .= ' ' . '<a target="_blank" href="' . $link . '">View</a>';
			$fields['data_protection/period_to_delete_error_log']['note_below'] = $note;
			
		} 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 ($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 == 'logos_and_branding') {
    		
    		//Internally, we allow people to upload multiple favicons for a site.
    		//However to make the admin UI less confusing, we'll only offer the ability to
    		//have at most two favicons: a .ico (for Microsoft Bing) and a .png (for Google).
    		$faviconIds = \ze::setting('favicon');
    		if (!empty($faviconIds)) {
	    		foreach (ze\ray::explodeAndTrim($faviconIds, true) as $imageId) {
	    			if ($file = ze\row::get('files', ['id', 'usage', 'mime_type'], $imageId)) {
	    				if ($file['usage'] != 'site_setting') {
	    					continue;
	    				}
	    				if ($file['mime_type'] == 'image/x-icon') {
	    					$values['favicon/favicon_ico'] = $imageId;
	    				} else {
	    					$values['favicon/favicon_png'] = $imageId;
	    				}
	    			}
	    		}
	    	}
	    }
	    			
		
		
		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('site_enabled')
				 || !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__library/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
				]];
			}
		}
		
		
		
		if ($settingGroup == 'security') {
			$days = ze\admin::getDaysBeforeAdminsAreInactive();
			
			$fields['admin_login/warn_when_admin_did_not_log_in_for_over_3_months']['label'] = ze\admin::nPhrase(
				"Warn when there are administrators on the site who haven't logged in for over 1 day",
				"Warn when there are administrators on the site who haven't logged in for over [[days]] days",
				$days,
				['days' => $days]
			);
		}
		
		if ($settingGroup == 'admin_passwords') {
			$box['key']['current_password_min_score_value'] = $values['passwords/min_admin_password_score'];
		}
	}

	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_all'])) {
			$fields['errors/show_all']['value'] =
			$fields['errors/show_all']['current_value'] = ((error_reporting() | E_NOTICE) & (E_ALL | E_NOTICE)) == (E_ALL | E_NOTICE);
		}

		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 ($settingGroup == 'head_and_foot') {
			$fields['head/twig_snippet']['values'] = ze\pluginAdm::listTwigSnippets($values['head/twig_snippet'], true);
			
			if (($snippet = $fields['head/twig_snippet']['values'][$values['head/twig_snippet']] ?? false)
			 && (!empty($snippet['path']))) {
				$values['head/twig'] = file_get_contents(CMS_ROOT. $snippet['path']);
				$fields['head/twig_path']['snippet']['label'] = $snippet['path'];
				
			} else {
				$values['head/twig'] = '';
				$fields['head/twig_path']['snippet']['label'] = ' ';
			}
		}

		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_robots/sitemap_enabled']['hidden'] = false;
			$fields['sitemap_robots/sitemap_disabled_warning']['hidden'] = true;
			if (isset($fields['sitemap_robots/sitemap_url'])) {
				if (!$fields['sitemap_robots/sitemap_url']['hidden'] = !$values['sitemap_robots/sitemap_enabled']) {
					$fields['sitemap_robots/sitemap_url']['value'] =
					$fields['sitemap_robots/sitemap_url']['current_value'] = ze\miscAdm::sitemapURL($values['sitemap_robots/sitemap_enabled']);
				}
			}
		} elseif (isset($fields['urls/mod_rewrite_enabled']) && !$values['urls/mod_rewrite_enabled']) {
			$fields['urls/friendly_urls_disabled_warning']['hidden'] = false;
			$fields['sitemap_robots/sitemap_enabled']['hidden'] = true;
			$fields['sitemap_robots/sitemap_url']['hidden'] = true;
			$values['sitemap_robots/sitemap_url'] = false;
			$fields['sitemap_robots/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\fileAdm::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\fileAdm::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 (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 (strpos($values['template/standard_email_template'], '[[email_body_content]]') === false) {
				$fields['template/standard_email_template']['notices_below']['merge_field_notice']['type'] = 'warning';
			} else {
				$fields['template/standard_email_template']['notices_below']['merge_field_notice']['type'] = 'information';
			}
		}

		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") {
							zenario_common_features::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,
							$addressReplyTo = false,
							$nameReplyTo = false,
							$ccs = '',
							$bccs = '',
							$action = 'To',
							$ignoreDebugMode = 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 section!
		if ($settingGroup == 'search_engine_optimisation') {
			$defaultConfig = ze\miscAdm::robotsTxtDefaultConfig($values['sitemap_robots/sitemap_enabled'], $values['sitemap_robots/sitemap_url']);
			$blockAll = ze\miscAdm::robotsTxtBlockAllConfig();
			
			if (!empty($fields['sitemap_robots/default_config']['pressed'])) {
				unset($fields['sitemap_robots/default_config']['pressed']);
				
				$fields['sitemap_robots/default_config']['disabled'] = true;
				$values['sitemap_robots/robots_txt_file_contents'] = $defaultConfig;
			} else {
				$fields['sitemap_robots/default_config']['disabled'] = false;
			}
			
			if (!empty($fields['sitemap_robots/block_all']['pressed'])) {
				unset($fields['sitemap_robots/block_all']['pressed']);
				
				$fields['sitemap_robots/block_all']['disabled'] = true;
				$values['sitemap_robots/robots_txt_file_contents'] = $blockAll;
			} else {
				$fields['sitemap_robots/block_all']['disabled'] = false;
			}
			
			$fields['sitemap_robots/robots_config_info_message__blocks_all']['hidden'] = true;
			$fields['sitemap_robots/robots_config_info_message__default_config']['hidden'] = true;
			
			if ($values['sitemap_robots/robots_txt_file_contents'] == $blockAll) {
				$fields['sitemap_robots/robots_config_info_message__blocks_all']['hidden'] = false;
			} elseif ($values['sitemap_robots/robots_txt_file_contents'] == $defaultConfig) {
				$fields['sitemap_robots/robots_config_info_message__default_config']['hidden'] = false;
			}
			
			$robotxTxtReferencesSitemap = false;
			if (strpos($values['sitemap_robots/robots_txt_file_contents'], 'Sitemap:') !== false) {
				$robotxTxtReferencesSitemap = true;
			}
			$box['tabs']['sitemap_robots']['notices']['robots_txt_refers_to_disabled_sitemap']['show'] = $robotxTxtReferencesSitemap && !$values['sitemap_robots/sitemap_enabled'];
			$box['tabs']['sitemap_robots']['notices']['robots_txt_does_not_include_sitemap']['show'] = !$robotxTxtReferencesSitemap && $values['sitemap_robots/sitemap_enabled'];
    	}
    	
    	if ($settingGroup == 'logos_and_branding') {
			$fields['favicon/favicon_png']['notices_below']['favicon_size_warning']['hidden'] = true;
			
			if ($imageId = $values['favicon/favicon_png']) {
				$mimeType = $imageWidth = $imageHeight = '';
				
				if (is_numeric($imageId) && ($file = ze\row::get('files', ['width', 'height', 'mime_type'], $imageId))) {
					$imageWidth = $file['width'];
					$imageHeight = $file['height'];
					$mimeType = $file['mime_type'];
				
				} elseif ($filepath = ze\file::getPathOfUploadInCacheDir($imageId)) {
					$imageSize = getimagesize($filepath);
					$imageWidth = $imageSize[0];
					$imageHeight = $imageSize[1];
					$mimeType = $imageSize['mime'];
				}
				
				if (ze\file::isImageOrSVG($mimeType) && ((($imageWidth % 48) != 0) || ($imageHeight % 48) != 0)) {
					$fields['favicon/favicon_png']['notices_below']['favicon_size_warning']['hidden'] = false;
				}
			}
    	}
    	
    	if ($settingGroup == 'admin_passwords') {
			if ($values['passwords/min_admin_password_score'] < 1) {
					$values['passwords/min_admin_password_score'] = 1;
				} elseif ($values['passwords/min_admin_password_score'] > 4) {
					$values['passwords/min_admin_password_score'] = 4;
				}
			
			if (
				$values['passwords/min_admin_password_score'] == 4
				&& (
					$values['passwords/min_admin_password_score'] != $box['key']['current_password_min_score_value']
					|| $values['passwords/min_admin_password_length'] < 12
				)
			) {
				$values['passwords/min_admin_password_length'] = 12;
			} elseif (
				$values['passwords/min_admin_password_score'] == 3
				&& (
					$values['passwords/min_admin_password_score'] != $box['key']['current_password_min_score_value']
					|| $values['passwords/min_admin_password_length'] < 10
				)
			) {
				$values['passwords/min_admin_password_length'] = 10;
			} elseif ($values['passwords/min_admin_password_length'] < 10) {
				$values['passwords/min_admin_password_length'] = 10;
			}
			
			$box['key']['current_password_min_score_value'] = $values['passwords/min_admin_password_score'];
			
			$cssClass = 'black';
			if ($values['passwords/min_admin_password_score'] == 3 || $values['passwords/min_admin_password_score'] == 4) {
				$cssClass = 'green';
			}
			
			$fields['passwords/min_admin_password_score']['slider']['class'] = $cssClass;
		}
	}


	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.');
			}
		}

		$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($values['file_storage/content_max_filesize'])
			&& $values['file_storage/content_max_filesize']
			&& ze\file::fileSizeBasedOnUnit($values['file_storage/content_max_filesize'], $values['file_storage/content_max_filesize_unit']) > ze\dbAdm::apacheMaxFilesize()
		) {
			$box['tabs']['file_storage']['errors'][] = ze\admin::phrase(
				'The Zenario maximum uploadable file size value should not exceed the server maximum uploadable file size ([[apacheMaxFilesize]]).',
				['apacheMaxFilesize' => $fields['file_storage/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' => 'backup_dir', 'file_storage' => 'docstore_dir']
		as $tab => $dir) {
			if ($saving
			 && isset($box['tabs'][$tab]['fields'][$dir])
			 && ze\ring::engToBoolean($box['tabs'][$tab]['edit_mode']['on'] ?? false)
			 && empty($box['tabs'][$tab]['fields'][$dir]['readonly'])) {
				if (!$values[$tab. '/'. $dir]) {
					$box['tabs'][$tab]['errors'][] = ze\admin::phrase('Please enter a directory.');
		
				} elseif (!is_dir($values[$tab. '/'. $dir])) {
					$box['tabs'][$tab]['errors'][] = ze\admin::phrase('This directory does not exist.');
		
				} elseif (false !== ze\ring::chopPrefix(realpath(CMS_ROOT). '/', realpath($values[$tab. '/'. $dir]). '/')) {
					$box['tabs'][$tab]['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'][$tab]['fields'][$dir]['current_value'] = preg_replace('/[\\\\\\/]+$/', '', $box['tabs'][$tab]['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 ($imageId = $values['favicon/favicon_png']) {
				$mimeType = $imageWidth = $imageHeight = '';
				
				if (is_numeric($imageId) && ($file = ze\row::get('files', ['width', 'height', 'mime_type'], $imageId))) {
					$imageWidth = $file['width'];
					$imageHeight = $file['height'];
					$mimeType = $file['mime_type'];
				
				} elseif ($filepath = ze\file::getPathOfUploadInCacheDir($imageId)) {
					$imageSize = getimagesize($filepath);
					$imageWidth = $imageSize[0];
					$imageHeight = $imageSize[1];
					$mimeType = $imageSize['mime'];
				}
				
				if (ze\file::isImageOrSVG($mimeType) && ($imageWidth > 528 || $imageHeight > 528)) {
					$fields['favicon/favicon_png']['error'] = ze\admin::phrase('The favicon dimensions may not exceed 528 x 528 px.');
				}
			}
		}
		
		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['sitemap_robots/robots_txt_file_contents_required_lines_description']['hidden'] = true;
			
			if ($values['sitemap_robots/robots_txt_file_contents']) {
				$rules = [];
				foreach (explode("\n", $values['sitemap_robots/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['sitemap_robots/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['sitemap_robots/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.');
					}
				}
			}
		}
		
		if ($settingGroup == 'data_protection') {
			//Make sure you cannot ask content to be stored longer than headers
			$headersDays = $values['data_protection/period_to_delete_the_email_template_sending_log_headers'];
			$contentDays = $values['data_protection/period_to_delete_the_email_template_sending_log_content'];
			
			if ($values['data_protection/delete_email_template_sending_log_content_sooner']
				&& ((is_numeric($headersDays) && is_numeric($contentDays) && ($contentDays > $headersDays))
					|| (is_numeric($headersDays) && $contentDays == 'never_delete')
				)
			) {
				$fields['data_protection/period_to_delete_the_email_template_sending_log_content']['error'] = ze\admin::phrase('You cannot save content for longer than the headers.');
			}
		}
		
		if ($settingGroup == 'admin_passwords') {
			if ($values['passwords/min_admin_password_length'] < 10 || $values['passwords/min_admin_password_length'] > 32) {
				$fields['passwords/min_admin_password_length']['error'] = ze\admin::phrase(
					'The minimum password length must be between [[min_password_length]] and [[max_password_length]].',
					['min_password_length' => 10, 'max_password_length' => 32]
				);
			} elseif (!ctype_digit($values['passwords/min_admin_password_length'])) {
				$fields['passwords/min_admin_password_length']['error'] = ze\admin::phrase('The value must be an integer.');
			}

			if ($values['passwords/min_admin_password_score'] < 3 || $values['passwords/min_admin_password_score'] > 4) {
				$fields['passwords/min_admin_password_score']['error'] = ze\admin::phrase(
					'The minimum password score must be either [[min_password_score]] or [[max_password_score]].',
					['min_password_score' => 3, 'max_password_score' => 4]
				);
			} elseif (!ctype_digit($values['passwords/min_admin_password_score'])) {
				$fields['passwords/min_admin_password_score']['error'] = ze\admin::phrase('The value must be an integer.');
			}

			if (
				($values['passwords/min_admin_password_score'] == 4 & $values['passwords/min_admin_password_length'] < 12)
				|| ($values['passwords/min_admin_password_score'] == 3 & $values['passwords/min_admin_password_length'] < 10)
			) {
				if ($values['passwords/min_admin_password_score'] == 4) {
					$requiredMinLength = 12;
				} elseif ($values['passwords/min_admin_password_score'] == 3) {
					$requiredMinLength = 10;
				}
				
				$fields['passwords/min_admin_password_length']['error'] = ze\admin::phrase(
					'To match score [[score]], the password length needs to be at least [[min_length]] characters.',
					['score' => $values['passwords/min_admin_password_score'], 'min_length' => $requiredMinLength]
				);
			}
		}
	}
	
	
	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;
	
			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']);
						$clearSiteSetting = false;
						
						//Get the value of the setting.
						
						//Don't save a value for a field if it was hidden.
						if (ze\ring::engToBoolean($field['hidden'] ?? false)
						 || ze\ring::engToBoolean($field['_cms_hidden'] ?? false)) {
							$value = '';
							$clearSiteSetting = true;
						} else {
							$value = $values[$tabName. '/'. $fieldName] ?? '';
						}
						
						//As per T12878, trim leading zeroes from integers
						if (ze\tuix::isIntField($field)) {
							$valWithZeros = trim($value);
							$value = ltrim($valWithZeros, '0');
							
							//Catch the case where "0" was trimmed to an empty string
							if ($value === ''
							 && $valWithZeros !== '') {
								$value = '0';
							}
						}
				
						//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\fileAdm::copyInDatabase('site_setting', $value);
							
							//Add new uploads into the pool.
							} elseif ($filepath = ze\file::getPathOfUploadInCacheDir($value)) {
								$oldPathCodename = $value;
								$value = ze\fileAdm::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),
									$clearSiteSetting);
							
								//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;
					
								} elseif ($setting == 'custom_thumbnail_2_width' || $setting == 'custom_thumbnail_2_height') {
									$recreateCustomThumbnailTwos = true;
								} elseif ($setting == 'standard_email_template') {
									$files = [];
									$htmlChanged = false;
									ze\contentAdm::syncInlineFileLinksWithoutTranscoding($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\fileAdm::rerenderWorkingCopyImages($recreateCustomThumbnailOnes, $recreateCustomThumbnailTwos, true);
			}
		}

		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));
			
    		//Internally, we allow people to upload multiple favicons for a site.
    		//However to make the admin UI less confusing, we'll only offer the ability to
    		//have at most two favicons: a .ico (for Microsoft Bing) and a .png (for Google).
			$faviconIds = [];
			if ($values['favicon/favicon_png']) {
				$faviconIds[] = $values['favicon/favicon_png'];
			}
			if ($values['favicon/favicon_ico']) {
				$faviconIds[] = $values['favicon/favicon_ico'];
			}
			ze\site::setSetting('favicon', implode(',', $faviconIds));
		}
		
		//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['file_storage/content_max_filesize']) && $values['file_storage/content_max_filesize']) {
			$maxFileSize = ze\file::fileSizeBasedOnUnit($values['file_storage/content_max_filesize'], $values['file_storage/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);
				}
			}
		}
		
		if ($settingGroup == 'cookies') {
			if ($values['cookies/cookie_require_consent']) {
				if ($values['cookies/cookie_require_consent'] == 'implied') {
					if (!$values['cookies/cookie_box1_02_continue_btn']) {
						ze\site::setSetting('cookie_box1_02_continue_btn', 'Continue');
					}
				} elseif ($values['cookies/cookie_require_consent'] == 'explicit') {
					if (!$values['cookies/cookie_box1_05_accept_btn']) {
						ze\site::setSetting('cookie_box1_05_accept_btn', 'Accept all');
					}
					
					if ($values['cookies/cookie_box1_06_necessary_only_checkbox'] && !$values['cookies/cookie_box1_07_necessary_only_btn']) {
						ze\site::setSetting('cookie_box1_07_necessary_only_btn', 'Necessary only');
					}
					
					if (!$values['cookies/cookie_box1_04_manage_btn']) {
						ze\site::setSetting('cookie_box1_04_manage_btn', 'Manage cookies');
					}
					
					if (!$values['cookies/cookie_box2_02_accept_all_btn']) {
						ze\site::setSetting('cookie_box2_02_accept_all_btn', 'Accept all');
					}
					
					if (!$values['cookies/cookie_box2_11_save_preferences_btn']) {
						ze\site::setSetting('cookie_box2_11_save_preferences_btn', 'Save preferences');
					}
				}
			}
		}
	}
	
	
	
	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]
		);
	}
}
