<?php
/*
 * Copyright (c) 2025, 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__content extends ze\moduleBaseClass {

	public function fillAdminBox($path, $settingGroup, &$box, &$fields, &$values) {
		
		//Experimental feature that lets an admin edit multiple content items by
		//selecting multiple in Organizer, but then editing them one at a time.
		//If there are multiple ids in the id, enable openNextMode.
		if (!empty($box['key']['id'])
		 && false !== strpos($box['key']['id'], ',')) {
			$box['key']['openNextMode'] = true;
		}
		
		//When we are using openNextMode, put the first id we're editing $box['key']['id']
		//and any remaining ids into $box['key']['nextIds'].
		if ($box['key']['openNextMode']) {
			$ids = ze\ray::explodeAndTrim($box['key']['id']);
			$box['key']['id'] = array_shift($ids);
			
			if (!empty($ids)) {
				$box['key']['nextIds'] = implode(',', $ids);
			}
			
			//Clear some imcompatible features to avoid bugs
			$box['key']['cID'] =
			$box['key']['cType'] =
			$box['key']['cVersion'] =
			$box['key']['from_cID'] =
			$box['key']['from_cType'] =
			$box['key']['target_cType'] =
			$box['key']['source_cID'] =
			$box['key']['source_cVersion'] =
			$box['key']['translate'] =
			$box['key']['equivId'] =
			$box['key']['duplicate'] =
			$box['key']['duplicate_from_menu'] = '';
		}
		
		
		
		//Try to set an example URL format, for use in the SEO preview box
		$sql = "
			SELECT ci.id, ci.type, ci.equiv_id, ci.alias, ci.language_id
			FROM ". DB_PREFIX. "content_items AS ci
			LEFT JOIN ". DB_PREFIX. "special_pages AS sp
			   ON sp.equiv_id = ci.equiv_id
			  AND sp.content_type = ci.type
			WHERE `type` = 'html'
			AND sp.equiv_id IS NULL
			ORDER BY id
			LIMIT 1";
		
		if ($egContent = ze\sql::fetchAssoc($sql)) {
			$values['meta_data/url_format'] =
				ze\link::toItem($egContent['id'], $egContent['type'], false, '', $egContent['alias'],
					false, $forceAliasInAdminMode = true,
					$egContent['equiv_id'], $egContent['language_id'], false,
					$useHierarchicalURLsIfEnabled = false, $overrideAlias = '[[alias]]', $overrideLangId = '[[langId]]'
				);
		}


		
		//Include an option to create a menu node and/or content item as a new child of an existing menu node
		if ($box['key']['id_is_menu_node_id'] || $box['key']['id_is_parent_menu_node_id']) {
	
			if ($box['key']['id'] && $box['key']['id_is_parent_menu_node_id']) {
				//Create a new content item/menu node under an existing one
				$box['key']['target_menu_parent'] = $box['key']['id'];
		
				$box['key']['target_menu_section'] = ze\row::get('menu_nodes', 'section_id', $box['key']['id']);
				$box['key']['cType'] = $box['key']['target_cType'];
	
			} elseif ($box['key']['id'] && $box['key']['id_is_menu_node_id']) {
				if ($box['key']['edit_linked_content_item'] && ($menuContentItem = ze\menu::getContentItem($box['key']['id']))) {
					//Edit an existing Content Item based on its Menu Node
					$box['key']['cID'] = $menuContentItem['equiv_id'];
					$box['key']['cType'] = $menuContentItem['content_type'];
					ze\content::langEquivalentItem($box['key']['cID'], $box['key']['cType'], $box['key']['target_language_id'] ?: (ze::get('languageId') ?: ze::$defaultLang));
					$box['key']['source_cID'] = $box['key']['cID'];
			
					$box['key']['target_menu_section'] = ze\row::get('menu_nodes', 'section_id', $box['key']['id']);
				} else {
					//Create a new Content Item/Menu Node under an existing child one
					$box['key']['target_menu'] = $box['key']['id'] . '_' . $box['key']['target_menu_section'];
					
					$box['key']['target_menu_section'] = ze\row::get('menu_nodes', 'section_id', $box['key']['id']);
					$box['key']['cType'] = $box['key']['target_cType'];
				}

			} else {
				$box['key']['target_menu_section'] = $box['key']['target_menu_section'] ?: (ze::request('sectionId') ?: ze::request('refiner__section'));
			}
			$box['key']['id'] = false;
		}

		if ($path == 'zenario_content') {
			//Include the option to duplicate a Content Item based on a MenuId
			if ($box['key']['duplicate_from_menu']) {
				//Handle the case where a language id is in the primary key
				if ($box['key']['id'] && !is_numeric($box['key']['id']) && ze::get('refiner__menu_node_translations')) {
					$box['key']['target_language_id'] = $box['key']['id'];
					$box['key']['id'] = $_GET['refiner__menu_node_translations'] ?? false;
		
				} elseif (is_numeric($box['key']['id']) && ze::get('refiner__language')) {
					$box['key']['target_language_id'] = $_GET['refiner__language'] ?? false;
				}
		
				if ($menuContentItem = ze\menu::getContentItem($box['key']['id'])) {
					$box['key']['source_cID'] = $menuContentItem['equiv_id'];
					$box['key']['cType'] = $menuContentItem['content_type'];
					$box['key']['id'] = false;
		
				} else {
					echo ze\admin::phrase('No content item was found for this menu node');
					exit;
				}
	
			//Include the option to duplicate to create a ghost in an translation chain,
			//and handle the case where a language id is in the primary key
			} else
			//Version for opening from the "translation chain" panel in Organizer:
			if (
				$box['key']['translate']
			 && ze::request('refinerName') == 'zenario_trans__chained_in_link'
			 && !ze\content::getCIDAndCTypeFromTagId($box['key']['source_cID'], $box['key']['cType'], $box['key']['id'])
			 && ze\content::getCIDAndCTypeFromTagId($box['key']['source_cID'], $box['key']['cType'], ze::request('refiner__zenario_trans__chained_in_link'))
			) {
				$box['key']['target_language_id'] = $box['key']['id'];
				
				$box['key']['source_cID'] = $_REQUEST['equivId'] ?? false;
				if ($box['key']['source_cID']) {
					$defaulltLangCID = ze\row::get('content_items', 'id', ['equiv_id' => $box['key']['source_cID'], 'type' => $box['key']['cType'], 'language_id' => ze::$defaultLang]);
					if ($defaulltLangCID) {
						$box['key']['source_cID'] = $defaulltLangCID;
					}
				}
				$box['key']['id'] = null;
			} else
			//Version for opening from the "translation chain" panel in the menu area in Organizer:
			if (
				$box['key']['translate']
			 && ze::request('refinerName') == 'zenario_trans__chained_in_link__from_menu_node'
			 && ze::request('equivId')
			 && ze::request('cType')
			) {
				$box['key']['target_language_id'] = $box['key']['target_menu_parent'];
				
				$box['key']['cType'] = $_REQUEST['cType'] ?? false;
				
				$box['key']['source_cID'] = $_REQUEST['equivId'] ?? false;
				if ($box['key']['source_cID']) {
					$defaulltLangCID = ze\row::get('content_items', 'id', ['equiv_id' => $box['key']['source_cID'], 'type' => $box['key']['cType'], 'language_id' => ze::$defaultLang]);
					if ($defaulltLangCID) {
						$box['key']['source_cID'] = $defaulltLangCID;
					}
				}
				
				$box['key']['id'] = null;
			} else
			//Version for opening from the Admin Toolbar
			if (
				$box['key']['translate']
			 && ze::request('cID') && ze::request('cType')
			 && !ze\content::getCIDAndCTypeFromTagId($box['key']['source_cID'], $box['key']['cType'], $box['key']['id'])
			) {
				$box['key']['target_language_id'] = $box['key']['id'];
				$box['key']['id'] = null;
				$box['key']['source_cID'] = $_REQUEST['cID'] ?? false;
				$box['key']['cType'] = $_REQUEST['cType'] ?? false;
				$box['key']['cID'] = '';
			} else {
				$numEnabledLanguages = ze\lang::count();
				if ($numEnabledLanguages == 1) {
					$box['key']['target_language_id'] = ze::$defaultLang;
				}
			}
		}


		//If creating a new content item from the content items (and missing translations) in language panel,
		//or the content items in the language X Panel, don't allow the language to be changed
		if (ze::get('refinerName') == 'language'
		 || (isset($_GET['refiner__language_equivs']) && ze::get('refiner__language'))) {
			$box['key']['target_language_id'] = $_GET['refiner__language'] ?? false;
		}
		
		
		//Only allow the language to be changed when duplicating or translating.
		//Also only allow if there is more than 1 language enabled on the site.
		$duplicatingOrTranslating = ($box['key']['duplicate'] || $box['key']['duplicate_from_menu'] || $box['key']['translate']);
		$lockLanguageId = false;
		if ($box['key']['target_language_id'] || $duplicatingOrTranslating) {
			$lockLanguageId = true;
		}
		
		//Populate the language select list
		ze\contentAdm::getLanguageSelectListOptions($fields['meta_data/language_id']);

		//Set up the primary key from the requests given
		if ($box['key']['id'] && !$box['key']['cID']) {
			ze\content::getCIDAndCTypeFromTagId($box['key']['cID'], $box['key']['cType'], $box['key']['id']);

		} elseif (!$box['key']['id'] && $box['key']['cID'] && $box['key']['cType']) {
			$box['key']['id'] = $box['key']['cType'].  '_'. $box['key']['cID'];
		}

		if ($box['key']['cID'] && !$box['key']['cVersion']) {
			$box['key']['cVersion'] = ze\content::latestVersion($box['key']['cID'], $box['key']['cType']);
		}

		if ($box['key']['cID'] && !$box['key']['source_cID']) {
			$box['key']['source_cID'] = $box['key']['cID'];
			$box['key']['source_cVersion'] = $box['key']['cVersion'];

		} elseif ($box['key']['source_cID'] && !$box['key']['source_cVersion']) {
			$box['key']['source_cVersion'] = ze\content::latestVersion($box['key']['source_cID'], $box['key']['cType']);
		}

		//If we're duplicating a content item, check to see if it has a menu node as well
		if ($duplicatingOrTranslating) {
			$box['key']['cID'] = $box['key']['cVersion'] = false;
	
			if ($menu = ze\menu::getFromContentItem($box['key']['source_cID'], $box['key']['cType'])) {
				$box['key']['target_menu_parent'] = $menu['parent_id'];
				$box['key']['target_menu_section'] = $menu['section_id'];
				
				$values['meta_data/menu_original'] = $menu['name'];
				
				//When translating, do not apply the title to the menu text.
				//The user will be expected to use the "Translate" button.
				if ($box['key']['translate']) {
					$newOninput = str_replace('zenarioAB.contentTitleChange();', '', $box['tabs']['meta_data']['fields']['title']['oninput']);
					$box['tabs']['meta_data']['fields']['title']['oninput'] = $newOninput;
				}
			}
		}

		//Enforce a specific content type
		if (ze::request('refiner__content_type')) {
			$box['key']['target_cType'] = $_REQUEST['refiner__content_type'] ?? false;
		}
		
		if (!empty($box['key']['create_from_toolbar'])) {
			$fields['meta_data/language_id']['disabled'] = true;
		}
		
		//Set the from_cID if the source_cID is set
		if ($box['key']['source_cID']) {
			$box['key']['from_cID'] = $box['key']['source_cID'];
			$box['key']['from_cType'] = $box['key']['cType'];
		}

		$contentType = ze\row::get('content_types', true, $box['key']['cType'] ?: $box['key']['target_cType']);
		
		$box['tabs']['meta_data']['fields']['title']['maxlength'] = (int) $contentType['maximum_title_length'];

		$content = $version = $status = $tag = false;
	
		//Specific logic for full create
		//Try to load details on the source content item, if one is set
		if ($box['key']['source_cID']) {
			$content =
				ze\row::get(
					'content_items',
					['id', 'type', 'tag_id', 'language_id', 'equiv_id', 'alias', 'visitor_version', 'admin_version', 'status'],
					['id' => $box['key']['source_cID'], 'type' => $box['key']['cType']]);
			
			if (!$content) {
				echo ze\admin::phrase('Source content item not found.');
				exit;
			}
		}

		$allowPinning = ze\row::get('content_types', 'allow_pinned_content', ['content_type_id' => $box['key']['cType']]);
		$fields['meta_data/pinned']['hidden'] = !$allowPinning;
		if ($duplicatingOrTranslating) {
			$fields['meta_data/pinned_original']['hidden'] =
			$fields['meta_data/pinned_original_more_info']['hidden'] =!$allowPinning;
		}

		//Pinning
		if ($allowPinning) {
			$scheduledTaskManagerIsRunning = ze\module::inc('zenario_scheduled_task_manager');
			$masterSwitchIsOn = $scheduledTaskManagerIsRunning && zenario_scheduled_task_manager::checkScheduledTaskRunning($jobName = false, $checkPulse = false);
			$cronTabConfiguredCorrectly = $scheduledTaskManagerIsRunning && zenario_scheduled_task_manager::checkScheduledTaskRunning($jobName = false, $checkPulse = true);
			$jobUnpinContentIsEnabled = $scheduledTaskManagerIsRunning && zenario_scheduled_task_manager::checkScheduledTaskRunning('jobUnpinContent');
			//Scheduled Task Manager status
			if ($scheduledTaskManagerIsRunning) {
				if (!$masterSwitchIsOn || !$cronTabConfiguredCorrectly || !$jobUnpinContentIsEnabled) {
					$fields['meta_data/pinned_duration']['values']['fixed_duration']['disabled'] =
					$fields['meta_data/pinned_duration']['values']['fixed_date']['disabled'] =
					$fields['meta_data/unpin_date']['disabled'] =
					$fields['meta_data/pinned_fixed_duration_value']['disabled'] =
					$fields['meta_data/pinned_fixed_duration_unit']['disabled'] = true;
				}
			} else {
				//If STM is not running, then hide the timed unpinning options.
				//Please note: there is additional code below for existing content items
				//which checks if there already is a value selected despite STM not running.
				$fields['meta_data/pinned_duration']['values']['fixed_duration']['hidden'] =
				$fields['meta_data/pinned_duration']['values']['fixed_date']['hidden'] =
				$fields['meta_data/unpin_date']['hidden'] =
				$fields['meta_data/pinned_fixed_duration_value']['hidden'] =
				$fields['meta_data/pinned_fixed_duration_unit']['hidden'] = true;
			}

			//Disable timed unpinning if needed
			if (!$scheduledTaskManagerIsRunning) {
				$fields['meta_data/pinned_duration']['values']['fixed_date']['side_note'] =
				$fields['meta_data/pinned_duration']['values']['fixed_duration']['side_note'] = ze\admin::phrase(
					'Scheduled unpinning is not available. The Scheduled Task Manager is not installed.'
				);
			} elseif (!$masterSwitchIsOn) {
				$fields['meta_data/pinned_duration']['values']['fixed_date']['side_note'] =
				$fields['meta_data/pinned_duration']['values']['fixed_duration']['side_note'] = ze\admin::phrase(
					'Scheduled unpinning is not available. The Scheduled Task Manager is enabled, but the master switch is Off.'
				);
			} elseif (!$cronTabConfiguredCorrectly) {
				$fields['meta_data/pinned_duration']['values']['fixed_date']['side_note'] =
				$fields['meta_data/pinned_duration']['values']['fixed_duration']['side_note'] = ze\admin::phrase(
					'Scheduled unpinning is not available. The Scheduled Task Manager is installed and the master switch is On, but the crontab is not set up correctly.'
				);
			} elseif (!$jobUnpinContentIsEnabled) {
				$fields['meta_data/pinned_duration']['values']['fixed_date']['side_note'] =
				$fields['meta_data/pinned_duration']['values']['fixed_duration']['side_note'] = ze\admin::phrase(
					'Scheduled unpinning is not available. The Scheduled Task Manager is set up correctly, but the scheduled unpinning task (jobUnpinContent) is not enabled.'
				);
			}

			if (!$scheduledTaskManagerIsRunning || !$masterSwitchIsOn || !$cronTabConfiguredCorrectly || !$jobUnpinContentIsEnabled) {
				$fields['meta_data/pinned_duration']['values']['fixed_date']['disabled'] =
				$fields['meta_data/pinned_duration']['values']['fixed_duration']['disabled'] = true;
			}
		}

		if ($content) {
			//On the language selector, disable languages for which translations already exist,
			//and mark the currently selected language.
			if (!ze\content::isSpecialPage($box['key']['cID'], $box['key']['cType'])) {
				$contentEquivId = ze\content::equivId($content['id'], $content['type']);
				$otherTranslationsResult =
					ze\row::query(
						'content_items',
						'language_id',
						['equiv_id' => (int) $contentEquivId, 'type' => $box['key']['cType'], 'id' => ['!' => $content['id']]]);
				$otherTranslations = ze\sql::fetchValues($otherTranslationsResult);
				if (!empty($otherTranslations)) {
					foreach ($otherTranslations as $otherTranslation) {
						if ($fields['meta_data/language_id']['values'][$otherTranslation]) {
							$fields['meta_data/language_id']['values'][$otherTranslation]['disabled'] = true;
							$fields['meta_data/language_id']['values'][$otherTranslation]['label'] .= ' (' . ze\admin::phrase('translation already exists') . ')';
						}
					}
				}
			}

			$values['meta_data/alias'] = $content['alias'];

			if ($duplicatingOrTranslating) {
				
				if ($box['key']['translate']) {
					$box['tabs']['categories']['hidden'] = true;
					$box['tabs']['privacy']['hidden'] = true;
		
					if (!ze::setting('translations_different_aliases')) {
						$fields['meta_data/alias']['readonly'] = true;
						$box['tabs']['meta_data']['fields']['alias']['note_below'] =
							ze\admin::phrase('All content items in a translation chain have the same alias (see site settings).');
					}
				} else {
					
				}
				
				
				$layoutId = ze\content::layoutId($box['key']['source_cID'], $box['key']['cType'], $box['key']['source_cVersion']);
				
				//Check to see if there are any library plugins on this page set at the item level
				$slots = [];
				ze\plugin::checkSlotContents($slots, $box['key']['source_cID'], $box['key']['cType'], $box['key']['source_cVersion']);
				
				$numPlugins = 0;
				foreach ($slots as $slotName => $slot) {
					if (!$slot->isVersionControlled()
					 && $slot->instanceId()
					 && $slot->level() == 1) {
						++$numPlugins;
					}
				}
				
				//If there are, show the plugins tab, with options for each one
				if ($numPlugins) {
					$box['tabs']['plugins']['hidden'] = false;
					
					$fields['plugins/desc']['snippet']['p'] =
						ze\admin::nPhrase('There is 1 plugin/nest/slideshow in a slot on this content item. Please select an action.',
							'There are [[count]] plugins/nests/slideshows in slots on this content item. Please select an action for each one.',
							$numPlugins
						);
						
					
					$changes = [];
					ze\tuix::setupMultipleRows(
						$box, $fields, $values, $changes, $filling = true,
						$box['tabs']['plugins']['custom_template_fields'],
						$numPlugins,
						$minNumRows = 0,
						$tabName = 'plugins'
					);
					
					
					$numPlugins = 0;
					foreach ($slots as $slotName => $slot) {
						
						if (!$slot->isVersionControlled()
						 && $slot->instanceId()
						 && $slot->level() == 1) {
							
							$instance = ze\plugin::details($slot->instanceId());
							
							++$numPlugins;
							$suffix = '__'. $numPlugins;
							$fields['plugins/contents' . $suffix]['snippet']['html'] = 
								'<div class="zenario_slotControl_inThisSlot"><span class="organizer_item_image slot"></span>' . htmlspecialchars($slotName) . '</div>
								<div class="zenario_slotControl_module"><span class="organizer_item_image module"></span>' . ze\module::displayName($slot->moduleId()) . '</div>';
							
							$values['plugins/instance_id'. $suffix] = $slot->instanceId();
							
							$values['plugins/slotname'. $suffix] = $slotName;
							
							$values['plugins/new_name'. $suffix] =  ze\admin::phrase('[[name]] (copy)', $instance);
							
							$className = ze\module::className($slot->moduleId());
							
							$pluginsLink = '';
							
							switch ($className) {
								case 'zenario_nest':
								case 'zenario_ajax_nest':
									$fields['plugins/action'. $suffix]['empty_value'] = ze\admin::phrase(' - Select what to do with this nest - ');
									$fields['plugins/action'. $suffix]['values']['original']['label'] = ze\admin::phrase('Use same nest');
									$pluginsLink = '#zenario__library/panels/plugins/refiners/nests////'. $slot->instanceId();
									break;
									
								case 'zenario_slideshow':
									$fields['plugins/action'. $suffix]['empty_value'] = ze\admin::phrase(' - Select what to do with this slideshow - ');
									$fields['plugins/action'. $suffix]['values']['original']['label'] = ze\admin::phrase('Use same slideshow');
									$pluginsLink = '#zenario__library/panels/plugins/refiners/slideshows////'. $slot->instanceId();
									break;
								
								default:
									$fields['plugins/action'. $suffix]['empty_value'] = ze\admin::phrase(' - Select what to do with this plugin - ');
									$fields['plugins/action'. $suffix]['values']['original']['label'] = ze\admin::phrase('Use same plugin');
									$pluginsLink = '#zenario__library/panels/modules/item//' . $slot->moduleId(). '//'. $slot->instanceId();
									break;
							}
							
							$usage = ze\pluginAdm::getUsage($slot->instanceId(), $layoutId, $content['tag_id']);
							$instance['plugins_link'] = htmlspecialchars('organizer.php?' . $pluginsLink);
							
							if (empty($usage)) {
								$pluginUsage = ze\admin::phrase(' <a target="_blank" href="[[plugins_link]]">[[instance_name]]</a>', $instance);
							} else {
								$usageLinks = [
									'content_items' => 'zenario__library/panels/plugins/item_buttons/usage_item//'. (int) $slot->instanceId(). '//', 
									'layouts' => 'zenario__library/panels/plugins/item_buttons/usage_layouts//'. (int) $slot->instanceId(). '//'
								];
								$instance['usage_text'] = implode(', ', ze\miscAdm::getUsageText($usage, $usageLinks, true));
								$pluginUsage = ze\admin::phrase(
									'[[ucPluginAdminName]] <a class="plugins_link_new_window" target="_blank" href="[[plugins_link]]"><span class="organizer_item_image plugin"></span>[[instance_name]]</a><br/>[[name]]<br /><span class="smaller_text">Used on [[usage_text]]</span>',
									$instance
								);
							}
							
							$fields['plugins/plugin_instance_id'. $suffix]['snippet']['html'] = $pluginUsage;
						}
					}
				}
				
	
			} else {
				//When editing an existing content item, make the example in the SEO preview box a little more accurate
				$values['meta_data/url_format'] =
					ze\link::toItemWithAlias($content['id'], $content['type'], false, '', $content['alias'],
						$content['equiv_id'], $content['language_id']
					);

				//The option to set the alias should be hidden when not creating something.
				$box['tabs']['categories']['hidden'] = true;
				
				//The option to set the privacy will be visible when not creating something,
				//but with a note saying the whole translation chain will be affected immediately.
				$fields['privacy/content_item_privacy_info_warning']['hidden'] = false;
				if (ze\lang::count() > 1) {
					$translationTagIds = ze\row::getArray('content_items', 'tag_id', ['equiv_id' => $content['equiv_id'], 'type' => $content['type']]);
					
					if ($translationTagIds && count($translationTagIds) > 1) {
						$string = 'Permissions are applied to the entire content item (not just this version), and all content items in its translation chain.
							Any change to permissions will go live immediately and affect all translations equally.';
					} else {
						$string = 'Permissions are applied to the entire content item and not just this version. Any change to permissions will go live immediately.';
					}
				} else {
					$string = 'Permissions are applied to the entire content item and not just this version. Any change to permissions will go live immediately.';
				}
				
				ze\lang::applyMergeFields($fields['privacy/content_item_privacy_info_warning']['snippet']['html'], ['content_item_privacy_changed_warning' => $string]);

				//Alias should be displayed but as a span.
				$fields['meta_data/alias']['read_only'] = true;

				// Change code for special page FAB
				$specialpagesresult = ze\row::get('special_pages', ['page_type'], ['equiv_id' => $content['equiv_id'], 'content_type' => $content['type']]);
				$pagetype = '';

				if ($specialpagesresult) {
					$pagetype = str_replace('_', ' ', ze\ring::chopPrefix('zenario_', $specialpagesresult['page_type'], true));
					
					$box['key']['is_special_page'] = true;
					$box['key']['special_page_type'] = $specialpagesresult['page_type'];
				}

				if ($pagetype) {
					$fields['meta_data/special_page_message']['hidden'] = false;
					$fields['meta_data/special_page_message']['snippet']['html'] = 'This is a special page: ' . $pagetype . ' page';
				}

				if (array_key_exists("refinerName",$_GET)) {
					if ($_GET['refinerName'] == 'special_pages') {

						if ($specialpagesresult['page_type'] == 'zenario_not_found' || $specialpagesresult['page_type'] == 'zenario_no_access') {
							$fields['meta_data/no_menu_warning']['hidden'] = true;
						}
					}
					
				}
				
				$box['identifier']['css_class'] = ze\contentAdm::getItemIconClass($content['id'], $content['type'], true, $content['status']);
				
				self::unsetOriginalContentItemFields($box);
			}
	
			$values['meta_data/language_id'] = $values['meta_data/language_id_on_load'] = $content['language_id'];
	
			$fields['meta_data/layout_id']['pick_items']['path'] = 
				'zenario__layouts/panels/layouts/refiners/content_type//' . $content['type']. '//';
	
			if ($version =
				ze\row::get(
					'content_item_versions',
					true,
					['id' => $box['key']['source_cID'], 'type' => $box['key']['cType'], 'version' => $box['key']['source_cVersion']])
			) {
				
				$values['meta_data/title'] = $version['title'];
				$values['meta_data/description'] = $version['description'];
				$values['meta_data/keywords'] = $version['keywords'];
				$values['meta_data/release_date'] = $version['release_date'];
				$values['meta_data/writer_id'] = $version['writer_id'];
				$values['meta_data/writer_name'] = $version['writer_name'];
				$values['meta_data/content_summary'] = $version['content_summary'];
				$values['meta_data/layout_id'] = $version['layout_id'];
				$values['meta_data/exclude_from_sitemap'] = !$version['in_sitemap'];
				$values['meta_data/apply_noindex_meta_tag'] = $version['apply_noindex_meta_tag'];
				$values['meta_data/css_class'] = $version['css_class'];
				
				//If a content item uses a file (local or S3),
				//the pickers will NOT be populated when duplicating or translating.
				
				if ($duplicatingOrTranslating) {
					//By default, use the title as a menu node...
					$values['meta_data/menu_text'] = $values['meta_data/title'];
					
					//... but check if the menu text already exists in the target language.
					//If it does, then display what it is and do not allow editing.
					if ($box['key']['target_language_id'] && $box['key']['target_language_id'] != $content['language_id']) {
						if (!empty($menu)) {
							$menuTextInTargetLanguage = ze\row::get('menu_text', 'name', ['menu_id' => $menu['mID'], 'language_id' => $box['key']['target_language_id']]);
							if ($menuTextInTargetLanguage) {
								$values['meta_data/menu_text'] = $menuTextInTargetLanguage;
								$fields['meta_data/menu_text_already_exists_warning']['hidden'] = false;
								ze\lang::applyMergeFields($fields['meta_data/menu_text_already_exists_warning']['snippet']['html'], ['language' => ze\lang::name($box['key']['target_language_id'])]);
							}
						}
					}
					
					//Also populate the source content item's data for a side-by-side view.
					$values['meta_data/title_original'] = $values['meta_data/title'];
					$values['meta_data/alias_original'] = $values['meta_data/alias'];
					
					$fields['meta_data/language_id_original']['values'] = $fields['meta_data/language_id']['values'];
					$values['meta_data/language_id_original'] = $values['meta_data/language_id'];
					
					$values['meta_data/release_date_original'] = $values['meta_data/release_date'];
					$values['meta_data/keywords_original'] = $values['meta_data/keywords'];
					$values['meta_data/description_original'] = $values['meta_data/description'];
					$values['meta_data/content_summary_original'] = $values['meta_data/content_summary'];
					
					$values['meta_data/writer_id_original'] = $values['meta_data/writer_id'];
					$values['meta_data/layout_original'] = $values['meta_data/layout_id'];
					
					$values['meta_data/css_class_field_original'] = $values['meta_data/css_class'];
					
					if (ze::setting('sitemap_enabled')) {
						$phrase = '';
						
						$contentEquivId = ze\content::equivId($content['id'], $content['type']);
						$privacy = ze\row::get('translation_chains', 'privacy', ['equiv_id' => $contentEquivId, 'type' => $content['type']]);
						$excludedFromSitemap = $values['meta_data/exclude_from_sitemap'];
						$noindexMetaTagApplied = $values['meta_data/apply_noindex_meta_tag'];
						
						if (ze::in(ze\content::isSpecialPage($box['key']['source_cID'], $box['key']['cType']), 'zenario_not_found', 'zenario_no_access')) {
							$phrase = 'Automatically excluded (is the not-found or no-access special page)';
						} elseif ($privacy == 'public') {
							if ($excludedFromSitemap) {
								$phrase = 'Excluded (manual override)';
								
								if ($noindexMetaTagApplied) {
									$phrase .= '; noindex meta tag applied';
								}
							} else {
								$phrase = 'Automatically included';
							}
						} else {
							$phrase = 'Automatically excluded (permission is not public)';
						}
						
						$values['meta_data/sitemap_original'] = ze\admin::phrase($phrase);
					} else {
						$values['meta_data/sitemap_original'] = $values['meta_data/sitemap_disabled'];
					}
				} else {
					$values['file/file'] = $version['file_id'];
					$values['file/s3_file_id'] = $version['s3_file_id'];
					$values['file/s3_file_name'] = $version['s3_filename'];
				}
				
				if (!empty($contentType['maximum_title_length']) && strlen($values['meta_data/title']) > $contentType['maximum_title_length']) {
					$fields['meta_data/title']['notices_below']['title_is_longer_than_the_allowed_length']['hidden'] = false;
				}
				
				//If a file has already been selected, don't rely on Zenario's standard function for
				//automatically looking up the label, as the internal filename might have been changed
				//and be different to the one used here. Specifically use this filename.
				if ($version['file_id']) {
					if ($file = \ze\file::labelDetails($version['file_id'], $version['filename'])) {
						
						if (empty($fields['file/file']['values'])) {
							$fields['file/file']['values'] = [];
						}
						$fields['file/file']['values'][$file['id']] = $file;
					}
				}
				
				if ($values['meta_data/writer_name']) {
					$fields['meta_data/writer_id']['note_below'] = ze\admin::phrase(
						"Zenario 9.2 migration: please note the previous writer name was [[writer_name]].",
						['writer_name' => $values['meta_data/writer_name']]
					);
				}

				if (ze::setting('enable_aws_support') && ze::setting('allow_document_content_items_to_be_stored_on_aws_s3')) {
					if ($values['file/s3_file_id'] && ze\module::inc('zenario_ctype_document')) {
						$s3FileDetails = zenario_ctype_document::getS3FileDetails($values['file/s3_file_id']);

						if (!empty($s3FileDetails) && isset($s3FileDetails['ContentType'])) {
							$values['file/s3_mime_type'] = $s3FileDetails['ContentType'];
						}

						$fields['file/s3_mime_type']['show_as_a_span'] = true;
					}
				}

				$values['meta_data/pinned'] = $version['pinned'];
				$values['meta_data/pinned_duration'] = $version['pinned_duration'];
				$values['meta_data/unpin_date'] = $version['unpin_date'];
				$values['meta_data/pinned_fixed_duration_value'] = $version['pinned_fixed_duration_value'];
				$values['meta_data/pinned_fixed_duration_unit'] = $version['pinned_fixed_duration_unit'];
				
				if ($allowPinning) {
					if ($values['meta_data/pinned']) {
						if (ze::in($values['meta_data/pinned_duration'], 'fixed_date', 'fixed_duration')) {
							if (!$scheduledTaskManagerIsRunning) {
								$fields['meta_data/pinned_error_scheduled_task_manager_not_running']['hidden'] = false;
							} elseif (!$masterSwitchIsOn) {
								$fields['meta_data/pinned_error_scheduled_task_master_switch_is_off']['hidden'] = false;
							} elseif (!$cronTabConfiguredCorrectly) {
								$fields['meta_data/pinned_error_scheduled_task_master_not_set_up_correctly']['hidden'] = false;
							} elseif (!$jobUnpinContentIsEnabled) {
								$fields['meta_data/pinned_error_scheduled_task_master_job_not_running']['hidden'] = false;
							}
	
							if (!$masterSwitchIsOn || !$cronTabConfiguredCorrectly || !$jobUnpinContentIsEnabled) {
								$fields['meta_data/pinned_duration']['values']['fixed_duration']['hidden'] =
								$fields['meta_data/pinned_duration']['values']['fixed_date']['hidden'] =
								$fields['meta_data/unpin_date']['hidden'] =
								$fields['meta_data/pinned_fixed_duration_value']['hidden'] =
								$fields['meta_data/pinned_fixed_duration_unit']['hidden'] = false;
							}
	
							$scheduledTaskHref = ze\link::absolute() . 'organizer.php#zenario__administration/panels/zenario_scheduled_task_manager__scheduled_tasks';
							$linkStart = '<a href="' . htmlspecialchars($scheduledTaskHref) . '" target="_blank">';
							$linkEnd = "</a>";
							$errorFields = [
								'pinned_error_scheduled_task_manager_not_running',
								'pinned_error_scheduled_task_master_switch_is_off',
								'pinned_error_scheduled_task_master_not_set_up_correctly',
								'pinned_error_scheduled_task_master_job_not_running'
							];
							foreach ($errorFields as $errorField) {
								ze\lang::applyMergeFields($fields['meta_data/' . $errorField]['snippet']['html'], ['link_start' => $linkStart, 'link_end' => $linkEnd]);
							}
							
							if ($values['meta_data/pinned']) {
								if ($duplicatingOrTranslating) {
									$values['meta_data/pinned_original'] = true;
								}
								
								if ($values['meta_data/pinned_duration'] == 'fixed_duration') {
									if (preg_match('/^[0-9]{1,2}$/', $values['meta_data/pinned_fixed_duration_value'])) {
										//Work out the unpin date
										$newEndDate = new DateTime();
										$newEndDate->setTime(00, 00);
										//Work out if this is supposed to be singular day/week or plural days/weeks.
										if ($values['meta_data/pinned_fixed_duration_value'] > 1) {
											$unit = $values['meta_data/pinned_fixed_duration_unit'] . 's';
										} else {
											$unit = $values['meta_data/pinned_fixed_duration_unit'];
										}
						
										//Example: "+1 day". "+2 weeks" etc.
										$newEndDate->modify('+' . $values['meta_data/pinned_fixed_duration_value'] . ' ' . $unit);
										$unpinDate = ze\admin::formatDate($newEndDate);
										
										if ($duplicatingOrTranslating) {
											$values['meta_data/pinned_original_more_info'] = ze\admin::phrase(
												'Pinned until the first run of scheduled task jobUnpinContent on or after [[date_and_time]]',
												['date_and_time' => $unpinDate]
											);
										}
									}
								} elseif ($values['meta_data/pinned_duration'] == 'fixed_date') {
									if ($duplicatingOrTranslating) {
										$unpinDate = ze\admin::formatDate($values['meta_data/unpin_date']);
										$values['meta_data/pinned_original_more_info'] = ze\admin::phrase(
											'Pinned until [[date_and_time]]',
											['date_and_time' => $unpinDate]
										);
									}
								}
							}
						} elseif ($values['meta_data/pinned_duration'] == 'until_unpinned') {
							if ($duplicatingOrTranslating) {
								$values['meta_data/pinned_original_more_info'] = ze\admin::phrase('Pinned indefinitely');
							}
						}
					}
				}
				
				if (isset($box['tabs']['categories']['fields']['categories'])) {
					ze\categoryAdm::setupFABCheckboxes(
						$fields['categories/categories'], true,
						$box['key']['source_cID'], $box['key']['cType'], $box['key']['source_cVersion']);
					
					if ($box['key']['duplicate'] || $box['key']['duplicate_from_menu']) {
						$fields['categories/categories_original']['values'] = $fields['categories/categories']['values'];
						$values['categories/categories_original'] = $values['categories/categories'];
					}
				}
		
				$tag = ze\content::formatTag($box['key']['source_cID'], $box['key']['cType'], ($content['alias'] ?? false));
		
				$status = ze\contentAdm::formatVersionStatus($content, $box['key']['source_cVersion']);
			}

			//Location (DB, docstore, s3)
			if ($values['file/file']) {
				$fileInfo = ze\row::get('files', ['location', 'path'], $values['file/file']);
				
				if (is_array($fileInfo) && !empty($fileInfo)) {
					$storageString = "Stored in the [[storage_location]]";
					if (!empty($fileInfo['location']) && $fileInfo['location'] == 'docstore') {
						$storageString .= ", folder name [[folder_name]].";
					} else {
						$storageString .= ".";
					}
				
					if ($fileInfo['path'] && !ze\file::docstorePath($fileInfo['path'])) {
						ze\lang::applyMergeFields($fields['file/file']['notices_below']['file_is_missing']['message'], ['path' => $fileInfo['path']]);
						$fields['file/file']['notices_below']['file_is_missing']['hidden'] = false;
					}

					$fields['file/file']['note_below'] = ze\admin::phrase($storageString, ['storage_location' => $fileInfo['location'] ?? '', 'folder_name' => $fileInfo['path'] ?? '']);
				}
			}
		} else {
			//If we are enforcing a specific content type, ensure that only layouts of that type can be picked
			if ($box['key']['target_cType']) {
				$fields['meta_data/layout_id']['pick_items']['path'] =
					'zenario__layouts/panels/layouts/refiners/content_type//'. $box['key']['target_cType']. '//';
				
				
				//T10208, Creating content items: auto-populate release date and author where used
				$contentTypeDetails = ze\contentAdm::cTypeDetails($box['key']['target_cType']);

				if ($contentTypeDetails['writer_field'] != 'hidden' && isset($fields['meta_data/writer_id'])) {
					$currentAdminId = ze\admin::id();

					//Check if this admin has a writer profile.
					$writerProfile = ze\row::get('writer_profiles', ['id'], ['admin_id' => (int) $currentAdminId]);
					if ($writerProfile) {
						$values['meta_data/writer_id'] = $writerProfile['id'];
					}
				}
			}
			
			self::unsetOriginalContentItemFields($box);
		}


		//We should have loaded or found the cID by now, if this was for editing an existing content item.
		//If there's no cID then we're creating a new content item
		if ($box['key']['cID']) {
			//Any admin can at least view a content item's details

		} elseif ($box['key']['translate']) {
			//When making a translation, check if the admin is allowed to make a translation in this language
			if (!ze\priv::onLanguage('_PRIV_EDIT_DRAFT', $box['key']['target_language_id'])) {
				exit;
			}

		} else {
			//Otherwise require _PRIV_EDIT_DRAFT for creating a new content item
			ze\priv::exitIfNot('_PRIV_EDIT_DRAFT', false, $box['key']['cType']);
		}



		//Set default values
		if ($content) {
			if ($duplicatingOrTranslating) {
				$values['meta_data/language_id'] = $values['meta_data/language_id_on_load'] = ($box['key']['target_language_id'] ?: ze::get('languageId')) ?: (ze::get('language') ?: $content['language_id']);
			}
		} else {
			$values['meta_data/language_id'] = $values['meta_data/language_id_on_load'] = $box['key']['target_language_id'] ?: (ze::get('languageId') ?: ze::$defaultLang);
		}
		
		if (!$version) {
			//Attempt to work out the default template and content type for a new content item
			if (($layoutId = $box['key']['target_template_id'] ?: ze::get('refiner__template'))
			 && ($box['key']['cType'] = ze\row::get('layouts', 'content_type', $layoutId))) {
		
	
			} else {
				$box['key']['cType'] = ($box['key']['target_cType'] ?: ($box['key']['cType'] ?: 'html'));
				
				if ($contentType && is_array($contentType) && !empty($contentType['default_layout_id'])) {
					$layoutId = $contentType['default_layout_id'];
				} else {
					$layoutId = 0;
				}
			}
			
			$values['meta_data/layout_id'] = $layoutId;
			
			if (isset($box['tabs']['categories']['fields']['categories'])) {
				
				ze\categoryAdm::setupFABCheckboxes($box['tabs']['categories']['fields']['categories'], true);
		
				if ($categories = $_GET['refiner__category'] ?? false) {
					
					$categories = ze\ray::explodeAndTrim($categories);
					$inCategories = array_flip($categories);
			
					foreach ($categories as $catId) {
						$categoryAncestors = [];
						ze\categoryAdm::ancestors($catId, $categoryAncestors);
				
						foreach ($categoryAncestors as $catAnId) {
							if (!isset($inCategories[$catAnId])) {
								$categories[] = $catAnId;
							}
						}
					}
			
					$box['tabs']['categories']['fields']['categories']['value'] = implode(',', $categories);
				}
			}
		}
		
		if (!$version && $box['key']['target_alias']) {
			$values['meta_data/alias'] = $box['key']['target_alias'];
		}
		if (!$version && $box['key']['target_title']) {
			$values['meta_data/title'] = $box['key']['target_title'];
		}
		
		if (isset($box['tabs']['categories']['fields']['desc'])) {
			$box['tabs']['categories']['fields']['desc']['snippet']['html'] = 
				ze\admin::phrase('You can put content item(s) into one or more categories. (<a[[link]]>Define categories</a>.)',
					['link' => ' href="'. htmlspecialchars(ze\link::absolute(). 'organizer.php#zenario__content/panels/categories'). '" target="_blank"']);
		
				if (ze\row::exists('categories', [])) {
					$fields['categories/no_categories']['hidden'] = true;
					$fields['categories/no_categories_original']['hidden'] = true;
				} else {
					$fields['categories/categories']['hidden'] = true;
					$fields['categories/categories_original']['hidden'] = true;
				}
		}
		
		if (!$duplicatingOrTranslating) {
			$fields['categories/categories_original']['hidden'] = true;
			$fields['categories/no_categories_original']['hidden'] = true;
		}

		//Turn edit mode on if we will be creating a new content item...
		if (!$box['key']['cID'] || $box['key']['cID'] != $box['key']['source_cID']) {
			foreach ($box['tabs'] as $i => &$tab) {
				if (is_array($tab) && isset($tab['edit_mode'])) {
					$tab['edit_mode']['enabled'] = true;
					$tab['edit_mode']['on'] = true;
				}
			}

		//... and turn it off if we are looking at an archived version of an existing content item, or a locked content item
		} elseif ($box['key']['cID']
			   && $content
			   && ($box['key']['cVersion'] < $content['admin_version'] || !ze\priv::check('_PRIV_EDIT_DRAFT', $box['key']['cID'], $box['key']['cType']))
		) {
			foreach ($box['tabs'] as $i => &$tab) {
				if (is_array($tab) && isset($tab['edit_mode'])) {
					$tab['edit_mode']['enabled'] = false;
				}
			}

		} else {
			foreach ($box['tabs'] as $i => &$tab) {
				if (is_array($tab) && isset($tab['edit_mode'])) {
					$tab['edit_mode']['enabled'] = true;
				}
			}
		}

		//Only display the "Auto-populate from file name" checkbox
		//for audio/video/picture/document content item when creating (not editing).
		if (!($contentType && ze::in($contentType['content_type_id'], 'audio', 'document', 'picture', 'video')) || $box['key']['cID']) {
			unset($box['tabs']['meta_data']['fields']['auto_populate_title_from_filename']);
		}

		if ($box['key']['source_cID']) {
			if ($box['key']['cID'] != $box['key']['source_cID']) {
				if ($box['key']['target_language_id'] && $box['key']['target_language_id'] != $content['language_id']) {
					$box['title'] =
						ze\admin::phrase('Duplicating content item [[tag]] ([[old_lang]]) for translation into [[lang]]',
							['tag' => $tag, 'old_lang' => $content['language_id'], 'lang' => ze\lang::name($box['key']['target_language_id'])]);
					//Check if the source content item is in the menu.
					//If it is, offer to add the translation to the menu.
					//Otherwise, do not show the menu section.
					$sourceContentItemMenu = ze\menu::getFromContentItem($box['key']['source_cID'], $box['key']['cType']);
					if (!$sourceContentItemMenu) {
						$fields['meta_data/menu_text']['hidden'] = true;
					} else {
						unset($fields['meta_data/menu_text']['indent']);
					}
					$fields['meta_data/menu_invisible']['hidden'] = true;
			
				} elseif ($box['key']['source_cVersion'] < $content['admin_version']) {
					$box['title'] =
						ze\admin::phrase('Duplicating the [[status]] (version [[version]]) Content Item "[[tag]]"',
							['tag' => $tag, 'status' => $status, 'version' => $box['key']['source_cVersion']]);
				} else {
					$box['title'] =
						ze\admin::phrase('Duplicating the [[status]] content item "[[tag]]"',
							['tag' => $tag, 'status' => $status]);
				}
			} else {
				if ($box['key']['source_cVersion'] < $content['admin_version']) {
					$box['title'] =
						ze\admin::phrase('Viewing metadata of content item "[[tag]]", version [[version]] ([[status]])',
							['tag' => $tag, 'status' => $status, 'version' => $box['key']['source_cVersion']]);
				} else {
					$box['title'] =
						ze\admin::phrase('Editing metadata of content item "[[tag]]", version [[version]] ([[status]])',
							['tag' => $tag, 'status' => $status, 'version' => $box['key']['source_cVersion']]);
				}
			}
		} elseif (($box['key']['target_cType'] || (!$box['key']['id'] && $box['key']['cType'])) && $contentType) {
			$box['title'] = ze\admin::phrase('Creating a content item, [[content_type_name_en]]', $contentType);
		}

		if ($lockLanguageId || ($box['key']['cID'] && $box['key']['cType'] && ze\content::isSpecialPage($box['key']['cID'], $box['key']['cType']))) {
			$box['tabs']['meta_data']['fields']['language_id']['show_as_a_span'] = true;
		}
		
		if ($content && $content['language_id'] && $fields['meta_data/language_id']['values'][$content['language_id']] && !$fields['meta_data/language_id']['show_as_a_span']) {
			$fields['meta_data/language_id']['values'][$content['language_id']]['label'] .= ' (' . ze\admin::phrase('selected') . ')';
		}
		
		//Attempt to load the content into the content tabs for each WYSIWYG Editor
		if (isset($box['tabs']['content1'])) {
			$i = 0;
			$slots = [];
			
			$moduleIds = ze\module::id('zenario_wysiwyg_editor');
			if ($box['key']['source_cID']
			 && $box['key']['cType']
			 && $box['key']['source_cVersion']
			 && ($slots = ze\contentAdm::mainSlot($box['key']['source_cID'], $box['key']['cType'], $box['key']['source_cVersion'], $moduleIds, false))
			 && (!empty($slots))) {
	
				//Set the content for each slot, with a limit of four slots
				foreach ($slots as $slot) {
					if (++$i > 4) {
						break;
					}
					$values['content'. $i. '/content'] =
						ze\contentAdm::getContent($box['key']['source_cID'], $box['key']['cType'], $box['key']['source_cVersion'], $slot);
					$fields['content'. $i. '/content']['pre_field_html'] =
						'<div class="zfab_content_in">'. ze\admin::phrase('Edit [[slotName]] (WYSIWYG area):', ['slotName' => $slot]). '</div>';
				}
			}
		}
		
		//Attempt to load the raw html into the content tabs for each RAW HTML
		if (isset($box['tabs']['rawhtml1'])) {
			$i = 0;
			$slots = [];
			$moduleIds = ze\module::id('zenario_html_snippet');
			if ($box['key']['source_cID']
			 && $box['key']['cType']
			 && $box['key']['source_cVersion']
			 && ($slots = ze\contentAdm::mainSlot($box['key']['source_cID'], $box['key']['cType'], $box['key']['source_cVersion'], $moduleIds, false))
			 && (!empty($slots))) {
	
				//Set the content for each slot, with a limit of four slots
				foreach ($slots as $slot) {
					if (++$i > 4) {
						break;
					}
					$values['rawhtml'. $i. '/content'] =
						ze\contentAdm::getContent($box['key']['source_cID'], $box['key']['cType'], $box['key']['source_cVersion'], $slot, 'zenario_html_snippet');
					$fields['rawhtml'. $i. '/content']['pre_field_html'] =
						'<div class="zfab_content_in">'. ze\admin::phrase('Edit [[slotName]] (Raw HTML):', ['slotName' => $slot]). '</div>';
				}
			}
		}

		// Hide categories if not enabled by cType
		if (!$contentType['enable_categories']) {
			$box['tabs']['categories']['hidden'] = true;
		}


		if ($box['key']['cID']) {
			$box['key']['id'] = $box['key']['cType']. '_'. $box['key']['cID'];
			$fields['meta_data/layout_id']['hidden'] = true;
		} else {
			$box['key']['id'] = null;
		}
		
		$this->fillMenu($box, $fields, $values, $contentType, $content, $version);
		
		if ($duplicatingOrTranslating) {
			if ($menu) {
				//If the content item we're copying is in the menu, we'll want to display its position.
				//N.b. when displaying an existing menu position, you need to enter a "3" into the child parameter.
				//(See the explination in ze\menuAdm::posToPathArray() for more information.)
				$menuPos = $menu['section_id']. '_'. $menu['id']. '_3';
				ze\menuAdm::setupPathPreview($menuPos, $fields['meta_data/menu_original'], $values['meta_data/language_id_original']);
				$values['meta_data/menu_original'] = $menu['name'];
			} else {
				$values['meta_data/menu_original'] = ze\admin::phrase('Not in menu');
			}
		}
		
		//To show history tab in content FAB
		if ($box['key']['id']) {
			$box['tabs']['history']['hidden'] = false;
			$content = ze\row::get('content_items', true, ['tag_id' => $box['key']['id']]);
			$sql = "SELECT version, created_datetime, 
							(SELECT username FROM " . DB_PREFIX . "admins as a WHERE a.id = v.creating_author_id) as creating_author,
							last_modified_datetime, 
							(SELECT username FROM " . DB_PREFIX . "admins as a WHERE a.id = v.last_author_id) as last_author,
							published_datetime,scheduled_publish_datetime,
							(SELECT username FROM " . DB_PREFIX . "admins as a WHERE a.id = v.publisher_id) as publisher
						FROM " . DB_PREFIX . "content_item_versions as v 
						WHERE v.tag_id = '" . ze\escape::asciiInSQL($box['key']['id']) . "'
						ORDER BY v.version desc";
			$result = ze\sql::select($sql);
			if (ze\sql::numRows($result) > 0 ) {
				
				$fields['history/th_version']['hidden'] =
				$fields['history/th_created']['hidden'] =
				$fields['history/th_last_edited']['hidden'] =
				$fields['history/th_status']['hidden'] =
				$fields['history/th_published']['hidden'] =
				$fields['history/th_comments']['hidden'] = false;
				
				
				$fields['history/no_history_recorded']['hidden'] = true;
				
				$totalRowNum = 0;
				while ($row = ze\sql::fetchAssoc($result)) {
					++$totalRowNum;
					$suffix = '__' . $totalRowNum;
					
					$values['history' . '/version' . $suffix] = $row['version'];
					
					$bycreating_author='';
					$bypublisher='';
					$bylast_author='';
					
					if($row['creating_author'])
						$bycreating_author = ' by '.$row['creating_author'];
				
					if($row['last_author'])
						$bylast_author = ' by '.$row['last_author'];
					
					if($row['publisher'])
						$bypublisher = ' by '.$row['publisher'];

					$values['history' . '/last_edited' . $suffix] = ze\admin::formatDateTime($row['last_modified_datetime'], 'vis_date_format_med').$bylast_author;
					$values['history' . '/published' . $suffix] = ze\admin::formatDateTime($row['published_datetime'], 'vis_date_format_med').$bypublisher;
					$values['history' . '/created' . $suffix]  = ze\admin::formatDateTime($row['created_datetime'],'vis_date_format_med').$bycreating_author;
					$values['history' . '/status' . $suffix] = ze\contentAdm::getContentItemVersionStatus($content, $row['version']);
					if($values['history' . '/status' . $suffix] == 'draft') {
						if($content['lock_owner_id']) {
							$admin_details = ze\admin::details($content['lock_owner_id']);
							$values['history' . '/comments' . $suffix] = ze\admin::phrase('Locked by [[username]]', $admin_details);
						}
					}
					if ($totalRowNum > 500) {
						break;
					}
				}
				
			}
			$changes = [];
				ze\tuix::setupMultipleRows(
					$box, $fields, $values, $changes, $filling = true,
					$box['tabs']['history']['custom_template_fields'],
					$totalRowNum,
					$minNumRows = 0,
					$tabName = 'history'
				);
			//To show warning message for locked content item in FAB	
		   	if($content['lock_owner_id']) {
				$box['tabs']['meta_data']['notices']['locked_warning']['show'] = true;
				$admin_details = ze\admin::details($content['lock_owner_id']);

				if(ze\admin::id() == $content['lock_owner_id'])
				{
					$box['tabs']['meta_data']['notices']['locked_warning']['message'] = ze\admin::phrase('This item is locked by you.');
				}
				else{
					$box['tabs']['meta_data']['notices']['locked_warning']['message'] = ze\admin::phrase('This item is locked by [[username]].', $admin_details);
				}
			
			}
			
			
			//Show a note if this is scheduled to be published
			$sql = "
				SELECT c.id, c.type, v.scheduled_publish_datetime
				FROM ". DB_PREFIX. "content_items AS c
				INNER JOIN ". DB_PREFIX. "content_item_versions AS v
				   ON v.id = c.id
				  AND v.type = c.type
				  AND v.version = c.admin_version
				WHERE c.id = ". (int) $box['key']['cID']. "
				  AND c.type = '". ze\escape::asciiInSQL($box['key']['cType']). "'
				  AND v.scheduled_publish_datetime IS NOT NULL";
		
			if ($row = ze\sql::fetchAssoc($sql)) {
				$box['tabs']['meta_data']['notices']['scheduled_warning']['show'] = true;
				
				$row['publication_time'] = 
					ze\admin::formatDateTime($row['scheduled_publish_datetime'], 'vis_date_format_med');
				
				$box['tabs']['meta_data']['notices']['scheduled_warning']['message'] =
					ze\admin::phrase("This item is scheduled to be published at [[publication_time]].", $row);
			}
			
			
			//Remember what file was selected upon opening this box.
			if (ze::in($box['key']['cType'], 'audio', 'document', 'picture', 'video')) {
				if ($values['file/file']) {
					$box['key']['local_file_id_on_load'] = $values['file/file'];
				}
			}
		}
		
		if (ze::setting('enable_aws_support') && ze::setting('allow_document_content_items_to_be_stored_on_aws_s3') && ze\module::inc('zenario_ctype_document')) {
			$fields['file/file']['label'] = ze\admin::phrase('Local file:');
			$fields['file/s3_file_upload']['hidden'] = false;
			$maxUploadSize = ze\file::fileSizeConvert(ze\dbAdm::apacheMaxFilesize());
			
			if (ze\dbAdm::apacheMaxFilesize() < ze\file::fileSizeBasedOnUnit(ze::setting('content_max_filesize'), ze::setting('content_max_filesize_unit'))) {
				$maxLocalUploadSize = $maxUploadSize;
			} else {
				$maxLocalUploadSize = ze\file::fileSizeConvert(ze\file::fileSizeBasedOnUnit(ze::setting('content_max_filesize'), ze::setting('content_max_filesize_unit')));
			}

			if (ze\dbAdm::apacheMaxFilesize() < 5368706371) {
				$maxS3UploadSize = $maxUploadSize;
			} else {
				$maxS3UploadSize = ze\file::fileSizeConvert(5368706371);
			}
			
			$box['tabs']['file']['fields']['document_desc']['snippet']['html'] =
				ze\admin::phrase('Please upload a local file (for storage in Zenario\'s docstore), maximum size [[maxLocalUploadSize]].', ['maxLocalUploadSize' => $maxLocalUploadSize]); 
			
			$box['tabs']['file']['fields']['s3_document_desc']['snippet']['html'] =
				ze\admin::phrase('You can upload a related file for storage on AWS S3, maximum size [[maxS3UploadSize]].', ['maxS3UploadSize' => $maxS3UploadSize]);
		} else {
			$fields['file/s3_file_upload']['hidden'] = true;
			$fields['file/s3_mime_type']['hidden'] = true;
		}

		if (!$contentType['enable_css_field']) {
			$box['tabs']['meta_data']['fields']['css_desc']['hidden'] =
			$box['tabs']['meta_data']['fields']['css_class']['hidden'] = true;
			
			if (isset($box['tabs']['meta_data']['fields']['css_class_field_original'])) {
				$box['tabs']['meta_data']['fields']['css_class_field_original']['hidden'] = true;
			}
		}
		
		if ($fields['meta_data/alias']['read_only']) {
			$editAliasLinkHref = ze\link::absolute() . 'organizer.php#zenario__content/panels/content/refiners/content_type//' . $box['key']['cType'] . '//' . $box['key']['id'] . '~.zenario_alias~tmeta_data~k{"id"%3A"' . $box['key']['id'] . '"}';
			$editAliasLinkStart = "<a href='" . $editAliasLinkHref . "' target='_blank'>";
			$editAliasLinkEnd = '</a>';
			$viewTranslationChainPhrase = ze\admin::phrase(
				'[[line_break]][[div_start]][[link_start]]Edit alias[[link_end]][[div_end]]',
				['line_break' => '<br />', 'link_start' => $editAliasLinkStart, 'link_end' => $editAliasLinkEnd, 'div_start' => '<div class="edit_alias_link">', 'div_end' => '</div>']
			);
			$fields['meta_data/alias']['post_field_html'] = $viewTranslationChainPhrase;
		}
	}
	

	public function formatAdminBox($path, $settingGroup, &$box, &$fields, &$values, $changes) {
		
		$existingMenuId = false;
		$menuSectionId = false;
		$parentMenuId = false;
		
		
		$box['tabs']['file']['hidden'] = true;
		if (ze::setting('enable_aws_support') && ze::setting('allow_document_content_items_to_be_stored_on_aws_s3') && ze\module::inc('zenario_ctype_document')) {
			$src = ze\link::protocol(). \ze\link::host(). SUBDIRECTORY.'zenario/s3FileUpload.php';
			$requests = '?cId='. $box['key']['cID'] .'&cType='. $box['key']['cType']. '&cVersion='. $box['key']['source_cVersion'] . '&mime_type=' . htmlspecialchars($values['file/s3_mime_type']);

			if ($values['file/s3_file_remove']) {
				$requests .= "&remove=1";
			}
				
			$s3_file_upload = "<iframe id=\"s3_file_upload\" name=\"s3_file_upload\" src=\"" . $src . $requests . "\" style=\"border: none;\"></iframe>\n";
			
			$fields['file/s3_file_upload']['snippet']['html'] = $s3_file_upload;
		}
		
				
		if (!$box['key']['cID']) {
			if ($values['meta_data/layout_id']) {
				$box['key']['cType'] = ze\row::get('layouts', 'content_type', $values['meta_data/layout_id']);
			}
		}

		if ($values['meta_data/layout_id']
		 && ($layout = ze\layout::details($values['meta_data/layout_id']))) {
	
			if ($layout['status'] != 'active') {
				$fields['meta_data/archived_template_notice']['hidden'] = false;
			} else {
				$fields['meta_data/archived_template_notice']['hidden'] = true;
			}
		}
		
		$fields['meta_data/description']['hidden'] = false;
		$fields['meta_data/writer']['hidden'] = false;
		$fields['meta_data/keywords']['hidden'] = false;
		$fields['meta_data/release_date']['hidden'] = false;
		$fields['meta_data/content_summary']['hidden'] = false;
		if ($box['key']['cType'] && $details = ze\contentAdm::cTypeDetails($box['key']['cType'])) {
			if ($details['description_field'] == 'hidden') {
				$fields['meta_data/description']['hidden'] = true;
				
				if (isset($fields['meta_data/description_original'])) {
					$fields['meta_data/description_original']['hidden'] = true;
				}
			}
			
			if ($details['keywords_field'] == 'hidden') {
				$fields['meta_data/keywords']['hidden'] = true;
				
				if (isset($fields['meta_data/keywords_original'])) {
					$fields['meta_data/keywords_original']['hidden'] = true;
				}
			}
			
			if ($details['release_date_field'] == 'hidden') {
				$fields['meta_data/release_date']['hidden'] = true;
				
				if (isset($fields['meta_data/release_date_original'])) {
					$fields['meta_data/release_date_original']['hidden'] = true;
				}
			} else {
				if ($details['auto_set_release_date'] && !$values['meta_data/release_date']) {
					$fields['meta_data/release_date']['note_below'] = ze\admin::phrase('Release date will be set automatically when the item is published.');
				} else {
					unset($fields['meta_data/release_date']['note_below']);
				}
			}
			
			if ($details['writer_field'] == 'hidden') {
				$fields['meta_data/writer_id']['hidden'] = true;
				
				if (isset($fields['meta_data/writer_id_original'])) {
					$fields['meta_data/writer_id_original']['hidden'] = true;
				}
			}
			
			if ($details['summary_field'] == 'hidden') {
				$fields['meta_data/content_summary']['hidden'] = true;
				
				if (isset($fields['meta_data/content_summary_original'])) {
					$fields['meta_data/content_summary_original']['hidden'] = true;
				}
			}
		}


		if ($box['key']['cID']) {
			$languageId = ze\content::langId($box['key']['cID'], $box['key']['cType']);
			$specialPage = ze\content::isSpecialPage($box['key']['cID'], $box['key']['cType']);
		} else {
			$languageId = ($values['meta_data/language_id'] ?: ($box['key']['target_template_id'] ?: ze::$defaultLang));
			$specialPage = false;
		}

		$keywordsCounterHTML = '
			<div class="snippet__keywords" >
				<div id="zaf_snippet__keywords_length" >
					<span id="zaf_snippet__keywords_counter">[[initial_characters_count]]</span>
				</div>
			</div>';

		$keywordsCounterHTML = str_replace('[[initial_characters_count]]', strlen($values['meta_data/keywords']) , $keywordsCounterHTML);
		$box['tabs']['meta_data']['fields']['keywords']['post_field_html'] = $keywordsCounterHTML;
		
		$WYSIWYGCount=0;
		$RawCount=0;
		$allowEditingContentInFab = ze\row::get('content_types', 'allow_editing_content_in_fab', $box['key']['cType'] ?: $box['key']['target_cType']);
		$duplicatingOrTranslating = ($box['key']['duplicate'] || $box['key']['duplicate_from_menu'] || $box['key']['translate']);
		//Set up content tabs (up to four of them), for each WYSIWYG Editor
		if (isset($box['tabs']['content1']) && $allowEditingContentInFab && !$duplicatingOrTranslating) {
			$i = 0;
			$slots = [];
			$rawslots = [];
			if ($box['key']['source_cID']
			 && $box['key']['cType']
			 && $box['key']['source_cVersion']) {
				// As per T11743 we need to show slot for more than one module ID 
				
				$rawmoduleIds = ze\module::id('zenario_html_snippet');
				$rawslots = ze\contentAdm::mainSlot($box['key']['source_cID'], $box['key']['cType'], $box['key']['source_cVersion'], $rawmoduleIds, false, $values['meta_data/layout_id']);

				$moduleIds = ze\module::id('zenario_wysiwyg_editor');
				
				
				$slots = ze\contentAdm::mainSlot($box['key']['source_cID'], $box['key']['cType'], $box['key']['source_cVersion'], $moduleIds, false, $values['meta_data/layout_id']);
			} else {
				$slots = ze\layoutAdm::mainSlot($values['meta_data/layout_id'], false, false);
			}
			
			if (!empty($slots)) {
				$rawslot = sizeof($rawslots);
			}

			if (!empty($slots)) {
				foreach ($slots as $slot) {
					if (++$i > 4) {
						break;
					}
		
					$box['tabs']['content'. $i]['hidden'] = false;
					if (count($slots) == 1 && $rawslot<1) {
						$box['tabs']['content'. $i]['label'] = ze\admin::phrase('Main content');
			
					} elseif (strlen($slot) <= 20) {
						$box['tabs']['content'. $i]['label'] = $slot;
			
					} else {
						$box['tabs']['content'. $i]['label'] = substr($slot, 0, 8). '...'. substr($slot, -8);
					}
					$WYSIWYGCount++;
					
					//Try and ensure that we use relative URLs where possible
					ze\contentAdm::stripAbsURLsFromAdminBoxField($box['tabs']['content'. $i]['fields']['content']);
					
					//The "in use" flagging feature.
					$box['tabs']['content'. $i]['in_use'] = !empty(trim(strip_tags($values['content'. $i. '/content'])));
				}
			}
			
	
			// Hide extra content tabs
			while (++$i <= 4) {
				$box['tabs']['content'. $i]['hidden'] = true;
			}
		}
		
		//Set up content tabs (up to four of them), for each Raw HTML Snippets
		if (isset($box['tabs']['rawhtml1']) && $allowEditingContentInFab && !$duplicatingOrTranslating) {
			$i = 0;
			$slots = [];
			$moduleIds = ze\module::id('zenario_html_snippet');
			if ($box['key']['source_cID']
			 && $box['key']['cType']
			 && $box['key']['source_cVersion']) {
				$slots = ze\contentAdm::mainSlot($box['key']['source_cID'], $box['key']['cType'], $box['key']['source_cVersion'], $moduleIds, false, $values['meta_data/layout_id']);
			} else {
				$slots = ze\layoutAdm::mainSlot($values['meta_data/layout_id'], $moduleIds, false);
			}

			if (!empty($slots)) {
				foreach ($slots as $slot) {
					if (++$i > 4) {
						break;
					}

					$box['tabs']['rawhtml'. $i]['hidden'] = false;
					if (count($slots) == 1 && $WYSIWYGCount==0) {
						$box['tabs']['rawhtml'. $i]['label'] = ze\admin::phrase('Main content');
			
					} elseif (strlen($slot) <= 20) {
						$box['tabs']['rawhtml'. $i]['label'] = $slot;
			
					} else {
						$box['tabs']['rawhtml'. $i]['label'] = substr($slot, 0, 8). '...'. substr($slot, -8);
					}
					$RawCount++;
					
					//Try and ensure that we use relative URLs where possible
					ze\contentAdm::stripAbsURLsFromAdminBoxField($box['tabs']['rawhtml'. $i]['fields']['content']);
					
					//The "in use" flagging feature.
					$box['tabs']['rawhtml'. $i]['in_use'] = !empty(trim(strip_tags($values['rawhtml'. $i. '/content'])));
				}
			}
			

			// Hide extra content tabs
			while (++$i <= 4) {
				$box['tabs']['rawhtml'. $i]['hidden'] = true;
			}
		}
		
		// Hide dropdown if the content setting is off, or if no content tabs are visible
		$bothCount = $WYSIWYGCount+$RawCount;
		if (!$allowEditingContentInFab || $bothCount <= 1) {
			$box['tabs']['content_dropdown']['hidden'] = true;
			if ($bothCount == 1 ) {
				unset($box['tabs']['rawhtml1']['parent']);
				unset($box['tabs']['content1']['parent']);
				unset($box['tabs']['rawhtml1']['in_use']);
				unset($box['tabs']['content1']['in_use']);
			}
			
		}
		
		if (isset($box['tabs']['meta_data']['fields']['content_summary'])) {
			//Try and ensure that we use relative URLs where possible
			ze\contentAdm::stripAbsURLsFromAdminBoxField($box['tabs']['meta_data']['fields']['content_summary']);
		}
		
		//Show the options for the site-map/search engine preview by default
		$fields['meta_data/excluded_from_sitemap']['hidden'] = true;
		$fields['meta_data/included_in_sitemap']['hidden'] = false;
		
		$duplicatingOrTranslating = ($box['key']['duplicate'] || $box['key']['duplicate_from_menu'] || $box['key']['translate']);
		
		if ($duplicatingOrTranslating) {
			$cIDToCheck = $box['key']['source_cID'];
		} else {
			$cIDToCheck = $box['key']['cID'];
		}
		
		if (
			($box['key']['cID'] || ($box['key']['translate'] && $box['key']['source_cID']))
		 	&& ze::in(ze\content::isSpecialPage($cIDToCheck, $box['key']['cType']), 'zenario_not_found', 'zenario_no_access')
		 ) {
			
			//Hide these options for the 403/404 pages
			$fields['meta_data/excluded_from_sitemap']['hidden'] = false;
			$fields['meta_data/included_in_sitemap']['hidden'] = true;
			
			$fields['meta_data/excluded_from_sitemap']['value'] = ze\admin::phrase('Automatically excluded (is the not-found or no-access special page)');
		} else {
			$fields['meta_data/excluded_from_sitemap']['value'] = ze\admin::phrase('Automatically excluded (permission is not public)');
		}
		
		$fields['meta_data/apply_noindex_meta_tag']['note_below'] = ze\admin::phrase(
			'<p>
				Put a <code>noindex</code> meta tag in the <head> section of the page when displaying this content item. This will be of the format:
				<br \>
				<code>&lt;meta name=&quot;robots&quot; content=&quot;noindex&quot;&gt;</code>
			</p>'
		);
		
		if (isset($box['key']['id'])) {
			$fields['meta_data/suggest_alias_from_title']['hidden'] = true;
			$cID = $cType = false;
			ze\content::getCIDAndCTypeFromTagId($cID, $cType, $box['key']['id']);
			$equivId = ze\content::equivId($cID, $cType);
			$contentItemPrivacy = ze\row::get('translation_chains', 'privacy', ['equiv_id' => $equivId, 'type' => $cType]);
			
			if ($contentItemPrivacy != 'public') {
				unset($fields['meta_data/title']['post_field_html']);
				unset($fields['meta_data/title']['note_below']);
				unset($fields['meta_data/description']['post_field_html']);
				unset($fields['meta_data/description']['note_below']);
			}

			//Extra info field when editing content items on a site
			//with multiple languages enabled
			$languagesEnabledOnSite = ze\lang::getLanguages(false, false, $defaultLangFirst = true);
			$numLanguageEnabled = count($languagesEnabledOnSite);
			$defaultLanguage = ze::$defaultLang;

			if ($numLanguageEnabled > 1) {
				$mainLanguageContentItemSql = "
					SELECT id, type, language_id, alias, visitor_version, admin_version, status, tag_id
					FROM ". DB_PREFIX. "content_items
					WHERE equiv_id = " . (int) $equivId . "
					AND type = '" . ze\escape::asciiInSQL($box['key']['cType']) . "'
					AND id = " . (int) $equivId;
				$mainLanguageContentItemResult = ze\sql::select($mainLanguageContentItemSql);
				$mainLanguageContentItem = ze\sql::fetchAssoc($mainLanguageContentItemResult);

				$translationsCountSql = "
					SELECT COUNT(id)
					FROM ". DB_PREFIX. "content_items
					WHERE equiv_id = " . (int) $equivId . "
					AND type = '" . ze\escape::asciiInSQL($box['key']['cType']) . "'
					AND id <> " . (int) $box['key']['cID'];
				$translationsCountResult = ze\sql::select($translationsCountSql);
				$translationsCount = ze\sql::fetchValue($translationsCountResult);

				$translationChainHref =
					ze\link::absolute(). 'organizer.php#zenario__content/panels/content/refiners/content_type//' 
					. htmlspecialchars($box['key']['cType']) . '//item_buttons/zenario_trans__view//' . htmlspecialchars($mainLanguageContentItem['tag_id']) . '//';
				$translationChainLinkStart = '<a href="' . $translationChainHref . '" target="_blank">';
				$translationChainLinkEnd = '</a>';
				$viewTranslationChainPhrase = ze\admin::phrase('[[link_start]]View translation chain[[link_end]]', ['link_start' => $translationChainLinkStart, 'link_end' => $translationChainLinkEnd]);
				
				$fields['meta_data/content_item_translation_info']['hidden'] = false;
				$fields['meta_data/content_item_translation_info']['snippet']['html'] = '<div class="zenario_fbInfo">';

				if ($box['key']['cID'] == $equivId) {
					//This is the main or the only content item in the chain.
					if ($values['meta_data/language_id_on_load'] == $defaultLanguage) {
						//If this is the content item in the site's main language,
						//show the translation counter.
						
						$fields['meta_data/content_item_translation_info']['snippet']['html'] .=
							ze\admin::nPhrase(
								"This content item has 1 translation.",
								"This content item has [[translation_count]] translations.",
								(int) $translationsCount,
								['translation_count' => (int) $translationsCount]
							);
						$fields['meta_data/content_item_translation_info']['snippet']['html'] .= ' ' . $viewTranslationChainPhrase;
					} else {
						if ($translationsCount > 0) {
							$defaultLanguageName = $languagesEnabledOnSite[$defaultLanguage]['english_name'];
							$fields['meta_data/content_item_translation_info']['snippet']['html'] .=
								ze\admin::phrase(
									'This item is in a translation chain with no item in the default language ([[default_language_name]]).',
									['default_language_name' => $defaultLanguageName]
								);
							$fields['meta_data/content_item_translation_info']['snippet']['html'] .= ' ' . $viewTranslationChainPhrase;
						} else {
							$fields['meta_data/content_item_translation_info']['snippet']['html'] .= ze\admin::phrase('This item is not in a translation chain.');
							$fields['meta_data/content_item_translation_info']['snippet']['html'] .= ' ' . $viewTranslationChainPhrase;
						}
					}
				} else {
					//This is a translation.
					if ($mainLanguageContentItem['language_id'] == $defaultLanguage) {
						//The main item in this chain is in the site's default language.
						$mainLanguageContentItemTag = ze\content::formatTag($mainLanguageContentItem['id'], $mainLanguageContentItem['type'], ($mainLanguageContentItem['alias'] ?? false));
						
						$fields['meta_data/content_item_translation_info']['snippet']['html'] .=
							ze\admin::phrase('This item is in the translation chain of "[[tag]]".', ['tag' => $mainLanguageContentItemTag]);
						$fields['meta_data/content_item_translation_info']['snippet']['html'] .= ' ' . $viewTranslationChainPhrase;
					} else {
						if ($translationsCount > 0) {
							$defaultLanguageName = $languagesEnabledOnSite[$defaultLanguage]['english_name'];
							$fields['meta_data/content_item_translation_info']['snippet']['html'] .=
								ze\admin::phrase(
									'This item is in a translation chain with no item in the default language ([[default_language_name]]).',
									['default_language_name' => $defaultLanguageName]
								);
							$fields['meta_data/content_item_translation_info']['snippet']['html'] .= ' ' . $viewTranslationChainPhrase;
						} else {
							$fields['meta_data/content_item_translation_info']['snippet']['html'] .= ze\admin::phrase('This item is not in a translation chain.');
							$fields['meta_data/content_item_translation_info']['snippet']['html'] .= ' ' . $viewTranslationChainPhrase;
						}
					}
				}

				$fields['meta_data/content_item_translation_info']['snippet']['html'] .= '</div>';
			}
			
			$sourceContentItemMenu = ze\menu::getFromContentItem($box['key']['source_cID'], $box['key']['cType']);
			
			if ($sourceContentItemMenu) {
				$existingMenuId = $sourceContentItemMenu['id'];
				$menuSectionId = $sourceContentItemMenu['section_id'];
				$parentMenuId = $sourceContentItemMenu['parent_id'];
				
				$fields['meta_data/redraft_menu_warning']['row_class'] = 'zfab_inline_warning_hidden';
				if ($values['meta_data/menu_text_when_editing'] != $values['meta_data/menu_text_when_editing_on_load']) {
					$fields['meta_data/redraft_menu_warning']['row_class'] = '';
				
					$status = ze\content::status($cID, $cType);
				
					if (ze::in($status, 'draft', 'hidden_with_draft', 'published', 'published_with_draft')) {
						if (ze::in($status, 'draft', 'hidden_with_draft', 'published_with_draft')) {
							$text = 'Warning: The change to the menu node text will go live immediately, but you will need to publish the content item so that its changes go live.';
						} elseif ($status == 'published') {
							$text = 'Warning: The change to the menu node text will go live immediately. For the content item, a new version will be created and you should publish this so that any other changes go live.';
						}
					
						$fields['meta_data/redraft_menu_warning']['snippet']['html'] = '
							<div id="zaf_redraft_menu_warning" class="zenario_fbWarning">
								' . ze\admin::phrase($text) . '
							</div>';
					} else {
						$fields['meta_data/redraft_menu_warning']['hidden'] = true;
					}
				}
			} else {
				$fields['meta_data/menu_text_when_editing']['hidden'] = true;
			}
		}
		if (!$values['meta_data/alias_changed']) {
			$fields['meta_data/suggest_alias_from_title']['style'] = 'display:none';
		} else {
			$fields['meta_data/suggest_alias_from_title']['style'] = '';
		}

		unset($fields['meta_data/pinned_fixed_duration_value']['note_below']);
		$allowPinning = ze\row::get('content_types', 'allow_pinned_content', ['content_type_id' => $box['key']['cType']]);
		if ($allowPinning && !$values['meta_data/pinned_duration']) {
			$values['meta_data/pinned_duration'] = 'until_unpinned';
		}
		if ($allowPinning && $values['meta_data/pinned']) {
			if ($values['meta_data/pinned_duration'] == 'fixed_duration') {
				if (preg_match('/^[0-9]{1,2}$/', $values['meta_data/pinned_fixed_duration_value'])) {
					//Work out the unpin date
					$newEndDate = new DateTime();
					$newEndDate->setTime(00, 00);
					//Work out if this is supposed to be singular day/week or plural days/weeks.
					if ($values['meta_data/pinned_fixed_duration_value'] > 1) {
						$unit = $values['meta_data/pinned_fixed_duration_unit'] . 's';
					} else {
						$unit = $values['meta_data/pinned_fixed_duration_unit'];
					}
	
					//Example: "+1 day". "+2 weeks" etc.
					$newEndDate->modify('+' . $values['meta_data/pinned_fixed_duration_value'] . ' ' . $unit);
					$unpinDate = ze\admin::formatDate($newEndDate);
	
					$taskId = (int) ze\row::get('jobs', 'id', ['job_name' => 'jobUnpinContent']);
					$scheduledTaskHref = ze\link::absolute() . 'organizer.php#zenario__administration/panels/zenario_scheduled_task_manager__scheduled_tasks//' . $taskId . '~.zenario_job~ttime_and_day~k{"id"%3A"' . $taskId . '"}';
					$linkStart = '<a href="' . htmlspecialchars($scheduledTaskHref) . '" target="_blank">';
					$linkEnd = "</a>";
					
					$fields['meta_data/pinned_fixed_duration_value']['note_below'] = ze\admin::phrase(
						'Will be unpinned on the first run of scheduled task jobUnpinContent on or after [[date_and_time]]. [[link_start]]Click for more info.[[link_end]]',
						['date_and_time' => $unpinDate, 'link_start' => $linkStart, 'link_end' => $linkEnd]
					);
				}
			}
		}
		
		if (isset($box['tabs']['meta_data']['fields']['auto_populate_title_from_filename'])) {
			if ($values['meta_data/auto_populate_title_from_filename']) {
				$fields['meta_data/title']['disabled'] = true;
				$fields['meta_data/title']['placeholder'] = ze\admin::phrase('Will auto-populate from file name');
			} else {
				$fields['meta_data/title']['disabled'] = false;
				unset($fields['meta_data/title']['placeholder']);
			}
		}
		
		$whenCreatingPutTitleInBody = ze\row::get('content_types', 'when_creating_put_title_in_body', $box['key']['cType'] ?: $box['key']['target_cType']);
		if ($whenCreatingPutTitleInBody) {
			$this->autoSetTitle($box, $fields, $values);
		}

		//Only show the SEO messages (title, description) for public content items, but not for the "Not found" and "No access" special pages.
		//If the Zenario Users module is not running, ignore the privacy check.
		//Also always display the message for alias field.
		$this->setAliasMessageAndEvent($box, $fields, $values);
		
		if (empty($values['privacy/privacy']) || ($values['privacy/privacy'] == 'public' && !ze::in($box['key']['special_page_type'], 'zenario_not_found', 'zenario_no_access'))) {
			$this->setSeoMessagesAndEvents($box, $fields, $values);
		} else {
			unset($box['tabs']['meta_data']['fields']['title']['note_below']);
			unset($box['tabs']['meta_data']['fields']['description']['note_below']);
			$box['tabs']['meta_data']['fields']['title']['progress_bar'] = false;
			$box['tabs']['meta_data']['fields']['description']['progress_bar'] = false;
		}
		
		
		
		//Set the menu path preview
		$menuPos = false;
		$fields['meta_data/menu_path_preview']['hidden'] = true;
		
		//Case when editing an existing content item
		if ($box['key']['cID']) {
			if ($existingMenuId) {
				//Set the menu position to the exsting node.
				//I'm using the "$isExistingNode" option here which is only supported by the ze\menuAdm::posToPathArray() function.
				//This option is not supported by position pickers nor the ze\menuAdm::addContentItems() function.
				$menuPos = $menuSectionId. '_'. $existingMenuId. '_3';
			}
		
		//Case when translating
		} elseif ($box['key']['translate']) {
			
			if ($box['key']['from_cID'] && ($menu = ze\menu::getFromContentItem($box['key']['from_cID'], $box['key']['from_cType']))) {
				$menuPos = $menu['section_id']. '_'. $menu['id']. '_3';
			}
		
		} else {
			
			//Work around a quirk where no options in the select lists will not be selected yet on the first load.
			//Just mark the first one in the array as selected.
			foreach (['menu_pos', 'menu_pos_suggested'] as $fieldCodeName) {
				if (!$values['meta_data/'. $fieldCodeName]) {
					if (!empty($fields['meta_data/'. $fieldCodeName]['values'])) {
						foreach ($fields['meta_data/'. $fieldCodeName]['values'] as $val => $lov) {
							if (empty($lov['hidden'])) {
								$values['meta_data/'. $fieldCodeName] = $val;
								break;
							}
						}
					}
				}
			}
			
			$menuPos = $this->getSelectedMenuPosition($values);
		}
		
		if ($menuPos) {
			ze\menuAdm::setupPathPreview($menuPos, $fields['meta_data/menu_path_preview'], $values['meta_data/language_id']);
			$fields['meta_data/menu_path_preview']['hidden'] = false;
			
			if ($box['key']['cID']) {
				$fields['meta_data/menu_path_preview']['value'] =
				$fields['meta_data/menu_path_preview']['current_value'] = $values['meta_data/menu_text_when_editing'];
			} else {
				$fields['meta_data/menu_path_preview']['value'] =
				$fields['meta_data/menu_path_preview']['current_value'] = $values['meta_data/menu_text'];
				
				if (!$values['meta_data/create_menu_node']) {
					$fields['meta_data/menu_path_preview']['hidden'] = true;
				}
			}
		}
	}
	
	public function autoSetTitle(&$box, &$fields, &$values) {
		
		//If we've creating a new content item...
		if (!$box['key']['cID'] && !$box['key']['source_cID']) {
			
			//...and the admin just changed the title...
			if ($box['key']['last_title'] != $values['meta_data/title']) {
				
				//Check if there's a main content area
				if (isset($box['tabs']['content1']['hidden'])
				 && empty($box['tabs']['content1']['hidden'])) {
					
					//Check if the main content area is empty, or was set by this algorithm before.
					if (empty($values['content1/content'])
					 || !($existingText = trim(str_replace('&nbsp;', ' ', strip_tags($values['content1/content']))))
					 || ($existingText == $box['key']['last_title'])
					 || ($existingText == htmlspecialchars($box['key']['last_title']))) {
						
						$whenCreatingPutTitleInBody = ze\row::get('content_types', 'when_creating_put_title_in_body', $box['key']['cType'] ?: $box['key']['target_cType']);
						if ($whenCreatingPutTitleInBody) {
							$values['content1/content'] = '<h1>'. htmlspecialchars($values['meta_data/title']). '</h1>';
						}
					}
				}
				
				$box['key']['last_title'] = $values['meta_data/title'];
			}
		}
		
	}
	
	public function validateAdminBox($path, $settingGroup, &$box, &$fields, &$values, $changes, $saving) {
		$whenCreatingPutTitleInBody = ze\row::get('content_types', 'when_creating_put_title_in_body', $box['key']['cType'] ?: $box['key']['target_cType']);
		if ($whenCreatingPutTitleInBody) {
			$this->autoSetTitle($box, $fields, $values);
		}
		
		$box['confirm']['show'] = false;
		$box['confirm']['message'] = '';
		
		if (!$box['key']['cID']) {
			if (!$values['meta_data/layout_id']) {
				$box['tab'] = 'meta_data';
				$fields['meta_data/layout_id']['error'] = ze\admin::phrase('Please select a layout.');
			} else {
				$box['key']['cType'] = ze\row::get('layouts', 'content_type', $values['meta_data/layout_id']);
			}

		} else {
			ze\layoutAdm::validateChangeSingleLayout($box, $box['key']['cID'], $box['key']['cType'], $box['key']['cVersion'], $values['meta_data/layout_id'], $saving);
		}

		if (!ze\contentAdm::isCTypeRunning($box['key']['cType'])) {
			$box['tabs']['meta_data']['errors'][] =
				ze\admin::phrase(
					'Drafts of "[[cType]]" type content items cannot be created as their handler module is missing or not running.',
					['cType' => $box['key']['cType']]);
		}

		$titleIsMissing = false;
		if (!$values['meta_data/title']) {
			if (isset($box['tabs']['meta_data']['fields']['auto_populate_title_from_filename']) && $values['meta_data/auto_populate_title_from_filename']) {
				//If autopopulating the title from filename, do not display errors when the filename is blank while switching tabs.
				//Complain when the admin tries to save.
				if ($saving && !$values['file/file']) {
					$titleIsMissing = true;
				}
			} else {
				$titleIsMissing = true;
			}
		}

		if ($titleIsMissing) {
			if (isset($box['tabs']['meta_data']['fields']['auto_populate_title_from_filename']) && $values['meta_data/auto_populate_title_from_filename']) {
				$fields['meta_data/title']['error'] = ze\admin::phrase("You've specified that the title should be auto-populated from the file name, but no local file has been attached. Please either attach a file or uncheck \"Auto-populate\" and enter a title manually.");
			} else {
				$fields['meta_data/title']['error'] = ze\admin::phrase("Please enter a title.");
			}
		}

		if (!empty($values['meta_data/alias']) && !$fields['meta_data/alias']['read_only']) {
			$errors = false;
			if ($box['key']['translate']) {
				if (ze::setting('translations_different_aliases')) {
					$errors = ze\contentAdm::validateAlias($values['meta_data/alias'], false, $box['key']['cType'], ze\content::equivId($box['key']['source_cID'], $box['key']['cType']));
				}
			} else {
				$errors = ze\contentAdm::validateAlias($values['meta_data/alias']);
			}
			
			if (!empty($errors) && is_array($errors)) {
				$fields['meta_data/alias']['error'] = implode('<br />', $errors);
			}
		}


		if ($box['key']['cType'] && $details = ze\contentAdm::cTypeDetails($box['key']['cType'])) {
			if ($details['description_field'] == 'mandatory' && !$values['meta_data/description']) {
				$fields['meta_data/description']['error'] = ze\admin::phrase('Please enter a description.');
			}
			
			if ($details['keywords_field'] == 'mandatory' && !$values['meta_data/keywords']) {
				$fields['meta_data/keywords']['error'] = ze\admin::phrase('Please enter keywords.');
			}
			
			if ($details['writer_field'] == 'mandatory' && !$values['meta_data/writer_id']) {
				$fields['meta_data/writer_id']['error'] = ze\admin::phrase('Please select a writer.');
			}
			
			if ($details['summary_field'] == 'mandatory' && !$values['meta_data/content_summary']) {
				$fields['meta_data/content_summary']['error'] = ze\admin::phrase('Please enter a summary.');
			}
		}

		if ($box['key']['translate'] || ($box['key']['cID'] && $values['meta_data/language_id'] != $values['meta_data/language_id_on_load'])) {
			$equivId = ze\content::equivId($box['key']['source_cID'], $box['key']['cType']);
	
			if (ze\row::exists('content_items', ['equiv_id' => $equivId, 'type' => $box['key']['cType'], 'language_id' => $values['meta_data/language_id']])) {
				$box['tabs']['meta_data']['errors'][] = ze\admin::phrase('This translation already exists.');
			}
		}
		
		$errorsOnTab = false;
		foreach ($box['tabs']['plugins']['fields'] as $field) {
			if (isset($field['error'])) {
				$errorsOnTab = true;
				break;
			}
		}
		
		if ($errorsOnTab) {
			$fields['plugins/table_end']['error'] = ze\admin::phrase('Please select an action for each plugin.');
		}

		//Pinned duration
		if ($values['meta_data/pinned'] && ze::in($values['meta_data/pinned_duration'], 'fixed_date', 'fixed_duration')) {
			if ($values['meta_data/pinned_duration'] == 'fixed_date') {
				if (!$values['meta_data/unpin_date']) {
					$fields['meta_data/unpin_date']['error'] = ze\admin::phrase('Please select the unpin date.');
				} else {
					$dateFrom = new DateTime();
					$timestampFrom = $dateFrom->getTimestamp();

					$dateTo = new DateTime($values['meta_data/unpin_date']);
					$timestampTo = $dateTo->getTimestamp();

					if ($timestampFrom > $timestampTo) {
						$fields['meta_data/unpin_date']['error'] = ze\admin::phrase('The unpin date cannot be in the past or on the same day.');
					}
				}
			} elseif ($values['meta_data/pinned_duration'] == 'fixed_duration') {
				if (!preg_match('/^[0-9]{1,2}$/', $values['meta_data/pinned_fixed_duration_value']) || $values['meta_data/pinned_fixed_duration_value'] < 1 || $values['meta_data/pinned_fixed_duration_value'] > 99) {
					$fields['meta_data/pinned_fixed_duration_value']['error'] = ze\admin::phrase('The value needs to be a whole number between 1 and 99.');
				}
			}
		}
		
		if (
			(!$box['key']['cID'] || $box['key']['cID'] != $box['key']['source_cID'])
			&& $values['meta_data/layout_id']
		 	&& ($layout = ze\layout::details($values['meta_data/layout_id']))
		 	&& $layout['status'] != 'active'
		) {
			if ($box['key']['translate']) {
				$fields['meta_data/layout_id']['error'] = ze\admin::phrase(
					'The chosen layout is retired. Please select a different layout. If you want both the original content and its translation to look exactly the same, you should first change the layout of the original content item to an available (non-retired) layout.'
				);
			} else {
				$fields['meta_data/layout_id']['error'] = ze\admin::phrase('The chosen layout is retired. Please select a different layout.');
			}
		}
	}
	
	protected $isNewContentItem = false;
	
	public function saveAdminBox($path, $settingGroup, &$box, &$fields, &$values, $changes) {
		if ($box['key']['cID'] && !ze\priv::check('_PRIV_EDIT_DRAFT', $box['key']['cID'], $box['key']['cType'])) {
			exit;
		}
		
		$this->isNewContentItem = !$box['key']['cID'];
		
		//Create a new content item, or a new draft of a content item, as needed.
		$newDraftCreated = ze\contentAdm::createDraft($box['key']['cID'], $box['key']['source_cID'], $box['key']['cType'], $box['key']['cVersion'], $box['key']['source_cVersion'], $values['meta_data/language_id']);

		if (!$box['key']['cID']) {
			exit;
		} else {
			$box['key']['id'] = $box['key']['cType'].  '_'. $box['key']['cID'];
		}

		$version = [];
		$newLayoutId = false;


		//Save the values of each field in the Meta Data tab
		if (ze\ring::engToBoolean($box['tabs']['meta_data']['edit_mode']['on'])
		 && ze\priv::check('_PRIV_EDIT_DRAFT', $box['key']['cID'], $box['key']['cType'])) {
			//Only save aliases for first drafts
			if (!empty($values['meta_data/alias']) && $box['key']['cVersion'] == 1) {
				if (!$box['key']['translate'] || ze::setting('translations_different_aliases')) {
					ze\row::set('content_items', ['alias' => ze\contentAdm::tidyAlias($values['meta_data/alias'])], ['id' => $box['key']['cID'], 'type' => $box['key']['cType']]);
				}
			}

			//Set the title.
			//If this is an audio/video/picture/document content item,
			//and the "Auto-populate from file name" checkbox is ticked, this will be blank for now.
			$version['title'] = $values['meta_data/title'];

			$version['description'] = $values['meta_data/description'];
			$version['keywords'] = $values['meta_data/keywords'];
			$version['release_date'] = $values['meta_data/release_date'];
			$version['writer_id'] = $values['meta_data/writer_id'];
			$version['in_sitemap'] = !$values['meta_data/exclude_from_sitemap'];
			$version['apply_noindex_meta_tag'] = ($values['meta_data/exclude_from_sitemap'] && $values['meta_data/apply_noindex_meta_tag']);

			//Pinned status
			$version['pinned'] = $values['meta_data/pinned'];

			//Default values in case a content item is not pinned
			$version['pinned_duration'] =
			$version['unpin_date'] =
			$version['pinned_fixed_duration_unit'] = null;
			$version['pinned_fixed_duration_value'] = 0;

			if ($values['meta_data/pinned']) {
				$version['pinned_duration'] = $values['meta_data/pinned_duration'];

				switch ($values['meta_data/pinned_duration']) {
					case 'fixed_date':
						$version['unpin_date'] = $values['meta_data/unpin_date'];
						break;
					case 'fixed_duration':
						$version['pinned_fixed_duration_value'] = (int) $values['meta_data/pinned_fixed_duration_value'];
						$version['pinned_fixed_duration_unit'] = $values['meta_data/pinned_fixed_duration_unit'];
						
						//Work out the unpin date
						$newEndDate = new DateTime();
						//Work out if this is supposed to be singular day/week or plural days/weeks.
						if ($values['meta_data/pinned_fixed_duration_value'] > 1) {
							$unit = $values['meta_data/pinned_fixed_duration_unit'] . 's';
						} else {
							$unit = $values['meta_data/pinned_fixed_duration_unit'];
						}

						//Example: "+1 day". "+2 weeks" etc.
						$newEndDate->modify('+' . $values['meta_data/pinned_fixed_duration_value'] . ' ' . $unit);
						$version['unpin_date'] = $newEndDate->format('Y-m-d H:i:s');
						break;
					case 'until_unpinned':
						//Do nothing, the values are already set
						break;
				}
			}
			
			
			$values['meta_data/content_summary'] = ze\ring::sanitiseWYSIWYGEditorHTML($values['meta_data/content_summary']);
			
			//Try and ensure that we use absolute URLs where possible
			ze\contentAdm::stripAbsURLsFromAdminBoxField($fields['meta_data/content_summary']);
			
			
			$version['content_summary'] = $values['meta_data/content_summary'];
		}

		//Set the layout
		if (ze\ring::engToBoolean($box['tabs']['meta_data']['edit_mode']['on'] ?? false)
		 && ze\priv::check('_PRIV_EDIT_DRAFT', $box['key']['cID'], $box['key']['cType'])) {
			$newLayoutId = $values['meta_data/layout_id'];
			$version['css_class'] = $values['meta_data/css_class'];
		}
		
		
		//If the admin selected the duplicate option for any plugins, duplicate those plugins and put the copies in the slots
		//where the old ones were.
		if ($box['key']['duplicate'] || $box['key']['duplicate_from_menu'] || $box['key']['translate']) {
			$startAt = 1;
			foreach (ze\tuix::loopThroughMultipleRows($fields, $startAt, 'plugins', 'instance_id') as $suffix => $deletePressed) {
				
				if ($values['plugins/action'. $suffix] == 'duplicate') {
					$newName = $values['plugins/new_name'. $suffix];
					$slotName = $values['plugins/slotname'. $suffix];
					$instanceId = $values['plugins/instance_id'. $suffix];
					$eggId = false;
					ze\pluginAdm::rename($instanceId, $eggId, $newName, $createNewInstance = true);
					ze\pluginAdm::updateItemSlot($instanceId, $slotName, $box['key']['cID'], $box['key']['cType'], $box['key']['cVersion']);
				} elseif ($values['plugins/action'. $suffix] == 'empty') {
					
					$slotName = $values['plugins/slotname'. $suffix];
					$instanceId = '';
					$eggId = false;
					ze\pluginAdm::updateItemSlot($instanceId, $slotName, $box['key']['cID'], $box['key']['cType'], $box['key']['cVersion']);
				}
			}
		}

		//Save the chosen file, if a file was chosen
		if (ze\ring::engToBoolean($box['tabs']['file']['edit_mode']['on'] ?? false)) {
			if ($values['file/file']
			 && ($path = ze\file::getPathOfUploadInCacheDir($values['file/file']))
			 && ($filename = preg_replace('/([^.a-z0-9_\(\)\[\]]+)/i', '-', basename($path)))
			 && ($fileId = ze\fileAdm::addToDocstoreDir('content', $path, $filename))) {
				$version['file_id'] = $fileId;
				$version['filename'] = $filename;
			} else {
				$version['file_id'] = $values['file/file'];
			}

			if ($version['file_id']) {
				if ($box['key']['cType'] && ze::in($box['key']['cType'], 'audio', 'document', 'picture', 'video')) {
					//Editing a draft
					if (!$newDraftCreated && $box['key']['cVersion'] == $box['key']['source_cVersion']) {
						//Look up the file ID for the published version.
						//Then look up the file ID for the current draft.
						//Delete the file if no other content item uses it, but beware not to affect the published version.
						$currentPublishedVersion = ze\row::get('content_items', 'visitor_version', ['id' => $box['key']['cID'], 'type' => $box['key']['cType']]);
						$currentPublishedFileId = ze\row::get('content_item_versions', 'file_id', ['id' => $box['key']['cID'], 'type' => $box['key']['cType'], 'version' => $currentPublishedVersion]);

						$currentDraftFileId = ze\row::get('content_item_versions', 'file_id', ['id' => $box['key']['cID'], 'type' => $box['key']['cType'], 'version' => $box['key']['cVersion']]);

						if ($currentDraftFileId != $currentPublishedFileId && $currentDraftFileId != $version['file_id']) {
								ze\fileAdm::deleteMediaContentItemFileIfUnused($box['key']['cID'], $box['key']['cType'], $currentDraftFileId);
						}
					}

					//If the "Auto-populate from file name" checkbox is ticked, use the file name as title.
					if (isset($box['tabs']['meta_data']['fields']['auto_populate_title_from_filename']) && $values['meta_data/auto_populate_title_from_filename']) {
						$filename = ze\row::get('files', 'filename', ['id' => $version['file_id']]);
						$version['title'] = $filename;
					}
				}
			}
			
			//If an S3 file was picked, save its details. Otherwise blank out the name and file ID.
			if ($values['file/s3_file_id']) {
				$version['s3_filename'] = $values['file/s3_file_name'];
				$version['s3_file_id'] = (int) $values['file/s3_file_id'];
			} else {
				$version['s3_file_id'] = 0;
				$version['s3_filename'] = '';
			}
			
		}
		
		$changes = !empty($version);

		//Update the layout
		if ($newLayoutId) {
			ze\layoutAdm::changeContentItemLayout($box['key']['cID'], $box['key']['cType'], $box['key']['cVersion'], $newLayoutId);
			$changes = true;
		}
		
		//Save the content tabs (up to four of them), for each WYSIWYG Editor
		if (isset($box['tabs']['content1'])
		 && ze\priv::check('_PRIV_EDIT_DRAFT', $box['key']['cID'], $box['key']['cType'])) {
			$i = 0;
			$moduleIds = ze\module::id('zenario_wysiwyg_editor');
			$slots = ze\contentAdm::mainSlot($box['key']['cID'], $box['key']['cType'], $box['key']['cVersion'], $moduleIds, false, $values['meta_data/layout_id']);

			if (!empty($slots)) {
				foreach ($slots as $slot) {
					if (++$i > 4) {
						break;
					}
			
					if (!empty($box['tabs']['content'. $i]['edit_mode']['on'])) {
						$values['content'. $i. '/content'] = ze\ring::sanitiseWYSIWYGEditorHTML($values['content'. $i. '/content'], false, $allowAdvancedInlineStyles = true);
						
						//Try and ensure that we use relative URLs where possible
						ze\contentAdm::stripAbsURLsFromAdminBoxField($fields['content'. $i. '/content']);
						
						ze\contentAdm::saveContent($values['content'. $i. '/content'], $box['key']['cID'], $box['key']['cType'], $box['key']['cVersion'], $slot);
						$changes = true;
					}
				}
			}
		}
		
		//Save the content tabs (up to four of them), for each RAW HTML
		if (isset($box['tabs']['rawhtml1'])
		 && ze\priv::check('_PRIV_EDIT_DRAFT', $box['key']['cID'], $box['key']['cType'])) {
			$i = 0;
			$moduleIds = ze\module::id('zenario_html_snippet');
			$slots = ze\contentAdm::mainSlot($box['key']['cID'], $box['key']['cType'], $box['key']['cVersion'], $moduleIds, false, $values['meta_data/layout_id']);

			if (!empty($slots)) {
				foreach ($slots as $slot) {
					if (++$i > 4) {
						break;
					}
			
					if (!empty($box['tabs']['rawhtml'. $i]['edit_mode']['on'])) {
						//Try and ensure that we use relative URLs where possible
						ze\contentAdm::stripAbsURLsFromAdminBoxField($fields['rawhtml'. $i. '/content']);
						
						ze\contentAdm::saveContent($values['rawhtml'. $i. '/content'], $box['key']['cID'], $box['key']['cType'], $box['key']['cVersion'], $slot,'zenario_html_snippet');
						$changes = true;
					}
				}
			}
		}
		
		//Update the content_item_versions table
		if ($changes) {
			ze\contentAdm::updateVersion($box['key']['cID'], $box['key']['cType'], $box['key']['cVersion'], $version);
		}


		//Update content item categories
		if (empty($box['tabs']['categories']['hidden'])
		 && ze\ring::engToBoolean($box['tabs']['categories']['edit_mode']['on'] ?? false)
		 && isset($values['categories/categories'])
		 && ze\priv::check('_PRIV_EDIT_DRAFT')) {
			ze\categoryAdm::setContentItemCategories($box['key']['cID'], $box['key']['cType'], ze\ray::explodeAndTrim($values['categories/categories']));
		}

		//Record and equivalence if this content item was duplicated into another Language
		$equivId = false;
		if ($box['key']['translate']) {
			$equivId = ze\contentAdm::recordEquivalence($box['key']['source_cID'], $box['key']['cID'], $box['key']['cType']);
		}
		
		//If changing the language of an existing content item, save it now.
		if ($values['meta_data/language_id_on_load'] != $values['meta_data/language_id']) {
			ze\row::set('content_items', ['language_id' => $values['meta_data/language_id']], ['id' => $box['key']['cID'], 'type' => $box['key']['cType']]);
			
			//If this content item's language gets changed to the site's default language,
			//the equiv ID of the entire chain will be changed to this content item's one.
			//Otherwise, nothing will happen.
			ze\contentAdm::resyncEquivalence($box['key']['cID'], $box['key']['cType']);
		}

		if ($version['file_id']) {
			if ($box['key']['cType'] && $box['key']['cType'] == 'document') {
				
				$fileChanged =
					empty($fields['file/file']['current_value'])
				 || $fields['file/file']['current_value'] != $version['file_id'];
				
				ze\fileAdm::updateDocumentContentItemExtract($box['key']['cID'], $box['key']['cType'], $box['key']['cVersion'], $version['file_id'], false, $fileChanged);
			}
			
			if ($box['key']['cType'] && ($box['key']['cType'] == 'document' || $box['key']['cType'] == 'picture')) {
				$file = ze\row::get('files', ['usage', 'filename', 'location', 'path', 'image_credit'], ['id' => $version['file_id']]);
				
				if (!empty($file) && $file['location'] == 'docstore' && ze\file::isImage(ze\file::mimeType($file['filename']))) {
					$location = ze\file::docstorePath($file['path']);
					$thumbnailId = ze\fileAdm::addToDatabase(
						'image', $location, $file['filename'], $mustBeAnImage = true, $deleteWhenDone = false, $addToDocstoreDirIfPossible = false,
						false, false, false, false, $file['image_credit']
					);
					
					ze\row::set('inline_images', [], [
						'image_id' => $thumbnailId,
						'foreign_key_to' => 'content',
						'foreign_key_id' => $box['key']['cID'],
						'foreign_key_char' => $box['key']['cType'],
						'foreign_key_version' => $box['key']['cVersion']
					]);
					ze\contentAdm::updateVersion($box['key']['cID'], $box['key']['cType'], $box['key']['cVersion'], ['feature_image_id' => $thumbnailId]);
					ze\contentAdm::updateContentItemCache($box['key']['cID'], $box['key']['cType'], $box['key']['cVersion']);
				}
			}
		}
		
		//Save the menu.
		//Please note: If duplicating a content item which is attached to a menu node,
		//the code below will make sure the new menu node has the same privacy setting.
		$this->saveMenu($box, $fields, $values, $changes, $equivId);
	}
	
	public function adminBoxSaveCompleted($path, $settingGroup, &$box, &$fields, &$values, $changes) {
		if ($box['key']['id_is_menu_node_id'] || $box['key']['id_is_parent_menu_node_id'] || $box['key']['duplicate_from_menu']) {
			$sectionId = isset($box['key']['target_menu_section']) ? $box['key']['target_menu_section'] : false;
			if ($menu = ze\menu::getFromContentItem($box['key']['cID'], $box['key']['cType'], $fetchSecondaries = false, $sectionId)) {
				$box['key']['id'] = $menu['id'];
			}
		}
		
		//If we're creating a new content item in the front-end, try to start off in Edit mode
		$showCreatedToast =
		$showDuplicatedToast = false;
		if (($this->isNewContentItem && !$box['key']['create_from_content_panel']) || $box['key']['duplicate']) {
			$_SESSION['page_toolbar'] = 'edit';
			$_SESSION['page_mode'] = 'edit';
			$_SESSION['last_item'] = $box['key']['cType'].  '_'. $box['key']['cID']. '.'. $box['key']['cVersion'];

			if ($box['key']['duplicate']) {
				$showDuplicatedToast = true;
			} else {
				$showCreatedToast = true;
			}
		}
		
		//If we're creating a new content item from the admin toolbar, navigate to that content item
		//after the FAB closes.
		if (!empty($box['key']['create_from_toolbar'])) {
			$contentItemLink = ze\link::toItemWithAlias($box['key']['cID'], $box['key']['cType']);
			if ($contentItemLink) {
				$flags = [];
				$flags['GO_TO_URL'] = $contentItemLink;
				
				if ($showCreatedToast) {
					$flags['TOAST_NEXT_PAGELOAD'] = ze\admin::phrase("New content item created! Now in Edit mode.");
				} elseif ($showDuplicatedToast) {
					$flags['TOAST_NEXT_PAGELOAD'] = ze\admin::phrase("Content item duplicated! Now in Edit mode.");
				}
				
				ze\tuix::closeWithFlags($flags);
				exit;
			}
		}
	}
	
	
	
	
	protected function setSeoMessagesAndEvents(&$box, &$fields, &$values) {
		$box['tabs']['meta_data']['fields']['title']['progress_bar'] = true;
		$box['tabs']['meta_data']['fields']['title']['note_below'] = 'title';

		if (strlen($values['meta_data/title']) < 1) {
			$fields['meta_data/title']['note_below'] = 'Please enter a meta tag title.';
		} elseif (strlen($values['meta_data/title']) < 12)  {
			$fields['meta_data/title']['note_below'] = 'For good SEO and on-site search, make the title longer.';
		} elseif (strlen($values['meta_data/title']) < 26)  {
			$fields['meta_data/title']['note_below'] = 'For good SEO and on-site search, make the title a little longer.';
		} elseif (strlen($values['meta_data/title']) < 66)  {
			$fields['meta_data/title']['note_below'] = 'This is a good title length.';
		} else {
			$fields['meta_data/title']['note_below'] = 'The title may not be fully visible in search engine results.';
		}

		$fields['meta_data/title']['onclick'] = $fields['meta_data/title']['oninput'];

		$box['tabs']['meta_data']['fields']['description']['progress_bar'] = true;
		$box['tabs']['meta_data']['fields']['description']['note_below'] = 'description';

		if (strlen($values['meta_data/description']) < 1) {
			$fields['meta_data/description']['note_below'] = 'For good SEO, enter a description. It may be visible in search engine result listings. If left blank, search engines will auto-generate one, which may not be as well-worded.';
		} elseif (strlen($values['meta_data/description']) < 50)  {
			$fields['meta_data/description']['note_below'] = 'For good SEO, make the description longer to entice people to click through from a result list.';
		} elseif (strlen($values['meta_data/description']) < 100)  {
			$fields['meta_data/description']['note_below'] = 'For good SEO, make the description a little longer to entice people to click through from a result list.';
		} elseif (strlen($values['meta_data/description']) < 156)  {
			$fields['meta_data/description']['note_below'] = 'This is a good description length for SEO.';
		} else {
			$fields['meta_data/description']['note_below'] = 'The description is a little long for good SEO as it may not be fully visible.';
		}
	}

	protected function setAliasMessageAndEvent(&$box, &$fields, &$values) {
		$box['tabs']['meta_data']['fields']['alias']['progress_bar'] = true;
		$box['tabs']['meta_data']['fields']['alias']['note_below'] = 'alias';
		
		if (empty($values['privacy/privacy']) || ($values['privacy/privacy'] == 'public')) {
			$values['meta_data/content_item_is_public'] = true;
			if (strlen($values['meta_data/alias']) < 1) {
				$fields['meta_data/alias']['note_below'] = 'For good SEO, set up an alias for this content item.';
			} else {
				$fields['meta_data/alias']['note_below'] = 'This content item has an alias.';
			}
		} else {
			$values['meta_data/content_item_is_public'] = false;
			if (strlen($values['meta_data/alias']) < 1) {
				$fields['meta_data/alias']['note_below'] = 'This content item does not have an alias. It is good practice to set one, even if the content item is not public.';
			} else {
				$fields['meta_data/alias']['note_below'] = 'This content item has an alias.';
			}
		}
	}
	
	protected function fillMenu(&$box, &$fields, &$values, $contentType, $content, $version) {
		
		//Menu positions are in the format CONCAT(section_id, '_', menu_id, '_', child_options)
		//Possible options for "child_options" are:
		$beforeNode = 0;
		$underNode = 1;
		$underNodeAtStart = 2;	//N.b. this option is not supported by position pickers using Organizer Select, but supported by ze\menuAdm::addContentItems() when saving
		$defaultPos = '';
		
		$createdFromHomePage = false;
		
		$menu = false;
		
		//If a content item was set as the "from" or "source", attempt to get details of its primary menu node
		if ($box['key']['from_cID']) {
			//If the admin was on the home page (in any language) before attempting to create a content item,
			//always suggest the "Main" menu section.
			//For now, do not set the menu path. This will be handled later.
			$equivId = ze\content::equivId($box['key']['from_cID'], $box['key']['from_cType']);
			
			if ($equivId == ze::$homeEquivId && $box['key']['from_cType'] == ze::$homeCType && !$box['key']['id']) {
				$createdFromHomePage = true;
			}
			
			if (!$createdFromHomePage) {
				$menu = ze\menu::getFromContentItem($box['key']['from_cID'], $box['key']['from_cType']);
			}
			
			//Change the default to "after" if there's a known position
			$defaultPos = 'after';
		
		//Watch out for the "create a child" option from Organizer
		} elseif ($box['key']['target_menu_parent']) {
			$menu = ze\menu::details($box['key']['target_menu_parent']);
			$defaultPos = 'under';
		
		} elseif ($box['key']['target_menu']) {
			$menu = ze\menu::details($box['key']['target_menu']);
			$defaultPos = 'under';
		
		}
		
		
		//Look for suggested menu nodes
		$suggestedPositions = [];
		if ($box['key']['cType'] != 'html') {
			foreach (ze\row::getAssocs('menu_nodes', ['id', 'section_id'], ['restrict_child_content_types' => $box['key']['cType']]) as $menuNode) {
				$mPath = ze\menuAdm::path($menuNode['id'], true). ' › '. ze\admin::phrase('[ Create at the start ]');
				$mVal = $menuNode['section_id']. '_'. $menuNode['id']. '_'. $underNodeAtStart;
				
				$suggestedPositions[$mVal] = $mPath;
			}
		}
		$suggestionsExist = !empty($suggestedPositions);
		$suggestionsForced = $suggestionsExist && $contentType['menu_node_position_edit'] == 'force';
		

		//Don't show the option to add a menu node when editing an existing content item...
		if ($box['key']['cID']) {
			
			$fields['meta_data/create_menu_node']['hidden'] = true;
			unset($fields['meta_data/no_menu_warning']['indent']);
			$values['meta_data/create_menu_node'] = '';
			
			if (
			//...or if an admin does not have the permissions to create a menu node...
				//(Though allow this through for restricted admins if they are forced to create a content item in one of the suggested places.)
			 ($box['key']['translate'] && !ze\priv::check('_PRIV_EDIT_MENU_TEXT'))
			 || (!$box['key']['translate'] && !$suggestionsForced && !ze\priv::check('_PRIV_CREATE_DELETE_MENU_ITEM'))
		
			//...or when translating a content item without a menu node.
			 || ($box['key']['translate'] && !$menu)
			 ) {
			
				$fields['meta_data/menu']['hidden'] = true;
			}
			
			if ($menu) {
				$values['meta_data/menu_content_status'] = $content['status'];
                //To show multilevel menu nodes "path"				
				$values['meta_data/menu_id_when_editing'] = $menu['mID'];
				$values['meta_data/menu_text_when_editing'] = $values['meta_data/menu_text_when_editing_on_load'] = $menu['name'];
				
				$fields['meta_data/no_menu_warning']['hidden'] = true;
			} elseif (empty($contentType['prompt_to_create_a_menu_node'])) {
				$fields['meta_data/no_menu_warning']['hidden'] = true;
			}
		
		//If we're translating, add the ability to add the text but hide all of the options about setting a position
		} elseif ($box['key']['translate']) {
			$fields['meta_data/menu_pos'] =
			$fields['meta_data/menu_pos_suggested'] =
			$fields['meta_data/menu_pos_before'] =
			$fields['meta_data/menu_pos_under'] =
			$fields['meta_data/menu_pos_after'] =
			$fields['meta_data/menu_pos_specific']['hidden'] = true;
			$fields['meta_data/create_menu_node']['hidden'] = true;
			$values['meta_data/create_menu_node'] = 1;
		
		} else {
			if ($menu) {
				//Set the menu positions for before/after/under
				$values['meta_data/menu_pos_before'] = $menu['section_id']. '_'. $menu['id']. '_'. $beforeNode;
				$values['meta_data/menu_pos_under'] = $menu['section_id']. '_'. $menu['id']. '_'. $underNode;

				if ($box['key']['target_menu']) {
					$values['meta_data/menu_pos_after'] =
					$values['meta_data/menu_pos_specific'] = $menu['section_id']. '_'. $menu['id']. '_'. $underNode;
				} else {
					$values['meta_data/menu_pos_after'] =
					$values['meta_data/menu_pos_specific'] = $menu['section_id']. '_'. $menu['parent_id']. '_'. $underNode;
				}
			
				//That last line of code above will actually place the new menu node at the end of the current line.
				//If there's a menu node after the current one, then that's not technically the position after this one,
				//so we'll need to correct this.
				if ($nextNodeId = ze\sql::fetchValue('
					SELECT id
					FROM '. DB_PREFIX. 'menu_nodes
					WHERE section_id = '. (int) $menu['section_id']. '
					  AND parent_id = '. (int) $menu['parent_id']. '
					  AND ordinal > '. (int) $menu['ordinal']. '
					ORDER BY ordinal ASC
					LIMIT 1
				')) {
					$values['meta_data/menu_pos_after'] = $menu['section_id']. '_'. $nextNodeId. '_'. $beforeNode;
				}
				
				$values['meta_data/menu_pos'] = $defaultPos;
			
			} else {
				//Remove the before/under/after options if we didn't find them above
				unset($fields['meta_data/menu_pos']['values']['before']);
				unset($fields['meta_data/menu_pos']['values']['under']);
				unset($fields['meta_data/menu_pos']['values']['after']);
				
				//If we know the menu section we're aiming to create in, at least pre-populate that
				if ($box['key']['target_menu_section']) {
					$values['meta_data/menu_pos_specific'] = $box['key']['target_menu_section']. '_0_'. $underNode;
				} elseif ($createdFromHomePage) {
					//If the admin was on the home page (in any language) before attempting to create a content item,
					//always suggest the "Main" menu section.
					if (ze\row::exists('menu_sections', 1)) {
						$values['meta_data/menu_pos_specific'] = '1_0_1';
					}
				}
				
				//Default the "create a menu node" checkbox to the value in the content type settings
				$values['meta_data/create_menu_node'] = $contentType['prompt_to_create_a_menu_node'] ?? 1;
			}
			
			if (empty($contentType['prompt_to_create_a_menu_node'])) {
				$fields['meta_data/no_menu_warning']['hidden'] = true;
			}
			
			//If there were some suggestions, default the radio-group to select them over the specific option
			if ($suggestionsExist) {
				$values['meta_data/menu_pos'] = 'suggested';
				$fields['meta_data/menu_pos_suggested']['values'] = $suggestedPositions;
				
				if (count($suggestedPositions) > 1) {
					$fields['meta_data/menu_pos']['values']['suggested']['label'] = ze\admin::phrase('Suggested positions');
				}
				
				//Lock down the choice to only suggestions, if this is enabled in the content type settings
				if ($suggestionsForced) {
					$fields['meta_data/menu_pos']['hidden'] =
					$fields['meta_data/menu_pos']['readonly'] = true;
					$fields['meta_data/menu_pos_locked_warning']['hidden'] = false;
					$fields['meta_data/menu_pos_suggested']['hide_with_previous_outdented_field'] = false;
				}

			} else {
				$values['meta_data/menu_pos'] = 'specific';
				unset($fields['meta_data/menu_pos']['values']['suggested']);
			}
		}
		
		if (!$box['key']['cID']) {
			$fields['meta_data/menu_text_when_editing']['hidden'] = true;
		}
	}
		
		
		
	
	
	private function getSelectedMenuPosition(&$values) {
		switch ($values['meta_data/menu_pos']) {
			case 'suggested':
				return $values['meta_data/menu_pos_suggested'];
				break;
			case 'before':
				return $values['meta_data/menu_pos_before'];
				break;
			case 'after':
				return $values['meta_data/menu_pos_after'];
				break;
			case 'under':
				return $values['meta_data/menu_pos_under'];
				break;
			case 'specific':
				return $values['meta_data/menu_pos_specific'];
				break;
		}
		
		return false;
	}
	
	public function saveMenu(&$box, &$fields, &$values, $changes, $equivId) {

		if ($box['key']['cVersion'] == 1) {
		
			//If translating a content item with a menu node, add the translated menu text
			if ($box['key']['translate']) {
				if ($equivId
				 && $values['meta_data/create_menu_node']
				 && ze\priv::check('_PRIV_EDIT_MENU_TEXT')) {
		
					//Check if a menu node text already exists in the target language.
					//If it does, update the text with the value entered in the field.
					$menuTextInTargetLanguage = '';
					$content = ze\row::get('content_items', ['language_id'], ['id' => $box['key']['source_cID'], 'type' => $box['key']['cType']]);
					
					$createNewNode = true;
					
					if ($box['key']['target_language_id'] && $box['key']['target_language_id'] != $content['language_id']) {
						if (!empty($menu = ze\menu::getFromContentItem($box['key']['from_cID'], $box['key']['from_cType']))) {
							$menuTextInTargetLanguage = ze\row::get('menu_text', 'name', ['menu_id' => $menu['mID'], 'language_id' => $box['key']['target_language_id']]);
							if ($menuTextInTargetLanguage) {
								ze\row::set('menu_text', ['name' => $values['meta_data/menu_text']], ['menu_id' => $menu['mID'], 'language_id' => $box['key']['target_language_id']]);
								$createNewNode = false;
							}
						}
					}
					
					if ($createNewNode) {
						//Create copies of any menu node text into this language
						$sql = "
							INSERT IGNORE INTO ". DB_PREFIX. "menu_text
								(menu_id, language_id, name, descriptive_text)
							SELECT menu_id, '". ze\escape::asciiInSQL($values['meta_data/language_id']). "', '". ze\escape::sql($values['meta_data/menu_text']). "', descriptive_text
							FROM ". DB_PREFIX. "menu_nodes AS mn
							INNER JOIN ". DB_PREFIX. "menu_text AS mt
							   ON mt.menu_id = mn.id
							  AND mt.language_id = '". ze\escape::asciiInSQL(ze\content::langId($box['key']['source_cID'], $box['key']['cType'])). "'
							WHERE mn.equiv_id = ". (int) $equivId. "
							  AND mn.content_type = '". ze\escape::asciiInSQL($box['key']['cType']). "'
							ORDER BY mn.id";
						ze\sql::update($sql);
					}
				}
			
			//If creating a new content item, add a new menu node at the specified position
			} else {
				if ($values['meta_data/create_menu_node']
				 && ($values['meta_data/menu_pos'] == 'suggested' || ze\priv::check('_PRIV_CREATE_DELETE_MENU_ITEM'))) {
					
					if ($menuPos = $this->getSelectedMenuPosition($values)) {
						$menuIds = ze\menuAdm::addContentItems($box['key']['id'], $menuPos);
						
						if ($menuId = array_shift($menuIds)) {
							ze\menuAdm::saveText($menuId, $values['meta_data/language_id'], ['name' => $values['meta_data/menu_text']]);

							if ($box['key']['duplicate'] || $box['key']['duplicate_from_menu']) {
								//If duplicating a content item which is attached to a menu node,
								//check its privacy setting, and copy to the new menu node.
								$currentMenu = ze\menu::getFromContentItem($box['key']['from_cID'], $box['key']['from_cType']);
								if (!empty($currentMenu)) {
									ze\row::set('menu_nodes', ['hide_private_item' => $currentMenu['hide_private_item']], ['id' => $menuId]);
								}
							}
						}
					}
				}
			}
		}
		
		//If editing an existing content item, check if the admin has changed the menu node text. Update accordingly.
		if ($box['key']['id']) {
			if (
				$values['meta_data/menu_id_when_editing']
				&& $values['meta_data/menu_text_when_editing']
				&& $values['meta_data/menu_text_when_editing_on_load']
				&& $values['meta_data/menu_text_when_editing'] != $values['meta_data/menu_text_when_editing_on_load']
			) {
				ze\row::update('menu_text', ['name' => $values['meta_data/menu_text_when_editing'], 'language_id' => $values['meta_data/language_id']], ['menu_id' => $values['meta_data/menu_id_when_editing'], 'language_id' => $values['meta_data/language_id_on_load']]);
			}
		}
		
		ze\contentAdm::syncMenuTextStatus($box['key']['cID'], $box['key']['cType']);
	}
	
	public function unsetOriginalContentItemFields(&$box) {
		$loopThrough = [
			'title_original',
			'language_id_original',
			'release_date_original',
			'menu_original',
			'alias_original',
			'description_original',
			'sitemap_original',
			'keywords_original',
			'writer_id_original',
			'pinned_original',
			'content_summary_original',
			'layout_original',
			'css_class_field_original',
			
			'grouping_title_left',
			'grouping_language_left',
			'grouping_release_date_left',
			'grouping_menu_left',
			'grouping_alias_left',
			'grouping_description_left',
			'grouping_sitemap_left',
			'grouping_keywords_left',
			'grouping_writer_left',
			'grouping_pinned_left',
			'grouping_summary_left',
			'grouping_layout_left',
			'grouping_css_class_field_left'
		];
		
		foreach ($loopThrough as $fieldName) {
			unset($box['tabs']['meta_data']['fields'][$fieldName]);
		}
		
		unset($box['css_class']);
	}
}