Viewed   66 times

How to make a html button execute a php script ?

I am working on a login system where only one user can login and whenever other users try to login, it should give them the warning pop up message saying another user is already logged in - Do you want to take over from them?

  • If userA is already logged in and userB tries to login then it should show on the popup as userA is already logged in, do you want to take over?.
  • Now for userA behind the scene, we will take away write access and show them another popup message that your write access is revoked.

Second point I can handle it later on but as of now I am focus on doing the point one. Below is my code in which I am trying to achieve the first point at LINE A -

if (isset($_POST['user_name'], $_POST['user_pass']) && $_POST['user_login'] == 1) {
    //Assigning posted values to variables.
    $username = $_POST['user_name'];
    $password = $_POST['user_pass'];

    //Checking the values are existing in the database or not
    $stmt = $connect->prepare("SELECT user_pass FROM userspanel WHERE user_name=?");
    $stmt->bind_param('s', $username);
    $stmt->execute();
    $result = $stmt->get_result();
    $user_from_db = $result->fetch_object();

    if ($user_from_db && password_verify($password, $user_from_db->user_pass)) {

        $_SESSION['user_name'] = $username;

        $sql = "SELECT * FROM trace_users where open='true'";
        $result1 = mysqli_query($connect, $sql);
        if($result1 = mysqli_query($connect, $sql)){
            if(mysqli_num_rows($result1) > 0){
                while($row = mysqli_fetch_array($result1)){
                    if($row['open'] == "true") {
                        if(!isset($_SESSION['pageadmin'])) {
                            $message = "user " . $row['user_name'] . " is logged in. Do you want to take over ?";
                            // LINE A
                            // how to show pop up button which shows $message on it
                            // and add action on ok and cancel button here?
                        }
                        break;
                    }
                }
            } else{
                $_SESSION['pageadmin'] = true;
                $open = "true";
                $read_access = "1";
                $write_access = "1";
                $stmt = $connect->prepare("UPDATE trace_users SET open=?, read_access=?, write_access=? WHERE user_name=?");
                $stmt->bind_param('ssss', $open, $read_access, $write_access, $username);
                $stmt->execute();
            }
        }

    } else {
        echo "Invalid username and password";
    }
}

I want to achieve the following tasks but I am confused on how to achieve it -

  • At LINE A, I want to show a pop up message saying "Previous user is logged in. Do you want to take over?" with Ok and Cancel buttons.
  • Once I click on Ok button on that pop up message then I want to execute certain code in php let's say print hello world for now and if I click the cancel button on that pop then I don't want to do anything.

In short, I want to achieve two things:

1. Create a popup message with Ok and Cancel buttons at Line A.
2. On clicking Ok button, I want to execute php script and on clicking Cancel button I don't want anything to happen.

 Answers

2

Basic scenario:

  • Store currently authenticated user's unique id and time in a .txt file in the following format (as JSON):
json_encode(['user_id' => 1, 'created_at' => (new DateTime('now'))->format('Y-m-d H:i:s')]);
  • Check the stored user_id and created_at fields in the file when a user attempts to sign in.
  • If the file is empty, log the user in and write user's unique id and time to the file.
  • If the file is not empty and user_id field is same as the id of the user who attempts to log in and created_at field is not older than 12 hours ago (or your custom logic), just update created_at field in the file and log the user in.
  • If the file is not empty and user_id field is same as the id of the user who attempts to log in, but passed more than 12 hours (or your custom logic), ask the user if he/she want to take over another user.
  • If the file is not empty and user_id field is not same as the id of the user who attempts to log in ask the user if he/she want to take over another user.

Basic implementation:

  1. Create a .txt file in your project directory.
  2. Add these helper functions to your project (helpers.php in my case):
if (! function_exists('check_auth')) {
    function check_auth(): bool
    {
        if (! isset($_SESSION['user_id'])) {
            return false;
        }

        if (! file_exists('current_user.txt') || filesize('current_user.txt') === 0) {
            return true;
        }

        $trace = json_decode(file_get_contents('current_user.txt'));

        // You can write your own logic here.
        return (int) $trace->user_id === $_SESSION['user_id'] && (new DateTime($trace->created_at))->modify('+12 hours') > new Datetime('now');
    }
}

if (! function_exists('logout'))
{
    function logout()
    {
        if (isset($_SESSION['user_id'])) {
            $trace = json_decode(file_get_contents('current_user.txt'));

            if ((int) $trace->user_id === $_SESSION['user_id']) {
                file_put_contents('current_user.txt', '');
            }

            unset($_SESSION['user_id']);
        }
    }
}

if (! function_exists('redirect')) {
    function redirect(string $url, int $status_code = 303): void
    {
        header('Location: ' . $url, true, $status_code);
        die();
    }
}
  1. Create a login page (login.php in my case):
<?php

declare(strict_types=1);

// Start session.
session_start();

// Include helper functions.
require_once 'helpers.php';

// Redirect user to homepage/dashboard if authenticated.
if (check_auth()) {
    redirect('index.php');
    return;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $pdo = new PDO('mysql:host=[DB_HOST];dbname=[DB_NAME];charset=utf8mb4', '[DB_USERNAME]', '[DB_PASSWORD]', [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
        PDO::ATTR_EMULATE_PREPARES   => false,
    ]);
    $stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
    $stmt->execute([$_POST['email']]);
    $user = $stmt->fetch();

    if (! ($user && password_verify($_POST['password'], $user->password))) {
        echo json_encode([
            'success' => false,
            'message' => 'These credentials don't match our records.',
        ]);
        return;
    }

    // Log user in if another is not authenticated.
    if (filesize('current_user.txt') === 0) {
        file_put_contents('current_user.txt', json_encode([
            'user_id'    => $user->id,
            'created_at' => (new DateTime('now'))->format('Y-m-d H:i:s'),
        ]));

        $_SESSION['user_id'] = $user->id;

        echo json_encode([
            'success' => true,
        ]);

        return;
    }

    $trace = json_decode(file_get_contents('current_user.txt'));

    // Log user in if the last authenticated user is himself/herself.
    if ((int) $trace->user_id === $user->id) {
        $trace->created_at = (new DateTime('now'))->format('Y-m-d H:i:s');

        file_put_contents('current_user.txt', json_encode($trace));

        $_SESSION['user_id'] = $user->id;

        echo json_encode([
            'success' => true,
        ]);

        return;
    }

    // Ask user if he/she wants to take over.
    echo json_encode([
        'success'  => false,
        'takeover' => true,
        'message'  => 'Another user is logged in. Do you want to take over?',
    ]);

    return;
}

?>

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Login</title>
</head>
<body>
    <form method="post" id="form">
        <div>
            <label for="email">Email:</label>
            <input type="email" id="email" name="email" placeholder="Email" required>
        </div>
        <div>
            <label for="password">Password:</label>
            <input type="password" id="password" name="password" placeholder="Password">
        </div>
        <div>
            <span id="message" style="color: red;"></span>
        </div>
        <button>Log in</button>
    </form>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script>
        $(function () {
            $('#form').submit(function (e) {
                e.preventDefault();
                $('#message').text('');

                $.post('login.php', $(this).serialize(), function (response) {
                    const res = JSON.parse(response);

                    if (res.takeover) {
                        // Ask user if he/she wants to take over. If user confirms, run `confirmed()` function.
                        confirm(res.message) && confirmed();
                        return;
                    }

                    if (res.success) {
                        // Login is successful. Reload or redirect user to another page.
                        location.reload();
                    } else {
                        // Login failed. Incorrect email or password entered.
                        $('#message').text(res.message || '');
                    }
                });
            });

            function confirmed() {
                $.post('confirmed.php', function (response) {
                    const res = JSON.parse(response);
                    console.log(res.data);
                });
            }
        });
    </script>
</body>
</html>
  1. Check if another user took over currently authenticated user in your pages (index.php in my case):
<?php

declare(strict_types=1);

// Start session.
session_start();

// Include helper functions.
require_once 'helpers.php';

?>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Home</title>
</head>
<body>
<?php if (check_auth()): ?>
    Welcome friend.
<?php else: ?>
    <a href="/login.php">Log in</a>
<?php endif; ?>

<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
    $(function () {
        // Check if another user took over currently authenticated user in every 3 seconds.
        setInterval(function () {
            $.post('check.php', function (response) {
                let res = JSON.parse(response);
                if (! res.auth && res.redirect) {
                    location.replace(res.redirect);
                }
            });
        }, 3000);
    });
</script>
</body>
</html>
  1. Implement your check logic (check.php in my case):
<?php

declare(strict_types=1);

// Start session.
session_start();

// Include helper functions.
require_once 'helpers.php';

if (! check_auth()) {
    logout();

    echo json_encode([
        'auth'     => false,
        'redirect' => 'login.php',
    ]);

    return;
}

echo json_encode([
    'auth' => true,
]);

  1. Finally, create your action/function for the case when user confirms to take over (confirmed.php in my case):
<?php

declare(strict_types=1);

// Start session.
session_start();

// Include helper functions.
require_once 'helpers.php';

/**
 * Run your action here if user confirms to take over another user.
 */
echo json_encode([
    'data' => 'User confirmed to take over another user.',
]);

Tested and works fine. But you should customize it for your needs.

Tuesday, December 27, 2022
1

In case it could be a javascript issue about override functions, do that:

<script>
(function(window, undefined){
    var win = window.open('your_url', '_blank');
    win.focus();
})(window);
</script>

That should make you can't use functions from other javascript code out of your function(window, undefined) wrapper-

Wednesday, October 26, 2022
2

You can use $("#bsModal3").modal('show'); inside your result.

See more about modal methods

$.ajax({
  type: 'post',
  url: 'test2.php',
  dataType: 'json',
  data: {
    txt: txtbox,
    hidden: hiddenTxt
  },
  cache: false,
  success: function(returndata) {
    if (returndata[4] === 1) {

      $("#bsModal3").modal('show');

    } else {
      // other code
    }
  },
  error: function() {
    console.error('Failed to process ajax !');
  }
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>




<!-- Modal -->
<div class="modal fade" id="bsModal3" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-sm">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title" id="mySmallModalLabel">Modal title</h4>
      </div>
      <div class="modal-body">
        Your content goes here...
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>
Monday, August 29, 2022
 
kez
 
kez
1

You could just write afterFind function in your model:

protected function afterFind()
{
    // convert to readable time format while viewing
    $this->readabletime = date('m/d/Y H:i:s', $this->time);

    parent::afterFind();
}

This way wherever readabletime is used, it will convert it to your desired format. CActiveRecord afterFind

Saturday, October 29, 2022
 
jrista
 
1

Please rethink your solution as this will likely create more problems (particularly security issues) than it solves. By having a PHP script execute your program you run the danger of a user entering the following into your form:

John Doe; rm windows*

or

John Doe; rm d:name*

You want to limit user input to a very controlled subset so that you won't get malicious command injection.

PHP does provide an exec() but be very careful.

Thursday, August 4, 2022
 
peon
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :