[ How to make a CMS 4 ] Validation

Linky
Article Count: 33
Posted: 21st February 03:06am
;Quick Note, This was originally posted on DarkMindZ by mitz247

Validation
There are two main reasons for validating a user's input, the first being security. Let me give you a quick example of how things can go wrong.
Let's say I have a query that searches the database for a value provided by the user. The query code would look something like:
PHP Code:
<?php
$thequery 
'SELECT * FROM products WHERE name = "'.$HTTP_POST_VARS['uservalue'].'"';
$connector->doQuery($thequery);
?>

The query is compiled from a string (SELECT...), and the user's input ($HTTP_POST_VARS...), before being executed. If the user searches for "waffles," then the query executed will be:
mySQL Code:
 
SELECT * FROM products WHERE name = "waffles"
 

And all is well in the world. However, if your system is accessed by someone a little less pleasant (such as a 13-year-old hacker on school vacation), malicious code could be inserted in place of the word "waffles." The best way to protect your system against this type of attack (called query injection) is to check that all input from the user is in the format you expect. It's difficult, if not impossible, to be 100 percent safe, but we can do our best.
The second reason for validation is convenience and error handling. For instance, if you have a form asking for a telephone number, you don't want the user to be able to insert letters by mistake. Likewise, you may wish to check that dates have been entered correctly, or a ZIP/ postal code is valid.
The Solution: a Validator Class
The idea is to create a Validator class that we can call everytime we need to deal with user input. It'll check whether the given input is safe and correct, and if not it will display an error.
To begin with, we'll create the framework for a 'Validator' class:
PHP Code:

<?php
require_once 'SystemComponent.php';
class 
Validator extends SystemComponent {
     var 
$errors// A variable to store a list of error messages
     
...
}
?>

There are a few basic types of data we may need to validate:
* General: Just check something was typed in
* Text Only (i.e., no punctuation or other symbols allowed)
* Text Only and no white spaces allowed
* E-Mail addresses
* Numbers
* Dates
We'll need to write a method for each of these. (A method is a chunk of code that performs a task, which we put inside the class.) I'll give an example of one here, the rest can be found in the source file at the end of the article.
PHP Code:

<?php
function validateNumber($theinput,$description ''){
    if (
is_numeric($theinput)) {
        return 
true// The value is numeric, return true
    
}else{
        
$this->errors[] = $description// Value not numeric! Add error description to list of errors
        
return false// Return false
    
}
}
?>

This method is very simple. It takes the data from the user as input (storing it in $theinput), as well as a message to display if validation fails. It then tests $theinput, and if it's a number returns "true." This will tell our system to move along and not get concerned. If the value turns out not to be numeric, the error message is stored in the variable $errors, which we created in the previous code snippet, above.
Once we've created methods for each of the data types required, only two more methods are needed. The first will allow us to check whether any errors have occurred, and the second returns a list of errors (if there were any). These are both quite straight-forward, and can be found in the source file at the end of the article.
So how do we use our new class with a form? It's simple. Let's say we've created a form to add an e-mail address to a mailing list. There are two text boxes in the form — one for the user's e-mail address, the other for the maximum number of messages they wish to receive per week. Here's how it works:
PHP Code:

<?php
// Gather the data from the form, store it in variables
$userEmail $HTTP_POST_VARS['email'];
$maxMessages $HTTP_POST_VARS['maximum'];

// Create a validator object
require_once('includes/Validator.php');
$theValidator = new Validator();

// Validate the forms
$theValidator->validateEmail($userEmail'Email Address');
$theValidator->validateNumber($maxMessages'Maximum number of messages');

// Check whether the validator found any problems
if ($theValidator->foundErrors() ){
    
// The were errors, so report them to the user
    
echo 'There was a problem with: '.$theValidator->listErrors('<br>'); // Show the errors, with a line between each
}else{
    
// All ok, so now add the user to the mailing list
}
?>

By checking that the user's input was valid, we've reduced a number of security risks, prevented incorrect entries in our database, and helped the user if they've forgotten to fill out any part of the form. We can now integrate this into all of our Intranet's forms, and move
on to some more creative stuff...
Getting Organized
We've covered how to create forms, manipulate the database, and set up a page for creating articles. But having an intranet with hundreds of articles will quickly become disorganized and unwieldy. The solution is to create a system of categories (sections), into which each article or news item can be stored. You'll notice that when we set up the database in Part 3 we created a "section" field. Well, now we'll use it.
We want to be able to dynamically add and remove sections from our system, so we'll need a new table in the database. Here's the schema:
Field Purpose Type

ID A unique ID for each section Integer
name The name of the section Varchar(20)
parentid If this is a sub-section, the id of the parent Integer
The SQL code to create this table is listed below:
mySQL Code:
 
CREATE TABLE `database`.`cmssections` (
`ID` int(4) unsigned NOT NULL auto_increment COMMENT 'The unique ID of the section',
`name` varchar(20) NULL COMMENT 'The section name',
`parentid` int(4) NULL DEFAULT 0 COMMENT 'The ID of the parent section',
PRIMARY KEY (`ID`)
);
 

(If you don't know how to run SQL queries, see a short explanation in the Intranet Journal Discussion Forum, SQLCourse.com, or consult a reference text on SQL.)
In the same way that we created an admin page for adding articles, it's simple to create a page to add, edit or delete sections. We want the page to look something like the one below:

21j94zm.jpg
When this page loads, a list of sections is displayed as well as a link to remove any of them. There's also a form to create a new section. Notice the drop-down list for choosing the "parent" section; a similar menu will be used on the Add Article page to choose which section an article belongs in.
How's all this coded? We begin by connecting to the database, and creating a Validator object (using the class we just designed):
PHP Code:

<?php
// Require the classes
require_once('../includes/DbConnector.php');
require_once(
'../includes/Validator.php');
// Create an object (instance) of the DbConnector and Validator
$connector = new DbConnector();
$validator = new Validator();
?>


Next, we'll add code to deal with the "delete" link. Notice that we use the Validator to make sure the ID number is numeric. To tell the page whether it should be adding, deleting or just listing the sections, we set the 'action' variable in the query string (i.e., http://yourintranet/cmsadmin/sectionEdit.php?action=XXX). This variable is read by the first line below:
PHP Code:

<?php
if($HTTP_GET_VARS['action'] == 'delete'){
    
// Store the ID of the section to be deleted in a variable
    
$sectionID $HTTP_GET_VARS['id'];
    
// Validate the section ID, and if it's ok then delete the section
    
if($validator->validateNumber($sectionID,'Section ID')){
        
// The validator returned true, so go ahead and delete the section
        
$connector->query('DELETE FROM cmssections WHERE ID = '.$sectionID);
        echo 
'Section Deleted <br><br>';
    }else{
        
// The validator returned false, meaning there was a problem
        
echo "Couldn't delete. There was a problem with: ".$validator->listErrors();
    }
}
?>

The code to insert a section is quite simple so I won't detail it here, you'll find it easy to understand by reading the source file at the end. The last part of the PHP code for this page is to list the sections as shown above, with the delete link along side:
PHP Code:

<?php
// Execute the query to retrieve articles
$result $connector->query('SELECT ID,name,parentid FROM cmssections');
// Get an array containing the results.
// Loop for each item in that array
while ($row $connector->fetchArray($result)){
    echo 
$row['name'].' -    '// Show the name of section
    
echo '<a href="editSections?action=delete&id='.$row['ID'].'"> Delete </a>'// Show the delete link
    
echo '<br>'// Show a carriage return
}
?>

And now we have a category system set up. You can use it to define the sections that will make up your site, and then assign articles to them. On the front end that your users will see, you could have a page called showarticles.php and use it to show only the articles in a particular category
(e.g., showarticles.php?id=1 for news, showarticles.php?id=2 for press releases, etc.).

Comments

Information:

No Comments.