I have a form on "add-category.php" that enables the admin to create a category and doing so includes uploading an image to a folder and inserts its file name and relevant text into the database. The script worked well with mysql_, but now it stopped working after I upgraded my "functions.php" to PDO. The issue is that the image cannot upload.
Warning: imagejpeg(/home/ script-directory/products/images/category/ec27a92192042fdc049e54477649fb30.jpg): failed to open stream: No such file or directory in /home/script-directory/includes/functions.php on line 385
This is my "add-category.php":
<?php
require_once '../../includes/config.php';
if(isset($_POST['txtName']))
{
$categoryName = $_POST['txtName'];
$categoryMtitle = $_POST['metaTitle'];
$categoryMkey = $_POST['metaKey'];
$categoryMdes = $_POST['metaDesc'];
$categoryDesc = $_POST['mtxDesc'];
$imgName = $_FILES['fleImage']['name'];
$tmpName = $_FILES['fleImage']['tmp_name'];
// we need to rename the image name just to avoid
// duplicate file names
// first get the file extension
$ext = strrchr($imgName, ".");
// then create a new random name
$newName = md5(rand() * time()) . $ext;
// the category image will be saved here
$imgPath = ALBUM_IMG_DIR . $newName;
// resize all category image
$result = createThumbnail($tmpName, $imgPath, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);
if (!$result) {
echo "Error uploading file";
exit;
}
if(!$query = "INSERT INTO prod_cat (cat_name, cat_metatitle, cat_metakeywords, cat_metadescription, cat_description, cat_image, cat_date)
VALUES (:categoryName, :categoryMtitle, :categoryMkey, :categoryMdes, :categoryDesc, :newName, NOW())")
{
adminapologize("Error, adding product category failed.");
}
$params = array(':categoryName' => $categoryName, ':categoryMtitle' => $categoryMtitle, ':categoryMkey' => $categoryMkey, ':categoryMdes' => $categoryMdes, ':categoryDesc' => $categoryDesc, ':newName' => $newName);
var_dump($params);
exit;
// the category is saved, go to the category list
echo "<script>window.location.href='index.php?page=list-category';</script>";
exit;
}
// include add category template
include("templates/add-category_template.php");
?>
Doing var_dump($params);
exit;
outputs this code:
array (size=6)
':categoryName' => string 'Balls' (length=5)
':categoryMtitle' => string 'Corporate Gift balls' (length=20)
':categoryMkey' => string 'ball, balls' (length=11)
':categoryMdes' => string 'Buy corporate gift items like balls' (length=35)
':categoryDesc' => string '<p>Buy corporate gift items like balls</p>' (length=42)
':newName' => string 'f59723c81fe0c4235b57ad338e981bff.jpg' (length=36)
Here is the definition of image location in "config.php":
// APP_ROOT will always be set to 2 directorys up from the location of this file
define('APP_ROOT', dirname(dirname(__FILE__)) . '/');
// a category can have an image used as thumbnail
// we save the category image here
define('ALBUM_IMG_DIR', APP_ROOT . 'products/images/category/');
// all images inside an category are stored here
define('GALLERY_IMG_DIR', APP_ROOT . 'products/images/gallery/');
In the "functions.php", I have this code regarding PDO and image upload:
/**
* Executes SQL statement, possibly with parameters, returning
* a pdo statement object on success, handling and halting execution on error.
*/
function query($sql, $parameters = null)
{
static $pdo; // define the var as static so that it will persist between function calls
try
{
// if no db connection, make one
if (!isset($pdo))
{
// connect to database
// you should set the character encoding for the connection
$pdo = new PDO("mysql:dbname=" . DB_NAME . ";host=" . DB_SERVER, DB_USERNAME, DB_PASSWORD);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // set the error mode to exceptions
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); // turn emulated prepares off
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC); // set default fetch mode to assoc so that you don't have to explicitly list the fetch mode every place
}
if(empty($parameters)){
// no bound inputs
$stmt = $pdo->query($sql);
} else {
// has bound inputs
$stmt = $pdo->prepare($sql);
// you should use explicit bindValue() statements to bind any inputs, instead of supplying them as a parameter to the ->execute() method. the comments posted in your thread lists the reasons why.
$stmt->execute($parameters);
}
}
catch (Exception $e)
{
// all errors with the connection, query, prepare, and execute will be handled here
// you should also use the line, file, and backtrace information to produce a detailed error message
// if the error is due to a query, you should also include the $sql statement as part of the error message
// if $pdo ($handle in your code) is set, it means that the connection was successful and the error is due to a query. you can use this to include the $sql in the error message.
trigger_error($e->getMessage(), E_USER_ERROR);
//exit; // note: E_USER_ERROR causes an exit, so you don't need an exit; here.
}
return $stmt; // if the query ran without any errors, return the pdo statement object to the calling code
}
/*
Upload an image and create the thumbnail. The thumbnail is stored
under the thumbnail sub-directory of $uploadDir.
Return the uploaded image name and the thumbnail also.
*/
function uploadImage($inputName, $uploadDir)
{
$image = $_FILES[$inputName];
$imagePath = '';
$thumbnailPath = '';
// if a file is given
if (trim($image['tmp_name']) != '') {
$ext = substr(strrchr($image['name'], "."), 1);
// generate a random new file name to avoid name conflict
// then save the image under the new file name
$imagePath = md5(rand() * time()) . ".$ext";
$result = move_uploaded_file($image['tmp_name'], $uploadDir . $imagePath);
if ($result) {
// create thumbnail
$thumbnailPath = md5(rand() * time()) . ".$ext";
$result = createThumbnail($uploadDir . $imagePath, $uploadDir . 'thumbnail/' . $thumbnailPath, THUMBNAIL_WIDTH);
// create thumbnail failed, delete the image
if (!$result) {
unlink($uploadDir . $imagePath);
$imagePath = $thumbnailPath = '';
} else {
$thumbnailPath = $result;
}
} else {
// the image cannot be uploaded
$imagePath = $thumbnailPath = '';
}
}
return array('image' => $imagePath, 'thumbnail' => $thumbnailPath);
}
/*
Create a thumbnail of $srcFile and save it to $destFile.
The thumbnail will be $width pixels.
*/
function createThumbnail($srcFile, $destFile, $width, $quality = 75)
{
$thumbnail = '';
if (file_exists($srcFile) && isset($destFile))
{
$size = getimagesize($srcFile);
$w = number_format($width, 0, ',', '');
$h = number_format(($size[1] / $size[0]) * $width, 0, ',', '');
$thumbnail = copyImage($srcFile, $destFile, $w, $h, $quality);
}
// return the thumbnail file name on sucess or blank on fail
return basename($thumbnail);
}
/*
Copy an image to a destination file. The destination
image size will be $w X $h pixels
*/
function copyImage($srcFile, $destFile, $w, $h, $quality = 75)
{
$tmpSrc = pathinfo(strtolower($srcFile));
$tmpDest = pathinfo(strtolower($destFile));
$size = getimagesize($srcFile);
if ($tmpDest['extension'] == "gif" || $tmpDest['extension'] == "jpg")
{
$destFile = substr_replace($destFile, 'jpg', -3);
$dest = imagecreatetruecolor($w, $h);
//imageantialias($dest, TRUE);
} elseif ($tmpDest['extension'] == "png") {
$dest = imagecreatetruecolor($w, $h);
//imageantialias($dest, TRUE);
} else {
return false;
}
switch($size[2])
{
case 1: //GIF
$src = imagecreatefromgif($srcFile);
break;
case 2: //JPEG
$src = imagecreatefromjpeg($srcFile);
break;
case 3: //PNG
$src = imagecreatefrompng($srcFile);
break;
default:
return false;
break;
}
imagecopyresampled($dest, $src, 0, 0, 0, 0, $w, $h, $size[0], $size[1]);
switch($size[2])
{
case 1:
case 2:
imagejpeg($dest,$destFile, $quality);
break;
case 3:
imagepng($dest,$destFile);
}
return $destFile;
}
Your help would be much appreciated. Thanks in advance.