SMF 1.1.11
Tiny Portal v1.0 beta 4
I've had a solid installation for awhile with no errors. I added a block of PHP code that runs fine as it's own page, but when placed in a panel block, it causes the following error to be generated twice in the forums logs:
8: Undefined variable: output
File: ...\forums\Themes\default\languages\TPShout.english.php (tp_above sub template - eval?)
Line: 26
The panel block is a panel on my home page. I turn the panel off, it goes away. I turn the panel on, and it returns. The code runs fine in the panel and returns the data formatted as expected, despite the TP error.
I fully admit I'm not a PHP coder. I've taken some code written by another author and modified it to fit my needs. I've tried defining the variable $output all kinds of ways in the block, but nothing seems to make TP happy.
Do I need to define it somewhere else in TP, and if so where and how?
Here's my current code. This code contacts a game server for current players and posts it on my forum:
$ip = "servername.com";
$port = 1234;
$pass = "password";
$flhookHeader = "please authenticate";
class admin{
var $loggedIn = false;
var $con;
var $timeout = 2;
var $errn;
var $errs;
var $error;
var $ok = "OK";
var $err = "ERR";
var $cmds = array("getplayers" => array(0,1));
function connect($ip, $port){
$this->con = fsockopen($ip,$port,$this->errn,$this->errs,$this->timeout);
}
function quit(){
fclose($this->con);
}
function sendCmd($cmd, $param=""){
fwrite($this->con, $cmd . " " .$param."\r\n");
while(1){
$output .= fgetc($this->con);
//\n and space used incase a player is named OK or ERR
if((trim(substr($output,-3,3) == "\nOK")) || (trim(substr($output,-4,4) == "ERR "))){
break;
}
else{
continue;
}
}
return trim($this->cleanOutput($output));
}
function processCmd($cmd, $params=""){
switch($this->cmds[$cmd][0]){
case 0:
$params = str_replace(" ","",$params);
$output = $this->cleanOutput($this->sendCmd($cmd, $params));
break;
case 1:
$params = str_replace(",","",$params);
$params = preg_replace("/[a-zA-Z]/","",$params);
$output = $this->cleanOutput($this->sendCmd($cmd, $params));
break;
case 2:
$output = $this->cleanOutput($this->sendCmd($cmd, $params));
break;
}
switch($this->cmds[$cmd][1]){
//No return needed, other than OK
case 0:
if(trim(substr($output,-2,2) == "OK")){
return true;
}
else{
$this->error = trim($output);
return false;
}
break;
//Data needs to be returned
case 1:
if(trim(substr($output,-2,2) == "OK")){
return substr($output,0,(strlen($output) - 2));
}
else{
$this->error = trim($output);
return false;
}
break;
}
}
function login($pass){
$check = $this->sendCmd("pass", $pass);
if($check == $this->ok){
$this->loggedIn = true;
}
else{
$this->loggedIn = true;
$this->error = $check;
}
}
function cleanOutput($output){
global $flhookHeader;
//Removes flhook welcome message, so we only have the data returned by the server after sending a command.
$remove = array("/".$flhookHeader."/");
$output = preg_replace($remove,"",$output);
return trim($output);
}
}
$flhook = new admin();
$flhook->connect($ip, $port);
if($flhook->con){
$flhook->login($pass);
if($flhook->loggedIn){
$players = explode("\n",$flhook->processCmd("getplayers"));
sort($players);
echo "<font face = \"verdana\" color=\"#557491\"><span style=\"font-size:11px\">";
echo "</br><img src=\"players.gif\"><b> Production Server Players Online: ".(count($players)-1)."</b></br></br>";
echo "</span></font>";
echo "<div class=\"wrapper\"><ul id=\"playerlist\">";
foreach($players as $playerline){
if(preg_match("/charname=(.+?) /",$playerline,$matches)){
echo "<li>".$matches[1]."</li>";
}
}
echo "</ul></div><!-- .wrapper -->";
echo "</br></br>";
}
}
Any help would be appreciated.
My guess is that $output just needs to be put with the other variables at the top of the class.
var $output;
Thanks.. I tried that, and it still didn't like it. I wonder if $output is used elsewhere and if that would matter. I could to a search through all the PHP code to find it.
If it does exist, would changing the variable name to something different perhaps help? Guess I could try that and see...
I suppose when you add the var $output; to the top, that you'll have to go and change the rest of the $output variables to be $this->output.
Maybe that's my problem. I'll give that a try tonight. Thanks for the advice!
I tried adding
var $output;
to the top, and adding $this-->output where needed. Still no dice (several errors generated).
Finally removed all the code, and added it back line by line until I found the error was in the two functions, sendCmd and processCmd. At the top of these commands, before I did any work with the $output variable, I added the line
$output = "";
and that made the error go away. I don't know why defining it up front would not work, and I don't know why it even matters since what I read re: PHP5 indicated you didn't have to predefine variables. Maybe TP is just checking against an older ruleset and throwing an error. As I mentioned earlier, if I copied the code into a php doc (test.php, for example), and ran it from the browser, it ran fine.
Anyway, it's solved now. Thank you for the help!