Adding Tasks to a Project Management Application

The previous articles covered adding, editing and viewing a project, capabilities any project management application needs. The next couple of articles will cover the "optional" parts of the application. They include adding project files and adding tasks to a project, both of which are not strictly necessary. We will also look at adding staff members to a particular project a little later on. This article, the fourth of seven parts, will deal with adding tasks to a project, after which we will look at editing a task.

A task in this case refer to a action that the project manager wants done by a certain date or time. The tasks for the project are not displayed on the view project page (the page that shows project contents in detail). Instead, you get a link that points you toward the different tasks that should be done on the given project.

The only link between all the scripts that deal with handling tasks, and the project itself, is the project id. As you may remember, all database tables for this application have a project id in them. So in order for this script work effectively, it will need to be given a project id by whatever script is referencing it. Otherwise the task that you create cannot be linked to any project. Below is a screen shot of what the page actually looks like:


And as always, here’s the entire code for the page:



<?php

include "dbcon.php";

include "functions.php";


$cpid=mysql_escape_String($_GET['pid']);


$getname = "SELECT title FROM projects WHERE pid = ‘".$cpid."’";

$g_result = mysql_query($getname);

if(!$g_result){

echo mysql_error();

}else{

$rowname = mysql_fetch_assoc($g_result);

$title = $row['title'];

}




if(isset($_POST['submit'])){

//check vars

$descr=mysql_escape_string($_POST['descr']);

$p_pid=mysql_escape_string($_POST['p_pid']);


//due date

$duedt = $_POST['yy'] . "-";

if($_POST['mm'] < 10) {

$duedt .= "0";

}

$duedt .= $_POST['mm'] . "-";

if($_POST['mm'] == 4 || $_POST['mm'] == 6 || $_POST['mm'] == 9 || $_POST['mm'] == 11) {

if($_POST['dd'] > 30) {

$duedt .= "30";

} else {

$duedt .= $_POST['dd'];

}

} elseif($_POST['mm'] == 2) {

if($_POST['yy'] == 2008 || $_POST['yy'] == 2012) {

if($_POST['dd'] > 29) {

$duedt .= "29";

} else {

$duedt .= $_POST['dd'];

}

} else {

if($_POST['dd'] > 28) {

$duedt .= "28";

} else {

$duedt .= $_POST['dd'];

}

}

} else {

$duedt .= $_POST['dd'];

}

 

//insert

$insert = "INSERT INTO tasks SET task_description = ‘".$descr."’,";

$insert .= "complete_by = ‘".$duedt."’,p_id= ‘".$p_pid."’";

if(!mysql_query($insert)){

echo mysql_error();

}

}

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"><!– InstanceBegin template="/Templates/PM_Main.dwt.php" codeOutsideHTMLIsLocked="false" –>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<!– InstanceBeginEditable name="doctitle" –>

<title>Untitled Document</title>

<!– InstanceEndEditable –>

<!– InstanceBeginEditable name="head" –>

<!– InstanceEndEditable –>

<link href="Templates/main.css" rel="stylesheet" type="text/css" />

</head>


<body>

<table width="100%" border="0">

<tr>

<td width="33%">&nbsp;</td>

<td width="28%">&nbsp;</td>

<td width="39%">Logged in: <!– InstanceBeginEditable name="login" –><? echo $_SESSION['name'];?> | <a href="logout.php">Logout</a><!– InstanceEndEditable –></td>

</tr>

<tr>

<td colspan="3" bgcolor="#6699CC" class="headertxt">Project Management Software </td>

</tr>

<tr>

<td colspan="3"><!– InstanceBeginEditable name="main" –>

<form action="add_task.php" method="post" name="f1">

 

<table width="100%" border="0">

<tr>

<td colspan="2" class="loginheader"><?php echo $title;?></td>

</tr>

<tr>

<td>&nbsp;</td>

<td>&nbsp;</td>

</tr>

<tr>

<td>Complete by</td>

<td><?php $dd = date("d");

$mm = date("m");

$yy = date("Y");

echo "<select name="dd">n";

for($i = 1; $i <= 31; $i++) {

echo "<option value="" . $i . """;

if($i == $dd) {

echo " selected";

}

echo ">" . $i . "</option>n";

}

echo "</select>&nbsp;<select name="mm">n";

for($i = 1; $i <= 12; $i++) {

echo "<option value="" . $i . """;

if($i == $mm) {

echo " selected";

}

echo ">" . $month_names[$i] . "</option>n";

}

echo "</select>&nbsp;<select name="yy">n";

for($i = $yy; $i <= ($yy + 1); $i++) {

echo "<option value="" . $i . """;

if($i == $yy) {

echo " selected";

}

echo ">" . $i . "</option>n";

}

echo "</select>";

?> <input name="p_pid" type="hidden" value="<?php echo $_GET['pid']?>" /></td>

</tr>

<tr>

<td valign="top">Description</td>

<td><label>

<textarea name="textarea"></textarea>

</label></td>

</tr>

<tr>

<td>&nbsp;</td>

<td><label>

<input type="submit" name="submit" value="Add task!" />

</label></td>

</tr>

</table>

 

</form>

<!– InstanceEndEditable –></td>

</tr>

<tr>

<td colspan="3"><!– InstanceBeginEditable name="nav" –><a href="main.php">View Project List</a> | <a href="admin/login.php">Administrators Corner </a><!– InstanceEndEditable –></td>

</tr>

<tr>

<td align="right" class="cright" colspan="3">copyright &copy; 2007 PM </td>

</tr>

</table>

</body><!– InstanceEnd –>

</html>

{mospagebreak title=Code Explained}

The code above lists both the PHP and HTML parts of the script. So we are going to look at each of them in some detail. As always the PHP part starts off with including the dbcon and functions files. In case any of you were wondering why these files are always included, at the very top of the page, it is because the dbcon file contains the session_start() function. This function needs to be called before any headers or ANY communication between the server and the browser takes place, otherwise you get a "headers already sent" error message or warning:


<?php

include "dbcon.php";

include "functions.php";


Then we clean the project id that is passed to the script:


$cpid=mysql_escape_String($_GET['pid']);


There are two reasons why we are getting the project id. First, it makes the only link between the task and the project that you want to link it to. Second, we need to retrieve the name of the project, because it will be displayed in the HTML form below. So we use the project id to retrieve the title of the project concerned and store it in the $title variable:


$getname = "SELECT title FROM projects WHERE pid = ‘".$cpid."’";

$g_result = mysql_query($getname);

if(!$g_result){

echo mysql_error();

}else{

$rowname = mysql_fetch_assoc($g_result);

$title = $row['title'];

}


Then we check to see if the form has been submitted:


if(isset($_POST['submit'])){




We clean the form values before using them in the insert query:


//check vars

$descr=mysql_escape_string($_POST['descr']);

$p_pid=mysql_escape_string($_POST['p_pid']);


//due date

$duedt = $_POST['yy'] . "-";

if($_POST['mm'] < 10) {

$duedt .= "0";

}

$duedt .= $_POST['mm'] . "-";

if($_POST['mm'] == 4 || $_POST['mm'] == 6 || $_POST['mm'] == 9 || $_POST['mm'] == 11) {

if($_POST['dd'] > 30) {

$duedt .= "30";

} else {

$duedt .= $_POST['dd'];

}

} elseif($_POST['mm'] == 2) {

if($_POST['yy'] == 2008 || $_POST['yy'] == 2012) {

if($_POST['dd'] > 29) {

$duedt .= "29";

} else {

$duedt .= $_POST['dd'];

}

} else {

if($_POST['dd'] > 28) {

$duedt .= "28";

} else {

$duedt .= $_POST['dd'];

}

}

} else {

$duedt .= $_POST['dd'];

}

 

The data is then inserted into the tasks table like so:


//insert

$insert = "INSERT INTO tasks SET task_description = ‘".$descr."’,";

$insert .= "complete_by = ‘".$duedt."’,p_id= ‘".$p_pid."’";

if(!mysql_query($insert)){

echo mysql_error();

}

}

?>


Notice that I’ve echoed a mysql_error() in the event that the query fails. I am only doing this because the application is in development. When or if you decide to use this application in a production environment, I would suggest that you write the error to a text file or log and then take it from there. Those of you who have seen PHP errors will know that they usually reveal a lot more than they should, and can provide ammunition to an attacker.

The HTML portion of the script shows a form with two fields, one to take the task description and another to take the due date for the task. Most of the rest of the form should be familiar to you by now:

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"><!– InstanceBegin template="/Templates/PM_Main.dwt.php" codeOutsideHTMLIsLocked="false" –>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<!– InstanceBeginEditable name="doctitle" –>

<title>Untitled Document</title>

<!– InstanceEndEditable –>

<!– InstanceBeginEditable name="head" –>

<!– InstanceEndEditable –>

<link href="Templates/main.css" rel="stylesheet" type="text/css" />

</head>


<body>

<table width="100%" border="0">

<tr>

<td width="33%">&nbsp;</td>

<td width="28%">&nbsp;</td>

<td width="39%">Logged in: <!– InstanceBeginEditable name="login" –><? echo $_SESSION['name'];?> | <a href="logout.php">Logout</a><!– InstanceEndEditable –></td>

</tr>

<tr>

<td colspan="3" bgcolor="#6699CC" class="headertxt">Project Management Software </td>

</tr>

<tr>

<td colspan="3"><!– InstanceBeginEditable name="main" –>

<form action="add_task.php" method="post" name="f1">

 

<table width="100%" border="0">

<tr>

<td colspan="2" class="loginheader"><?php echo $title;?></td>

</tr>

<tr>

<td>&nbsp;</td>

<td>&nbsp;</td>

</tr>

<tr>

<td>Complete by</td>

<td>

{mospagebreak title=Date Building Code Explained}

The date building code sends the following form variables up to the PHP portion of the page:

$_POST['yy']

$_POST['mm']

$_POST['dd']


The three represent the year, month and day portions of the date that the user selects from the select boxes. Then when these parts are processed, they are basically concatenated and separated by the dash (-) sign. So the end result is "yyyy-mm-dd" which is the format used by MySQL:


<?php $dd = date("d");

$mm = date("m");

$yy = date("Y");

echo "<select name="dd">n";

for($i = 1; $i <= 31; $i++) {

echo "<option value="" . $i . """;

if($i == $dd) {

echo " selected";

}

echo ">" . $i . "</option>n";

}

echo "</select>&nbsp;<select name="mm">n";

for($i = 1; $i <= 12; $i++) {

echo "<option value="" . $i . """;

if($i == $mm) {

echo " selected";

}

echo ">" . $month_names[$i] . "</option>n";

}

echo "</select>&nbsp;<select name="yy">n";

for($i = $yy; $i <= ($yy + 1); $i++) {

echo "<option value="" . $i . """;

if($i == $yy) {

echo " selected";

}

echo ">" . $i . "</option>n";

}

echo "</select>";


Also notice that a hidden field is created with a project id value. This value is received directly from the sending script and is very important in the sense that it provides the link between the task and the project itself:


?> <input name="p_pid" type="hidden" value="<?php echo $_GET['pid']?>" /></td>


</tr>

<tr>

<td valign="top">Description</td>

<td><label>

<textarea name="textarea"></textarea>

</label></td>

</tr>

<tr>

<td>&nbsp;</td>

<td><label>

<input type="submit" name="submit" value="Add task!" />

</label></td>

</tr>

</table>

 

</form>

<!– InstanceEndEditable –></td>

</tr>

<tr>

<td colspan="3"><!– InstanceBeginEditable name="nav" –><a href="main.php">View Project List</a> | <a href="admin/login.php">Administrators Corner </a><!– InstanceEndEditable –></td>

</tr>

<tr>

<td align="right" class="cright" colspan="3">copyright &copy; 2007 PM </td>

</tr>

</table>

</body><!– InstanceEnd –>


{mospagebreak title=View Tasks Script} 

The next script we will be looking at is the view tasks script. It is responsible for displaying tasks that are linked to a particular project. This page can only be accessed when viewing project details. It will list all the tasks that are related to the project that you are viewing. The HTML portion of the page is made up of a dynamic HTML table that will dynamically create as many table rows as commanded by the PHP. Below is a screen shot of the page:


Also, here is the entire code for the page:


<?php

include "dbcon.php";

include "functions.php";


if(isset($_GET['pid'])){

//clean pid

if(!is_numeric($_GET['pid'])){

//the value received is not numeric. redirect the user to login

header("location:login.php");

}


//otherwise clean the received value for query use


$cpid = mysql_escape_string($_GET['pid']);

}

//get project name


$getname = "SELECT title FROM projects WHERE pid = ‘".$cpid."’";

$g_result = mysql_query($getname);

if(!$g_result){

echo mysql_error();

}else{

$rowname = mysql_fetch_assoc($g_result);

$title = $row['title'];

}

//get the tasks

$gettask="SELECT * FROM tasks WHERE p_id = ‘".$cpid."’ ORDER BY tid";

$result = mysql_query($gettask);

if(!$result){

echo mysql_error();

}else{

$num=mysql_num_rows($result);

}


?>




<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"><!– InstanceBegin template="/Templates/PM_Main.dwt.php" codeOutsideHTMLIsLocked="false" –>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<!– InstanceBeginEditable name="doctitle" –>

<title>Untitled Document</title>

<!– InstanceEndEditable –>

<!– InstanceBeginEditable name="head" –>

<!– InstanceEndEditable –>

<link href="Templates/main.css" rel="stylesheet" type="text/css" />

</head>


<body>

<table width="100%" border="0">

<tr>

<td width="33%">&nbsp;</td>

<td width="28%">&nbsp;</td>

<td width="39%">Logged in: <!– InstanceBeginEditable name="login" –><? echo $_SESSION['name'];?> | <a href="logout.php">Logout</a><!– InstanceEndEditable –></td>

</tr>

<tr>

<td colspan="3" bgcolor="#6699CC" class="headertxt">Project Management Software </td>

</tr>

<tr>

<td colspan="3"><!– InstanceBeginEditable name="main" –>

<table width="100%" border="0">

<tr>

<td colspan="2" class="loginheader"><?php echo $title;?> </td>

</tr>

<tr>

<td>&nbsp;</td>

<td>&nbsp;</td>

</tr>

<tr>

<td>Task Description: </td>

<td>To be completed by: </td>

</tr>

<?php

if($num > 0){

while($row = mysql_fetch_assoc($result)){?>

<tr>

<td><?php echo $row['task_description']?></td>

<td><?php echo $row['complete_by']?></td>

</tr>

<?php

}

}else{

?>

 

 

<tr>

<td colspan="2"><p>There are no tasks registered for this project.</p></td>

</tr>

<?php }

 

?>

</table>

<!– InstanceEndEditable –></td>

</tr>

<tr>

<td colspan="3"><!– InstanceBeginEditable name="nav" –><table width="100%" border="0">

<tr>

<td><a href="edit_task.php?pid=<?php echo $_GET['pid'];?>">Edit Task</a> | <a href="admin/login.php">Administrators Corner </a></td>

</tr>

</table><!– InstanceEndEditable –></td>

</tr>

<tr>

<td align="right" class="cright" colspan="3">copyright &copy; 2007 PM</td>

</tr>

</table>

</body>

<!– InstanceEnd –></html>



Let’s look at the code that makes this page come to life. The code first checks to see if the project id that it received is a number. If not, the user is redirected to the login page. It does this by using the ‘is_numeric()’ function:


<?php

include "dbcon.php";

include "functions.php";


if(isset($_GET['pid'])){

//clean pid

if(!is_numeric($_GET['pid'])){

//the value received is not numeric. redirect the user to login

header("location:login.php");

}


If the id passes the numeric test, it is cleaned for query use. The first thing the code does is retrieve the project title from the projects table:


//otherwise clean the received value for query use

$cpid = mysql_escape_string($_GET['pid']);

}

//get project name


$getname = "SELECT title FROM projects WHERE pid = ‘".$cpid."’";

$g_result = mysql_query($getname);

if(!$g_result){

echo mysql_error();

}else{

$rowname = mysql_fetch_assoc($g_result);

$title = $row['title'];

}


The code retrieves all the tasks that are related to the project id and stores the results in the $num variable:


//get the tasks

$gettask="SELECT * FROM tasks WHERE p_id = ‘".$cpid."’ ORDER BY tid";

$result = mysql_query($gettask);

if(!$result){

echo mysql_error();

}else{

$num=mysql_num_rows($result);

}


?>

And that’s it. Be sure to check back next week for the fifth part of this seven-part series.

[gp-comments width="770" linklove="off" ]

antalya escort bayan antalya escort bayan Antalya escort diyarbakir escort