DA plugin with AJAX issue

Hondo

Verified User
Joined
Mar 17, 2009
Messages
14
Location
St. Albert, AB
I created a DA plugin to Start/Stop a chat server under the user's account. The plugin has one button which is used to both start and stop the chat server. The button initiates an AJAX script which in turn calls a PHP script. The PHP script basically determines the status of the chat server, and based on that status either starts or stops the server. Once the action is completed, the status of the server is returned to the AJAX script which presents the user with the status of the server underneath the button.

The issue: When the status is returned to the AJAX script, the header and the footer are redrawn in the iframe along with the status of the server.

Code:
#!/usr/local/bin/php

<!-- Start Palace Controls -->
<script language="JavaScript">
var xmlHttp;
        function showStatus(){
                xmlHttp = GetXmlHttpObject();
                if(xmlHttp == null)
                {
                        alert("Browser does not support HTTP Request.");
                        return;
                }
                var url="start-stop.php";
                xmlHttp.onreadystatechange = stateChanged;
                xmlHttp.open("GET",url,true);
                xmlHttp.send(null);
        }
        function stateChanged(){
                if (xmlHttp.readyState == 4 || xmlHttp.readyState == "complete"){
                        document.getElementById("status").innerHTML = xmlHttp.responseText;
                }
        }
        function GetXmlHttpObject(){
                var xmlHttp = null;
                try{
                        // FireFox, Opera, Safari
                        xmlHttp = new XMLHttpRequest();
                }
                catch(e){
                        // Internet Explorer
                        try{
                                xmlHttp = new ActiveXObject("Msxml12.XMLHTTP");
                        }
                        catch(e){
                                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
                        }
                }
                return xmlHttp;
        }
</script>
<input value="Start/Stop" name="startstop" type="button" onclick="showStatus()" />

<p>Server Status: <span id="status"></span></p>
Maybe I missed a post in my search, or maybe I'm Googleing the wrong words, so if anyone can point me in the right direction or share their expertise it would be greatly appreciated.
 
I believe the only way around this would be to put the file giving the response in the 'images' folder or possibly the 'scripts' one.
 
I realize that my description still may be a little vague and could use an illustration. Since I am not able to shutdown the current server, I rendered an image about 99% close to what the actual screen looks like.
 

Attachments

  • directadmin_plugin.jpg
    directadmin_plugin.jpg
    141.6 KB · Views: 244
Directadmin is setup to send all responses with the normal header/footer unless you have the script in the 'images' folder or use the special system noted above. That's why you see Directadmin inside itself like that.
 
Directadmin is setup to send all responses with the normal header/footer unless you have the script in the 'images' folder or use the special system noted above. That's why you see Directadmin inside itself like that.

If I am understanding you correctly, I would need to place the start-stop.php script (which is called by the AJAX code) in the images folder. Or would I need to remove the AJAX/Javascript portion and place that in the images folder?

By the way, thank you for your responses, it is very much appreciated.
 
If I am understanding you correctly, I would need to place the start-stop.php script (which is called by the AJAX code) in the images folder. Or would I need to remove the AJAX/Javascript portion and place that in the images folder?

By the way, thank you for your responses, it is very much appreciated.
Yup. That's how I would do it (put the start-stop.php script in the images folder). But that's still the somewhat crude work-around. The official way is still using this method:
http://www.directadmin.com/features.php?id=610

Directadmin assumes that all you'll have in the 'images' folder are images. So it doesn't force the header/footer on the files that are outputted from it. Therefor, I'd assume any scripts run from there would respond without the header/footer getting shoved in there which is your current problem. I've never used PHP files in it personally to try, but I had the problem using an external Javascript file and ended up throwing it in there to use.
 
Thank you very much Dravu,

I'll schedule a shutdown for the chat server and try that.

As for the link, I did read that earlier but I was not sure if I would need to rewrite the whole script in bash or if I could leave it in PHP and just change the extension.

Later I'll post the results of putting the start-stop.php in the images folder.


Update:

It appears placing a php script in the images folder does not resolve the issue. I went ahead and changed the extension on the PHP file and to start-stop.raw and that resolved the issue of the header and footer showing within itself.

I would assume one would need to close the socket, once the transaction is complete. If so, should that be done with the AJAX/javascript or in the PHP file?

Using the *.raw extension did come with a price. The AJAX/javascript will only show the chat server status when it is shutdown. When it is started up, the status remains blank until you refresh the page, where it shows a status of "Error starting palace server". This status is incorrect though because if I use 'ps' it shows the server is in fact running. I'll make another post regarding this.
 
Last edited:
This is the start-stop script (I probably should comment my html files the same way :-S)
PHP:
#!/usr/local/bin/php

<?php
////////////////////////////////////////////////
// File: start-stop.php
// Version: 0.3
// Last changed: 03.22.2009 12:46
// Purpose: Start or stop Pserver
// Author: Al Zuniga
// Copyright: (c) 2009 Al Zuniga
// Product: PServer DirectAdmin Plugin
////////////////////////////////////////////////

  $homedir = getenv('HOME');                        // Get's the user's home directory

  $pserverpid = '/palace/logs/pserver.pid';         // Pserver.pid file location in
                                                    // relation to $homedir

  $pidexist = file_exists($homedir . $pserverpid);  // Checks for pserver.pid file

  if($pidexist == 1){                               // If pserver.pid does exist
    exec($homedir . '/bin/stop-palace');            // stop the pserver

    $pserverstate = checkStatus("stop");     // Check if server stopped
  }
  else{
    exec($homedir . '/bin/start-plugin');           // If pserver.pid does not exist
                                                    // start the pserver
    $pserverstate = checkStatus("start");
  }


/*************** checkStatus() *****************
 * Function to check the status of the pserver
 * and return it's current state.
 **********************************************/

  function checkStatus($check){

    $checkforpid = file_exists($homedir . $pserver.pid); // Check for pserver.pid

    switch($check){

      case "stop":                                       // Check if successful in
        if($checkforpid == 1){                           // shutting down pserver
          $status = "Error stopping Palace Server.";
        }
    else{
          $status = "Palace Server stopped.";
        }
    break;

      case "start":                                      // Check if successful in
        if($checkforpid == 1){                           // starting pserver
          $status = "Palace Server is up.";
        }
    else{
          $status = "Error starting Palace Server.";
        }
    break;

      default:                                           // Unknown error starting-
        $status = "Unknown error.";                      // stopping pserver
    }

    return $status;
  }
/************** End checkStatus() *************/
echo $pserverstate;
?>
 
Since I don't use a copy of the software you're using this with, it took a little while to get it setup to where I could have an environment setup like your's so I could find the problem. Here's your script back in working order:
PHP:
#!/usr/local/bin/php

<?php
////////////////////////////////////////////////
// File: start-stop.php
// Version: 0.3
// Last changed: 03.22.2009 12:46
// Purpose: Start or stop Pserver
// Author: Al Zuniga
// Copyright: (c) 2009 Al Zuniga
// Product: PServer DirectAdmin Plugin
////////////////////////////////////////////////

$homedir = getenv('HOME');								// Get's the user's home directory

$pserverpid = '/palace/logs/pserver.pid';						// Pserver.pid file location in relation to $homedir

$pidexist = file_exists($homedir . $pserverpid);					// Checks for pserver.pid file

/*************** checkStatus() *****************
 * Function to check the status of the pserver
 * and return it's current state.
 **********************************************/

function checkStatus($check){

	global $homedir;									// Make variables
	global $pserverpid;								// usable in function
	
    $checkforpid = file_exists($homedir . $pserverpid);				// Check for pserver.pid

    switch($check){

      case "stop":										// Check if successful in
        if($checkforpid){									// shutting down pserver
			$status = "Error stopping Palace Server.";
        } else{
	        $status = "Palace Server stopped.";
        }
		break;

    case "start":										// Check if successful in
        if($checkforpid){									// starting pserver
			$status = "Palace Server is up.";
        } else{
			$status = "Error starting Palace Server.";
        }
		break;

	default:										// Unknown error starting-
		$status = "Unknown error.";						// stopping pserver
		break;
    }

    return $status;
}
/************** End checkStatus() *************/

if($pidexist){
	exec($homedir . '/bin/stop-palace');						// Stop server

	$pserverstate = checkStatus("stop");					// Check if server stopped
} else {
	exec($homedir . '/bin/start-plugin');						// Start server

	$pserverstate = checkStatus("start");					// Check if server started
}

echo $pserverstate;

?>
Sorry for moving some stuff around. I typically like to have my PHP scripts go in order by: Variables, Functions, Actions/Content. Your problem was not globalizing the variables. When a variable is declared outside a function, you have to use "global $variable;" to make it useable inside it.
 
Last edited:
Thanks Dravu, I really appreciate your help with this.

In the past when I have used globals, they are outside of the scope of the functions that call them, but with PHP I see this is not the case.

There's no problem with the rearranging of the code. It's good to see a 'format' per se', versus just putting the code in as you go (like me :-S ) lol.

Would you mind if you I gave you credit in the script, since you did contribute to it?

Thanks again for all your help, it is greatly appreciated.
 
Thanks Dravu, I really appreciate your help with this.

In the past when I have used globals, they are outside of the scope of the functions that call them, but with PHP I see this is not the case.

There's no problem with the rearranging of the code. It's good to see a 'format' per se', versus just putting the code in as you go (like me :-S ) lol.

Would you mind if you I gave you credit in the script, since you did contribute to it?

Thanks again for all your help, it is greatly appreciated.
No problem and I leave that up to you. :)

Also, I forgot, but you also made a small typo on one line:
PHP:
$checkforpid = file_exists($homedir . $pserver.pid);

That made it so that variable always returned false which means it always thought the file was non-existant. The smallest things cause the biggest headaches. :D
 
No problem and I leave that up to you. :)

Also, I forgot, but you also made a small typo on one line:
PHP:
$checkforpid = file_exists($homedir . $pserver.pid);
That made it so that variable always returned false which means it always thought the file was non-existant. The smallest things cause the biggest headaches. :D

I noticed you updated the code without the header(). I had an issue with it as well.

As far as the:
PHP:
$checkforpid = file_exists($homedir . $pserver.pid);

Would I still need to append the '.pid' to the $pserver variable although it is in the earlier declaration?
PHP:
$pserverpid = '/palace/logs/pserver.pid';

I would like to credit you in the script, would you prefer 'Dravu' or another name?
 
This line:
PHP:
$checkforpid = file_exists($homedir . $pserver.pid);
Would need to be:
PHP:
$checkforpid = file_exists($homedir . $pserverpid);
Leave the variable declaration like it is.

I had the headers in there as it was suggested by DA, but adding it made things a bit more complicated. Since things worked without putting the headers, it's probably best just to leave it out like you did.

You can just use "Dravu". :)
 
It appears the status of the server is now correct, but for some reason "Palace server is up" status will not return to the page. I looked over the both the html page and the start-stop.raw and can't seem to find an issue with the code. I'm thinking it has to do with the HTTP headers.

I found out the reason the header() portion of the PHP was not working because there can not be absolutely any white space before the <?php or after the ?> tags.

Example (Doesn't work):
PHP:
#!/usr/local/bin/php

<?php header("HTTP/1.1 200 OK"); ?>
The above will not work because of the white space between the:
PHP:
#!/usr/local/bin/php
WHITESPACE
<?php header("HTTP/1.1 200 OK"); ?>
or the white space after the:
PHP:
<?php header("HTTP/1.1 200 OK"); ?>
WHITESPACE
both of these situations will throw the errors we were probably seeing.

Example (Works):

#!/usr/local/bin/php
<?php header("HTTP/1.1 200 OK"); ?><!-- No white space after this -->

As I am writing this, I tried to correct this in my HTML file thinking maybe the AJAX/javascript request was causing the issue. I am going to try it as the DA instructions say and I will let you know.
 
It worked perfectly for me. Try going to the start-stop.raw file directly and see what's being outputted to the page. Also, you're right about whitespace at the top. Things can come after the headers, but not before as the headers are supposed to be the first thing sent. The only exception is using the output buffer:
http://us2.php.net/ob_start
 
Back
Top