I am currently having problems in inserting captions whilst uploading images using class.upload.php.
The image rename worked well, but all of the images has the same caption, eventhough I have setup individual textboxes for each image.
The code:
<form action="" enctype="multipart/form-data" id="form" method="post" name="form" role="form">
<table>
<tr>
<td><input class="form-control" id="customFieldValue2" name="photo_title[]" type="text"></td>
<td><input class="form-control" id="customFieldName2" name="image_field[]" type="file"></td>
</tr>
<tr>
<td><input class="form-control" id="customFieldValue2" name="photo_title[]" type="text"></td>
<td><input class="form-control" id="customFieldName2" name="image_field[]" type="file"></td>
</tr>
</table>
</form>
The processor:
$files = array();
foreach ($_FILES['image_field'] as $k => $l) {
foreach ($l as $i => $v) {
if (!array_key_exists($i, $files))
$files[$i] = array();
$files[$i][$k] = $v;
}
}
$hitung=0;
foreach ($files as $file)
{
$handle = new Upload($file);
if ($handle->uploaded)
{
$hitung++;
$newname = $t_timestamp."_".$hitung;
$handle->file_new_name_body = $newname;
$handle->Process("../uploaded/");
if ($handle->processed)
{
$filename=$newname.".jpg";
$query ="INSERT INTO tbl_report_photos SET
photo_title='".$filename."',
photo_link='".$filename."',
photo_unique='".$aid."'";
if ($sql = mysqli_query($con,$query))
{
echo "<script>alert('Report Updated');window.location.href='index.php';</script>";
}
}
else
{
echo 'Error: ' . $handle->error;
}
}
else
{
echo 'Error: ' . $handle->error;
}
unset($handle);
}
I have edited the code. it has one less loop
The reason you have the same title is in it's own loop which is not arraying the variable, but rather overwriting itself. Make it an array, then write the corresponding key:
$taitel[$i] = $_POST['photo_title'][$i];
You have so many loops going on, it's hard to suggest the best spot to put it in your script.
EDIT: Since you are having issues setting this up, I will give a demonstration. There are a bunch of things I might try. One, I would create a file observer and two, make an extended class of your Uploads class. That one seems a bit awkward:
UploadObserver.php
/*
** @description This will take over for a couple of pieces of your script
*/
class UploadObserver
{
private $Upload;
/*
** @description Pass your database. I like PDO and know it better so I am using that connection
** You would have to change this to accept your MySQLi connection
*/
public function __construct(\PDO $con)
{
$this->con = $con;
}
/*
** @description Create a new instance of a version of the Upload class
*/
public function upload($file)
{
# Create a new instance of our extended class
$this->Upload = new \PowerUpload($file);
# Return it for use
return $this->Upload;
}
/*
** @description This is the class that will process the files array
*/
public function getFiles($key = 'image_field')
{
$files = array();
foreach ($_FILES[$key] as $k => $l) {
foreach ($l as $i => $v) {
if (!array_key_exists($i, $files))
$files[$i] = array();
$files[$i][$k] = $v;
}
}
# Send back formatted array
return $files;
}
/*
** @description Checks to see if the files array has files
*/
public function filesSet($key = 'image_field')
{
return (!empty($_FILES[$key]));
}
/*
** @description This will write the row to your database
*/
public function saveToDb($settings)
{
# Make sure to prepare and bind your values just in case
$sql ="INSERT INTO tbl_report_photos SET
photo_title = ?,
photo_link = ?,
photo_unique = ?";
$query = $this->con->prepare($sql);
$query->execute($settings);
}
/*
** @description You could store this in a View class, but for sake of ease I included it here
*/
public function getSuccess()
{
ob_start();
?>
<script>
alert('Report Updated');
window.location.href = 'index.php';
</script>
<?php
$data = ob_get_contents();
ob_end_clean();
return $data;
}
}
Upload.php
This is just a guess of what this class would look like based on what you have demonstrated in your example.
class Upload
{
public $uploaded,
$file_new_name_body,
$processed,
$error;
protected $filename,
$fileArray;
public function __construct($fileArray)
{
$this->fileArray = $fileArray;
}
public function process($path)
{
if(!is_dir($path))
mkdir($path,0755,true);
if(empty($this->file_new_name_body))
$this->file_new_name_body = $this->fileArray['name'];
$this->error = $this->fileArray['error'];
$this->processed = move_uploaded_file($this->fileArray['tmp_name'],str_replace('//','/',$path.'/'.$this->file_new_name_body));
if(!$this->processed)
throw new \Exception("File was unable to upload.");
}
}
PowerUpload.php
/*
** @description If you can, I would extend the Upload class and save some more readable methods to it
*/
class PowerUpload extends Upload
{
public function setNewFile($fileArray)
{
$this->fileArray = $fileArray;
return $this;
}
public function setFileName($name)
{
$this->file_new_name_body = $name;
return $this;
}
public function checkHasUploaded()
{
$files = (!empty($this->fileArray));
if(!$files)
throw new \Exception("File array can not be empty.");
return $files;
}
public function hasProcessed()
{
return $this->processed;
}
public function processUpload($path)
{
$this->process($path);
}
public function getError()
{
return $this->error;
}
}
Revised script based on changes: Note that the form input names have actual key values so you can match up the files with the names easier.
# Create the upload observer, $con is your database connection
$Uploader = new UploadObserver($con);
# If there are files uploading
if($Uploader->filesSet()) {
# Create a loop from the new array
# Keep the $key value to match it up with the files value
foreach($Uploader->getFiles() as $key => $file) {
# Use a try because the uploader submits exceptions on failures
try {
# Set the name
$newname = $t_timestamp."_".$key;
# Tag on the extension
$filename = $newname.".jpg";
# Create the upload instance
$handle = $Uploader->upload($file);
# This will throw exception if failed
$handle->checkHasUploaded();
# Assign the file name and upload the file to folder
$handle->setFileName($newname)->processUpload(realpath(__DIR__.'/..').'/uploaded/');
# Save the file info to your database using the connection passed originally
# You should throw exception here on database fail, PDO does it automatically so it's caught
$Uploader->saveToDb(array($_POST['photo_title'][$key],$filename,$aid));
# Create javascript view
echo $Uploader->getSuccess();
}
# Catch error(s) from the non-db classes
catch(\Exception $e) {
echo 'Error: '.$e->getMessage();
}
# Catch error(s) from the db classes
catch(\PDOException $e) {
echo 'Error: '.$e->getMessage();
}
}
}
?>
<form method="post" enctype="multipart/form-data" action="<?php echo $this->getDataNode('_SERVER')->REQUEST_URI ?>">
<table>
<tr>
<td><input class="form-control" id="customFieldValue2" name="photo_title[1]" type="text"></td>
<td><input class="form-control" id="customFieldName2" name="image_field[1]" type="file"></td>
</tr>
<tr>
<td><input class="form-control" id="customFieldValue2" name="photo_title[2]" type="text"></td>
<td><input class="form-control" id="customFieldName2" name="image_field[2]" type="file"></td>
</tr>
</table>
<input type="submit" value="SAVE" />
</form>