<?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__organizer__menu_nodes extends ze\moduleBaseClass {
	
	protected $numSyncAssistLangs = 0;
	
	public function preFillOrganizerPanel($path, &$panel, $refinerName, $refinerId, $mode) {
		if (!ze\module::isRunning('zenario_users')) {
			unset($panel['inline_buttons']['linked_content_item_privacy']['admin_box']);
		}

		if ($path != 'zenario__menu/panels/menu_nodes') return;
		
		if (!(ze::get('refiner__language') && ze::get('refiner__language') != ze::$defaultLang)
		 && !ze::get('refiner__show_language_choice')
		 && !ze::in($mode, 'typeahead_search', 'get_item_name', 'get_item_links')) {
			$panel['db_items']['where_statement'] = $panel['db_items']['custom_where_statement_if_no_missing_items'];
		}
		
		if (ze::in($mode, 'full', 'quick', 'select')) {
			//Note down which content types have categories
			$panel['custom__content_types_with_categories'] =
				ze\ray::valuesToKeys(ze\row::getValues('content_types', 'content_type_id', ['enable_categories' => 1]));
		}
		
		
		//Some specific code to handle sorting items whilst searching in flat view.
		//When not searching, items will be displayed in hierarchy view, and the JavaScript in the panel instance
		//will need things sorted by the ordinal in each level.
		//However when we are doing a search, hierarchy view will be switched off and items will be shown in flat view.
		//We need to write some SQL to make sure they are sorted in the correct hierarchical order.
		if (isset($_GET['_search'])) {
			
			//Work out what the largest possible depth is in the menu.
			//(N.b. this field has an index so this query should be fast.)
			$largestMenuDepth = (int) ze\sql::fetchValue("SELECT MAX(separation) FROM ". DB_PREFIX. "menu_hierarchy");
			
			//Special case:
			//If there are no menu nodes that are children of other menu nodes, we can just leave the sort column
			//as the ordinal and skip this step.
			if ($largestMenuDepth > 0) {
				
				//Start writing the SQL needed to sort the matched menu nodes into order hierarchically.
				$join = '';
				$sortCol = 'mi.ordinal';
				
				//For every possible parent-child relationship, add a new table join,
				//and then add that table join to the ordinal column.
				//The logic I've written below will show all of the top level nodes first,
				//then second level, and so on. After that they'll be sorted in hierarchical menu node order.
				//You could use different logic than that, but only if you could work out a way to write the joins/SQL.
				for ($i = 1; $i <= $largestMenuDepth; ++$i) {
					$l = $i - 1;
					
					$join .= '
						LEFT JOIN '. DB_PREFIX. 'menu_nodes AS p'. $i;
					
					if ($i == 1) {
						$join .= '
						   ON mi.parent_id != 0
						  AND p'. $i. '.id = mi.parent_id';
					} else {
						$join .= '
						   ON p'. $l. '.parent_id != 0
						  AND p'. $i. '.id = p'. $l. '.parent_id';
					}
					
					$sortCol = 'p'. $i. '.ordinal, '. $sortCol;
				}
				
				
				$panel['db_items']['table'] .= $join;
				$panel['columns']['ordinal']['sort_column'] = $sortCol;
			}
		}
	}
	
	public function fillOrganizerPanel($path, &$panel, $refinerName, $refinerId, $mode) {
		if ($path != 'zenario__menu/panels/menu_nodes') return;
		
		$path = false;
		$separator = ' › ';
		$sectionSeparator = ': ';
		$isFlatView = !isset($_REQUEST['_openToItemInHierarchy']) && !isset($_REQUEST['_openItemsInHierarchy']);
		$numLanguages = ze\lang::count();

		$menuItem = $menuParent = false;
		if (ze::get('refiner__children')) {
			$menuParent = ze\menu::details(ze::get('refiner__children'));
		}

		$panel['key']['languageId'] = (ze::get('refiner__language') ?: ze::get('languageId')) ?: (ze::get('language') ?: ze::$defaultLang);
		$panel['key']['sectionId'] = ze\menu::sectionId(($menuItem['section_id'] ?? false) ?: (($menuParent['section_id'] ?? false) ?: ze::get('refiner__section')));
		$panel['key']['parentId'] =
		$panel['key']['parentMenuID'] = $menuParent['id'] ?? false;
		
		$mrg = [
			'lang' => ze\lang::name($panel['key']['languageId']),
			'language_name' => ze\lang::name($panel['key']['languageId'], false),
			'section' => ze\menu::sectionName($panel['key']['sectionId'])];

		//Hide the "view content items under this menu node" if not showing the default language
		if ($panel['key']['languageId'] != ze::$defaultLang) {
			unset($panel['item_buttons']['view_content']);
		}


		//Pass the Storekeeper Mode onto the create and edit buttons
		if (isset($panel['item_buttons']['edit'])) {
			$panel['item_buttons']['edit']['admin_box']['key']['mode'] = $mode;
		}
		if (isset($panel['collection_buttons']['create'])) {
			$panel['collection_buttons']['create']['admin_box']['key']['mode'] = $mode;
		}

		if (isset($panel['item_buttons']['edit_menu_text'])) {
			if($numLanguages==1){
				$panel['item_buttons']['edit_menu_text']['label'] = ze\admin::phrase('Edit menu text');
			}else{
				$panel['item_buttons']['edit_menu_text']['label'] =
					ze\admin::phrase('Edit menu text in [[language_name]]', $mrg);
			}
		}

		if (isset($panel['item_buttons']['define_menu_text'])) {
			$panel['item_buttons']['define_menu_text']['label'] =
				ze\admin::phrase('Create menu text in [[language_name]]', $mrg);
		}
			
			
		if (isset($panel['item_buttons']['duplicate'])) {
			$panel['item_buttons']['duplicate']['label'] =
				ze\admin::phrase('Duplicate content item for translation into [[language_name]]', $mrg);
		}


		$panel['item']['tooltip_when_link_is_active'] = ze\admin::phrase('View child menu nodes of &quot;[[name]]&quot;.');
		
		if ($refinerName == 'menu_nodes_using_image') {
			$mrg = ze\row::get('files', ['filename'], $refinerId);
			$panel['title'] = ze\admin::phrase('Menu nodes using the image "[[filename]]"', $mrg);
			$panel['no_items_message'] = ze\admin::phrase('There are no menu nodes using the image "[[filename]]"', $mrg);

		} elseif ($panel['key']['parentId']) {
			$mrg['parent'] = ze\menu::name($panel['key']['parentId'], $panel['key']['languageId']);
			$mrg['n'] = ze\menuAdm::level($panel['key']['parentId']) + 1;
	
			$panel['title'] = ze\admin::phrase('"[[section]]" Section in [[lang]]: child menu nodes of "[[parent]]" (Level [[n]])', $mrg);
			$panel['no_items_message'] = ze\admin::phrase('The "[[parent]]" menu node has no child nodes.', $mrg);
	
			if ($isFlatView) {
				$path = ze\menuAdm::path($panel['key']['parentId'], $panel['key']['languageId'], $separator);
			}

		} elseif ($panel['key']['sectionId']) {
			$panel['title'] = ze\admin::phrase('Menu nodes in the menu section "[[section]]" in [[lang]]', $mrg);
			$panel['no_items_message'] = ze\admin::phrase('No menu nodes found in menu section "[[section]]"', $mrg);
			$panel['no_items_in_search_message'] = ze\admin::phrase('No menu nodes in the "[[section]]" section match your search.', $mrg);

		} else {
			unset($panel['reorder']);
			unset($panel['item']['tooltip']);
		}


		if ($isFlatView) {
			$panel['force_view_mode'] = 'list';
	
			$panel['columns']['ordinal']['align_right'] = false;
			$panel['columns']['ordinal']['format'] = 'remove_zero_padding';
	
			unset($panel['reorder']);
			unset($panel['item']['link']);
			unset($panel['item']['tooltip']);
			foreach ($panel['item_buttons'] as $tagName => &$button) {
				if (is_array($button)) {
					$button['hidden'] = $tagName != 'go_to_menu_in_sk';
				}
			}
			foreach ($panel['collection_buttons'] as $tagName => &$button) {
				if (is_array($button)) {
					$button['hidden'] = true;
				}
			}

		} else {
			unset($panel['item_buttons']['go_to_menu_in_sk']);
		}
	
	
		//If this is full, quick or select mode, and the admin looking at this only has permissions
		//to edit specific menu items, we'll need to check if the current admin can edit each
		//item.
		$checkSpecificPerms = ze::in($mode, 'full', 'quick', 'select') && ze\admin::hasSpecificPerms();

		//Get all enabled content types. This data will be used to:
		//1) Check if a content type can be pinned,
		//2) Generate "Create menu node and _content type_ item" buttons.
		$enabledContentTypes = ze\content::getContentTypes(true, true);
		$enabledContentTypesIds = array_column($enabledContentTypes, 'content_type_id');
		
		//As HTML pages are always enabled, include them in here for pinning check...
		array_unshift($enabledContentTypesIds, 'html');
		$pinningEnabledSql = '
			SELECT content_type_id
			FROM ' . DB_PREFIX . 'content_types
			WHERE content_type_id IN (' . ze\escape::in($enabledContentTypesIds) . ')
			AND allow_pinned_content = 1';
		$pinningEnabledResult = ze\sql::select($pinningEnabledSql);
		$pinningEnabled = ze\sql::fetchValues($pinningEnabledResult);

		//...and category check.
		$categoriesEnabledSql = '
			SELECT content_type_id
			FROM ' . DB_PREFIX . 'content_types
			WHERE content_type_id IN (' . ze\escape::in($enabledContentTypesIds) . ')
			AND enable_categories = 1';
		$categoriesEnabledResult = ze\sql::select($categoriesEnabledSql);
		$categoriesEnabled = ze\sql::fetchValues($categoriesEnabledResult);
		
		if ($numLanguages > 1) {
			$defaultLanguageName = ze\lang::name(ze::$defaultLang);
			ze\lang::applyMergeFields($panel['item_buttons']['delete']['disabled_tooltip'], ['default_language_name' => $defaultLanguageName]);
			ze\lang::applyMergeFields($panel['item_buttons']['delete_recursive']['disabled_tooltip'], ['default_language_name' => $defaultLanguageName]);
			
			$panel['item_buttons']['delete']['ajax']['confirm']['message'] = ze\admin::phrase(
				'Delete menu node "[[name]]"? This will affect the menu in all languages.'
			);
			$panel['item_buttons']['delete']['ajax']['confirm']['multiple_select_message'] = ze\admin::phrase(
				'Delete the selected menu nodes? This will affect the menu in all languages.'
			);
		}
		
		$sectionsUsedByBreadcrumbs = [];
		if (ze\module::isRunning('zenario_breadcrumbs')) {
			$pluginInstancesAndSettings = ze\module::getModuleInstancesAndPluginSettings('zenario_breadcrumbs');
			
			foreach ($pluginInstancesAndSettings as $instance) {
				if ($instance['settings']['breadcrumb_trail'] == 'other_menu_node') {
					$position = explode('_', $instance['settings']['breadcrumb_prefix_menu']);
					$menuNodeId = $position[1] ?? 0;
					$sectionsUsedByBreadcrumbs[] = $menuNodeId;
				}
			}
			
			$sectionsUsedByBreadcrumbs = array_unique($sectionsUsedByBreadcrumbs);
		}
        
		foreach ($panel['items'] as &$item) {
	
			$id = $item['mid'];
			
			$internalTarget = $item['target_loc'] == 'int' && $item['equiv_id'];
	        
	        $item['row_class'] = '';
			$item['css_class'] = ze\menuAdm::cssClass($item);
	        
			if ($internalTarget) {
				if ($item['redundancy'] == 'unique') {
					//$item['tooltip'] = ze\admin::phrase('This is a unique menu node. No other menu node links to this content item.');
					$item['tooltip'] = '';
				} elseif ($item['redundancy'] == 'primary') {
					$item['tooltip'] = ze\admin::phrase("Primary menu node. Other, secondary, nodes link to the same content item.");
				} else {
					$item['tooltip'] = ze\admin::phrase("Secondary menu node. A primary menu node also links to its content item.");
				}
			} elseif ($item['target_loc'] == 'doc' && $item['document_id']) {
				if ($item['redundancy'] == 'unique') {
					//$item['tooltip'] = ze\admin::phrase('This is a unique menu node. No other menu node links to this document.');
					$item['tooltip'] = '';
				} elseif ($item['redundancy'] == 'primary') {
					$item['tooltip'] = ze\admin::phrase("Primary menu node. Other, secondary, menu nodes link to the same document.");
				} else {
					$item['tooltip'] = ze\admin::phrase("Secondary menu node. A primary menu node also links to its document.");
				}
			} elseif ($item['target_loc'] == 'ext' && $item['target']) {
				$item['tooltip'] = ze\admin::phrase('This menu node links to an external URL.');
	
			} else {
				$item['tooltip'] = ze\admin::phrase('This menu node doesn\'t link to anything. Unlinked menu nodes are hidden from visitors unless they have a child menu node that is visible.');
			}
			
			if ($item['restrict_child_content_types']) {
				$contentTypeDetails = ze\contentAdm::cTypeDetails($item['restrict_child_content_types']);
				
				if (!empty($contentTypeDetails) && is_array($contentTypeDetails)) {
					if($item['tooltip']) $item['tooltip'] .= '<br /><br />';
					$item['tooltip'] .= ze\admin::phrase(
						'Preferential menu node for [[suggested_content_type]] content items.',
						['suggested_content_type' => $contentTypeDetails['content_type_name_en']]
					);
				}
			}
		
			if ($item['children']) {
				// T11769: Added grand child logic for delete menu node.
				$Child = ze\row::get('menu_nodes', ['id'], array('parent_id' => $item['mid'])); ;
				$grandChild = ze\row::get('menu_nodes', ['id'], array('parent_id' => $Child['id'])); 
			
				if ($grandChild && $grandChild['id'] > 0) {
					$item['has_grandchild'] =  true;
				}
				else
				{
					$item['has_children'] = true;
				}
			} 
			else {
				$item['childless'] = true;
			}
			
	
			if ($item['name'] === null) {
				$item['css_class'] .= ' zenario_menunode_unlinked';
		
				//Apply formatting for untranslated menu nodes
				foreach ($panel['columns'] as $columnName => &$column) {
					if (isset($column['title'])) {
						if (ze::in($columnName, 'ordinal', 'translations')) {
							//leave the column as is
				
						} elseif (ze::in($columnName, 'name', 'redundancy', 'language_id')) {
							//ghost the column
							$item[$columnName. '__css_class'] = 'ghost';
						} else {
							//Don't show anything in the column
							$item[$columnName] = '';
						}
					}
				}
		
				//Missing Menu Nodes should have their target faded,
				//with the exception of the rare case where a Content Item exists in a Language but the Menu Text does not
				if (!$item['target_lang'] || $item['target_lang'] != ($item['text_lang'] ?: $panel['key']['languageId'])) {
					$item['cell_css_classes'] = [];
					$item['cell_css_classes']['target'] = 'ghost';
			
					if ($internalTarget && !$item['target_content_id']) {
						$item['can_duplicate'] = true;
					}
				}
		
				$item['ghost'] = true;
		
				$item['name'] = ze\menu::name($id, $panel['key']['languageId'], '[[name]] [[[language_id]] (menu node untranslated)');
				$item['row_class'] .= ' organizer_untranslated_menu_node';
				$item['tooltip'] = ze\admin::phrase('This menu node has not been translated into [[language_name]].', $mrg);
		
				if ($isFlatView) {
					if ($path) {
						$item['path'] = $path. $separator. $item['name'];
					} else {
						$item['path'] = ze\menuAdm::pathWithLevel($id, $panel['key']['languageId'], $separator);
					}
					$item['path'] = ze\admin::phrase('MISSING [[name]]', ['name' => $item['path']]);
				}
	
			} else {
				if ($isFlatView) {
					if ($path) {
						$item['path'] = $path. $separator. $item['name'];
		
					} else {
						$item['path'] = ze\menuAdm::pathWithLevel($id, $panel['key']['languageId'], $separator);
					}
				}
		
				//Missing Menu Nodes to Content Items can be created by duplicating the Content Item
				if (!$item['target_lang'] || $item['target_lang'] != ($item['text_lang'] ?: $panel['key']['languageId'])) {
					if ($internalTarget) {
						$item['can_duplicate'] = true;
					}
				}
		
				if ($panel['key']['languageId'] == ze::$defaultLang || empty($item['translations']) || $item['translations'] == 1) {
					$item['can_be_removed'] = true;
				}
			}
	
			if (!empty($internalTarget)) {
				$item['frontend_link'] = ze\link::toItem($item['target_content_id'], $item['target_content_type']);
				$item['content'] = true;
	
			} elseif (!empty($item['target'])) {
				$item['frontend_link'] = $item['target'];
			}
	
			if ($mode == 'get_item_links' || $isFlatView) {
				$item['navigation_path'] = ze\menuAdm::organizerLink($id, $panel['key']['languageId']);
			}
	
			if (isset($item['translations'])) {
				if ($item['translations'] == 1) {
					$item['translations'] = ze\admin::phrase('untranslated');
				} else {
					$item['translations'] .= ' / '. $numLanguages;
				}
			}
	
			unset($item['target_loc']);
			unset($item['sync_assist']);
			unset($item['equiv_id']);
			unset($item['ext_url']);
			unset($item['target_content_id']);
			unset($item['target_content_type']);
	
			if ($isFlatView) {
				$item['ordinal'] = ze\menuAdm::sortableOrdinalPath($id);
			}
			
			if ($checkSpecificPerms) {
				if (ze\priv::onMenuText('_PRIV_EDIT_MENU_TEXT', $id, $panel['key']['languageId'], $item['section_id'])) {
					$item['_specific_perms'] = true;
				}
			}

			//If a menu node uses a static method, display the details.
			if ($item['module_class_name'] && $item['method_name']) {
				$item['uses_static_method'] = '[Static method used]';
			}

			$item['linked_content_item'] = false;
			$item['linked_content_item_status'] = '';
			$item['linked_content_item_is_draft'] = false;

			$menuContentItem = ze\menu::getContentItem($item['mid']);
			if ($menuContentItem) {
				//Display extra buttons if a menu node has a linked content item:
				$item['linked_content_item'] = true;
				
				//content item status...
				$menuContentItem['latest_version'] = ze\content::latestVersion($menuContentItem['content_id'], $menuContentItem['content_type']);
				$linkedItemTagId = $menuContentItem['content_type'] . '_' . $menuContentItem['content_id'];
				$item['linked_content_item_type'] = $menuContentItem['content_type'];
				$item['linked_content_item_tag_id'] = $linkedItemTagId;
				$item['navigation_path'] = 'zenario__content/panels/content/refiners/content_type//' . $menuContentItem['content_type'] . '//' . $linkedItemTagId;
				
				$menuContentItemStatus = ze\row::get('content_items', 'status', ['id' => $menuContentItem['content_id'], 'type' => $menuContentItem['content_type']]);
				$item['linked_content_item_status'] = ze\contentAdm::getItemIconClass($menuContentItem['content_id'], $menuContentItem['content_type'], true, $menuContentItemStatus);
				$item['linked_content_item_status_label'] = ze\contentAdm::statusPhrase($menuContentItemStatus);
				$item['linked_content_item_is_draft'] = ze\content::isDraft($menuContentItemStatus);

				//content item layout...
				$menuContentItemLayoutId = ze\content::layoutId($menuContentItem['content_id'], $menuContentItem['content_type']);
				$item['linked_content_item_layout'] = ze\layoutAdm::codeName($menuContentItemLayoutId);
				
				$menuContentItemLayoutStatus = ze\row::get('layouts', 'status', ['layout_id' => $menuContentItemLayoutId]);
				$item['row_class'] .= ' layout_status_' . $menuContentItemLayoutStatus;

				//content item privacy...
				$menuContentItemPrivacyAndLocation = ze\row::get('translation_chains', ['privacy', 'at_location'], ['equiv_id' => $menuContentItem['equiv_id'], 'type' => $menuContentItem['content_type']]);
				//If this content item is set to a group or smart group,
				//go get a better description which includes the name.
				if (ze::in($menuContentItemPrivacyAndLocation['privacy'], 'group_members', 'with_role', 'in_smart_group', 'logged_in_not_in_smart_group')) {
					$menuContentItemPrivacyData = [
						'id' => $menuContentItem['content_id'],
						'type' => $menuContentItem['content_type'],
						'equiv_id' => $menuContentItem['equiv_id'],
						'privacy' => $menuContentItemPrivacyAndLocation['privacy'],
						'at_location' => $menuContentItemPrivacyAndLocation['at_location']
					];

					$item['linked_content_item_privacy'] =
						ze\admin::phrase('Permissions: [[privacyDesc]]', ['privacyDesc' => ze\contentAdm::privacyDesc($menuContentItemPrivacyData)]);
				} else {
					$item['linked_content_item_privacy'] = $menuContentItemPrivacyAndLocation['privacy'];
				}

				$item['row_class'] .= ' privacy_' . $menuContentItemPrivacyAndLocation['privacy'];

				$versionData = ze\row::get('content_item_versions', true, ['id' => $menuContentItem['content_id'], 'type' => $menuContentItem['content_type'], 'version' => $menuContentItem['latest_version']]);
				
				//content item pinned status...
				if (in_array($menuContentItem['content_type'], $pinningEnabled)) {
					$item['linked_content_item_allow_pinning'] = true;
					
					if ($versionData && is_array($versionData) && $versionData['pinned']) {
						$item['linked_content_item_pinned'] = $versionData['pinned'];
					}
				} else {
					$item['linked_content_item_allow_pinning'] = false;
				}
				
				//content item categories...
				if (in_array($menuContentItem['content_type'], $categoriesEnabled)) {
					$item['linked_content_item_categories_enabled'] = true;
					$item['linked_content_item_categories_count'] = ze\row::count('category_item_link', ['equiv_id' => $menuContentItem['equiv_id'], 'content_type' => $menuContentItem['content_type']]);
				} else {
					$item['linked_content_item_categories_enabled'] = false;
				}
				
				//content item Head and Foot HTML.
				if ($versionData && is_array($versionData) && $versionData['head_html']) {
					$item['head_html_populated'] = true;
				} else {
					$item['head_html_populated'] = false;
				}
				
				if ($versionData && is_array($versionData) && $versionData['foot_html']) {
					$item['foot_html_populated'] = true;
				} else {
					$item['foot_html_populated'] = false;
				}
				
				if (ze\contentAdm::allowHide($menuContentItem['content_id'], $menuContentItem['content_type'])) {
					$item['linked_content_item_can_be_hidden'] = true;
				}
				
				if (ze\contentAdm::allowTrash($menuContentItem['content_id'], $menuContentItem['content_type'])) {
					$item['linked_content_item_can_be_trashed'] = true;
				}
			}
			
			if (in_array($id, $sectionsUsedByBreadcrumbs) && !empty($item['can_be_removed'])) {
				$item['in_use_by_breadcrumbs_plugin'] = true;
			}
		}

		if (!$isFlatView) {
			$panel['columns']['path']['hidden'] = true;
		}
		
		if (ze\priv::check('_PRIV_CREATE_DELETE_MENU_ITEM')) {
			$j = 0;  
			$ord = 1000;
			
			foreach ($enabledContentTypes as $contentType) {
	
				++$j;
				$panel['collection_buttons']['create_menu_node_and_content_item_'. $j] = [
					'ord' => ++$ord,
					'parent' => 'create_dropdown',
					'label' => ze\admin::phrase("Level 1 menu node with [[content_type_name_en]]", $contentType),
					'hide_in_select_mode' => true,
					'hide_on_filter' => true,
					'admin_box' => [
						'path' => 'zenario_content',
						'key' => [
							'target_cType' => $contentType['content_type_id'],
							'id' => $panel['key']['sectionId'],
							'id_is_parent_menu_node_id' => 1
						]
					]
				];
				$panel['item_buttons']['create_menu_node_and_content_item_'. $j] = [
					'ord' => ++$ord,
					'parent' => 'create_child_dropdown',
					'label' => ze\admin::phrase("Menu node with [[content_type_name_en]]", $contentType),
					'hide_in_select_mode' => true,
					'hide_on_filter' => true,
					'admin_box' => [
						'path' => 'zenario_content',
						'key' => [
							'target_cType' => $contentType['content_type_id'],
							'id_is_menu_node_id' => 1
						]
					]
				];
			}    
		}
	}
	
	public function handleOrganizerPanelAJAX($path, $ids, $ids2, $refinerName, $refinerId) {
		if ($path != 'zenario__menu/panels/menu_nodes') return;
		
		// mass_add_to_menu used in both content and menu nodes
		if (ze::post('mass_add_to_menu') && ze\priv::check('_PRIV_CREATE_DELETE_MENU_ITEM')) {
			// Get tag ID from menu node ID
			$menuNodeDetails = ze\menu::details($ids);
			$ids = $menuNodeDetails['content_type'] . '_' . $menuNodeDetails['equiv_id'];
			ze\menuAdm::addContentItems($menuNodeDetails['content_type'] . '_' . $menuNodeDetails['equiv_id'], $ids2);
	
		//Unlink a Menu Node from its Content Item
		} elseif (ze::post('detach') && ze\priv::check('_PRIV_EDIT_MENU_ITEM')) {
	
			$submission = [
				'target_loc' => 'none'];
	
			ze\menuAdm::save($submission, ze::post('mID'));
			ze\menuAdm::ensureContentItemHasPrimaryNode(ze\content::equivId($_POST['cID'] ?? false, ze::post('cType')), ze::post('cType'));
	
		//Move one or more Menu Nodes to a different parent and/or the top level
		} elseif (ze::post('move') && ze\priv::check('_PRIV_EDIT_MENU_ITEM')) {
	
			//By default, just move to the top level
			$languageId = $_POST['languageId'] ?? false;
			$newParentId = 0;
			$newSectionId = $_POST['child__refiner__section'] ?? false;
			$newNeighbourId = 0;
	
			//Look for a menu node in the request
			if ($ids2) {
				//If this is a numeric id, look up its details and move next to that Menu Node
				if (is_numeric($ids2) && $neighbour = ze\menu::details($ids2)) {
					$newParentId = $neighbour['parent_id'];
					$newSectionId = $neighbour['section_id'];
					$newNeighbourId = $ids2;
		
				} else {
					//Check for a menu position, in the format CONCAT(section_id, '_', menu_id, '_', is_dummy_child)
					$menu_position = explode('_', $ids2);
					if (count($menu_position) == 3) {
				
						if ($menu_position[2]) {
							//Move the menu node to where a dummy placeholder is
							$newSectionId = $menu_position[0];
							$newParentId = $menu_position[1];
				
						} elseif ($menu_position[1]) {
							//Move the menu node to where another menu node is
							$newSectionId = $menu_position[0];
							$newParentId = ze\menu::parentId($menu_position[1]);
							$newNeighbourId = $menu_position[1];
						}
					}
				}
			}
			
			$menuIds = \ze\ray::explodeAndTrim($ids);
			
			//Check a given movement is valid.
			//Note: The code in this function is a bit old, it will print a message and exit instead of returning false.
			foreach ($menuIds as $menuId) {
				ze\menuAdm::checkMoveIsValid(
					$newSectionId,
					$menuId,
					$newParentId,
					$newNeighbourId
				);
			}
			
			foreach ($menuIds as $menuId) {
				ze\menuAdm::moveMenuNode(
					$newSectionId,
					$menuId,
					$newParentId,
					$newNeighbourId
				);
			}
	

		} elseif (ze::post('remove') && ze\priv::check('_PRIV_CREATE_DELETE_MENU_ITEM') && ze::request('languageId') != ze::$defaultLang) {
			foreach (ze\ray::explodeAndTrim($ids) as $id) {
				//Only remove translation if another translation still exists
				if (($result = ze\row::query('menu_text', 'menu_id', ['menu_id' => $id]))
				 && (ze\sql::fetchRow($result))
				 && (ze\sql::fetchRow($result))) {
					ze\menuAdm::removeText($id, ze::request('languageId'));
				}
			}

		} elseif (ze::post('delete') && ze\priv::check('_PRIV_CREATE_DELETE_MENU_ITEM')) {
			foreach (ze\ray::explodeAndTrim($ids) as $id) {
				ze\menuAdm::delete($id);
			}

		//Move or reorder Menu Nodes
		} elseif ((ze::post('reorder') || ze::post('hierarchy')) && ze\priv::check('_PRIV_REORDER_MENU_ITEM')) {
			$sectionIds = [];
	
			//Loop through each moved Menu Node
			foreach (ze\ray::explodeAndTrim($ids) as $id) {
				//Look up the current section, parent and ordinal
				if ($menuNode = ze\row::get('menu_nodes', ['section_id', 'parent_id', 'ordinal'], $id)) {
					$cols = [];
			
					//Update the ordinal if it is different
					if (isset($_POST['ordinals'][$id]) && $_POST['ordinals'][$id] != $menuNode['ordinal']) {
						$cols['ordinal'] = $_POST['ordinals'][$id];
					}
			
					//Update the parent id if it is different, and remember that we've done this
					if (isset($_POST['parent_ids'][$id]) && $_POST['parent_ids'][$id] != $menuNode['parent_id']) {
						$cols['parent_id'] = $_POST['parent_ids'][$id];
						$sectionIds[$menuNode['section_id']] = true;
					}
					ze\row::update('menu_nodes', $cols, $id);
				}
			}
	
			//Recalculate the Menu Hierarchy for any Menu Sections where parent ids have changed
			foreach ($sectionIds as $id => $dummy) {
				ze\menuAdm::recalcHierarchy($id);
			}
			
			//The top column is updated
			if(ze\module::inc('zenario_menu_multicolumn')){
				foreach (ze\ray::explodeAndTrim($ids) as $id) {
					if(ze\row::exists(ZENARIO_MENU_MULTICOLUMN_PREFIX. 'nodes_top_of_column', ['node_id' => $id])){
						$isEnabled = ze\row::get(ZENARIO_MENU_MULTICOLUMN_PREFIX. 'nodes_top_of_column','top_of_column', ['node_id' => $id]);
						if($isEnabled){
							$nodeLevel = self::getNodeLevel($id);
							if($nodeLevel == 2){
								ze\row::update(ZENARIO_MENU_MULTICOLUMN_PREFIX. 'nodes_top_of_column',['top_of_column' => 0],['node_id' => $id]);
							}
						}
					}
				}
			}
			
		} elseif (ze::post('make_primary')) {
			$menuNodeDetails = ze\menu::details($ids);
			$submission = [
				'equiv_id' => $menuNodeDetails['equiv_id'],
				'target_loc' => 'int',
				'content_type' => $menuNodeDetails['content_type'],
				'redundancy' => 'primary'];
			ze\menuAdm::save($submission, $ids);
			
		//Duplicate menu node under iteself
		} elseif (ze::post('duplicate_as_child') && ze\priv::check('_PRIV_CREATE_DELETE_MENU_ITEM')) {
			$menuNodeDetails = ze\menu::details($ids);
			
			//We want this to be in the first position under the menu node, so we need to work out the $position to pass.
			//The format will depend of whether there is an existing menu node under it or not.
			$sql = '
				SELECT id
				FROM ' . DB_PREFIX . 'menu_nodes
				WHERE parent_id = ' . (int)$ids . '
				ORDER BY ordinal
				LIMIT 1';
			$result = ze\sql::select($sql);
			$firstChildId = ze\sql::fetchValue($result);
			if ($firstChildId) {
				$position = $menuNodeDetails['section_id'] . '_' . $firstChildId . '_0';
			} else {
				$position = $menuNodeDetails['section_id'] . '_' . $menuNodeDetails['id'] . '_1';
			}
			$newIds = ze\menuAdm::addContentItems($menuNodeDetails['content_type'] . '_' . $menuNodeDetails['equiv_id'], $position);
			
			//Make new node primary
			$newId = array_values($newIds)[0];
			$newMenuNodeDetails = ze\menu::details($newId);
			$submission = [
				'equiv_id' => $newMenuNodeDetails['equiv_id'],
				'target_loc' => 'int',
				'content_type' => $newMenuNodeDetails['content_type'],
				'redundancy' => 'primary'];
			ze\menuAdm::save($submission, $newId);
			
			return $newIds;
		} elseif (ze::get('create_draft_by_copying')) {
			$menuContentItem = ze\menu::getContentItem($ids);
			$currentContentItemTagId = $menuContentItem['content_type'] . '_' . $menuContentItem['content_id'];
			
			$message = "
				Copy the contents of the content item [[source_content_item]] over the content item [[target_content_item]]?
                                
                This will create a draft of the current content item with the contents of the one you selected.";
            
            $replace = [
            	'source_content_item' => ze\content::formatTagFromTagId($ids2),
            	'target_content_item' => ze\content::formatTagFromTagId($ids)
            ];
            
            $currentAlias = ze\row::get('content_items', 'alias', ['tag_id' => $currentContentItemTagId]);
            if ($currentAlias) {
            	$message .= "
            		
            		This item will keep its alias \"[[current_alias]]\", but its content (meta data, version-controlled content, plugins, nests and slideshows) and choice of layout will be overwritten.";
            	$replace['current_alias'] = $currentAlias;
            }
            
            if (ze\lang::count() > 1) {
            	$sourceContentItemLang = ze\row::get('content_items', 'language_id', ['tag_id' => $ids2]);
            	$targetContentItemLang = ze\row::get('content_items', 'language_id', ['tag_id' => $currentContentItemTagId]);
            	
            	if ($sourceContentItemLang != $targetContentItemLang) {
            		$message .= "
            			
            			Note that you are copying from an item in [[source_content_item_lang]] over an item in [[target_content_item_lang]].";
            		
            		$replace['source_content_item_lang'] = ze\lang::name($sourceContentItemLang);
            		$replace['target_content_item_lang'] = ze\lang::name($targetContentItemLang);
            	}
            }
            
			echo ze\admin::phrase($message, $replace);
		} elseif (ze::get('create_draft_by_overwriting')) {
			$menuContentItem = ze\menu::getContentItem($ids);
			$currentContentItemTagId = $menuContentItem['content_type'] . '_' . $menuContentItem['content_id'];
			
			$message = "
            	Copy the contents of the content item [[source_content_item]] over the current draft of the content item [[target_content_item]]?";
			
			$replace = [
            	'source_content_item' => ze\content::formatTagFromTagId($ids2),
            	'target_content_item' => ze\content::formatTagFromTagId($ids)
            ];
            
            $currentAlias = ze\row::get('content_items', 'alias', ['tag_id' => $currentContentItemTagId]);
            if ($currentAlias) {
            	$message .= "
            		
            		This item will keep its alias \"[[current_alias]]\", but its content (meta data, version-controlled content, plugins, nests and slideshows) and choice of layout will be overwritten.";
            	$replace['current_alias'] = $currentAlias;
            }
			
			if (ze\lang::count() > 1) {
            	$sourceContentItemLang = ze\row::get('content_items', 'language_id', ['tag_id' => $ids2]);
            	$targetContentItemLang = ze\row::get('content_items', 'language_id', ['tag_id' => $currentContentItemTagId]);
            	
            	if ($sourceContentItemLang != $targetContentItemLang) {
            		$message .= "
            			
            			Note that you are copying from an item in [[source_content_item_lang]] over an item in [[target_content_item_lang]].";
            		
            		$replace['source_content_item_lang'] = ze\lang::name($sourceContentItemLang);
            		$replace['target_content_item_lang'] = ze\lang::name($targetContentItemLang);
            	}
            }
            
			echo ze\admin::phrase($message, $replace);
		} elseif (
			(ze::post('create_draft_by_copying') && ze\priv::check('_PRIV_EDIT_DRAFT'))
			|| (ze::post('create_draft_by_overwriting') && ze\priv::check('_PRIV_EDIT_DRAFT'))
		) {
			$sourceCID = $sourceCType = false;
			//Edit an existing Content Item based on its Menu Node
			$sourceCID = $sourceCType = false;
			
			$menuContentItem = ze\menu::getContentItem($ids);
			$menuContentItemTagId = $menuContentItem['content_type'] . '_' . $menuContentItem['equiv_id'];
			if (ze\content::getCIDAndCTypeFromTagId($sourceCID, $sourceCType, $ids2)
			 && ($content = ze\row::get('content_items', ['id', 'type', 'status'], ['tag_id' => $menuContentItemTagId]))
			 && (ze\priv::check('_PRIV_EDIT_DRAFT', $content['id'], $content['type']))) {
				$hasDraft = ze\content::isDraft($content['status']);
		
				if (!$hasDraft || ze\priv::check('_PRIV_EDIT_DRAFT', $content['id'], $content['type'])) {
					if ($hasDraft) {
						ze\contentAdm::deleteDraft($content['id'], $content['type'], false);
					}
			
					$cVersionTo = false;
					ze\contentAdm::createDraft($content['id'], $sourceCID, $content['type'], $cVersionTo);
				}
			}

		}
	}
	
	
	public function getNodeLevel($nodeId,$i=1){
		if($parentId = ze\row::get('menu_nodes', 'parent_id', ['id'=>$nodeId])){
			self::getNodeLevel($parentId,++$i);
		}
		return $i;
	}
	
	public function organizerPanelDownload($path, $ids, $refinerName, $refinerId) {
		
	}
}
