/**
  * Add a menu item as a template.
  *
  * @param array $wpItem
  * @param int $position
  * @param string|null $parent
  */
 private function addItem($wpItem, $position, $parent = null)
 {
     $item = ameMenuItem::fromWpItem($wpItem, $position, $parent);
     //Skip separators.
     if ($item['separator']) {
         $this->wasPreviousItemSeparated = true;
         return;
     }
     //Skip blacklisted menus.
     if (isset($item['url'], $this->blacklist[$item['url']])) {
         return;
     }
     $name = $this->sanitizeMenuTitle($item['menu_title']);
     if ($parent === null) {
         $this->parentNames[$item['file']] = $name;
     } else {
         $name = $this->parentNames[$parent] . ' -> ' . $name;
     }
     $templateId = ameMenuItem::template_id($item);
     $this->templates[$templateId] = array('name' => $name, 'used' => false, 'defaults' => $item);
     //Remember the relative order of menu items. It's a bit like a linked list.
     $this->templateOrder[$templateId] = array('previous_item' => $this->previousItemId, 'was_previous_item_separated' => $this->wasPreviousItemSeparated);
     $this->previousItemId = $templateId;
     $this->wasPreviousItemSeparated = false;
 }
 /**
  * Merge a custom menu with the current default WordPress menu. Adds/replaces defaults,
  * inserts new items and removes missing items.
  *
  * @uses self::$item_templates
  *
  * @param array $tree A menu in plugin's internal form
  * @return array Updated menu tree
  */
 function menu_merge($tree)
 {
     //Iterate over all menus and submenus and look up default values
     //Also flag used and missing items.
     $orphans = array();
     foreach ($tree as &$topmenu) {
         if (!ameMenuItem::get($topmenu, 'custom')) {
             $template_id = ameMenuItem::template_id($topmenu);
             //Is this menu present in the default WP menu?
             if (isset($this->item_templates[$template_id])) {
                 //Yes, load defaults from that item
                 $topmenu['defaults'] = $this->item_templates[$template_id]['defaults'];
                 //Note that the original item was used
                 $this->item_templates[$template_id]['used'] = true;
             } else {
                 //Record the menu as missing, unless it's a menu separator
                 if (empty($topmenu['separator'])) {
                     $topmenu['missing'] = true;
                     $temp = ameMenuItem::apply_defaults($topmenu);
                     $temp = $this->set_final_menu_capability($temp);
                     $this->add_access_lookup($temp, 'menu', true);
                 }
             }
         }
         if (is_array($topmenu['items'])) {
             //Iterate over submenu items
             foreach ($topmenu['items'] as &$item) {
                 if (!ameMenuItem::get($item, 'custom')) {
                     $template_id = ameMenuItem::template_id($item);
                     //Is this item present in the default WP menu?
                     if (isset($this->item_templates[$template_id])) {
                         //Yes, load defaults from that item
                         $item['defaults'] = $this->item_templates[$template_id]['defaults'];
                         $this->item_templates[$template_id]['used'] = true;
                         //We must move orphaned items elsewhere. Use the default location if possible.
                         if (isset($topmenu['missing']) && $topmenu['missing']) {
                             $orphans[] = $item;
                         }
                     } else {
                         if (empty($item['separator'])) {
                             //Record as missing, unless it's a menu separator
                             $item['missing'] = true;
                             $temp = ameMenuItem::apply_defaults($item);
                             $temp = $this->set_final_menu_capability($temp);
                             $this->add_access_lookup($temp, 'submenu', true);
                         }
                     }
                 } else {
                     //What if the parent of this custom item is missing?
                     //Right now the custom item will just disappear.
                 }
             }
         }
     }
     //If we don't unset these they will f**k up the next two loops where the same names are used.
     unset($topmenu);
     unset($item);
     //Now we have some items marked as missing, and some items in lookup arrays
     //that are not marked as used. Lets remove the missing items from the tree.
     $tree = ameMenu::remove_missing_items($tree);
     //Lets merge in the unused items.
     foreach ($this->item_templates as $template_id => $template) {
         //Skip used menus and separators
         if (!empty($template['used']) || !empty($template['defaults']['separator'])) {
             continue;
         }
         //Found an unused item. Build the tree entry.
         $entry = ameMenuItem::blank_menu();
         $entry['template_id'] = $template_id;
         $entry['defaults'] = $template['defaults'];
         $entry['unused'] = true;
         //Note that this item is unused
         //Add the new entry to the menu tree
         if (!empty($template['defaults']['parent'])) {
             if (isset($tree[$template['defaults']['parent']])) {
                 //Okay, insert the item.
                 $tree[$template['defaults']['parent']]['items'][] = $entry;
             } else {
                 //This can happen if the original parent menu has been moved to a submenu.
                 $tree[$template['defaults']['file']] = $entry;
             }
         } else {
             $tree[$template['defaults']['file']] = $entry;
         }
     }
     //Move orphaned items back to their original parents.
     foreach ($orphans as $item) {
         $defaultParent = !empty($item['defaults']['parent']) ? $item['defaults']['parent'] : null;
         if (isset($defaultParent) && isset($tree[$defaultParent])) {
             $tree[$defaultParent]['items'][] = $item;
         } else {
             //This can happen if the parent has been moved to a submenu.
             //Just put the orphan at the bottom of the menu.
             $tree[$item['defaults']['file']] = $item;
         }
     }
     //Resort the tree to ensure the found items are in the right spots
     $tree = ameMenu::sort_menu_tree($tree);
     return $tree;
 }
Esempio n. 3
0
 /**
  * Merge a custom menu with the current default WordPress menu. Adds/replaces defaults,
  * inserts new items and removes missing items.
  *
  * @uses self::$item_templates
  *
  * @param array $tree A menu in plugin's internal form
  * @return array Updated menu tree
  */
 function menu_merge($tree)
 {
     //Iterate over all menus and submenus and look up default values
     foreach ($tree as &$topmenu) {
         if (!ameMenuItem::get($topmenu, 'custom')) {
             $template_id = ameMenuItem::template_id($topmenu);
             //Is this menu present in the default WP menu?
             if (isset($this->item_templates[$template_id])) {
                 //Yes, load defaults from that item
                 $topmenu['defaults'] = $this->item_templates[$template_id]['defaults'];
                 //Note that the original item was used
                 $this->item_templates[$template_id]['used'] = true;
             } else {
                 //Record the menu as missing, unless it's a menu separator
                 if (empty($topmenu['separator'])) {
                     $topmenu['missing'] = true;
                     $temp = ameMenuItem::apply_defaults($topmenu);
                     $temp['access_level'] = $this->get_menu_capability($temp);
                     $this->add_access_lookup($temp, 'menu', true);
                 }
             }
         }
         if (is_array($topmenu['items'])) {
             //Iterate over submenu items
             foreach ($topmenu['items'] as &$item) {
                 if (!ameMenuItem::get($item, 'custom')) {
                     $template_id = ameMenuItem::template_id($item);
                     //Is this item present in the default WP menu?
                     if (isset($this->item_templates[$template_id])) {
                         //Yes, load defaults from that item
                         $item['defaults'] = $this->item_templates[$template_id]['defaults'];
                         $this->item_templates[$template_id]['used'] = true;
                     } else {
                         if (empty($item['separator'])) {
                             //Record as missing, unless it's a menu separator
                             $item['missing'] = true;
                             $temp = ameMenuItem::apply_defaults($item);
                             $temp['access_level'] = $this->get_menu_capability($temp);
                             $this->add_access_lookup($temp, 'submenu', true);
                         }
                     }
                 }
             }
         }
     }
     //If we don't unset these they will f**k up the next two loops where the same names are used.
     unset($topmenu);
     unset($item);
     //Now we have some items marked as missing, and some items in lookup arrays
     //that are not marked as used. Lets remove the missing items from the tree.
     $filteredTree = array();
     foreach ($tree as $file => $topmenu) {
         if ($topmenu['missing']) {
             continue;
         }
         $filteredSubmenu = array();
         if (is_array($topmenu['items'])) {
             foreach ($topmenu['items'] as $index => $item) {
                 if (!$item['missing']) {
                     $filteredSubmenu[$index] = $item;
                 }
             }
         }
         $topmenu['items'] = $filteredSubmenu;
         $filteredTree[$file] = $topmenu;
     }
     $tree = $filteredTree;
     //Lets merge in the unused items.
     foreach ($this->item_templates as $template_id => $template) {
         //Skip used menus and separators
         if (!empty($template['used']) || !empty($template['defaults']['separator'])) {
             continue;
         }
         //Found an unused item. Build the tree entry.
         $entry = ameMenuItem::blank_menu();
         $entry['template_id'] = $template_id;
         $entry['defaults'] = $template['defaults'];
         $entry['unused'] = true;
         //Note that this item is unused
         //Add the new entry to the menu tree
         if (!empty($template['defaults']['parent'])) {
             if (isset($tree[$template['defaults']['parent']])) {
                 //Okay, insert the item.
                 $tree[$template['defaults']['parent']]['items'][] = $entry;
             } else {
                 //This can happen if the original parent menu has been moved to a submenu.
                 //Todo: Handle this unusual situation.
             }
         } else {
             $tree[$template['defaults']['file']] = $entry;
         }
     }
     //Resort the tree to ensure the found items are in the right spots
     $tree = ameMenu::sort_menu_tree($tree);
     return $tree;
 }