/**
  * Create a unique name for a specific field of a specific menu item.
  * Intended for use with the icl_register_string() function.
  *
  * @param array $item Admin menu item in the internal format.
  * @param string $field Field name.
  * @return string
  */
 private function get_wpml_name_for($item, $field = '')
 {
     $name = ameMenuItem::get($item, 'template_id');
     if (empty($name)) {
         $name = 'custom: ' . ameMenuItem::get($item, 'file');
     }
     if (!empty($field)) {
         $name = $name . '[' . $field . ']';
     }
     return $name;
 }
Beispiel #2
0
 /**
  * Generate CSS rules for menu items that have user-defined colors.
  *
  * This method stores the CSS at the "color_css" key in the menu structure and returns a modified menu.
  * By storing the color scheme CSS in the menu itself we avoid having to regenerate it on every page load.
  * We also don't have to worry about cache lifetime - when the menu is modified the old CSS will be
  * overwritten automatically.
  *
  * @param array $custom_menu Admin menu in the internal format.
  * @return array Modified menu.
  */
 public function add_menu_color_css($custom_menu)
 {
     if (empty($custom_menu) || !is_array($custom_menu) || !isset($custom_menu['tree'])) {
         return $custom_menu;
     }
     if (!class_exists('ameMenuColorGenerator')) {
         require_once dirname(__FILE__) . '/extras/menu-color-generator.php';
     }
     $generator = new ameMenuColorGenerator();
     $css = array();
     $used_ids = array();
     $colorized_menu_count = 0;
     foreach ($custom_menu['tree'] as &$item) {
         if (!isset($item['colors']) || empty($item['colors'])) {
             continue;
         }
         $colorized_menu_count++;
         //Each item needs to have a unique ID so we can target it in CSS. Using a class would be cleaner,
         //but the selectors wouldn't have enough specificity to override WP defaults.
         $id = ameMenuItem::get($item, 'hookname');
         if (empty($id) || isset($used_ids[$id])) {
             $id = (empty($id) ? 'ame-colorized-item' : $id) . '-';
             $id .= $colorized_menu_count . '-t' . time();
             $item['hookname'] = $id;
         }
         $used_ids[$id] = true;
         $item_css = $generator->getCss($id, $item['colors']);
         if (!empty($item_css)) {
             $css[] = sprintf('/* %1$s (%2$s) */', str_replace('*/', ' ', ameMenuItem::get($item, 'menu_title', 'Untitled menu')), str_replace('*/', ' ', ameMenuItem::get($item, 'file', '(no URL)')));
             $css[] = $item_css;
         }
     }
     if (!empty($css)) {
         $css = implode("\n", $css);
         $custom_menu['color_css'] = $css;
         $custom_menu['color_css_modified'] = time();
     } else {
         $custom_menu['color_css'] = '';
         $custom_menu['color_css_modified'] = 0;
     }
     return $custom_menu;
 }
 /**
  * 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;
 }
Beispiel #4
0
 /**
  * Compress menu configuration (lossless).
  *
  * Reduces data size by storing commonly used properties and defaults in one place
  * instead of in every menu item.
  *
  * @param array $menu
  * @return array
  */
 public static function compress($menu)
 {
     $property_dict = ameMenuItem::blank_menu();
     unset($property_dict['defaults']);
     $common = array('properties' => $property_dict, 'basic_defaults' => ameMenuItem::basic_defaults(), 'custom_item_defaults' => ameMenuItem::custom_item_defaults());
     $menu['tree'] = self::map_items($menu['tree'], array(__CLASS__, 'compress_item'), array($common));
     $menu = self::add_format_header($menu);
     $menu['format']['compressed'] = true;
     $menu['format']['common'] = $common;
     return $menu;
 }
Beispiel #5
0
 /**
  * Check if a menu contains any items with the "hidden" flag set to true.
  *
  * @param array $menu
  * @return bool
  */
 public static function has_hidden_items($menu)
 {
     if (!is_array($menu) || empty($menu) || empty($menu['tree'])) {
         return false;
     }
     foreach ($menu['tree'] as $item) {
         if (ameMenuItem::get($item, 'hidden')) {
             return true;
         }
         if (!empty($item['items'])) {
             foreach ($item['items'] as $child) {
                 if (ameMenuItem::get($child, 'hidden')) {
                     return true;
                 }
             }
         }
     }
     return false;
 }
 private function get_virtual_caps_for($item)
 {
     $caps = array();
     if ($item['template_id'] !== '') {
         $required_cap = ameMenuItem::get($item, 'access_level');
         foreach ($item['grant_access'] as $grant => $has_access) {
             if ($has_access) {
                 if (!isset($caps[$grant])) {
                     $caps[$grant] = array();
                 }
                 $caps[$grant][$required_cap] = true;
             }
         }
     }
     foreach ($item['items'] as $sub_item) {
         $caps = array_merge_recursive($caps, $this->get_virtual_caps_for($sub_item));
     }
     return $caps;
 }
Beispiel #7
0
 /**
  * Flag menus (and menu items) that are set to open in a new window
  * so that they can be identified later. 
  * 
  * Adds a <span class="ws-new-window-please"></span> element to the title
  * of each detected menu.  
  * 
  * @param array $item
  * @return array
  */
 function flag_new_window_menus($item)
 {
     $open_in = ameMenuItem::get($item, 'open_in', 'same_window');
     if ($open_in == 'new_window') {
         $old_title = ameMenuItem::get($item, 'menu_title', '');
         $item['menu_title'] = $old_title . '<span class="ws-new-window-please" style="display:none;"></span>';
         //For compatibility with Ozh's Admin Drop Down menu, record the link ID that will be
         //assigned to this item. This lets us modify it later.
         if (function_exists('wp_ozh_adminmenu_sanitize_id')) {
             $subid = 'oamsub_' . wp_ozh_adminmenu_sanitize_id(ameMenuItem::get($item, 'file', ''));
             $this->ozhs_new_window_menus[] = '#' . str_replace(array(':', '&'), array('\\\\:', '\\\\&'), $subid);
         }
     }
     return $item;
 }
 /**
  * Convert internal menu representation to the form used by WP.
  * 
  * Note : While this function doesn't cause any side effects of its own, 
  * it executes several filters that may modify global state. Specifically,
  * IFrame-handling callbacks in 'extras.php' may insert items into the 
  * global $menu and $submenu arrays.
  *
  * @param array $tree
  * @return array $menu and $submenu
  */
 function tree2wp($tree)
 {
     $menu = array();
     $submenu = array();
     $title_lookup = array();
     //Sort the menu by position
     uasort($tree, array(&$this, 'compare_position'));
     //Prepare the top menu
     $first_nonseparator_found = false;
     foreach ($tree as $topmenu) {
         //Skip missing menus, unless they're user-created and thus might point to a non-standard file
         $custom = $this->get_menu_field($topmenu, 'custom', false);
         if (!empty($topmenu['missing']) && !$custom) {
             continue;
         }
         //Skip leading menu separators. Fixes a superfluous separator showing up
         //in WP 3.0 (multisite mode) when there's a custom menu and the current user
         //can't access its first item ("Super Admin").
         if (!empty($topmenu['separator']) && !$first_nonseparator_found) {
             continue;
         }
         $first_nonseparator_found = true;
         //Menus that have both a custom icon URL and a "menu-icon-*" class will get two overlapping icons.
         //Fix this by automatically removing the class. The user can set a custom class attr. to override.
         if (ameMenuItem::is_default($topmenu, 'css_class') && !ameMenuItem::is_default($topmenu, 'icon_url') && !in_array($topmenu['icon_url'], array('', 'none', 'div'))) {
             $new_classes = preg_replace('@\\bmenu-icon-[^\\s]+\\b@', '', $topmenu['defaults']['css_class']);
             if ($new_classes !== $topmenu['defaults']['css_class']) {
                 $topmenu['css_class'] = $new_classes;
             }
         }
         //Apply defaults & filters
         $topmenu = $this->apply_defaults($topmenu);
         $topmenu = $this->apply_menu_filters($topmenu, 'menu');
         //Skip hidden entries
         if (!empty($topmenu['hidden'])) {
             continue;
         }
         //Build the menu structure that WP expects
         $menu[] = array($topmenu['menu_title'], $topmenu['access_level'], $topmenu['file'], $topmenu['page_title'], $topmenu['css_class'], $topmenu['hookname'], $topmenu['icon_url']);
         //Prepare the submenu of this menu
         if (!empty($topmenu['items'])) {
             $items = $topmenu['items'];
             //Sort by position
             uasort($items, array(&$this, 'compare_position'));
             foreach ($items as $item) {
                 //Skip missing items, unless they're user-created
                 $custom = $this->get_menu_field($item, 'custom', false);
                 if (!empty($item['missing']) && !$custom) {
                     continue;
                 }
                 //Special case : plugin pages that have been moved to a different menu.
                 //If the file field hasn't already been modified, we'll need to adjust it
                 //to point to the old parent. This is required because WP identifies
                 //plugin pages using *both* the plugin file and the parent file.
                 if ($this->get_menu_field($item, 'is_plugin_page', false) && $item['file'] === null) {
                     $default_parent = '';
                     if (isset($item['defaults']) && isset($item['defaults']['parent'])) {
                         $default_parent = $item['defaults']['parent'];
                     }
                     if ($topmenu['file'] != $default_parent) {
                         $item['file'] = $default_parent . '?page=' . $item['defaults']['file'];
                     }
                 }
                 $item = $this->apply_defaults($item);
                 $item = $this->apply_menu_filters($item, 'submenu', $topmenu['file']);
                 //Skip hidden items
                 if (!empty($item['hidden'])) {
                     continue;
                 }
                 $submenu[$topmenu['file']][] = array($item['menu_title'], $item['access_level'], $item['file'], $item['page_title']);
                 //Make a note of the page's correct title so we can fix it later
                 //if necessary.
                 $title_lookup[$item['file']] = $item['menu_title'];
             }
         }
     }
     return array($menu, $submenu, $title_lookup);
 }
Beispiel #9
0
 /**
  * Convert the WP menu structure to the internal representation. All properties set as defaults.
  *
  * @param array $menu
  * @param array $submenu
  * @return array Menu in the internal tree format.
  */
 public static function wp2tree($menu, $submenu)
 {
     $tree = array();
     foreach ($menu as $pos => $item) {
         $tree_item = ameMenuItem::blank_menu();
         $tree_item['defaults'] = ameMenuItem::fromWpItem($item, $pos);
         $tree_item['separator'] = $tree_item['defaults']['separator'];
         //Attach sub-menu items
         $parent = $tree_item['defaults']['file'];
         if (isset($submenu[$parent])) {
             foreach ($submenu[$parent] as $position => $subitem) {
                 $tree_item['items'][$subitem[2]] = array_merge(ameMenuItem::blank_menu(), array('defaults' => ameMenuItem::fromWpItem($subitem, $position, $parent)));
             }
         }
         $tree[$parent] = $tree_item;
     }
     $tree = self::sort_menu_tree($tree);
     return $tree;
 }