Browse Source

Merge pull request #1494 from MissAllSunday/hooking_goodies

Hooking goodies
Jessica González 10 years ago
parent
commit
cc91318f4f
4 changed files with 151 additions and 60 deletions
  1. 13 1
      Sources/Admin.php
  2. 12 0
      Sources/Profile.php
  3. 84 57
      Sources/Subs.php
  4. 42 2
      index.php

+ 13 - 1
Sources/Admin.php

@@ -24,7 +24,8 @@ if (!defined('SMF'))
  */
 function AdminMain()
 {
-	global $txt, $context, $scripturl, $modSettings, $settings, $sourcedir, $options, $boarddir;
+	global $txt, $context, $scripturl, $modSettings, $settings;
+	global $sourcedir, $options, $boarddir, $db_show_debug;
 
 	// Load the language and templates....
 	loadLanguage('Admin');
@@ -489,8 +490,19 @@ function AdminMain()
 	{
 		// Is there an instance already? nope? then create it!
 		if (empty($context['instances'][$admin_include_data['class']]) || !($context['instances'][$admin_include_data['class']] instanceof $admin_include_data['class']))
+		{
 			$context['instances'][$admin_include_data['class']] = new $admin_include_data['class'];
 
+			// Add another one to the list.
+			if ($db_show_debug === true)
+			{
+				if (!isset($context['debug']['instances']))
+					$context['debug']['instances'] = array();
+
+				$context['debug']['instances'][$admin_include_data['class']] = $admin_include_data['class'];
+			}
+		}
+
 		$call = array($context['instances'][$admin_include_data['class']], $admin_include_data['function']);
 	}
 

+ 12 - 0
Sources/Profile.php

@@ -27,6 +27,7 @@ function ModifyProfile($post_errors = array())
 {
 	global $txt, $scripturl, $user_info, $context, $sourcedir, $user_profile, $cur_profile;
 	global $modSettings, $memberContext, $profile_vars, $post_errors, $user_settings;
+	global $db_show_debug;
 
 	// Don't reload this as we may have processed error strings.
 	if (empty($post_errors))
@@ -728,8 +729,19 @@ function ModifyProfile($post_errors = array())
 	{
 		// Is there an instance already? nope? then create it!
 		if (empty($context['instances'][$profile_include_data['class']]) || !($context['instances'][$profile_include_data['class']] instanceof $profile_include_data['class']))
+		{
 			$context['instances'][$profile_include_data['class']] = new $profile_include_data['class'];
 
+			// Add another one to the list.
+			if ($db_show_debug === true)
+			{
+				if (!isset($context['debug']['instances']))
+					$context['debug']['instances'] = array();
+
+				$context['debug']['instances'][$profile_include_data['class']] = $profile_include_data['class'];
+			}
+		}
+
 		$call = array($context['instances'][$profile_include_data['class']], $profile_include_data['function']);
 	}
 

+ 84 - 57
Sources/Subs.php

@@ -3991,7 +3991,7 @@ function setupMenuContext()
 	{
 		$context['menu_buttons']['moderate']['title'] .= ' <span class="amt">' . $total_mod_reports . '</span>';
 	}
-	
+
 }
 
 /**
@@ -4017,8 +4017,8 @@ function smf_seed_generator()
  * calls all functions of the given hook.
  * supports static class method calls.
  *
- * @param string $hook
- * @param array $parameters = array()
+ * @param string $hook The hook name
+ * @param array $parameters An array of parameters this hook implements
  * @return array the results of the functions
  */
 function call_integration_hook($hook, $parameters = array())
@@ -4042,84 +4042,56 @@ function call_integration_hook($hook, $parameters = array())
 	foreach ($functions as $function)
 	{
 		$function = trim($function);
+		$call = '';
 
-		// Found a call to a method.
-		if (strpos($function, '::') !== false)
+		// Do we found a file to load?
+		if (strpos($function, '|') !== false)
 		{
-			$call = explode('::', $function);
+			list($file, $func) = explode('|', $function);
 
-			// Get the file and the class::method.
-			if (strpos($call[1], ':') !== false)
-			{
-				list($func, $file) = explode(':', $call[1]);
+			// Match the wildcards to their regular vars.
+			if (empty($settings['theme_dir']))
+				$absPath = strtr(trim($file), array('$boarddir' => $boarddir, '$sourcedir' => $sourcedir));
 
-				// Need to temp delete the #
-				if (strpos($file, '#') !== false)
-					$file = str_replace('#', '', $file);
+			else
+				$absPath = strtr(trim($file), array('$boarddir' => $boarddir, '$sourcedir' => $sourcedir, '$themedir' => $settings['theme_dir']));
 
-				// Match the wildcards to their regular vars.
-				if (empty($settings['theme_dir']))
-					$absPath = strtr(trim($file), array('$boarddir' => $boarddir, '$sourcedir' => $sourcedir));
-				else
-					$absPath = strtr(trim($file), array('$boarddir' => $boarddir, '$sourcedir' => $sourcedir, '$themedir' => $settings['theme_dir']));
+			// Load the file if it can be loaded.
+			if (file_exists($absPath))
+				require_once($absPath);
+
+			// No? try a fallback to $sourcedir
+			else
+			{
+				$absPath = $sourcedir .'/'. $file;
 
-				// Load the file if it can be loaded.
 				if (file_exists($absPath))
 					require_once($absPath);
 
-				// No? tell the admin about it.
+				// Sorry, can't do much for you at this point.
 				else
 				{
 					loadLanguage('Errors');
 					log_error(sprintf($txt['hook_fail_loading_file'], $absPath), 'general');
 				}
-
-				// Check if a new object will be created.
-				if (strpos($call[1], '#') !== false)
-				{
-					// Don't need to create a new instance for every method.
-					if (empty($context['instances'][$call[0]]) || !($context['instances'][$call[0]] instanceof $call[0]))
-					{
-						$context['instances'][$call[0]] = new $call[0];
-
-						// Add another one to the list.
-						if ($db_show_debug === true)
-							$context['debug']['instances'][$call[0]] = $hook;
-					}
-
-					$call = array($context['instances'][$call[0]], $func);
-				}
-
-				// Right then, this is a call to a static method.
-				else
-					$call = array($call[0], $func);
 			}
+
+			$call = call_hook_helper($func);
 		}
+
+		// Figuring out what to do.
 		else
-		{
-			$call = $function;
-			if (strpos($function, ':') !== false)
-			{
-				list($func, $file) = explode(':', $function);
-				if (empty($settings['theme_dir']))
-					$absPath = strtr(trim($file), array('$boarddir' => $boarddir, '$sourcedir' => $sourcedir));
-				else
-					$absPath = strtr(trim($file), array('$boarddir' => $boarddir, '$sourcedir' => $sourcedir, '$themedir' => $settings['theme_dir']));
-				if (file_exists($absPath))
-					require_once($absPath);
-				$call = $func;
-			}
-		}
+			$call = call_hook_helper($function);
 
 		// Is it valid?
-		if (is_callable($call))
+		if (!empty($call) && is_callable($call))
 			$results[$function] = call_user_func_array($call, $parameters);
 
 		// Whatever it was suppose to call, it failed :(
-		elseif (!empty($func) && !empty($absPath))
+		elseif (!empty($function) && !empty($absPath))
 		{
 			loadLanguage('Errors');
-			log_error(sprintf($txt['hook_fail_call_to'], $func, $absPath), 'general');
+			log_error(sprintf($txt['hook_fail_call_to'], $function, $absPath), 'general');
 		}
 	}
 
@@ -4227,6 +4199,61 @@ function remove_integration_function($hook, $function, $file = '', $object = fal
 	$modSettings[$hook] = implode(',', $functions);
 }
 
+/**
+ * Receives a string and tries to figure it out if its a method or a function.
+ * If a method is found, it looks for a "#" which indicates SMF should create a new instance of the given class.
+ * Prepare and returns a callable depending on the type of method/function found.
+ *
+ * @param string $string The string containing a function name
+ * @return string|array Either a string or an array that contains a callable function name or an array with a class and method to call
+ */
+function call_hook_helper($string)
+{
+	global $context, $db_show_debug;
+
+	// Really?
+	if (empty($string))
+		return false;
+
+	// Found a method.
+	if (strpos($string, '::') !== false)
+	{
+		list($class, $method) = explode('::', $string);
+
+		// Check if a new object will be created.
+		if (strpos($method, '#') !== false)
+		{
+			// Need to remove the # thing.
+			$method = str_replace('#', '', $method);
+
+			// Don't need to create a new instance for every method.
+			if (empty($context['instances'][$class]) || !($context['instances'][$class] instanceof $class))
+			{
+				$context['instances'][$class] = new $class;
+
+				// Add another one to the list.
+				if ($db_show_debug === true)
+				{
+					if (!isset($context['debug']['instances']))
+						$context['debug']['instances'] = array();
+
+					$context['debug']['instances'][$class] = $class;
+				}
+			}
+
+			return array($context['instances'][$class], $method);
+		}
+
+		// Right then. This is a call to a static method.
+		else
+			return array($class, $method);
+	}
+
+	// Nope! just a plain regular function.
+	else
+		return $string;
+}
+
 /**
  * Microsoft uses their own character set Code Page 1252 (CP1252), which is a
  * superset of ISO 8859-1, defining several characters between DEC 128 and 159

+ 42 - 2
index.php

@@ -172,7 +172,8 @@ obExit(null, null, true);
  */
 function smf_main()
 {
-	global $modSettings, $settings, $user_info, $board, $topic, $board_info, $maintenance, $sourcedir;
+	global $modSettings, $settings, $user_info, $board, $topic;
+	global $board_info, $maintenance, $sourcedir, $db_show_debug, $context;
 
 	// Special case: session keep-alive, output a transparent pixel.
 	if (isset($_GET['action']) && $_GET['action'] == 'keepalive')
@@ -384,7 +385,46 @@ function smf_main()
 
 	// Otherwise, it was set - so let's go to that action.
 	require_once($sourcedir . '/' . $actionArray[$_REQUEST['action']][0]);
-	return $actionArray[$_REQUEST['action']][1];
+
+	// Found a method?
+	if (strpos($actionArray[$_REQUEST['action']][1], '::') !== false)
+	{
+		// Handle it better.
+		$string = $actionArray[$_REQUEST['action']][1];
+
+		list($class, $method) = explode('::', $string);
+
+		// Check if a new object will be created.
+		if (strpos($method, '#') !== false)
+		{
+			// Need to remove the # thing.
+			$method = str_replace('#', '', $method);
+
+			// Don't need to create a new instance for every method.
+			if (empty($context['instances'][$class]) || !($context['instances'][$class] instanceof $class))
+			{
+				$context['instances'][$class] = new $class;
+
+				// Add another one to the list.
+				if ($db_show_debug === true)
+				{
+					if (!isset($context['debug']['instances']))
+						$context['debug']['instances'] = array();
+
+					$context['debug']['instances'][$class] = $class;
+				}
+			}
+
+			return array($context['instances'][$class], $method);
+		}
+
+		// Right then. This is a call to a static method.
+		else
+			return array($class, $method);
+	}
+
+	else
+		return $actionArray[$_REQUEST['action']][1];
 }
 
 ?>