Clean PHP – Managing our first management

Here we go. In our admin folder, create users.php. This will be our user management page. It’s easy to work with this new page. Simply copy the index.php page and change some text on it.

admin/usermanagement.php

1
2
3
<?php require_once($_SERVER['DOCUMENT_ROOT'].'/admin/header.php'); ?>
    <p>Users</p>
<?php require_once($_SERVER['DOCUMENT_ROOT'].'/admin/footer.php'); ?>

And don’t forget our header. We need to modify it to include our new linked file.

admin/header.php

1
2
3
4
5
6
....
    <!-- NEW CODE -->
            <ul>
                <li><a href="/admin/">Dashboard</a></li>
                <li><a href="/admin/usermanagement.php">User Managememt</a></li>
            </ul>

We can leave the .php on these files, since it’s an admin section and only we are working with them for now. Later you can change them by altering our .htaccess file.

Next thing to do is to get and display our users. Let’s see how that works out for us:

admin/usermanagement.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php require_once($_SERVER['DOCUMENT_ROOT'].'/admin/header.php'); ?>
    <p>Users</p>
    <table>
        <thead>
        <tr>
            <th>ID</th>
            <th>username</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>E-Mail Address</th>
        </tr>
        </thead>
        <tbody>
        <?php
        $users = getProfiles();
        foreach ($users as $user) {
            ?>
            <tr>
                <td><?php echo $user['id']; ?></td>
                <td><?php echo $user['username']; ?></td>
                <td><?php echo $user['fname']; ?></td>
                <td><?php echo $user['lname']; ?></td>
                <td><?php echo $user['email']; ?></td>
            </tr>
            <?php
        }
        ?>
        </tbody>
    </table>
<?php require_once($_SERVER['DOCUMENT_ROOT'].'/admin/footer.php'); ?>

Yes, I’ve used the table element. This is exactly what tables were meant for originally. Data. This is proper use for tables. Eventually, we’ll paginate the end users when we have too many to handle. Let’s see how we can add the other actions to our document.

We could create a useredit.php page, but then we’ll end up with 5 or more pages for each entity, like users, videos, posts, etc. Five pages for each “section” will become a nightmare. Let’s place our code in a function. Let’s call this function the listAction function. This will tell us that this is a viewable list of items. Do this:

admin/usermanagement.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/admin/header.php');

function listAction() {
    ?>
        <p>Users</p>
        <table>
            ...
        </table>

    <?php
}

require_once($_SERVER['DOCUMENT_ROOT'].'/admin/footer.php');
?>

Although we created this function, nothing is calling it, so we see nothing on the page, just header and footer stuff. This will get our data back:

admin/usermanagement.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/admin/header.php');

listAction();

require_once($_SERVER['DOCUMENT_ROOT'].'/admin/footer.php');


function listAction() {
    ?>
        <p>Users</p>
        <table>
            ...
        </table>

    <?php
}
?>

Notice, function at the bottom. Function called from between the header and footer lines. But what if we wanted to add MORE functions to this page, so that we can add, edit, update, delete, view individual user.

Adding functionality to our page. Rather, multi-functionality. Where we call the listAction function, make that a switch statement. Use your querystring variables. Remember, ugly URLs are not important to us in the admin section. One step at a time.

Our switch statement at the top of the page should be like this:

1
2
3
4
5
6
7
8
9
10
<?php
if ( isset($_GET['action']) ) {
    switch ($_GET['action']) {
        default:
            listAction();
    }
} else {
    listAction();
}
?>

Agreed, this looks like a lot of work for the listing of one page. Think in the future. We can make hundreds of different cases based on the “action” querystring variable being passed in. In the above example, we simply run the listAction function in case we don’t list an action, or if we list an action that’s not listed in the soon to be case statements.

In our listAction function, go ahead and modify the listing of the end users as such:

1
2
3
4
5
6
7
8
9
10
...
                <tr>
                    <td><?php echo $user['id']; ?></td>
                    <td><a href="?action=view&username=<?php echo $user['username']; ?>"><?php echo $user['username']; ?></a></td>
                    <td><?php echo $user['fname']; ?></td>
                    <td><?php echo $user['lname']; ?></td>
                    <td><?php echo $user['email']; ?></td>
                    <td></td>
                </tr>
...

We basically created a link that adds our requested action whenever we click on the user’s username value. In this case, our action querystring variable will be called “view”. This “view” will be processed in our switch/case conditional statement as such:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
if ( isset($_GET['action']) ) {
    switch ($_GET['action']) {
        case "view":
            viewAction();
            break;
        default:
            listAction();
    }
} else {
    listAction();
}
?>

This case statement is dependent on our viewAction() function that does not currently exist, so let’s make one:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
function viewAction() {
    $username = $_GET['username'];
    $user = getProfile($username);

    if ($user) {
        ?>
        <a href="usermanagement.php">« Back to users</a>
        <table>
            <tr>
                <td><?php echo $user['id']; ?></td>
                <td><?php echo $user['username']; ?></td>
                <td><?php echo $user['fname']; ?></td>
                <td><?php echo $user['lname']; ?></td>
                <td><?php echo $user['email']; ?></td>
            </tr>
        </table>
        <a href="?action=edit&username=<?php echo $user['username']; ?>">Edit User</a>
        <?php
    }
}
?>

Clicking on the username from the usermanager list, will take you to the individual user’s page. So we’ve accomplished quite a feat. Let’s recap and see what we did so far with our user management page, or module, or whatever you want to call it.

We have created a list of users, and clicking on one of the user’s username will take us to the individual user’s page.

Here’s the rest of the functions for editing, updating, and deleting:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
function editAction () {
    $username = $_GET['username'];
    $user = getProfile($username);

    if ($user) {
        ?>
        <form action="?action=update&username=<?php echo $username; ?>" method="post">

            <label for="fname">First Name</label>
            <input type="text" name="fname" value="<?php echo $user['fname']; ?>">

            <label for="lname">Last Name</label>
            <input type="text" name="fname" value="<?php echo $user['lname']; ?>">

            <label for="email">E-Mail Address</label>
            <input type="text" name="fname" value="<?php echo $user['email']; ?>">

            <input type="submit" value="Update">
        </form>
        <a href="?action=view&username=<?php echo $username; ?>">Cancel</a>
        <?php
    }
}

function updateAction () {
    $username = $_GET['username'];

    $sql = "UPDATE profiles SET
            `fname` = '"
.$_POST['fname']."',
            `lname` = '"
.$_POST['lname']."',
            `email` = '"
.$_POST['email']."'
            WHERE username = '"
.$username."'";
    mysql_query($sql);
    header('Location: usermanagement.php?action=view&username='.$username);
}

function deleteAction () {
    $username = $_GET['username'];

    $sql = "DELETE FROM profiles WHERE username = '".$username."'";
    header('Location: usermanagement.php');
}
?>

Ok, before continuing, we need to sort some things out. Some of our functions include header redirects. Unfortunately, this is after we’re already rendered some things in the header. We could take care of this with a templating system, or re-arranging our switch case router and controller by splitting it in two and determining what actions should be taken before and/or after the header has been rendered.

There is a 3rd choice, however. Read on to see what it is.