From a3739de86fd13ece8045bf2d09d512777f2736f0 Mon Sep 17 00:00:00 2001
From: Ameen Ross <info@amdev.eu>
Date: Fri, 27 Apr 2012 17:26:02 +0200
Subject: [PATCH] Fix compatibility with modules like superfish.

---
 special_menu_items.module |  118 +++++++++++++++++++++-----------------------
 1 files changed, 56 insertions(+), 62 deletions(-)

diff --git a/special_menu_items.module b/special_menu_items.module
index 2c9363f..1bb129b 100644
--- a/special_menu_items.module
+++ b/special_menu_items.module
@@ -1,14 +1,14 @@
-<?php 
+<?php
 
 /**
  * @file
- *  Module to enable placeholder or separator menu items.Placeholder is a menu item which is 
- *  actually not a link. Something like this is useful with drop down menus where we want to 
- *  have a parent link which is actually not linking to a page but which is just acting as a 
+ *  Module to enable placeholder or separator menu items.Placeholder is a menu item which is
+ *  actually not a link. Something like this is useful with drop down menus where we want to
+ *  have a parent link which is actually not linking to a page but which is just acting as a
  *  parent and grouping some children below it.
- *  A separator menu item is something like "-------" which is also not linking anywhere but 
+ *  A separator menu item is something like "-------" which is also not linking anywhere but
  *  merely a mean to structure menus.
- * 
+ *
  *  Written by Tamir Al Zoubi and Karim Djelid - Servit Open Source Solutions - www.servit.ch
  */
 
@@ -18,16 +18,16 @@
 function special_menu_items_menu() {
   $items['<nolink>'] = array(
     'page callback' => 'drupal_not_found',
-    'access callback' => TRUE, 
+    'access callback' => TRUE,
     'type' => MENU_CALLBACK,
   );
-  
+
   $items['<separator>'] = array(
     'page callback' => 'drupal_not_found',
     'access callback' => TRUE,
     'type' => MENU_CALLBACK,
   );
-  
+
   $items['admin/config/system/special_menu_items'] = array(
     'title' => 'Special Menu Items',
     'description' => 'Configure Special Menu Items.',
@@ -36,63 +36,55 @@ function special_menu_items_menu() {
     'access arguments' => array('administer site configuration'),
     'type' => MENU_NORMAL_ITEM,
   );
-  
+
  return $items;
 }
 
 /**
- * Override of theme_menu_item_link()
- * This function will render link if it is "nolink" or "separator". Otherwise it will call originally 
- * overwriten menu_item_link function. 
+ * Override of theme_link()
+ * This function will render link if it is "nolink" or "separator". Otherwise it will call originally
+ * overwriten theme_link function.
  */
-
-function special_menu_items_menu_link(array $variables) {
-  // Find special menu link
-  if (in_array($variables['element']['#href'], array('<nolink>', '<separator>'))) {
-    $element = $variables['element'];
-    $sub_menu = '';
-    
-    if ($element['#below']) {
-      $sub_menu = drupal_render($element['#below']);
-    }
-    
-    switch ($element['#href']) {
+function special_menu_items_link($variables) {
+  if ($variables['path'] == '<nolink>' || $variables['path'] == '<separator>') {
+    switch ($variables['path']) {
       case '<nolink>':
         $tag = variable_get('special_menu_items_nolink_tag', '<span>');
-        $title = strip_tags(l($element['#title'], $element['#href'], $element['#localized_options']));
-        $output = special_menu_items_render_menu_item($tag, $title);
-        $element['#attributes']['class'][] = 'nolink';
-        break;
-        
+        $title = ($variables['options']['html'] ? $variables['text'] : check_plain($variables['text']));
+        $attributes = drupal_attributes($variables['options']['attributes']);
+        // <a> tags can have these but a <span> cannot, so we remove them.
+        $attributes = preg_replace('/ accesskey=".*?"/i', "", $attributes);
+        $attributes = preg_replace('/ target=".*?"/i', "", $attributes);
+        $attributes = preg_replace('/ rel=".*?"/i', "", $attributes);
+        $attributes = preg_replace('/ name=".*?"/i', "", $attributes);
+
+        $output = special_menu_items_render_menu_item($tag, $title, $attributes);
+      break;
       case '<separator>':
         $output = variable_get('special_menu_items_separator_value', '<hr>');
-        $element['#attributes']['class'][] = 'separator';
-
-        break;
+      break;
     }
-    
-    return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
+    return $output;
   }
   // Call the original theme function for normal menu link.
-  return theme('menu_link_default',$variables);
+  return theme('link_default', $variables);
 }
 
-
 /**
  * Returns menu item rendered.
  */
-function special_menu_items_render_menu_item($tag, $value, $css = NULL) {
+function special_menu_items_render_menu_item($tag, $value, $attributes = NULL) {
   $length = strlen($tag);
-   
+
   //Validate the tags
   if ($tag[0] == '<' && $tag[$length - 1] == '>') {
     $closingtag = str_replace('<', '</', $tag);
-    if ($css) {
-      $tag = str_replace('>', ' class="' . $css . '">', $tag);        
-    } 
+    if ($attributes) {
+      $tag = str_replace('>', $attributes . '>', $tag);
+    }
   } else {
-    if ($css) {       
-      $classtag = '<' . $tag . ' class="' . $css . '">';
+    if ($attributes) {
+      $classtag = '<' . $tag . $attributes . '>';
       $tag = '<' . $tag . '>';
       $closingtag = str_replace('<', '</', $tag);
       $tag = $classtag;
@@ -100,7 +92,7 @@ function special_menu_items_render_menu_item($tag, $value, $css = NULL) {
       $tag = '<' . $tag . '>';
       $closingtag = str_replace('<', '</', $tag);
     }
-  }  
+  }
 
   return $tag . $value . $closingtag;
 }
@@ -125,7 +117,6 @@ function special_menu_items_preprocess_page(&$vars, $hook) {
           case '<separator>':
             $vars[$menu][$key]['title'] = variable_get('special_menu_items_separator_value', '<hr>');
             $vars[$menu][$key]['attributes']['class'][] = 'separator';
-
             break;
         }
         //render in HTML
@@ -145,8 +136,8 @@ function special_menu_items_preprocess_page(&$vars, $hook) {
  */
 function special_menu_items_theme_registry_alter(&$registry) {
   // Save previous value from registry in case another theme overwrites menu_item_link
-  $registry['menu_link_default'] = $registry['menu_link'];
-  $registry['menu_link']['function'] = 'special_menu_items_menu_link';
+  $registry['link_default'] = $registry['link'];
+  $registry['link']['function'] = 'special_menu_items_link';
 }
 
 /**
@@ -154,16 +145,19 @@ function special_menu_items_theme_registry_alter(&$registry) {
  * Description changed, added nolink and separator as path types.
  */
 function special_menu_items_form_menu_edit_item_alter(&$form, &$form_state) {
-  $default_value = $form['link_path']['#default_value'];
+  // Some menu items have a pre-defined path which cannot be modified hence no default_value
+  if (isset($form['link_path']['#default_value'])) {
+    $default_value = $form['link_path']['#default_value'];
+
+    if (preg_match('/^<nolink>\/[0-9]+$/', $default_value)) {
+      $default_value = '<nolink>';
+    } elseif (preg_match('/^<separator>\/[0-9]+$/', $default_value)) {
+      $default_value = '<separator>';
+    }
 
-  if (preg_match('/^<nolink>\/[0-9]+$/', $default_value)) {
-    $default_value = '<nolink>';
-  } elseif (preg_match('/^<separator>\/[0-9]+$/', $default_value)) {
-    $default_value = '<separator>';
+    $form['link_path']['#default_value'] = $default_value;
+    $form['link_path']['#description'] .=  ' ' . t('Enter "%nolink" to generate non-linkable item, enter "%separator" to generate separator item.', array('%nolink' => '<nolink>', '%separator' => '<separator>'));
   }
-
-  $form['link_path']['#default_value'] = $default_value;
-  $form['link_path']['#description'] .=  ' ' . t('Enter "%nolink" to generate non-linkable item, enter "%separator" to generate separator item.', array('%nolink' => '<nolink>', '%separator' => '<separator>')); 
 }
 
 /**
@@ -177,10 +171,10 @@ function special_menu_items_init() {
     if (strlen(strstr($crumb,'<nolink>')) > 0) {
       $crumb = strip_tags($crumb);
       $tag = variable_get('special_menu_items_nolink_tag', '<span>');
-      $breadcrumb[$key] = special_menu_items_render_menu_item($tag, $crumb);      
+      $breadcrumb[$key] = special_menu_items_render_menu_item($tag, $crumb);
     }
   }
-  
+
   drupal_set_breadcrumb($breadcrumb);
 }
 
@@ -190,14 +184,14 @@ function special_menu_items_init() {
  * @return
  * The settings form used by Special Menu Items.
  */
-function special_menu_items_admin_settings_form() { 
+function special_menu_items_admin_settings_form() {
   $form['special_menu_items_nolink_tag'] = array(
     '#type' => 'textfield',
     '#title' => t('HTML tag for "nolink"'),
     '#description' => t('By default, Special Menu Items will use a span tag for the nolink menu item. Here you can specify your own tag.'),
     '#default_value' => variable_get('special_menu_items_nolink_tag', '<span>'),
   );
-  
+
   $form['special_menu_items_separator_tag'] = array(
     '#type' => 'textfield',
     '#title' => t('HTML tag for "separator"'),
@@ -223,7 +217,7 @@ function special_menu_items_admin_settings_form() {
 /*
 function special_menu_items_menu_link_update($link) {
     //do all links in db
-    global $db_type;  
+    global $db_type;
     if ($db_type == 'pgsql') {
      db_query("UPDATE {menu_links} SET link_path=link_path||'/'||mlid WHERE (link_path='<nolink>' OR link_path='<separator>') AND hidden != -1");
     }
@@ -231,5 +225,5 @@ function special_menu_items_menu_link_update($link) {
      db_query("UPDATE {menu_links} SET link_path=CONCAT(CONCAT(link_path,'/'),mlid) WHERE (link_path='<nolink>' OR link_path='<separator>') AND hidden!=-1");
     }
 }
- * 
+ *
  */
\ No newline at end of file
-- 
1.7.7.GIT

