MyBB Community Forums

Full Version: Few Questions
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I'm working on a plugin at the moment and it's nearly done. I've used other plugins, the MyBB Wiki, and my small PHP knowledge to guide myself through the process. I'm kind of stuck, now.

This plugin is supposed to display extra information on users' postbits. The information is stored in a template that is called through a variable on the postbit or postbit_classic template.

Upon turning it on, I get this error:

Quote:Warning [2] call_user_func_array() [function.call-user-func-array]: First argument is expected to be a valid callback, 'global_rpgstats' was given - Line: 141 - File: inc/class_plugins.php PHP 5.2.6 (Linux)
  • /inc/class_plugins.php
  • 141
  • call_user_func_array
  • /inc/functions_post.php
  • 591
  • pluginSystem->run_hooks_by_ref
  • /showthread.php
  • 778
  • build_postbit

I'm certain it has something to do with how I did the hooks. I really have no clue what hooks do, or how to use them, but this is what I have after the error handling:

$plugins->add_hook('postbit', 'postbit_author_rpgstats');

And another thing. The find and replace functions don't seem to be working for me. Upon activation, the following functions were set to run.

	// This inserts RPG stats var into postbit tempaltes.
	find_replace_templatesets('postbit',			"#{\$post['button_delete_pm']}#", "{\$post['button_delete_pm']}<br />{\$rpg_details}"); 
	find_replace_templatesets('postbit_classic', 	"#{\$post['button_delete_pm']}#", "{\$post['button_delete_pm']}<br />{\$rpg_details}");
Neither of these happen.

I'm losing hair quickly. If someone could point me in the right direction, it'd be nice.

Thanks.
Hi,
For your error, it means that the function global_rpgstats doesn't exist. Either you added a hook you don't use, forgot to define a function or made a typo somewhere.

For your find_replace_templatesets issue, your regex is incorrect. You might want to consider using preg_quote around it, eg:
    // This inserts RPG stats var into postbit tempaltes.
    find_replace_templatesets('postbit',            "#".preg_quote("{\$post['button_delete_pm']}")."#", "{\$post['button_delete_pm']}<br />{\$rpg_details}"); 
    find_replace_templatesets('postbit_classic',     "#".preg_quote("{\$post['button_delete_pm']}")."#", "{\$post['button_delete_pm']}<br />{\$rpg_details}"); 
Hope that helps.

(might be easier if you post all the code up)
Hey, Zinga. I'll drop the plugin, here goes:

<?php
/*================================*\
|| RPG Statistics v1.0.0 - by Sam ||
\*================================*/

// Idiot-Poofing \\
if(!defined('IN_MYBB'))
{
	die('This file cannot be accessed directly!');
}

// Hook It \\
$plugins->add_hook('postbit', 'postbit_author_rpgstats');

// Plugin Infos \\
function rpgstats_info() {
	return array(
		'name'			=>	'RPG Statistics',
		'description'	=>	'This plugin generates RPG stats and displays them on postbits.',
		'website'		=>	'http://s43.eclipstice.com',
		'author'		=>	'Sam',
		'authorsite'	=>	'http://s43.eclipstice.com',
		'version'		=>	'1.0.0',
		'guid'        => '',
		'compatibility' => '14*',
	);
}

// Activate The Plugin \\
function rpgstats_activate() {
	// Necessary Stuff \\
	require MYBB_ROOT.'/inc/adminfunctions_templates.php';
	global $db;
	// Create the Setting Group \\
	$rpgstat_group = array(
		'name'			=> 'rpgstats',
		'title'		 	=> 'RPG Statistics',
		'description'	=> 'This selection allows you to make small tweaks to the general functionality of the RPG Statistics plugin.',
		'disporder'		=> '100',
		'isdefault'		=> 'no',
	);
	// Insert the Setting Group Into the Databutz \\
	$db->insert_query('settinggroups',$rpgstat_group);
	$gid = $db->insert_id();
	// Create Individual Settings \\
	// This is for the on/off setting.
	$rpgstat_setting_1 = array(
		'name'			=> 'rpgonoff',
		'title'			=> 'RPG Offline',
		'description'	=> $db->escape_string('Do you want to show generated RPG statistics on users\' postbits?'),
		'optionscode'	=> 'onoff',
		'value'			=> 'on',
		'disporder'		=> '1',
		'gid'			=> intval($gid),
	);
	// This is for the buff multiple.
	$rpgstat_setting_2 = array(
		'name'			=> 'rpgbuff',
		'title'			=> 'Buff Multiple',
		'description'	=> 'The generated HP and MP will be multiplied by this number.',
		'optionscode'	=> 'text',
		'value'			=> '10',
		'disporder'		=> '2',
		'gid'			=> intval($gid),
	);
	// Insert the Settings Into the Databutz \\
	$db->insert_query('settings', $rpgstat_setting_1);
	$db->insert_query('settings', $rpgstat_setting_2);
	// Create a Template \\
	$rpgstat_template = array(
		"title"			=> 	'postbit_author_rpgstats',
		"template"		=> 	$db->escape_string('
<table width="100%">
	<tr>
		<td width="33%">
			<span class="smalltext"><span style="font-weight:bold;">HP:</span> {$hpcur} / {$hpmax}</span><br />
			{$hpbar}<br />
			<span class="smalltext"><span style="font-weight:bold;">Level:</span> {$level}</span>
		</td>
		<td width="33%">
			<span class="smalltext"><span style="font-weight:bold;">MP:</span> {$mpcur} / {$mpmax}</span><br />
			{$mpbar}
		</td>
		<td width="33%">
			<span class="smalltext"><span style="font-weight:bold;">EXP:</span> {$exptotal}</span><br />
			{$expbar}<br />
			<span class="smalltext"><span style="font-weight:bold;">To Next:</span> {$expnext} ({$expcent}%)</span>
		</td>
	</tr>
</table>
		'),
		'sid'			=>	'-1',
	);
	// Insert the Template Into the Databutz \\
	$db->insert_query('templates',$rpgstat_template);
	// This inserts RPG stats var into postbit tempaltes.
	find_replace_templatesets('postbit',			"#{\$post['button_delete_pm']}#", "{\$post['button_delete_pm']}<br />{\$rpg_details}"); 
	find_replace_templatesets('postbit_classic', 	"#{\$post['button_delete_pm']}#", "{\$post['button_delete_pm']}<br />{\$rpg_details}");
	// Rebuild Settings \\
	rebuild_settings();
}

// Deactivate The Plugin \\
function rpgstats_deactivate() {
	// Necessary Stuff \\
	require MYBB_ROOT."/inc/adminfunctions_templates.php";
	global $db;
	// Delete Settings \\
	$db->write_query("DELETE FROM ".TABLE_PREFIX."settings WHERE name IN('rpgonoff','rpgbuff')");
	// Delete Setting Group \\
	$db->write_query("DELETE FROM ".TABLE_PREFIX."settinggroups WHERE name='rpgstats'");
	// Delete Template \\
	$db->write_query("DELETE FROM ".TABLE_PREFIX."templates WHERE title='postbit_author_rpgstats'");
	// This removes RPG stats var from the postbit templates.
	find_replace_templatesets('postbit',			"#{\$rpg_details}#", "");
	find_replace_templatesets('postbit_classic', 	"#{\$rpg_details}#", ""); 
	// Rebuilt Settings \\
	rebuild_settings();
}


function unreadpm() {
	global $mybb, $templates, $rpgstats;
	if($mybb->settings['rpgonoff'] != 'off') {
		// Buff HP and MP \\
		$hp = $hp * $mybb->settings['rpgbuff'];
		$mp = $mp * $mybb->settings['rpgbuff'];
		eval("\$rpg_details = \"".$templates->get('global_rpgstats')."\";");
	}
}

// Math \\
function rpgstats_postbit($post) {
	// This Was All Done by Ryan Ashbrook \\
  	global $mybb, $db;
  	$post['postnum'] = str_replace($mybb->settings['thousandssep'], '', $post['postnum']);
  	$daysreg = (time() - $post['regdate']) / (24*3600);
	$postsperday = $post['postnum'] / $daysreg;
	$postsperday = round($postsperday, 2);
	if($postsperday > $post['postnum']) {
		$postsperday = $post['postnum'];
	}
	$rpglvl = $post['postnum'];
	$level = pow (log10 ($rpglvl), 3);
	$ep = floor (100 * ($level - floor ($level)));
	$showlevel = floor ($level + 1);
	$hpmulti = round ($postsperday / 6, 1);
	if ($hpmulti > 1.5) {
		$hpmulti = 1.5;
	}
	if ($hpmulti < 1) {
		$hpmulti = 1;
	}
	$maxhp = $level * 25 * $hpmulti;
	$hp = $postsperday / 1;
	if ($hp >= 1) {
		$hp = $maxhp;
	}
	else {
		$hp = floor ($hp * $maxhp);
	}
	$hp = floor ($hp);
	$maxhp = floor ($maxhp);
	if ($maxhp <= 0) {
		$zhp = 1;
	}
	else {
		$zhp = $maxhp;
	}
	$hpf = floor (100 * ($hp / $zhp)) - 1;
	$maxmp = ($daysreg * $level) / 5;
	$mp = $rpglvl / 3;
	if ($mp >= $maxmp) {
		$mp = $maxmp;
	}
	$maxmp = floor ($maxmp);
	$mp = floor ($mp);
	if ($maxmp <= 0) {
		$zmp = 1;
	}
	else {
		$zmp = $maxmp;
	}
	$mpf = floor (100 * ($mp / $zmp)) - 1;
	$showlevel = my_number_format($showlevel);
	$maxhp = my_number_format($maxhp);
	$hp = my_number_format($hp);
	$maxmp = my_number_format($maxmp);
	$mp = my_number_format($mp);
	// Back to Me! Me, me, me! \\
	// This calculates all the other EXP parameters.
	$delevel = $showlevel - 1;
	$earnedexp = $delevel * 1000;
	$remainexp = $ep * 10;
	$totalexp = $earnexp + $remainexp;
	$nextexp = $showlevel * 1000;
	$totalexp = my_number_format($totalexp);
	$nextexp = my_number_format($nextexp);
	// Set Parameter Vars \\
	$level		= '{$showlevel}';
	$hpcur		= '{$hp}';
	$hpmax		= '{$maxhp}';
	$hpbar		= '
	<table class="rpg1" align="center" width="100px" cellspacing="0">
		<tr> 
			<td class="rpg2" nowrap="nowrap">
				<img src="images/rpg/bhg.gif" alt="{$post[\'username\']}\'s HP" width="{$hpf}%" height="8px" /><img alt="{$post[\'username\']}\'s HP" src="images/rpg/bhb.gif" width="1px" height="8px" />
			</td>
		</tr>
	</table>
	';
	$mpcur		= '{$mp}';
	$mpmax		= '{$maxmp}';
	$mpbar		= '
	<table class="rpg1" align="center" width="100px" cellspacing="0">
		<tr> 
			<td class="rpg2" nowrap="nowrap">
				<img src="images/rpg/bmg.gif" alt="{$post[\'username\']}\'s MP" width="{$mpf}%" height="8px" /><img alt="{$post[\'username\']}\'s MP" src="images/rpg/bmb.gif" width="1px" height="8px" />
			</td>
		</tr>
	</table>
	';
	$exptotal	= '{$totalexp}';
	$expnext	= '{$nextexp}';
	$expcent	= '{$ep}';
	$expbar		= '
	<table class="rpg1" align="center" width="100px" cellspacing="0">
		<tr> 
			<td class="rpg2" nowrap="nowrap">
				<img src="images/rpg/bxg.gif" alt="{$post[\'username\']}\'s EXP" width="{$ep}%" height="8px" /><img alt="{$post[\'username\']}\'s EXP" src="images/rpg/bxb.gif" width="1px" height="8px" />
			</td>
		</tr>
	</table>
	';
}
?>

Blam. Yeah. Thanks for your find and replace help. I'll implement that as soon as I get this hook thing sorted out. As for the hook, I only use it at the top. I don't know what else it's for, I pretty much got most of this done by looking at other plugins. >XD

Thanks for your help! (I am the G Ninja Wink)
After fixing the find_replace_templatesets function from _activate and _deactivate, do this:
replace:
$plugins->add_hook('postbit', 'postbit_author_rpgstats');
with
$plugins->add_hook('postbit', 'rpgstats_postbit');
(the second argument should be the same as the function name)


(2008-08-12, 12:16 AM)Toasty Wrote: [ -> ]I am the G Ninja
O_O
Awesome. Everything is working perfectly except one thing.
<?php
/*================================*\
|| RPG Statistics v1.0.0 - by Sam ||
\*================================*/

// Idiot-Poofing \\
if(!defined('IN_MYBB'))
{
	die('This file cannot be accessed directly!');
}

// Hook It \\
$plugins->add_hook('postbit', 'rpgstats_postbit');

// Plugin Infos \\
function rpgstats_info() {
	return array(
		'name'			=> 'RPG Statistics',
		'description'	=> 'This plugin generates RPG stats and displays them on postbits.',
		'website'		=> 'http://s43.eclipstice.com',
		'author'		=> 'Sam',
		'authorsite'	=> 'http://s43.eclipstice.com',
		'version'		=> '1.0.0',
		'guid'			=> '69696969696969696969696969',
		'compatibility' => '14*',
	);
}

// Activate The Plugin \\
function rpgstats_activate() {
	// Necessary Stuff \\
	require MYBB_ROOT.'/inc/adminfunctions_templates.php';
	global $db;
	// Create the Setting Group \\
	$rpgstat_group = array(
		'name'			=> 'rpgstats',
		'title'		 	=> 'RPG Statistics',
		'description'	=> 'This selection allows you to make small tweaks to the general functionality of the RPG Statistics plugin.',
		'disporder'		=> '100',
		'isdefault'		=> 'no',
	);
	// Insert the Setting Group Into the Databutz \\
	$db->insert_query('settinggroups',$rpgstat_group);
	$gid = $db->insert_id();
	// Create Individual Settings \\
	// This is for the on/off setting.
	$rpgstat_setting_1 = array(
		'name'			=> 'rpgonoff',
		'title'			=> 'RPG Offline',
		'description'	=> $db->escape_string('Do you want to show generated RPG statistics on users\' postbits?'),
		'optionscode'	=> 'onoff',
		'value'			=> 'on',
		'disporder'		=> '1',
		'gid'			=> intval($gid),
	);
	// This is for the buff multiple.
	$rpgstat_setting_2 = array(
		'name'			=> 'rpgbuff',
		'title'			=> 'Buff Multiple',
		'description'	=> 'The generated HP and MP will be multiplied by this number.',
		'optionscode'	=> 'text',
		'value'			=> '10',
		'disporder'		=> '2',
		'gid'			=> intval($gid),
	);
	// Insert the Settings Into the Databutz \\
	$db->insert_query('settings', $rpgstat_setting_1);
	$db->insert_query('settings', $rpgstat_setting_2);
	// Create a Template \\
	$rpgstat_template = array(
		"title"			=> 	'postbit_author_rpg',
		"template"		=> 	$db->escape_string('
<table width="100%">
	<tr>
		<td width="33%">
			<span class="smalltext"><span style="font-weight:bold;">HP:</span> {$hpcur} / {$hpmax}</span><br />
			{$hpbar}<br />
			<span class="smalltext"><span style="font-weight:bold;">Level:</span> {$level}</span>
		</td>
		<td width="33%">
			<span class="smalltext"><span style="font-weight:bold;">MP:</span> {$mpcur} / {$mpmax}</span><br />
			{$mpbar}
		</td>
		<td width="33%">
			<span class="smalltext"><span style="font-weight:bold;">EXP:</span> {$exptotal}</span><br />
			{$expbar}<br />
			<span class="smalltext"><span style="font-weight:bold;">To Next:</span> {$expnext} ({$expcent}%)</span>
		</td>
	</tr>
</table>
		'),
		'sid'			=>	'-1',
	);
	// Insert the Template Into the Databutz \\
	$db->insert_query('templates',$rpgstat_template);
	
	// This inserts RPG stats var into postbit tempaltes.
    find_replace_templatesets('postbit',            "#".preg_quote("{\$post['button_delete_pm']}")."#", "{\$post['button_delete_pm']}<br />{\$rpg_details}"); 
    find_replace_templatesets('postbit_classic',    "#".preg_quote("{\$post['button_delete_pm']}")."#", "{\$post['button_delete_pm']}<br />{\$rpg_details}");
	// Rebuild Settings \\
	rebuild_settings();
}

// Deactivate The Plugin \\
function rpgstats_deactivate() {
	// Necessary Stuff \\
	require MYBB_ROOT."/inc/adminfunctions_templates.php";
	global $db;
	// Delete Settings \\
	$db->write_query("DELETE FROM ".TABLE_PREFIX."settings WHERE name IN('rpgonoff','rpgbuff')");
	// Delete Setting Group \\
	$db->write_query("DELETE FROM ".TABLE_PREFIX."settinggroups WHERE name='rpgstats'");
	// Delete Template \\
	$db->write_query("DELETE FROM ".TABLE_PREFIX."templates WHERE title='postbit_author_rpg'");
	// This removes RPG stats var from the postbit templates.
	find_replace_templatesets('postbit',			"#".preg_quote("{\$rpg_details}")."#", "");
	find_replace_templatesets('postbit_classic', 	"#".preg_quote("{\$rpg_details}")."#", ""); 
	// Rebuilt Settings \\
	rebuild_settings();
}

// Math \\
function rpgstats_postbit($post) {
	global $mybb, $templates, $rpgstats;
	if($mybb->settings['rpgonoff'] != 'off') {
		// Buff HP and MP \\
		$hp = $hp * $mybb->settings['rpgbuff'];
		$mp = $mp * $mybb->settings['rpgbuff'];
		eval("\$rpg_details = \"".$templates->get('postbit_author_rpg')."\";");
	}
	// This Was All Done by Ryan Ashbrook \\
  	global $mybb, $db;
  	$post['postnum'] = str_replace($mybb->settings['thousandssep'], '', $post['postnum']);
  	$daysreg = (time() - $post['regdate']) / (24*3600);
	$postsperday = $post['postnum'] / $daysreg;
	$postsperday = round($postsperday, 2);
	if($postsperday > $post['postnum']) {
		$postsperday = $post['postnum'];
	}
	$rpglvl = $post['postnum'];
	$level = pow (log10 ($rpglvl), 3);
	$ep = floor (100 * ($level - floor ($level)));
	$showlevel = floor ($level + 1);
	$hpmulti = round ($postsperday / 6, 1);
	if ($hpmulti > 1.5) {
		$hpmulti = 1.5;
	}
	if ($hpmulti < 1) {
		$hpmulti = 1;
	}
	$maxhp = $level * 25 * $hpmulti;
	$hp = $postsperday / 1;
	if ($hp >= 1) {
		$hp = $maxhp;
	}
	else {
		$hp = floor ($hp * $maxhp);
	}
	$hp = floor ($hp);
	$maxhp = floor ($maxhp);
	if ($maxhp <= 0) {
		$zhp = 1;
	}
	else {
		$zhp = $maxhp;
	}
	$hpf = floor (100 * ($hp / $zhp)) - 1;
	$maxmp = ($daysreg * $level) / 5;
	$mp = $rpglvl / 3;
	if ($mp >= $maxmp) {
		$mp = $maxmp;
	}
	$maxmp = floor ($maxmp);
	$mp = floor ($mp);
	if ($maxmp <= 0) {
		$zmp = 1;
	}
	else {
		$zmp = $maxmp;
	}
	$mpf = floor (100 * ($mp / $zmp)) - 1;
	$showlevel = my_number_format($showlevel);
	$maxhp = my_number_format($maxhp);
	$hp = my_number_format($hp);
	$maxmp = my_number_format($maxmp);
	$mp = my_number_format($mp);
	// Back to Me! Me, me, me! \\
	// This calculates all the other EXP parameters.
	$delevel = $showlevel - 1;
	$earnedexp = $delevel * 1000;
	$remainexp = $ep * 10;
	$totalexp = $earnexp + $remainexp;
	$nextexp = $showlevel * 1000;
	$totalexp = my_number_format($totalexp);
	$nextexp = my_number_format($nextexp);
	// Set Parameter Vars \\
	$level		= '{$showlevel}';
	$hpcur		= '{$hp}';
	$hpmax		= '{$maxhp}';
	$hpbar		= '
	<table class="rpg1" align="center" width="100px" cellspacing="0">
		<tr> 
			<td class="rpg2" nowrap="nowrap">
				<img src="images/rpg/bhg.gif" alt="{$post[\'username\']}\'s HP" width="{$hpf}%" height="8px" /><img alt="{$post[\'username\']}\'s HP" src="images/rpg/bhb.gif" width="1px" height="8px" />
			</td>
		</tr>
	</table>
	';
	$mpcur		= '{$mp}';
	$mpmax		= '{$maxmp}';
	$mpbar		= '
	<table class="rpg1" align="center" width="100px" cellspacing="0">
		<tr> 
			<td class="rpg2" nowrap="nowrap">
				<img src="images/rpg/bmg.gif" alt="{$post[\'username\']}\'s MP" width="{$mpf}%" height="8px" /><img alt="{$post[\'username\']}\'s MP" src="images/rpg/bmb.gif" width="1px" height="8px" />
			</td>
		</tr>
	</table>
	';
	$exptotal	= '{$totalexp}';
	$expnext	= '{$nextexp}';
	$expcent	= '{$ep}';
	$expbar		= '
	<table class="rpg1" align="center" width="100px" cellspacing="0">
		<tr> 
			<td class="rpg2" nowrap="nowrap">
				<img src="images/rpg/bxg.gif" alt="{$post[\'username\']}\'s EXP" width="{$ep}%" height="8px" /><img alt="{$post[\'username\']}\'s EXP" src="images/rpg/bxb.gif" width="1px" height="8px" />
			</td>
		</tr>
	</table>
	';
}
?>

That's the new code with all the corrections (I even found a ton inconsistencies in the variables and stuff, it wouldn't have worked anyways; they're corrected now. >XD). Everything is functioning correctly, except $rpg_details isn't displaying postbit_author_rpg like it should. I think it has something to do with this line, here:

eval("\$rpg_details = \"".$templates->get('postbit_author_rpg')."\";");
And yes, I do have the setting turned on. I'm clearly overlooking something. Sad
By default, all variables defined within a function have local scope (which means they can only be "seen" from within the function).

Before the eval line, try adding:
global $rpg_details;
^ This forces the variable to be in the global scope.
That didn't seem to work. I checked the HTML source, and the template is still not even including onto the postbit. By the way, would I also have to put the individual variables used in the template in the global spectrum?
Oops, I made a mistake. (ignore what I said above)

A few things:
Use $post['rpg_details'] instead of $rpg_details, as the latter isn't available when evaling the postbit (you'll need to change your template edit as well).
Secondly, change:
function rpgstats_postbit($post) {
to:
function rpgstats_postbit(&$post) {
Ah, I initially had everything in the $post array, but I thought that's what was causing the original error.

Done and done. Now it's finally displaying, but the individual variables in postbit_author_rpg don't seem to be displaying. All the parameters show up, but what I've defined in things like $hpcur and $hpbar won't show what I've defined them as. I tried changing the variable names to include $post, but that doesn't work either.

EDIT: I just found out that when deactivating, it doesn't find and replace "<br />{$post['rpg_details']}" into "". I tried it without preg_quote just for kicks and giggles and it still doesn't work. I have absolutely no clue why this isn't functioning normally.
Oh oops, forgot I needed to respond here Undecided
Anyways, I can help with small issues, but for issues relating to the whole plugin, you're going to have to do it yourself. The reason the variables aren't showing is because the code isn't placed right, and it's more than just a simple modification to fix. You're really going to have to know what you're doing, unfortunately, or it's not going to work.

For deactivation find_replace_templatesets, make sure you supply "0" as the 4th argument.