Browse Source

Merge pull request #1123 from MissAllSunday/create_object

Create object
Michael Eshom 11 years ago
parent
commit
b84998d38d

+ 1 - 0
Sources/Logging.php

@@ -248,6 +248,7 @@ function displayDebug()
 	', $txt['debug_language_files'], count($context['debug']['language_files']), ': <em>', implode('</em>, <em>', $context['debug']['language_files']), '</em>.<br />
 	', $txt['debug_stylesheets'], count($context['debug']['sheets']), ': <em>', implode('</em>, <em>', $context['debug']['sheets']), '</em>.<br />
 	', $txt['debug_hooks'], empty($context['debug']['hooks']) ? 0 : count($context['debug']['hooks']) . ' (<a href="javascript:void(0);" onclick="document.getElementById(\'debug_hooks\').style.display = \'inline\'; this.style.display = \'none\'; return false;">', $txt['debug_show'], '</a><span id="debug_hooks" style="display: none;"><em>' . implode('</em>, <em>', $context['debug']['hooks']), '</em></span>)', '<br />
+	',(isset($context['debug']['instances']) ? ($txt['debug_instances'] . (empty($context['debug']['instances']) ? 0 : count($context['debug']['instances'])) . ' (<a href="javascript:void(0);" onclick="document.getElementById(\'debug_instances\').style.display = \'inline\'; this.style.display = \'none\'; return false;">'. $txt['debug_show'] .'</a><span id="debug_instances" style="display: none;"><em>'. implode('</em>, <em>', array_keys($context['debug']['instances'])) .'</em></span>)'. '<br />') : ''),'
 	', $txt['debug_files_included'], count($files), ' - ', round($total_size / 1024), $txt['debug_kb'], ' (<a href="javascript:void(0);" onclick="document.getElementById(\'debug_include_info\').style.display = \'inline\'; this.style.display = \'none\'; return false;">', $txt['debug_show'], '</a><span id="debug_include_info" style="display: none;"><em>', implode('</em>, <em>', $files), '</em></span>)<br />';
 
 	// What tokens are active?

+ 29 - 12
Sources/ManageMaintenance.php

@@ -1914,7 +1914,7 @@ function MaintainMassMoveTopics()
 	{
 		$conditions .= '
 			AND t.locked = {int:locked}';
-		$params['locked'] = 1;	
+		$params['locked'] = 1;
 	}
 
 	// What about sticky topics?
@@ -2175,7 +2175,7 @@ function MaintainRecountPosts()
 /**
  * Generates a list of integration hooks for display
  * Accessed through ?action=admin;area=maintain;sa=hooks;
- * Allows for removal or disabing of selected hooks
+ * Allows for removal or disabling of selected hooks
  */
 function list_integration_hooks()
 {
@@ -2254,7 +2254,7 @@ function list_integration_hooks()
 						global $txt;
 
 						if (!empty($data[\'included_file\']))
-							return $txt[\'hooks_field_function\'] . \': \' . $data[\'real_function\'] . \'<br />\' . $txt[\'hooks_field_included_file\'] . \': \' . $data[\'included_file\'];
+							return $txt[\'hooks_field_function\'] . \': \' . $data[\'real_function\'] . \'<br />\' . $txt[\'hooks_field_included_file\'] . \': \' . $data[\'included_file\'] . (!empty($data[\'instance\']) ? \'<br>\'. $txt[\'hooks_field_function_method\'] : \'\');
 						else
 							return $data[\'real_function\'];
 					'),
@@ -2350,7 +2350,7 @@ function list_integration_hooks()
 }
 
 /**
- * Gets all of the files in a directory and its chidren directories
+ * Gets all of the files in a directory and its children directories
  *
  * @param type $dir_path
  * @return array
@@ -2409,6 +2409,14 @@ function get_integration_hooks_data($start, $per_page, $sort)
 				{
 					foreach ($functions as $function_o)
 					{
+						$object = false;
+
+						if (strpos($function_o, '#') !== false)
+						{
+							$function_o = str_replace('#', '', $function_o);
+							$object = true;
+						}
+
 						$hook_name = str_replace(']', '', $function_o);
 						if (strpos($hook_name, '::') !== false)
 						{
@@ -2417,6 +2425,7 @@ function get_integration_hooks_data($start, $per_page, $sort)
 						}
 						else
 							$function = $hook_name;
+
 						$function = explode(':', $function);
 						$function = $function[0];
 
@@ -2429,8 +2438,10 @@ function get_integration_hooks_data($start, $per_page, $sort)
 						}
 						elseif (strpos(str_replace(' (', '(', $fc), 'function ' . trim($function) . '(') !== false)
 						{
-							$hook_status[$hook][$hook_name]['exists'] = true;
-							$hook_status[$hook][$hook_name]['in_file'] = $file['name'];
+							$hook_status[$hook][$function]['exists'] = true;
+							$hook_status[$hook][$function]['in_file'] = $file['name'];
+							$hook_status[$hook][$function]['instance'] = $object;
+
 							// I want to remember all the functions called within this file (to check later if they are enabled or disabled and decide if the integrare_*_include of that file can be disabled too)
 							$temp_data['function'][$file['name']][] = $function_o;
 							unset($temp_hooks[$hook][$function_o]);
@@ -2497,11 +2508,12 @@ function get_integration_hooks_data($start, $per_page, $sort)
 		{
 			foreach ($functions as $function)
 			{
+				// Gotta remove the # bit.
+				if (strpos($function, '#') !== false)
+					$function = str_replace('#', '', $function);
+
 				$enabled = strstr($function, ']') === false;
 				$function = str_replace(']', '', $function);
-				$hook_exists = !empty($hook_status[$hook][$function]['exists']);
-				$file_name = isset($hook_status[$hook][$function]['in_file']) ? $hook_status[$hook][$function]['in_file'] : ((substr($hook, -8) === '_include') ? 'zzzzzzzzz' : 'zzzzzzzza');
-				$sort[] = $$sort_options[0];
 
 				if (strpos($function, '::') !== false)
 				{
@@ -2510,13 +2522,18 @@ function get_integration_hooks_data($start, $per_page, $sort)
 				}
 				$exploded = explode(':', $function);
 
+				$hook_exists = !empty($hook_status[$hook][$exploded[0]]['exists']);
+				$file_name = isset($hook_status[$hook][$exploded[0]]['in_file']) ? $hook_status[$hook][$exploded[0]]['in_file'] : ((substr($hook, -8) === '_include') ? 'zzzzzzzzz' : 'zzzzzzzza');
+				$sort[] = $$sort_options[0];
+
 				$temp_data[] = array(
 					'id' => 'hookid_' . $id++,
 					'hook_name' => $hook,
 					'function_name' => $function,
 					'real_function' => $exploded[0],
 					'included_file' => isset($exploded[1]) ? strtr(trim($exploded[1]), array('$boarddir' => $boarddir, '$sourcedir' => $sourcedir, '$themedir' => $settings['theme_dir'])) : '',
-					'file_name' => (isset($hook_status[$hook][$function]['in_file']) ? $hook_status[$hook][$function]['in_file'] : ''),
+					'file_name' => (isset($hook_status[$hook][$exploded[0]]['in_file']) ? $hook_status[$hook][$exploded[0]]['in_file'] : ''),
+					'instance' => (isset($hook_status[$hook][$exploded[0]]['instance']) ? $hook_status[$hook][$exploded[0]]['instance'] : ''),
 					'hook_exists' => $hook_exists,
 					'status' => $hook_exists ? ($enabled ? 'allow' : 'moderate') : 'deny',
 					'img_text' => $txt['hooks_' . ($hook_exists ? ($enabled ? 'active' : 'disabled') : 'missing')],
@@ -2546,8 +2563,8 @@ function get_integration_hooks_data($start, $per_page, $sort)
 }
 
 /**
- * Simply returns the total count of integraion hooks
- * Used but the intergation hooks list function (list_integration_hooks)
+ * Simply returns the total count of integration hooks
+ * Used by the integration hooks list function (list_integration_hooks)
  *
  * @global type $context
  * @return int

+ 57 - 10
Sources/Subs.php

@@ -4021,11 +4021,18 @@ function smf_seed_generator()
  */
 function call_integration_hook($hook, $parameters = array())
 {
-	global $modSettings, $settings, $boarddir, $sourcedir, $db_show_debug, $context;
+	global $modSettings, $settings, $boarddir, $sourcedir, $db_show_debug;
+	global $context, $txt;
 
 	if ($db_show_debug === true)
 		$context['debug']['hooks'][] = $hook;
 
+	// Need to have some control.
+	if (!isset($context['instances']))
+		$context['instances'] = array();
+
+	 loadLanguage('Errors');
+
 	$results = array();
 	if (empty($modSettings[$hook]))
 		return $results;
@@ -4035,19 +4042,54 @@ function call_integration_hook($hook, $parameters = array())
 	foreach ($functions as $function)
 	{
 		$function = trim($function);
+
+		// Found a call to a method.
 		if (strpos($function, '::') !== false)
 		{
 			$call = explode('::', $function);
+
+			// Get the file and the class::method.
 			if (strpos($call[1], ':') !== false)
 			{
 				list($func, $file) = explode(':', $call[1]);
+
+				// Need to temp delete the #
+				if (strpos($file, '#') !== false)
+					$file = str_replace('#', '', $file);
+
+				// 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);
-				$call = array($call[0], $func);
+
+				// No? tell the admin about it.
+				else
+					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);
 			}
 		}
 		else
@@ -4069,6 +4111,10 @@ function call_integration_hook($hook, $parameters = array())
 		// Is it valid?
 		if (is_callable($call))
 			$results[$function] = call_user_func_array($call, $parameters);
+
+		// Whatever it was suppose to call, it failed :(
+		elseif (!empty($func) && !empty($absPath))
+			log_error(sprintf($txt['hook_fail_call_to'], $func, $absPath), 'general');
 	}
 
 	return $results;
@@ -4078,16 +4124,17 @@ function call_integration_hook($hook, $parameters = array())
  * Add a function for integration hook.
  * does nothing if the function is already added.
  *
- * @param string $hook
- * @param string $function
- * @param string $file
- * @param bool $permanent = true if true, updates the value in settings table
+ * @param string $hook The complete hook name.
+ * @param string $function Function name, can be a call to a method via Class::method.
+ * @param string $file Must include one of the following wildcards: $boarddir, $sourcedir, $themedir, example: $sourcedir/Test.php
+ * @param bool $object Boolean Indicates if your class will be instantiated when its respective hook is called, your function must be a method.
+ * @param bool $permanent = true if true, updates the value in settings table.
  */
-function add_integration_function($hook, $function, $file = '', $permanent = true)
+function add_integration_function($hook, $function, $file = '', $object = false, $permanent = true)
 {
 	global $smcFunc, $modSettings;
 
-	$integration_call = (!empty($file) && $file !== true) ? $function . ':' . $file : $function;
+	$integration_call = (!empty($file) && $file !== true) ? ($function . ':' . $file . ($object ? '#' : '')) : $function;
 
 	// Is it going to be permanent?
 	if ($permanent)
@@ -4137,11 +4184,11 @@ function add_integration_function($hook, $function, $file = '', $permanent = tru
  * @param string $function
  * @param string $file
  */
-function remove_integration_function($hook, $function, $file = '')
+function remove_integration_function($hook, $function, $file = '', $object = false)
 {
 	global $smcFunc, $modSettings;
 
-	$integration_call = (!empty($file)) ? $function . ':' . $file : $function;
+	$integration_call = (!empty($file)) ? $function . ':' . $file .($object ? '#' : '') : $function;
 
 	// Get the permanent functions.
 	$request = $smcFunc['db_query']('', '

+ 1 - 0
Themes/default/languages/Admin.english.php

@@ -696,6 +696,7 @@ $txt['paid_subs_view'] = 'View Subscriptions';
 $txt['hooks_title_list'] = 'Integration Hooks';
 $txt['hooks_field_hook_name'] = 'Hook Name';
 $txt['hooks_field_function_name'] = 'Function Name';
+$txt['hooks_field_function_method'] = 'Function is a method and its class is instantiated';
 $txt['hooks_field_function'] = 'Function';
 $txt['hooks_field_included_file'] = 'Included file';
 $txt['hooks_field_file_name'] = 'File Name';

+ 4 - 0
Themes/default/languages/Errors.english.php

@@ -422,6 +422,10 @@ $txt['email_no_template'] = 'The email template &quot;%1$s&quot; could not be fo
 $txt['search_api_missing'] = 'The search API could not be found. Please contact the admin to check they have uploaded the correct files.';
 $txt['search_api_not_compatible'] = 'The selected search API the forum is using is out of date - falling back to standard search. Please check file %1$s.';
 
+// Handling hook calls
+$txt['hook_fail_loading_file'] = 'Hook call: The file at path: %s could not be loaded.';
+$txt['hook_fail_call_to'] = 'Hook call: function "%1$s" in file %2$s could not be called.';
+
 // Restore topic/posts
 $txt['cannot_restore_first_post'] = 'You cannot restore the first post in a topic.';
 $txt['parent_topic_missing'] = 'The parent topic of the post you are trying to restore has been deleted.';

+ 1 - 0
Themes/default/languages/index.english.php

@@ -818,5 +818,6 @@ $txt['debug_hide_queries'] = '[Hide Queries]';
 $txt['debug_tokens'] = 'Tokens: ';
 $txt['debug_browser'] = 'Browser ID: ';
 $txt['debug_hooks'] = 'Hooks called: ';
+$txt['debug_instances'] = 'Instances created: ';
 $txt['are_sure_mark_read'] = 'Are you sure you want to mark messages as read?';
 ?>