INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

Need a button

Need a button

(OP)
I need to create a button within a PHP script that, when clicked, takes some information from the script and runs another PHP script to perform a MySQL query and display the result in a popup window. I believe AJAX is the way to do it but I don't know where to start. I need guidance on the AJAX part.

RE: Need a button

I'm sorry, I can't resist it: "Button, Button, who's got the button?" spin2
Seriously, let me make sure I have this straight: You want to put a button on the Client page that passes data to and executes a script on the server?

RE: Need a button

here is a trivial example (this is not necessarily a good approach. it is included to show you how it might be done).

CODE --> formpage.php

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8"/>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    /* attach event listeners to the buttons */
    $('.myButton').on('click', function(e){
        e.preventDefault();
        var id=$(this).attr('actionid');

        /* make ajax call */
        $.ajax(
                {
                    async:      false,
                    url:        'ajaxServer.php',
                    type:       'POST',
                    dataType:   'json',
                    data:       {id:id},
                    success:    function(data){
                        if(data.result == 'ok'){
                            alert(data.data);
                        }else{
                            alert(data.error);
                        }
                    }
                });
    });
});
</script>
</head>
<body>
<?php
doList();
?></body>
</html>
<?php 

include_once 'dbconnect.php';
function doList(){
    $query = "Select * from users where deleted != 1";
    $result = mysql_query($query) or die(mysql_error());
    $first = true;
    $cellFormat = "<td>%s</td>";
    $rowFormat = "<tr>%s</td>";
    $headingCellFormat = "<th>%s</th>";
    $headingFormat = "<thead>%</thead>";
    $buttonFormat = '<button class="myButton" actionid="%s">Lookup</button>';
    if(mysql_num_rows() > 0) echo '<table>';
    while($row = mysql_fetch_assoc($result)):
        if($first):
            $count = count($row);
            $headings = array_keys($row);
            $output = '';
            foreach($headings as $heading):
                $output .= sprintf($headingCellFormat, htmlspecialchars($heading));
            endforeach;
            $output .= sprintf($headingCellFormat, 'Action');
            $output = sprintf($headingFormat, sprintf($rowFormat, $output));
            echo $output;
            $first = false;
        endif;
        $output = '';
        foreach($row as $item):
            $output .= sprintf($cellFormat, htmlspecialchars($item));
        endforeach;
        $button = sprintf($buttonFormat, $row['id']);
        $output .= sprintf($cellFormat, $button);
        $output = sprintf($rowFormat, $output);
        echo $output;
    endwhile;
    if(!$first) echo '</table>';
    
}
?> 

CODE --> ajaxServer.php

<?php 
if(!isset($_POST['id'])) die('');
include_once 'dbConnect.php';
$query = 'Select * from users where id="%s"';
$query = sprintf($query, mysql_real_escape_string($_POST['id']));
$result = mysql_query($query);
if($result):
	$row = mysql_fetch_assoc($result);
	echo json_encode(array('result'=>'ok', 'data'=>$row));
	die;
else:
	echo json_encode(array('result'=>'error', 'errorMessage'=>mysql_error()));
	die;
endif;
?> 

RE: Need a button

(OP)
Jpadie: thanks, I'll go through this to see if I can follow it

Prattaratt: Yes. The initial script does a mysql query and presents some information. One bit of the information is excluded (actually not part of the query) and a button is put in its place. On clicking that button, another script runs, validates that the user has access to the information, runs another query, then displays the output in a popup.

RE: Need a button

the above does not provide for a popup. it just splashes a js alert box. if you want a pop-up, you don't actually really need ajax at all. just spawn a child window and provide a url that has the id of the record populated.

e.g.

CODE --> onclick

onclick='window.open("windowServer.php?id=3", "some title");' 

CODE --> jQuery

$('.myButton').on('click',function(){
 var childWindow = window.open("windowServer.php?id=" . $(this).attr('actionid'), "some title");
}); 

I prefer the jQuery approach for readability.
you could also add a native event listener.

RE: Need a button

(OP)
Alert box is ok. Actually better.

RE: Need a button

(OP)
In the code above, I need to change this:

CODE

include_once 'dbconnect.php';
function doList(){ 

to this:

CODE

function doList(){
include_once 'dbconnect.php'; 

for it to work. Is that normal? A good idea?

RE: Need a button

it depends on the contents of your dbconnect.php file. typically if it just has this

CODE

mysql_connect($host, $user, $pwd);
mysql_select_db($dbName); 
then the connection can be in the global scope and thus automatically will be available in every functional scope too.

If you are using mysqli or PDO then something like this would be more normal

CODE --> dbConnect.php

$pdo = new PDO("mysql:host=$host;dbName=$dbName", $user, $pwd); 

CODE

include_once 'dbConnect.php';

function doList(){
 global $pdo;
 ...
} 

if you have to put the include in to the functional scope it is because the mysql resource handle is being stored in a variable rather than 'floating' as part of the library. so you have to make the variable ($conn, sometimes) available to the function. using the global keyword does this. Or, as you have done, you can put the include into the function. In which case do not use include_once, but include. Note that this is less good overall from a performance and memory handling perspective.

RE: Need a button

(OP)
I'm making progress, but how can I get a variable from PHP into the function without using globals?

RE: Need a button

typically by passing the argument

CODE

doList($something);

function doList($myVar){

} 

RE: Need a button

(OP)
Here is what I have. What am I missing?

CODE

<body>
<?php
doList();
?></body>
</html>
<?php
$test = '1234';
function doList($test){
    $buttonFormat = '<button class="myButton" actionid="%s">Lookup</button>';
    $button = sprintf($buttonFormat, $test);
    echo $button;
}
?> 

RE: Need a button

php is linear. like most languages.

so try this


CODE

<body>
<?php
$test = 1234;

doList( $test );
?></body>
</html>
<?php
function doList($id){
    $buttonFormat = '<button class="myButton" actionid="%s">Lookup</button>';
    $button = sprintf($buttonFormat, $id);
    echo $button;
}
?> 

the value of $test is passed to doList and is available within the function as $id. note that this creates a _copy_ of the variable and is not a pointer to the variable. This can sometimes have material benefits, and equally sometimes is not what you want. In either case if you are coming from a C or C# or C++ etc background, knowing the difference is important.

RE: Need a button

(OP)
That works. Now I have a problem when I try to implement sessions with this. The problem is with the second script (ajaxServer.php above).

Here is the example trying to use sessions. $user is set by the session creation script. The $user is validated correctly, but it dies at the json_encode line.

CODE

<?php 
$allowedusers = array("john", "bob", "bill", "jane");
if (in_array($user, $allowedusers)) {
	$result 			= mysql_query("SELECT secretvoodoo from voodoo_list WHERE id = $id");
	$row 				= mysql_fetch_array($result);
	$secretvoodoo		= $row['secretvoodoo'];
	if($secretvoodoo):
		echo json_encode(array('result'=>'ok', 'data'=>$secretvoodoo));
		die;
	else:
		echo json_encode(array('result'=>'error', 'errorMessage'=>mysql_error()));
		die;
	endif;
} else {
	echo json_encode(array('result'=>'error', 'errorMessage'=>"unauthorized"));
	die;
}
?> 

If I define $user specifically in the script as below and omit the session script, it works ok.

CODE

<?php 
$user = "john";
$allowedusers = array("john", "bob", "bill", "jane");
if (in_array($user, $allowedusers)) {
	$result 			= mysql_query("SELECT secretvoodoo from voodoo_list WHERE id = $id");
	$row 				= mysql_fetch_array($result);
	$secretvoodoo		= $row['secretvoodoo'];
	if($secretvoodoo):
		echo json_encode(array('result'=>'ok', 'data'=>$secretvoodoo));
		die;
	else:
		echo json_encode(array('result'=>'error', 'errorMessage'=>mysql_error()));
		die;
	endif;
} else {
	echo json_encode(array('result'=>'error', 'errorMessage'=>"unauthorized"));
	die;
}
?> 

Here is the session script for reference.

CODE

session_start(); 

// set timeout period in seconds
$inactive = 900;
// check to see if $_SESSION['timeout'] is set
if(isset($_SESSION['timeout']) ) {
	$session_life = time() - $_SESSION['timeout'];
	if($session_life > $inactive) { 
		session_destroy();
		header("Location: /login.php"); 
	}
}
$_SESSION['timeout'] = time();


if (!isset($_SESSION['user'])) {
	echo ("Unauthorized Access");
	echo ("<br />");
	echo "<META HTTP-EQUIV='Refresh' Content='0; URL=../login.php'>";
	exit();
}
$user = $_SESSION['user']; 

RE: Need a button

not convinced that your session script covers all the use cases. here is a slight reorganisation of your code

CODE

<?php
if(session_id() == '') session_start(); 
// set timeout period in seconds
$inactive = 900;
if(isset($_SESSION['user'])){
	$user = $_SESSION['user'];
	$timeout = isset($_SESSION['timeout']) ? $_SESSION['timeout'] : 1000;
	$session_life = time() - $timeout;
	if ($session_life > $inactive) {
		unset($_SESSION);
		session_destroy();
		session_write_close();
		header("Location: /login.php");
		die(); //always explicitly kill the script after a redirect
	} else {
		$_SESSION['timeout'] = time();
		session_write_close();
	}
} else {
	unset($_SESSION);
	session_destroy();
	echo <<<HTML
<!DOCTYPE HTML>
<html>
<head>
<title>Unauthorized Access</title>
<META HTTP-EQUIV="Refresh" Content='5; URL=../login.php'>
</head>
<body>
Unauthorized access
</body>
</html>
HTML;
}
exit;
?> 

and please also try an alternative to the main script

CODE

<?php 
require_once 'session.php';
$allowedusers = array("john", "bob", "bill", "jane");
if (in_array($user, $allowedusers)) {
	$result 			= mysql_query("SELECT secretvoodoo from voodoo_list WHERE id = $id");
	if($result):
		$row 				= mysql_fetch_array($result);
		if($row):
			$secretvoodoo		= $row['secretvoodoo'];
			echo json_encode(array('result'=>'ok', 'data'=>$row['secretvoodoo']));
			die;
		else:
			echo json_encode(array('result'=>'error', 'errorMessage'=>'No records found'));
			die;
		endif;
	else:
		echo json_encode(array('result'=>'error', 'errorMessage'=>mysql_error()));
		die;
	endif;
} else {
	echo json_encode(array('result'=>'error', 'errorMessage'=>"unauthorized"));
	die;
}
?> 

RE: Need a button

(OP)
There's something in there that PHP doesn't like. On the second script, I get an error referring to an unexpected '}' at the } else {. Does mixing the : and { cause that?

RE: Need a button

Can you provide the actual error message.

RE: Need a button

just fyi - it works fine for me.

on the first script, make _sure_ that the HTML; is absolutely flush to the left hand side and that your code editor does not enforce any silly indenting (several code editors do). if you cannot guarantee this then change the heredoc for single quotes.

CODE

echo '
<!DOCTYPE HTML>
<html>
<head>
<title>Unauthorized Access</title>
<META HTTP-EQUIV="Refresh" Content='5; URL=../login.php'>
</head>
<body>
Unauthorized access
</body>
</html>
'; 

RE: Need a button

(OP)
I fixed it by making all of the if statements consistent using {} instead of :. Now I need to map out all of my scripts a little more closely because it's still sticking. Might take a day.

RE: Need a button

(OP)
Is there a way to debug the ajax? The second script gets up to the echo json_encode line, but I can't see if it's getting past it.

RE: Need a button

easiest way is in firebug on firefox. just take a look at what is returned in the xhr code.

make sure that error_reporting is set to E_ALL and error display turned in, in php. if you don't have access to php.ini (restart the server after each change) you can add this to the beginning of each script

CODE

ini_set('display_errors', true);
error_reporting(E_ALL); 

if by any chance you don't have json_encode as a function on your server then you may need to install that. assuming you are on linux and have an apt based package manager you would run this command

CODE

sudo apt-get install php5-json 

this is particularly relevant on recent versions of ubuntu.

RE: Need a button

(OP)
Using Firebug, the response is getting back to the main script, but the alert box isn't coming up.

RE: Need a button

(OP)
Something else I noticed. When I include the session script, firebug doesn't show a json tab. When I don't include it, the json tab is there.

RE: Need a button

if firebug does not show a json tab it means that it is not receiving json type data back from your server.

so there is an error somewhere that is interrupting the flow. this should be displayed in the firebug response, providing that you have properly turned on error display and output.

try navigating directly to the ajaxserver and see what output you get.

RE: Need a button

(OP)
I get nothing when I hit ajaxserver.php directly.

RE: Need a button

then probably you have not got the error display and reporting set properly. triple check that. force an error in your code and make sure that something is spat out.

RE: Need a button

(OP)
I'm definitely getting errors in the phperrors.log, just not related to this. When I enable the following I get the same errors just displayed in the output.

CODE

ini_set('display_errors', true);
error_reporting(E_ALL); 

RE: Need a button

great. what are the errors (verbatim, please)

RE: Need a button

(OP)
There is no error. None. Everything is happy as far as the log goes. I get errors for unrelated things, so I know the logs are working.

RE: Need a button

I see.

Can you then post the scripts verbatim (delete the passwords).

Another thing to try is to force output with some echo footprinting. It will break the json but help the debug.

RE: Need a button

(OP)
Here they are:

formpage.php

CODE

<!DOCTYPE HTML>
<?php 
include("dbconnect.php");
require($_SERVER['DOCUMENT_ROOT'].'/user_header.php');
if (! @mysql_select_db("$database") ) {
  echo( "<P>Unable to locate the " .
        "database at this time.</P>" );
  exit();
}
?>
<html>
<head>
<meta charset="utf-8"/>
<script type="text/javascript" src="jquery-1.10.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    /* attach event listeners to the buttons */
    $('.myButton').on('click', function(e){
        e.preventDefault();
        var id=$(this).attr('actionid');
        /* make ajax call */
        $.ajax(
                {
                    async:      false,
                    url:        'ajaxserver.php',
                    type:       'POST',
                    dataType:   'json',
                    data:       {id:id},
                    success:    function(data){
                        if(data.result == 'ok'){
                            alert(data.data);
                        }else{
                            alert('You are not authorized to view this information.');
                        }
                    }
                });
    });
});
</script>
</head>
<body>
<?php
if (isset ($_GET['id'])) {
	$voodooid 	= $_GET['id'];
}
doList($voodooid);
?></body>
</html>
<?php
function doList($id){
	$buttonFormat = '<button class="myButton" actionid="%s">Show Voodoo</button>';
    $button = sprintf($buttonFormat, $id);
    echo $button;
}
?> 

ajaxserver.php

CODE

<?php 
include("dbconnect.php");
require($_SERVER['DOCUMENT_ROOT'].'/user_header.php');
if (! @mysql_select_db("$database") ) {
  echo( "<P>Unable to locate the " .
        "database at this time.</P>" );
  exit();
}
if(!isset($_POST['id'])) die('');
$id = $_POST['id'];
$allowedusers = array("bill", "john");
if (in_array($user, $allowedusers)) {
	$result 			= mysql_query("SELECT secretvoodoo from voodoo_list WHERE id = $id");
	$row 				= mysql_fetch_array($result);
	$secretvoodoo		= $row['secretvoodoo'];
	if($secretvoodoo):
		echo json_encode(array('result'=>'ok', 'data'=>$secretvoodoo));
		die;
	else:
		echo json_encode(array('result'=>'error', 'errorMessage'=>mysql_error()));
		die;
	endif;
} else {
	echo json_encode(array('result'=>'error', 'errorMessage'=>"unauthorized"));
	die;
}
?> 

user_header.php

CODE

<?php
if(session_id() == '') session_start();  
// set timeout period in seconds
$inactive = 900;
// check to see if $_SESSION['timeout'] is set
if(isset($_SESSION['timeout']) ) {
	$session_life = time() - $_SESSION['timeout'];
	if($session_life > $inactive) { 
		session_destroy();
		header("Location: /login.php"); 
	}
}
$_SESSION['timeout'] = time();
if (!isset($_SESSION['user'])) {
	echo ("Unauthorized Access");
	echo ("<br />");
	echo "<META HTTP-EQUIV='Refresh' Content='0; URL=../login.php'>";
	exit();
}
$user = $_SESSION['user'];
?> 

login.php

CODE

<?php
include("dbconnect.php");
if (!$connect) {
  echo( "<P>Unable to connect to the " .
        "database server at this time.</P>" );
  exit();
}
if (! @mysql_select_db("$database") ) {
  echo( "<P>Unable to locate the " .
        "database at this time.</P>" );
  exit();
}
if(session_id() == '') session_start(); 
$client_ip = $_SERVER['REMOTE_ADDR'];
// authenticate.php contains the ldap authentication function
include("authenticate.php");
// check to see if user is logging out
if(isset($_GET['out'])) {
    // destroy session
    session_unset();
    $_SESSION = array();
    unset($_SESSION['user'],$_SESSION['access']);
    session_destroy();
}
// check to see if login form has been submitted
if(isset($_POST['userLogin'])){
    // run information through authenticator function at authenticate.php
	// the authenticate function returns true if the user is authenticated
    if(authenticate($_POST['userLogin'],$_POST['userPassword'])) {
        // authentication passed
		$error = 0;
		$user = $_POST['userLogin'];
        header("Location: /index.php");
        die();
    } else {
        // authentication failed
        $error = 1;
		$user = $_POST['userLogin'];
    }
}
// output error to user
if ($error == 1) {
    unset($_SESSION['user'],$_SESSION['access']);
    session_destroy();
	echo "Login failed: Incorrect user name, password, or permissions<br />";
}
// output logout success
if (isset($_GET['out'])) echo "Logout successful<br />";
?>
<TITLE>Login</TITLE>
<form method="post" action="login.php">
    User: <input type="text" name="userLogin" /><br />
    Password: <input type="password" name="userPassword" /><br />
    <input type="submit" name="submit" value="Submit" />
</form> 

RE: Need a button

you have not included dbConnect.php or authenticate.php (so I cannot tell what happens with the session inside those files, nor if there are any errors). Are you _certain_ that there is nothing in those files that could cause an error, warning or notice to be thrown? If any html is output then the session can fail and the ajax will receive html rather than json.

the ajaxserver now has a debug function. this will break the json but will provide feedback that will be visible either by browsing direct to the ajaxserver.php file or by the console in firebug.

CODE --> user_header.php

<?php
ini_set('display_errors', true);
error_reporting(E_ALL);
if(session_id() == '') session_start();  
// set timeout period in seconds
$inactive = 900;
// check to see if $_SESSION['timeout'] is set
if(isset($_SESSION['timeout']) ) {
    $session_life = time() - $_SESSION['timeout'];
    if($session_life > $inactive) { 
        session_destroy();
        session_write_close();
        header("Location: /login.php"); 
        exit; /* very important */
    }
}
$_SESSION['timeout'] = time();
if (!isset($_SESSION['user'])) {
    echo ("Unauthorized Access");
    echo ("<br />");
    echo "<META HTTP-EQUIV='Refresh' Content='0; URL=../login.php'>";
    exit();
}
$user = $_SESSION['user'];
?> 

CODE --> ajaxserver.php

<?php 
function isDebug(){
    return isset($_POST['debug']) || isset($_GET['debug']);
}
function footprint($message = ''){
    if(empty($message)) return;
    if(isDebug()) echo $message . "\n";
}

require_once "dbconnect.php";
footprint("connected to db");

require_once $_SERVER['DOCUMENT_ROOT'].'/user_header.php';
footprint("done sessions");

if(!function_exists('json_encode')):
    footprint('json_encode function does not exist');
    die;
endif;

if (! @mysql_select_db($database) ):
    echo json_encode(array( 'result'=>'error',
                            'errorMessage'=>'Unable to locate the database at this time.'));
    die;
else:
    footprint('selected database');
endif;

/*  change back to POST when the scripts are working */
/*  useful to allow GET requests while debugging */
if(!isset($_REQUEST['id'])):
    echo json_encode(array( 'result'=>'error',
                            'errorMessage'=>'No ID provided.'));
    die;
endif;

$id = mysql_real_escape_string($_REQUEST['id']); //always escape and enquote all user input to avoid sql injection
$allowedusers = array("bill", "john");
if (in_array($user, $allowedusers)):

    footprint('user is allowed');

    $result = @mysql_query("SELECT secretvoodoo from voodoo_list WHERE id = '$id'");
    
    if($result):
        footprint('secretvoodoo query done');
        $row = @mysql_fetch_assoc($result);
        if(!$row):
            echo json_encode(array( 'result'=>'error', 
                                    'errorMessage'=>"Nothing found for that ID"
                            ));
            die;
        else:
            echo json_encode(array( 'result'=>'ok', 
                                    'data'=>$row['secretvoodoo']
                                ));
            die;
        endif;  
    else:
        echo json_encode(array(     'result'=>'error', 
                                    'errorMessage'=>mysql_error()
                                ));
        die;    
    endif;
else:
    echo json_encode(array(         'result'=>'error', 
                                    'errorMessage'=>"unauthorized"
                                ));
    die;
endif;
?> 

CODE --> formpage.php

<!DOCTYPE HTML>
<html>
<?php 
function doList($id){
    if(empty($id))return;
    $buttonFormat = '<button class="myButton" actionid="%s">Show Voodoo</button>';
    printf($buttonFormat, $id);
}
require_once "dbconnect.php";
require_once $_SERVER['DOCUMENT_ROOT'].'/user_header.php';
if (! @mysql_select_db("$database") ) :
  echo( "<P>Unable to locate the " .
        "database at this time.</P>" );
  exit();
endif;
$voodooid = isset($_GET['id']) ? $_GET['id'] : '';
?>
<head>
<meta charset="utf-8"/>
<script type="text/javascript" src="jquery-1.10.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    /* attach event listeners to the buttons */
    $('.myButton').on('click', function(e){
        e.preventDefault();
        var id=$(this).attr('actionid');
        /* make ajax call */
        $.ajax(
                {
                    async:      false,
                    url:        'ajaxserver.php?debug=1',
                    type:       'POST',
                    dataType:   'json',
                    data:       {id:id},
                    success:    function(data){
                        if(data.result == 'ok'){
                            alert(data.data);
                        }else{
                            alert(data.errorMessage);
                        }
                    },
                    complete:   function(data){
                        console.log(data);
                        }
                });
    });
});
</script>
</head>
<body>
<?php doList($voodooid); ?></body>
</html> 

CODE --> login.php

<?php
function showForm(){
    ?>
<!DOCTYPE HTML>
<html>
<meta charset="utf-8"/>
<head>
<TITLE>Login</TITLE>
</head>
<body>
<form method="post" action="login.php">
    User: <input type="text" name="userLogin" /><br />
    Password: <input type="password" name="userPassword" /><br />
    <input type="submit" name="submit" value="Submit" />
</form> 
</body>
</html>
<?php 
}

require_once "dbconnect.php";
if (!$connect) {
  echo( "<P>Unable to connect to the " .
        "database server at this time.</P>" );
  exit();
}
if (! @mysql_select_db("$database") ) {
  echo( "<P>Unable to locate the " .
        "database at this time.</P>" );
  exit();
}
if(session_id() == '') session_start(); 
$client_ip = $_SERVER['REMOTE_ADDR'];
// authenticate.php contains the ldap authentication function
require_once "authenticate.php";
// check to see if user is logging out
if(isset($_GET['out'])):
    // destroy session
    $_SESSION = array();
    session_destroy();
    session_write_close();
    echo "Logout successful<br />";
    showForm();
elseif(isset($_POST['userLogin'])):     // check to see if login form has been submitted
    // run information through authenticator function at authenticate.php
    // the authenticate function returns true if the user is authenticated
    if(authenticate($_POST['userLogin'],$_POST['userPassword'])):
        // authentication passed
        $error = 0;
        $user = $_POST['userLogin'];
        $_SESSION['user'] = $user;
        $_SESSION['timeout'] = time();
        session_write_close();
        header("Location: /index.php");
        die();
    else:
        // authentication failed
        $error = 1;
        $user = $_POST['userLogin'];
        unset($_SESSION['user'],$_SESSION['access']);
        session_destroy();
        session_write_close();
        echo "Login failed: Incorrect user name, password, or permissions<br />";
        showForm();
    endif;
endif;
?> 

RE: Need a button

(OP)
When I hit ajaxserver directly I get {"result":"error","errorMessage":"No ID provided."}. an expected result. Firebug shows nothing. The button on the formpage doesn't work, but is that expected? Firebug shows nothing.

Here are the other scripts.

dbconnect.php

CODE

<?php
$username="vduser";
$password="xxxxx";
$database="voodoo";
$server="localhost";
$connect = @mysql_connect("localhost", "vduser", "xxxxx");
?> 

authenticate.php

CODE

<?php
function authenticate($user, $password) {
	include("ldap.php");  
    $ldap_user_group = "Voodoo";
    $ldap = ldap_connect($LDAPHost) or die("Could not connect to LDAP");	
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3); 
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
    if($bind = @ldap_bind($ldap, $user . $LDAPUserDomain, $password)) {
        $filter = "(sAMAccountName=" . $user . ")";
        $attr = array("memberof");
        $result = ldap_search($ldap, $dn, $filter, $attr);
        $entries = ldap_get_entries($ldap, $result);
        ldap_unbind($ldap);
        foreach($entries[0]['memberof'] as $grps) {
            if (strpos($grps, $ldap_user_group)) $access = 1;
        }
        if ($access != 0) {
            $_SESSION['user'] = $user;
            $_SESSION['access'] = $access;
            return true;
        } else {
            return false;
        }
    } else {
		return false;
    }
}
?> 



RE: Need a button

that's expected. yes.
now try adding an id. ajaxserver.php?id=someid

thanks for posting those two scripts. if you are comfortable that they are functional (and their includes, likewise) then all i would suggest is to comment out this line in my version of login.php (as it is already set within authenticate())

CODE

$_SESSION['user'] = $user; 

RE: Need a button

(OP)
Adding the id works as expected too. {"result":"ok","data":"1234"}

When I hit formpage with or without commenting that line, I get nothing if the user_header is included. Without it, I get the button but it doesn't work.

RE: Need a button

commenting the line won't affect functionality. it's just for cleanliness.

so as I understand it, the script is working at the moment if you point your browser directly at the ajax server. but not if BOTH these two things are true:

1. you load up the form and rely on ajax for server interaction
2. the form includes user_header

however the ajaxserver direct route works fine when user_header is included.

i'm not certain what this indicates as you have not posted any site where we can test this and examine the raw headers and responses. But i suspect that the most likely culprit is somehow related to the session management and/or timeout.

let's try to fix the button before attempting the ajax functionality.

please use this version of user_header.php to test with.

CODE

<?php
ini_set('display_errors', true);
error_reporting(E_ALL);
if(session_id() == '') session_start();  
echo '<pre>';
echo 'Current session data: ';
print_r($_SESSION);
echo '</pre>';
// set timeout period in seconds
$inactive = 900;
// check to see if $_SESSION['timeout'] is set
if(isset($_SESSION['timeout']) ) {
    $session_life = time() - $_SESSION['timeout'];
    if($session_life > $inactive) { 
        session_destroy();
        session_write_close();
        header("Location: /login.php"); 
        exit; /* very important */
    }
}
$_SESSION['timeout'] = time();
if (!isset($_SESSION['user'])) {
    echo "Unauthorized Access";
    echo "<br />";
    echo "REDIRECT SUSPENDED FOR DEBUGGING";
    exit();
}
echo '<pre>Finished parsing user_header.php</pre>';
$user = $_SESSION['user'];
?> 

and then post back the verbatim output please.

RE: Need a button

(OP)
Before I change anyting. I don't think your version of user_header is working at all. I get no prompt to login.

RE: Need a button

if you implement that file you will get some output. if only the content of $_SESSION. that is the first stage in debugging.

but please also comment out the header redirect line. the point is to force the page to remain in place and give you feedback.

RE: Need a button

(OP)
The first time I hit formpage directly, with no id, I get

CODE

Current session data: Array
(
)
Unauthorized Access
REDIRECT SUSPENDED FOR DEBUGGING 

The second time I hit it, I get

CODE

Current session data: Array
(
    [timeout] => 1389622536
)
Unauthorized Access
REDIRECT SUSPENDED FOR DEBUGGING 

RE: Need a button

ok. so the problem is that the user variable is not being set within the session store.

browse to the login page manually and log in.
at the end of login.php before the last endif; insert a line and add this

CODE

else: 
 showform(); 
(this will cause the form to show when you browse there)
once you are logged in, browse back to the form page manually and post back the response.

RE: Need a button

(OP)
After I login, it just goes to a blank page. I think there's a problem with the auth. I get a new error in the php log.

CODE

[13-Jan-2014 10:02:58] PHP Parse error:  syntax error, unexpected T_VARIABLE in C:\test\ldap.php on line 3 

Here is the ldap.php that I forgot to post earlier.

CODE

<?php
$crypt = "xxxxxxxx"
$LDAPHost = "ldaps://ldap.domain.com";
$dn = "dc=domain,dc=com"; 
$LDAPUserDomain = "@domain.com"; 
$LDAPUser = "ldapuser";        
$LDAPUserPasswordHash = "yyyyyyyyyyy=";
$LDAPUserPassword = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($crypt), base64_decode($LDAPUserPasswordHash), MCRYPT_MODE_CBC, md5(md5($crypt))), "\0");
?> 

RE: Need a button

there is an error in your ldap file. a semicolon is missing from the end of line 1.

RE: Need a button

(OP)
Doh! Sorry.

After login, I get:

CODE

Current session data: Array
(
    [timeout] => 1389628547
    [user] => bill
    [access] => 1
)

Finished parsing user_header.php 

When I hit formpage I get the same. When I add the ?id=, I get the same but the button shows up. When I click the button I get nothing.

RE: Need a button

ok. so we seem to be at a point where the user_header is working ok and the session is populating.

on formpage the buttons will show up when the id is populated as a query string. so that is working as you wanted.

so the issue now is what happens when you click the button.
_something_ must happen. firebug (on firefox) should report that there is an XHR request and give details of what that request looked like and what the results of that request was. it should also provide the response.

at the moment the response will be in html form (not ajax) because the debug switch is set. but there will still be some output if the script is being addressed at all.

if there is NO output, then there will also be NO successful XHR request (firebug will inform you) or NO XHR request at all. In which case the issue is in the javascript.

if there is an XHR request but not one that is successful, then usually this is because the address is not accurate. replace the current url with an absolutely qualified url.

if the issue is in the javascript please post the source code of the html rendered page (i.e not the php but the resulting output from the php page)

RE: Need a button

(OP)
Firebug shows only one thing:

CODE

ReferenceError: $ is not defined
formpage.php?id=1001()formpa...id=1001 (line 13)
$(document).ready(function(){ 

Here is the source for the HTML.

CODE

<!DOCTYPE HTML>
<html>
<pre>Current session data: Array
(
    [timeout] => 1389629321
    [user] => bill
    [access] => 1
)
</pre><pre>Finished parsing user_header.php</pre> <head>
<meta charset="utf-8"/>
<script type="text/javascript" src="jquery-1.10.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    /* attach event listeners to the buttons */
    $('.myButton').on('click', function(e){
        e.preventDefault();
        var id=$(this).attr('actionid');
        /* make ajax call */
        $.ajax(
                {
                    async:      false,
                    url:        'ajaxserver.php?debug=1',
                    type:       'POST',
                    dataType:   'json',
                    data:       {id:id},
                    success:    function(data){
                        if(data.result == 'ok'){
                            alert(data.data);
                        }else{
                            alert(data.errorMessage);
                        }
                    },
                    complete:   function(data){
                        console.log(data);
                        }
                });
    });
});
</script>
</head>
<body>
<button class="myButton" actionid="111">Show Voodoo</button></body>
</html> 

RE: Need a button

ah.

then you are not loading jQuery. which means that the jQuery script (jquery-1.10.1.min.js) is not available on your site.

most people reference jQuery on a CDN. replace the src attribute as follows

CODE

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> 

or if you want to host locally, save that file to your web root and reference it properly.

RE: Need a button

(OP)
I broke that when I moved things for testing. I still don't see anything for XHR.

I get:

CODE

connected to db
done sessions
selected database
user is allowed
secretvoodoo query done
{"result":"ok","data":"1234"} 

RE: Need a button

That is working then.
Turn off the debug switch in the JavaScript. And try again.

RE: Need a button

(OP)
That seems to work. Is that it? Should be good? I'll have to go back and check that these new scripts don't break other stuff that uses them. Thanks.

RE: Need a button

should be all that is necessary. do make sure that you completely switch off the debug functionality.

CODE

$.ajax(
                {
                    async:      false,
                    url:        'ajaxserver.php?debug=1',
                    type:       'POST',
                    dataType:   'json',
                    data:       {id:id},
                    success:    function(data){
                        if(data.result == 'ok'){
                            alert(data.data);
                        }else{
                            alert(data.errorMessage);
                        }
                    },
                    complete:   function(data){
                        console.log(data);
                        }
                }); 

RE: Need a button

(OP)
I had a mistake in my final testing. I had $user = 'bill'; specified and the user_header was commented out in the ajaxserver. If I switch it, I get everything but the alert box.

RE: Need a button

please post what firebug reports as the response to the XHR request.

RE: Need a button

(OP)
I don't see XHR anywhere.

RE: Need a button

see this screenshot of a typical firebug (on firefox) installation



xhr is clearly marked as a button to the right of javascript in the Net tab.

RE: Need a button

(OP)
I didn't look at the net pulldown. I was on Console.

This is on the response tab with XHR selected:

CODE

<pre>Current session data: Array
(
    [user] => bill
    [access] => 1
    [timeout] => 1389704898
)
</pre><pre>Finished parsing user_header.php</pre> {"result":"ok","data":"1234"} 

RE: Need a button

you did not go back to the non-debug version of user_header.php

CODE

<?php
ini_set('display_errors', true);
error_reporting(E_ALL);
if(session_id() == '') session_start();  
/*
echo '<pre>';
echo 'Current session data: ';
print_r($_SESSION);
echo '</pre>';
*/
// set timeout period in seconds
$inactive = 900;
// check to see if $_SESSION['timeout'] is set
if(isset($_SESSION['timeout']) ) {
    $session_life = time() - $_SESSION['timeout'];
    if($session_life > $inactive) { 
        session_destroy();
        session_write_close();
        header("Location: /login.php"); 
        exit; /* very important */
    }
}
$_SESSION['timeout'] = time();
if (!isset($_SESSION['user'])) {
    echo "Unauthorized Access";
    echo "<br />";
    echo '<meta http-equiv="refresh" content="5; url=login.php">';
    exit();
}
//echo '<pre>Finished parsing user_header.php</pre>';
$user = $_SESSION['user'];
?> 

RE: Need a button

(OP)
I've narrowed down the problem.
if:
1. A TITLE tag is placed in the user_header.php and
2. Sessions are used to get the user for ajaxserver.php
The alert box doesn't work.

if:
1. A TITLE tag is placed in the user_header.php and
2. $user is defined directly without enabling the session in ajaxserver.php
The alert box works.

RE: Need a button

oh dear.

we seem to have gone back a number of steps.

before, everything was working fine. you were just getting the session data displayed which was breaking the json encoding. stopping the output of session data would make everything work.

you are now saying (and I assume here that you have done NOTHING other than change the code as I posted) that a whole bunch of new symptoms are being exhibited simply by stopping the session data from being output.

If this is the case then either (i) you have introduced errors in following my suggestions; or (ii) you have the most oddly corrupted version of php that I have ever come across.

user_header.php, as posted by you, contains nothing that should be output in an interaction with the server by a user that is already logged in. The only time that there is _ever_ output of any sort is when either the no user is set in the session store (no login) or there is a timeout. In the first instance, output is sent to the user with a meta redirect. In the second instance, the browser is redirected at the http response level back to the login. both of those are scenarios where login must be redone and thus not part of the current process.

there is nothing in the above script (as posted) that can possibly give any output other than as stated. and certainly nothing that contains a <title> tag.

so we will have to wait to hear from you which of (i) and (ii) above you think it is.

Alternatively, provide a link to your site and a login and we can test from here.

RE: Need a button

(OP)
The problem is that I neglected to show an included script that set the title for everything using the user_header.php. I thought, incorrectly, that it was insignificant. I've been using it all along and thus the problem. Here is the included script:

CODE

<?php
echo "<TITLE>VooDoo (DEVELOPMENT)</TITLE>";
echo "<body bgcolor='#F6CECE'>";
?> 

I think the problem is that the occurrence of this <TITLE> tag breaks the <head> tag for the script. (you've now seen every script that this touches).

RE: Need a button

yes - it is definitely a good thing, when asking for help, to be completely transparent as to what all of your scripts (and includes) look like. Otherwise debug efforts are rather difficult.

the user_header script deals with authentication. I would say it is not a great idea to use it for outputting content.

two solutions:

1. move the authentication layer to another include, and in ajaxserver point to the new include rather than user_header
2. change the ajaxserver script to discard the extraneous output

CODE

<?php 
function isDebug(){
    return isset($_POST['debug']) || isset($_GET['debug']);
}
function footprint($message = ''){
    if(empty($message)) return;
    if(isDebug()) echo $message . "\n";
}

ob_start();

require_once "dbconnect.php";
footprint("connected to db");

require_once $_SERVER['DOCUMENT_ROOT'].'/user_header.php';
footprint("done sessions");

if(!isDebug()) ob_end_clean();

if(!function_exists('json_encode')):
    footprint('json_encode function does not exist');
    die;
endif;

if (! @mysql_select_db($database) ):
    echo json_encode(array( 'result'=>'error',
                            'errorMessage'=>'Unable to locate the database at this time.'));
    die;
else:
    footprint('selected database');
endif;

/*  change back to POST when the scripts are working */
/*  useful to allow GET requests while debugging */
if(!isset($_REQUEST['id'])):
    echo json_encode(array( 'result'=>'error',
                            'errorMessage'=>'No ID provided.'));
    die;
endif;

$id = mysql_real_escape_string($_REQUEST['id']); //always escape and enquote all user input to avoid sql injection
$allowedusers = array("bill", "john");
if (in_array($user, $allowedusers)):

    footprint('user is allowed');

    $result = @mysql_query("SELECT secretvoodoo from voodoo_list WHERE id = '$id'");
    
    if($result):
        footprint('secretvoodoo query done');
        $row = @mysql_fetch_assoc($result);
        if(!$row):
            echo json_encode(array( 'result'=>'error', 
                                    'errorMessage'=>"Nothing found for that ID"
                            ));
            die;
        else:
            echo json_encode(array( 'result'=>'ok', 
                                    'data'=>$row['secretvoodoo']
                                ));
            die;
        endif;  
    else:
        echo json_encode(array(     'result'=>'error', 
                                    'errorMessage'=>mysql_error()
                                ));
        die;    
    endif;
else:
    echo json_encode(array(         'result'=>'error', 
                                    'errorMessage'=>"unauthorized"
                                ));
    die;
endif;
?> 

the better is the first solution.

RE: Need a button

(OP)
I've managed to fix it. What are all those footprint lines you added? I can't find any reference to that anywhere.

RE: Need a button

At the top of the script there is a footprint function.
Glad you have it working.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close