0

how can I show all the users in the users table in the database in a html table? I have to show all the users in a html table and each user can be selected using a check box. The selected users are then deleted from the database. I am using the technique mvc and I have a page "DeleteUser" that contains only the html, a controller and a public file.

View/DeleteUser.php contains:

 <form method="post" action="../public/deleteUser.php">
    <table>  
        <tr>
           <td>#</td>
           <td>Username</td>
           <td>First name</td>
           <td>Last name</td>         
           <td>City</td>
           <td>Gender</td>
           <td>E-mail</td> 
           <td>Check</td> 
        </tr>

        <tr>
           <td><input type="submit" name="submit-deleteuser" value="Delete user"/></td>
        </tr>
    </table>
  </form>

public/deleteUser.php contains:

  $controller = new DeleteUserController();
  $view = $controller->invoke();
  $view->render();

The invoke() method in Controller/DeleteUserController.php contains:

  class DeleteUserController {

     public $user;
     public $users;
     public $userRepository;
     public $view;

     public function __construct() {
        $username = $_SESSION['username']; 
        $this->userRepository = new UserRepository();
        $this->user = $this->userRepository->findByUsername($username);    
        $this->users = array();
        $this->view = new View('DeleteUser');
        $db = Database::getInstance();
     }

     public function listUsers() {
        $this->users = $this->userRepository->fetchAll();
        foreach($this->users as $u) {
           $str = "<tr>
                       <td><?php $u->getId() ?></td>
                   </tr>";    
        }
     }

     public function deleteUsers() {
        if(isset($_POST['submit-deleteuser'])) {
           $del_id = $_POST['users'];
           foreach($del_id as $value) {
              $value->delete();
           }
        }      
     }

     public function work() {
        $this->listUsers();
        $this->deleteUsers();
     }

     public function invoke() {
        $this->work();
        $this->view->setData('user', $this->user);
        return $this->view;   
     }

If I had not had to use mvc I would have done so:

  <table>  
     <tr>
        <td>#</td>
        <td>Username</td>
        <td>Fisrt name</td>
        <td>Last name</td>         
        <td>City</td>
        <td>Gender</td>
        <td>E-mail</td> 
        <td>Check</td> 
     </tr>
     <?php
        $utente = $_SESSION['username'];
        $query = "SELECT * FROM users ORDER BY id";
        $result = mysql_query($query);
        while($row = mysql_fetch_array($result)) {
              echo "<tr>
                       <td>$row[id]</td>
                       <td>$row[username]</td>
                       <td>$row[fisrt_name]</td>
                       <td>$row[last_name]</td>
                       <td>$row[city]</td>
                       <td>$row[gender]</td>
                       <td>$row[email]</td>    
                       <td><input type=\"checkbox\" name=\"users[]\" value=\"" .$row['id']. "\"></td>   
                    </tr>";                                    
           }
        }
     ?>
     <tr>
        <td colspan="9"><input type="submit" name="submit-deleteuser" value="Delete users"/></td>
     </tr>
  </table>

But now I do not know how to do. The two methods listUsers() and deleteUsers() are wrong and do not know how to complete them or correct them. First it was simple, I put the php code that showed users in the html tag that I wanted (<table>...</table>) but now? I do not know how to handle this thing. Give me advice? Thank you :)


fetchAll() is:

    public function fetchAll(){
    $db = Database::getInstance();
    $stmt = $db->prepare("SELECT * FROM `users`");
    $stmt->execute();
    $users = array();
    while($result = $stmt->fetch()) {
        $users[] = User::load($result);
    }   
    return $users;
}

1 Answers1

1

The attempt to use the MVC pattern is admirable, but a little bit off in this case :). What is missing, is the concept of controller actions.

Maybe try to restructure your code something like this:

Directory Structure

  • controllers/
    • UsersController.php
  • models/
    • UsersModel.php
  • core
    • View.php
  • views/
    • header.tpl.php
    • footer.tpl.php
    • users/
      • list.tpl.php
      • delete.tpl.php
  • users.php

1. Start with a users model that interacts with the database

class UsersModel {

    public function fetchAll() {
        $result = array();

        // Build SELECT query, fetch all users from db., and store in $result
        // ...

        return $result;
    }

    public function deleteMany(array $ids) {
        $result = array();

        // Build DELETE query, execute it, and store the number of affected records in $result
        // ...

        return $result;
    }
}

2. Make a UsersController instead of a DeleteUserController. Create two methods: listUsersAction and deleteUsersAction.

class UsersController {

    public function listUsersAction() {
        $model = new UsersModel();
        $data = $model->fetchAll();

        return new View(
            'users/list',
            $data
        );
    }

    public function deleteUsersAction() {
        // This is simplistic, but the idea is to get the required input from the request (and actually validate it!)
        // Also see the users/list template further down
        $ids = $_POST['user_ids'];

        $model = new UsersModel();
        $numRecords = $model->deleteMany($ids);

        return new View(
            'users/delete',
            array('deleted_records' => $numRecords)
        );
    }
}

3. Our View class should store the template name and the view data, and be able to render the template

class View {

    public static $viewDirectory;

    public $template;
    public $data = array();

    public function __construct($template, $data) {
        if (!View::$viewDirectory) {
            View::$viewDirectory = dirname(__FILE__) . '/views/';
        }

        $this->template = $template;
        $this->data = $data;
    }

    public function render() {

        // Make the data available in the template
        $data = $this->data;

        // Include the template.
        require(realpath(View::$viewDirectory . $this->template . '.tpl.php'));
    }
}

4. The users/list template could then look something like this

// views/users/list.tpl.php
<form action="/users.php?action=delete" method="post">
<?php foreach ($data as $user): ?>
<div>
    <input type="checkbox" name="user_ids[<?= $user['id'] ?>]" value="1"/>
    <?= $user['username'] ?>
</div>
<?php endforeach; ?>
</form>

5. Tie everything together in users.php

<?php
    // users.php

    // (include all previously defined classes here)

    // We'll want to include a HTML header of some sort:
    include("views/header.tpl.php");

    /**********
     *  Poor man's routing; valid urls:
     *  /users.php?action=listUsers
     *  /users.php?action=deleteUsers with POST data
     */

    // Determine the action from the GET parameter. If no action is set, the default action is listUsers

    //$action = (array_key_exists('action', $_GET) ? $_GET['action'] : 'listUsers');

    // Equivalent of:
    if (array_key_exists('action', $_GET)) {
        $action = $_GET['action'];
    } else {
        $action = 'listUsers';
    }
    //--

    $actionMethod = $action . 'Action';

    $controller = new UsersController();

    if (method_exists($controller, $actionMethod)) {
        $view = $controller->$actionMethod();
        $view->render();

    } else {
        echo "<div class='error'>The action '$action' is invalid for the Users controller.'</div>";
    }

    // We'll want to include a footer as well:
    include("views/footer.tpl.php");
?>
wkampmann
  • 1,405
  • 12
  • 13
  • Thanks for the reply! I did not understand this line: `$action = (array_key_exists('action', $_GET) ? $_GET['action'] : 'listUsers');` –  Jan 12 '14 at 20:26
  • I replaced it with an equivalent if/else construct in the code. It looks if the action parameter has been set in the URL and assigns it to `$action` if that is the case. Otherwise it sets `$action` to 'listUsers', i.e. the default action. The ternary condition operator `$cond ? $trueval : $falseval` is explained [here](http://stackoverflow.com/questions/1080247/what-is-the-php-operator-called-and-what-does-it-do) – wkampmann Jan 12 '14 at 20:57