Index: wp-includes/functions.php
===================================================================
RCS file: /cvsroot/cafelog/wordpress/wp-includes/functions.php,v
retrieving revision 1.270
diff -u -r1.270 functions.php
--- wp-includes/functions.php	19 Feb 2005 20:53:04 -0000	1.270
+++ wp-includes/functions.php	20 Feb 2005 17:01:12 -0000
@@ -875,95 +875,131 @@
 
 	merge_filters($tag);
 	
-	if (isset($wp_filter[$tag])) {
-		foreach ($wp_filter[$tag] as $priority => $functions) {
-			if (!is_null($functions)) {
-				foreach($functions as $function) {
-					$accepted_args = 1;
-					$all_args = array_merge(array($string), $args);
-
-					if (!is_array($function)) {
-						$args_marker = strrpos($function, ':');
-						if ($args_marker > 0) {
-							$accepted_args = intval(substr($function, $args_marker+1));
-							$function = substr($function, 0, $args_marker);
-						}
-					} else {
-						$args_marker = strrpos($function[1], ':');
-						if ($args_marker > 0) {
-							$accepted_args = intval(substr($function[1], $args_marker+1));
-							$function[1] = substr($function[1], 0, $args_marker);
-						}
-					}
-
-					if ($accepted_args > 0) {
-						$args = array_slice($all_args, 0, $accepted_args);
-					} elseif($accepted_args == 0) {
-						$args = NULL;
-					} else {
-						$args = $all_args;
-					}
-
-					$string = call_user_func_array($function, $args);
+	if (!isset($wp_filter[$tag])) {
+		return $string;
+	}
+	foreach ($wp_filter[$tag] as $priority => $functions) {
+		if (!is_null($functions)) {
+			foreach($functions as $function) {
+
+				$all_args = array_merge(array($string), $args);
+				$function_name = $function['function'];
+				$accepted_args = $function['accepted_args'];
+
+				if ($accepted_args > 0) {
+					$args = array_slice($all_args, 0, $accepted_args);
+				} elseif($accepted_args == 0) {
+					$args = NULL;
+				} else {
+					$args = $all_args;
 				}
+
+				$string = call_user_func_array($function_name, $args);
 			}
 		}
 	}
 	return $string;
 }
 
-function add_filter($tag, $function_to_add, $priority = 10) {
+function add_filter($tag, $function, $priority = 10, $accepted_args = 1) {
 	global $wp_filter;
-	// So the format is wp_filter['tag']['array of priorities']['array of functions']
-	if (!@in_array($function_to_add, $wp_filter[$tag]["$priority"])) {
-		$wp_filter[$tag]["$priority"][] = $function_to_add;
+
+	list($function, $accepted_args) = _parse_incoming_filter($function, $accepted_args);
+
+	// check that we don't already have the same filter at the same priority
+	if (isset($wp_filter[$tag]["$priority"])) {
+		foreach($wp_filter[$tag]["$priority"] as $filter) {
+			// uncomment if we want to match function AND accepted_args
+			//if ($filter == array($function, $accepted_args)) {
+			if ($filter['function'] == $function) {
+				return true;
+			}
+		}
 	}
+
+	// So the format is wp_filter['tag']['array of priorities']['array of ['array (functions, accepted_args)]']
+	$wp_filter[$tag]["$priority"][] = array('function'=>$function, 'accepted_args'=>$accepted_args);
 	return true;
 }
 
-function remove_filter($tag, $function_to_remove, $priority = 10) {
+function remove_filter($tag, $function, $priority = 10, $accepted_args = 1) {
 	global $wp_filter;
-	if (@in_array($function_to_remove, $wp_filter[$tag]["$priority"])) {
-		foreach ($wp_filter[$tag]["$priority"] as $function) {
-			if ($function_to_remove != $function) {
+
+	list($function, $accepted_args) = _parse_incoming_filter($function, $accepted_args);
+
+	// rebuild the list of filters
+	if (isset($wp_filter[$tag]["$priority"])) {
+		foreach($wp_filter[$tag]["$priority"] as $filter) {
+			if ($filter['function'] != $function) {
 				$new_function_list[] = $function;
 			}
 		}
 		$wp_filter[$tag]["$priority"] = $new_function_list;
 	}
-	//die(var_dump($wp_filter));
 	return true;
 }
 
+function _parse_incoming_filter($function, $accepted_args) {
+	// parse for the presence of :X in $function, where X is $accepted_args
+	if (!is_array($function)) {
+		$args_marker = strrpos($function, ':');
+		if ($args_marker > 0) {
+			$accepted_args = intval(substr($function, $args_marker+1));
+			$function = substr($function, 0, $args_marker);
+		}
+	} else {
+		$args_marker = strrpos($function[1], ':');
+		if ($args_marker > 0) {
+			$accepted_args = intval(substr($function[1], $args_marker+1));
+			$function[1] = substr($function[1], 0, $args_marker);
+		}
+	}
+	return array($function, $accepted_args);
+}
+
 // The *_action functions are just aliases for the *_filter functions, they take special strings instead of generic content
 
 function do_action($tag, $arg = '') {
 	global $wp_filter;
-
+	$extra_args = array_slice(func_get_args(), 2);
 	if ( is_array($arg) )
-		$args = $arg + array_slice(func_get_args(), 2);
+		$args = array_merge($arg, $extra_args);
 	else
-		$args = array($arg) + array_slice(func_get_args(), 2);
+		$args = array_merge(array($arg), $extra_args);
 	
 	merge_filters($tag);
 	
-	if (isset($wp_filter[$tag])) {
-		foreach ($wp_filter[$tag] as $priority => $functions) {
-			if (!is_null($functions)) {
-				foreach($functions as $function) {
-					$string = call_user_func_array($function, $args);
+	if (!isset($wp_filter[$tag])) {
+		return;
+	}
+	foreach ($wp_filter[$tag] as $priority => $functions) {
+		if (!is_null($functions)) {
+			foreach($functions as $function) {
+
+				$all_args = array_merge(array($string), $args);
+				$function_name = $function['function'];
+				$accepted_args = $function['accepted_args'];
+
+				if ($accepted_args > 0) {
+					$args = array_slice($all_args, 0, $accepted_args);
+				} elseif($accepted_args == 0) {
+					$args = NULL;
+				} else {
+					$args = $all_args;
 				}
+
+				$string = call_user_func_array($function_name, $args);
 			}
 		}
 	}
 }
 
-function add_action($tag, $function_to_add, $priority = 10) {
-	add_filter($tag, $function_to_add, $priority);
+function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
+	add_filter($tag, $function_to_add, $priority, $accepted_args);
 }
 
-function remove_action($tag, $function_to_remove, $priority = 10) {
-	remove_filter($tag, $function_to_remove, $priority);
+function remove_action($tag, $function_to_remove, $priority = 10, $accepted_args = 1) {
+	remove_filter($tag, $function_to_remove, $priority, $accepted_args);
 }
 
 function get_page_uri($page_id) {

