Kevin Yank chapter 7 add and edit joke form

Hi there !

I am reading Kevin Yank’s book ‘Build Your Own Database Driven Website Using PHP and SQL’ and I have trouble with some code in chapter 7. In this book, we have a joke database containing jokes, their author, date etc… Now, we are installing a CMS. In the CMS, there is a form page to add a new joke, assign an author and a category to the joke contained in different sql tables. The problem is when I click the “Add new joke” link, nothing happens. It stays on the searchform.html.php page. Here is the code (a little bit long sorry):

searchform.html.php

<?php include_once $_SERVER['DOCUMENT_ROOT'] .'/includes/helpers.inc.php'; ?>
<!DOCTYPE html>

<html lang="en">
 <head>
     <meta charset="utf-8">
     <title>Manage Jokes</title>
 </head>
<body>
	
<h2>Manage Jokes</h2>
<p><a href="?add">Add new joke</a></p>
<form action = "" method ="get">
    <p>View jokes satisfying the following criteria :</p>
    <div>
    <label for = "author">By author: </label>   
        <select name="author" id="auhtor">
        <option value="">Any author</option>
        <?php foreach ($authors as $author): ?>
        <option value = "<?php htmlout($author['id']); ?>"><?php htmlout($author['name']); ?> </option>    
        <?php endforeach ?>
        </select>
    </div>
    <div>
         <label for="category">By category:</label>
           <select name="category" id="category">
         <option value="">Any category</option>
         <?php foreach ($categories as $category): ?>
         <option value="<?php htmlout($category['id']); ?>"><?php
         htmlout($category['name']); ?></option>
         <?php endforeach; ?>
         </select>
    </div>
    <div>
         <label for="text">Containing text:</label>
         <input type="text" name="text" id="text">
    </div>
    <div>
         <input type="hidden" name="action" value="search">
         <input type="submit" value="Search">
 </div>
 </form>
 <p><a href="..">Return to JMS home</a></p>
 </body>
</html>

form.html.php

<?php include_once $_SERVER['DOCUMENT_ROOT'] .'/includes/helpers.inc.php'; ?>
<!DOCTYPE html>
<html lang="en">
    
 <head>
     <meta charset="utf-8">
     <title><?php htmlout($pageTitle); ?></title>
     <style type="text/css">
     textarea {
     display: block;
     width: 100%;
     }</style>
 </head>
    
 <body>
 <h2><?php htmlout($pageTitle); ?></h2>
     <form action="?<?php htmlout($action); ?>" method="post">
     <div>
         <label for="text">Type your joke here:</label>
         <textarea id="text" name="text" rows="3" cols="40"><?php
         htmlout($text); ?></textarea>
     </div>
     <div>
             <label for="author">Author:</label>
             <select name="author" id="author">
             <option value="">Select one</option>
             <?php foreach ($authors as $author): ?>
             <option value="<?php htmlout($author['id']); ?>"<?php
             if ($author['id'] == $authorid)
             {
             echo ' selected';
             }
             ?>><?php htmlout($author['name']); ?></option>
             <?php endforeach; ?>
             </select>
     </div>
         
     <fieldset>
         <legend>Categories:</legend>
         <?php foreach ($categories as $category): ?>
         <div><label for="category<?php htmlout($category['id']);
         ?>"><input type="checkbox" name="categories[]"
         id="category<?php htmlout($category['id']); ?>"
         value="<?php htmlout($category['id']); ?>"<?php
         if ($category['selected'])
         {
         echo ' checked';
         }
         ?>><?php htmlout($category['name']); ?></label></div>
         <?php endforeach; ?>
     </fieldset>
         
     <div>
         <input type="hidden" name="id" value="<?php
         htmlout($id); ?>">
         <input type="submit" value="<?php htmlout($button); ?>">
     </div>
     </form>
     
 </body>
</html>

index.php The only relevant part here is starting at //OPEN the add joke form, but I will put it all anyway in case there is something else wrong

<?php 

// Display search form

include $_SERVER['DOCUMENT_ROOT'] . '/includes/db.inc.php';

//Select authors
try
{
 $result = $pdo->query('SELECT id, name FROM author');
}
catch (PDOException $e)
{
 $error = 'Error fetching authors from database!';
 include 'error.html.php';

 exit();
}

foreach ($result as $row)
{
 $authors[] = array('id' => $row['id'], 'name' => $row['name']);
}

//select categories
try
{
 $result = $pdo->query('SELECT id, name FROM category');
}
catch (PDOException $e)
{
 $error = 'Error fetching categories from database!';
 include 'error.html.php';
 exit();
}

foreach ($result as $row)
{
 $categories[] = array('id' => $row['id'], 'name' => $row['name']);
}
include 'searchform.html.php';


//--------------------------------


// search a joke 

// SELECT : The basic SELECT statement : if nothing is selected it will select all the jokes
if (isset($_GET['action']) and $_GET['action'] == 'search')
{
 include $_SERVER['DOCUMENT_ROOT'] . '/includes/db.inc.php';
 
    
 $select = 'SELECT id, joketext';
 $from = ' FROM joke';
 $where = ' WHERE TRUE';}



//now if someting else is selected...

 $placeholders = array();

//An author is selected
 if ($_GET['author'] != '')
 {
 $where .= " AND authorid = :authorid";
 $placeholders[':authorid'] = $_GET['author'];
 }

// An category is selected
if ($_GET['category'] != '') 
 {
 $from .= ' INNER JOIN jokecategory ON id = jokeid';
 $where .= " AND categoryid = :categoryid";
 $placeholders[':categoryid'] = $_GET['category'];
 }

// Some search text was specified
 if ($_GET['text'] != '') 
 {
 $where .= " AND joketext LIKE :joketext";
 $placeholders[':joketext'] = '%' . $_GET['text'] . '%';
 }


//final selection with the criteria    
try
 {
 $sql = $select . $from . $where ;  //SELECT STRING
 $s = $pdo->prepare($sql);   //PREPARE
$s->execute($placeholders);     // execute 
 }
 catch (PDOException $e)
 {
 $error = 'Error fetching jokes.';
 include 'error.html.php';
 exit();
 }
 foreach ($s as $row)  //puts each joke selected with criteria into an arraw
 {
 $jokes[] = array('id' => $row['id'], 'text' =>
 $row['joketext']);
 }
 include 'jokes.html.php';  //runs the result template
 exit();

//--------------------------

//OPEN the add joke form


include_once $_SERVER['DOCUMENT_ROOT'] .'/includes/magicquotes.inc.php';

if (isset($_GET['add']))
{
 $pageTitle = 'New Joke';
 $action = 'addform';
 $text = '';
 $authorid = '';
 $id = '';
 $button = 'Add joke';
 include $_SERVER['DOCUMENT_ROOT'] . '/includes/db.inc.php';
 
    // Build the list of authors
 try
 {
 $result = $pdo->query('SELECT id, name FROM author'); // select authors available to assign that joke
 }
 catch (PDOException $e)
 {
 $error = 'Error fetching list of authors.';
 include 'error.html.php';
 exit();
 }
 foreach ($result as $row)  //puts the authors into an array
 {
 $authors[] = array('id' => $row['id'], 'name' => $row['name']);
 }
 // Build the list of categories
 
    try
 {
 $result = $pdo->query('SELECT id, name FROM category');
 }
 
    catch (PDOException $e)
 {
 $error = 'Error fetching list of categories.';
 include 'error.html.php';
 exit();
 }
 
    foreach ($result as $row)
 {
 $categories[] = array('id' => $row['id'],'name' => $row['name'],'selected' => FALSE); //sets selected to false be default
 }
 include 'form.html.php';
 exit();
}

//add a submitdd joke INSERT
if (isset($_GET['addform']))
{
 include $_SERVER['DOCUMENT_ROOT'] . '/includes/db.inc.php';
 
    if ($_POST['author'] == '') //if no author selected, error message
 {
 $error = 'You must choose an author for this joke.
 Click &lsquo;back&rsquo; and try again.';
 include 'error.html.php';
 exit();
 }
    
    try //insert the joke into database    
 {
 $sql = 'INSERT INTO joke SET
 joketext = :joketext,
 jokedate = CURDATE(),
 authorid = :authorid';
 $s = $pdo->prepare($sql);
 $s->bindValue(':joketext', $_POST['text']);
 $s->bindValue(':authorid', $_POST['author']);
 $s->execute();

 }
 catch (PDOException $e)
 {
 $error = 'Error adding submitted joke.';
 include 'error.html.php';
 exit();
 }
    
$jokeid = $pdo->lastInsertId();  //retrieves the ID of the newly inserted joke
}

//add the category(ies) to the newly added joke 

if (isset($_POST['categories']))
 {
 
    try //insert into jokecategory the category id and joke id
 {
 $sql = 'INSERT INTO jokecategory SET
 jokeid = :jokeid,
 categoryid = :categoryid';
 $s = $pdo->prepare($sql);
     
 
        foreach ($_POST['categories'] as $categoryid)   //create a single variable from each of the array value (category id)
 {
 $s->bindValue(':jokeid', $jokeid);
 $s->bindValue(':categoryid', $categoryid);
 $s->execute();
 }
 }
 catch (PDOException $e)
 {
 $error = 'Error inserting joke into selected categories.';
 include 'error.html.php';
 exit();
 }
 
 header('Location: .');
 exit();
}

//--------------------------

//OPEN edit joke form


if (isset($_POST['action']) and $_POST['action'] == 'Edit')
{
 include $_SERVER['DOCUMENT_ROOT'] . '/includes/db.inc.php';
 
    try     //select the info about the existing joke
 {
 $sql = 'SELECT id, joketext, authorid FROM joke WHERE id = :id';
 $s = $pdo->prepare($sql);
 $s->bindValue(':id', $_POST['id']);
 $s->execute();
 }

 catch (PDOException $e)
 {
 $error = 'Error fetching joke details.';
 include 'error.html.php';
 exit();
 }
    // creates the form with appropriate variables
 $row = $s->fetch();
 $pageTitle = 'Edit Joke';
 $action = 'editform';
 $text = $row['joketext'];
 $authorid = $row['authorid'];
 $id = $row['id'];
 $button = 'Update joke';
    
 // Build the list of authors
 try //selects authors
 {
 $result = $pdo->query('SELECT id, name FROM author');
 }
 catch (PDOException $e)
 {
 $error = 'Error fetching list of authors.';
 include 'error.html.php';
 exit();
 }
 foreach ($result as $row)  //puts author into an array
 {
 $authors[] = array('id' => $row['id'], 'name' => $row['name']);
 }
    
    
 // Get list of categories containing this joke
 try
 {
 $sql = 'SELECT categoryid FROM jokecategory WHERE jokeid = :id';
 $s = $pdo->prepare($sql);
 $s->bindValue(':id', $id);
 $s->execute();
 }
 catch (PDOException $e)
 {
 $error = 'Error fetching list of selected categories.';
 include 'error.html.php';

 exit();
 }
 foreach ($s as $row) //puts already selected category id into an array
 {
 $selectedCategories[] = $row['categoryid'];
 }
    
 // Build the list of all categories
 try
 {
 $result = $pdo->query('SELECT id, name FROM category');
 }
 catch (PDOException $e)
 {
 $error = 'Error fetching list of categories.';
 include 'error.html.php';
 exit();
 }
 foreach ($result as $row)
 {
 $categories[] = array(
 'id' => $row['id'],
 'name' => $row['name'],
 'selected' => in_array($row['id'], $selectedCategories));
 }
 include 'form.html.php';
 exit();
}


//UPDATE info of editing a joke 

if (isset($_GET['editform']))
{
 include $_SERVER['DOCUMENT_ROOT'] . '/includes/db.inc.php';
 
    if ($_POST['author'] == '') //if no author selected 
 {
 $error = 'You must choose an author for this joke.
 Click &lsquo;back&rsquo; and try again.';
 include 'error.html.php';
 exit();
 }
    
 
    try //Update the info of the joke
 {
 $sql = 'UPDATE joke SET
 joketext = :joketext,
 authorid = :authorid
 WHERE id = :id';
 $s = $pdo->prepare($sql);
 $s->bindValue(':id', $_POST['id']);
 $s->bindValue(':joketext', $_POST['text']);
 $s->bindValue(':authorid', $_POST['author']);
 $s->execute();
 }
 
    catch (PDOException $e)
 {
 $error = 'Error updating submitted joke.';
 include 'error.html.php';
 exit();
 }
 
    try //update (delete) the category id if it changed
 {
 $sql = 'DELETE FROM jokecategory WHERE jokeid = :id';
 $s = $pdo->prepare($sql);
 $s->bindValue(':id', $_POST['id']);
 $s->execute();
 }
 catch (PDOException $e)
 {
 $error = 'Error removing obsolete joke category entries.';
 include 'error.html.php';
 exit();

 }
    
 if (isset($_POST['categories']))       //if new category assigned 
 {
    try
 {
 $sql = 'INSERT INTO jokecategory SET
 jokeid = :jokeid,
 categoryid = :categoryid';
 $s = $pdo->prepare($sql);
 
        foreach ($_POST['categories'] as $categoryid)
 {
 $s->bindValue(':jokeid', $_POST['id']);
 $s->bindValue(':categoryid', $categoryid);
 $s->execute();
 }
 }
 
     catch (PDOException $e)
 {
 $error = 'Error inserting joke into selected categories.';
 include 'error.html.php';
 exit();
 }
 }
 header('Location: .');
 exit();
}

//--------------------------

//DELETE A JOKE

if (isset($_POST['action']) and $_POST['action'] == 'Delete')
{
 include $_SERVER['DOCUMENT_ROOT'] . '/includes/db.inc.php';
 
    // Delete category assignments for this joke
 
    try
 {
 $sql = 'DELETE FROM jokecategory WHERE jokeid = :id';
 $s = $pdo->prepare($sql);
 $s->bindValue(':id', $_POST['id']);
 $s->execute();
 }
 
    catch (PDOException $e)
 {
 $error = 'Error removing joke from categories.';
 include 'error.html.php';
 exit();
 }
 // Delete the joke
 
    try
 {
 $sql = 'DELETE FROM joke WHERE id = :id';
 $s = $pdo->prepare($sql);
 $s->bindValue(':id', $_POST['id']);
 $s->execute();
 }
 catch (PDOException $e)
 {
 $error = 'Error deleting joke.';
 include 'error.html.php';
 exit();
 }
 header('Location: .');
 exit();
}


?>

Thank you !

And you’re running it by running index.php, not by running searchform.html.php directly? As I see it, you need to run index, it will include the searchform, which will then call itself when you click the link. If you run searchform directly, it will just call itself, and it doesn’t include any code to deal with adding a joke.

I haven’t been through all your code, but in this line

<form action="?<?php htmlout($action); ?>" method="post">

you seem to have a spurious ?

I hadn’t noticed that, but I think it’s because the code re-uses the same form, and passes the action through in the $action variable. So the action value should end up as something like "?action=Edit" when the form is rendered.

I say “should”, because there’s also a bit missing from that. The code to process the various stages checks for the presence of either $_POST['action'] or $_GET['action'], which would be fine, except that while there is a variable called $action created, the actual parameter name is not output. So I suspect it should really look like

<form action="?action=<?php htmlout($action); ?>" method="post">

or maybe the various lines that assign $action should include the parameter name.

I’m struggling to follow the code a bit as it seems to be overly complex in an attempt to re-use the form whether creating new or editing existing jokes. I can’t see a point where there would be a variable called $_POST['action'] coming in from that form, for example, but it might be in there somewhere. The form action would come in as $_GET, and the only hidden variable I see is the joke id.

Perhaps the OP could confirm exactly which “Add” link is not working - the initial one, or the button to submit the form once the new details have been entered.

1 Like

I have find the mistake !! There was a pair of curly brakets {} missing in my if statement of my basic search form in :if (isset($_GET['action']) and $_GET['action'] == 'search') {{ ... } include 'jokes.html.php'; //runs the result template exit();} So it was only running the joke.html.php in all the index …!! Thank you everyone

@Gandalf no it is part of the php declaration code , but thanks

@droopsnoot in your first comment you said I was running index.php. I always had that question in mind. When I run my main folder, which program this folder runs first ? I assume now it is my index.php, but what if I wanted to run another program first ? How do I do that

1 Like

That depends on the configuration of your http server. They’re often configured to something like “index.*”, or maybe “default.*”, or maybe both in a sequence. Then there will be an extension search sequence, so for example it might look for index.php, then index.shtml, then index.html, then index.htm. It’s down to your server.

I believe that in some servers you can also apply rules in the .htaccess file to provide different options. Or you can just specify the complete URL rather than just the folder name.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.