Forums

Upload to a directory according to an input field

gg4j 18 Dec, 2008
§Hi all.

How would it be possible to upload a file in a folder build as:
DS.$formname.DS.$selectedinputfield.DS.$filename

where the variable "selectedinputfield" is the name of an input field in the form.
Basically, according to the choice, the system will store images in a proper subfolder in upload>nameform>images

I am looking at: chronocontact.php


if ( $fileok ) {
					$uploadedfile = JFile::upload($original_name, JPATH_COMPONENT.DS.'uploads'.DS.$formname.DS.$category_1.DS.$filename);//handle_uploaded_files($original_name, $filename);
					$posted[$allowed_s2[0]] = $filename;
					JRequest::setVar($allowed_s2[0], $filename);
					if ( $uploadedfile ) {
                        $attachments[$allowed_s2[0]] = JPATH_COMPONENT.DS.'uploads'.DS.$formname.DS.$filename;
						if ( $debug ) {
							$mainframe->enqueueMessage($filename.' has been uploaded OK');
						}
					}else{
						if ( $debug ) {
							$mainframe->enqueueMessage($filename.' has NOT been uploaded!!');
						}
					}
				}


Many thanks!
GreyHead 18 Dec, 2008
Hi gg4j,

I'd avoid hacking the core code here and instead add code to one of the OnSubmit boxes to move the file to wherever I needed it. There's a function at the end of ChronoContact.php that will almost do thsi for you - but not quite. You can easily adapt the code though:
function handle_uploaded_files($uploadedfile, $filename, $limits = TRUE, $directory = FALSE)
{
    $uploaded_files = "";
    $upload_path = JPATH_SITE.'/components/com_chronocontact/upload/';
    if ( is_file($uploadedfile) ) {
        $targetfile = $upload_path.$filename;
        while ( file_exists($targetfile) ) {
            $targetfile = $upload_path.rand(1,1000).'_'.$filename;
        }
        move_uploaded_file($uploadedfile, $targetfile);
        $uploaded_files = $targetfile;
    }
    return $uploaded_files;
}

Bob
gg4j 18 Dec, 2008
mmm thanks Bob, I tried to understand how to customize it..

So I tried to place this code ON sumbit after email:

<?php
if($paramsvalues->dbconnection == "Yes"){
$user = JFactory::getUser();
$row =& JTable::getInstance("chronoforms_photocontest", "Table");
srand((double)microtime()*10000);
$inum = "I" . substr(base64_encode(md5(rand())), 0, 16);
[...]

$post = JRequest::get( "post" , JREQUEST_ALLOWRAW );
if (!$row->bind( $post )) {
JError::raiseWarning(100, $row->getError());
}
if (!$row->store()) {
JError::raiseWarning(100, $row->getError());
}
global $row_jos_chronoforms_photocontest;
$row_jos_chronoforms_photocontest = $row;
}



function handle_uploaded_files($uploadedfile, $inputfield, $filename, $limits = TRUE, $directory = FALSE)
{
$uploaded_files = "";
$upload_path = JPATH_SITE.'/components/com_chronocontact/upload/';
if ( is_file($uploadedfile) ) {
$targetfile = $upload_path.$inputfield.$filename;
while ( file_exists($targetfile) ) {
$targetfile = $upload_path.rand(1,1000).'_'.$inputfield.'_'.$filename;
}
move_uploaded_file($uploadedfile, $targetfile);
$uploaded_files = $targetfile;
}
return $uploaded_files;
}

?>

So in this case the filename should be saved with the inputfield value..
..but how to pass the parameter of the inputfield in the php after submitting?
..and how to call the function ..? .. if I would like to store in a folder which should be created as the parameter is passed :? 🙄
Max_admin 18 Dec, 2008
Hi,

try this code in the onsubmit after email box:


<?php
$chronofile 	= JRequest::getVar( 'file_field_name', '', 'files', 'array' );
$original_name   = $chronofile['tmp_name'];
$uploadedfile = JFile::upload($original_name, JPATH_COMPONENT.DS.'uploads'.DS.$formname.DS.$filename);
?>


Change the path and the field name in the code!

Regards
Max
Max, ChronoForms developer
ChronoMyAdmin: Database administration within Joomla, no phpMyAdmin needed.
ChronoMails simplifies Joomla email: newsletters, logging, and custom templates.
gg4j 18 Dec, 2008
Got this error:

Warning! - Failed to move file.

I make a try by doing this simple form, 2 fields:
a select field (name=select_0)
and a file field (name=file_1)

code onsubmit
<?php
$chronofile    = JRequest::getVar( 'file_1', '', 'files', 'array' );
$original_name   = $chronofile['tmp_name'];
$uploadedfile = JFile::upload($original_name, JPATH_COMPONENT.DS.'uploads'.DS.$formname.DS.$filename);
?>



I need to save the file in two different folder, the folder names are the options in select field.
Another simple option would be change the writing of the uploaded file name, such as: "option_yyyymmdd_filename.jpg"
But how to do it?

How to pass as parameters the variables of two input field that the user will post?
Could you please sumbit the piece of code to put onsubmit, or should I change the chronocontact.php? Could you please give instructinos?
Thank you so much!
😑
GreyHead 20 Dec, 2008
Hi gg4,

OK - I've developed a code snippet that seems to work. Please test it and let me know! Notice that I've saved these to folders in the site/images/stories folder, you may need to change this, any folder where you have the appropriate permissions should work OK.
<?php
// set field names for your form
$field_name = 'file_1';
$select_name = 'select_1';

// get the folder to save to
$folder = JRequest::getString($select_name, '', 'post');

// set the path to save to
$target_folder = JPATH_SITE.DS.'images'.DS.'stories'.DS.$folder;

// create the target folder if it doesn't exist
if ( !JFolder::exists($target_folder) ) {
    JFolder::create($target_folder);
}

// get the file name
$filename = basename($attachments[$field_name]);

// check that the file exists and move it
if ( JFile::exists($attachments[$field_name]) ) {
    JFile::move($attachments[$field_name], $target_folder.DS.$filename);
}
?>
NB For once this is tested and debugged :-) - Joomla 1.5 code, won't work with J1.0
Bob
gg4j 20 Dec, 2008
WOW! THANKS Greyhead, it works exactly marvelously!😀
I was just trying to adapt it and improve it now:
what if I have a multiple upload?
I tried the following, but it just register the directory, without moving the files..


<?php
// set field names for your form
$field_name_1 = 'file_1';
$select_name_1 = 'category_1';
$field_name_2 = 'file_2';
$select_name_2 = 'category_2';
$field_name_3 = 'file_3';
$select_name_3 = 'category_3';

// get the folder to save to
$folder_1 = JRequest::getString($select_name_1, '', 'post');
$folder_2 = JRequest::getString($select_name_2, '', 'post');
$folder_3 = JRequest::getString($select_name_3, '', 'post');

// set the path to save to
$target_folder_1 = JPATH_SITE.DS.'images'.DS.'stories'.DS.$folder_1;
$target_folder_2 = JPATH_SITE.DS.'images'.DS.'stories'.DS.$folder_2;
$target_folder_3 = JPATH_SITE.DS.'images'.DS.'stories'.DS.$folder_3;

// create the target folder if it doesn't exist
if ( !JFolder::exists($target_folder_1) ) {
    JFolder::create($target_folder_1);
}
if ( !JFolder::exists($target_folder_2) ) {
    JFolder::create($target_folder_2);
}
if ( !JFolder::exists($target_folder_3) ) {
    JFolder::create($target_folder_3);
}

// get the file name
$filename_1 = basename($attachments[$field_name_1]);
$filename_2 = basename($attachments[$field_name_2]);
$filename_3 = basename($attachments[$field_name_3]);

// check that the file exists and move it
if ( JFile::exists($attachments[$field_name_1]) ) {
    JFile::move($attachments[$field_name_1], $target_folder.DS.$filename_1);
}
if ( JFile::exists($attachments[$field_name_2]) ) {
    JFile::move($attachments[$field_name_2], $target_folder.DS.$filename_2);
}
if ( JFile::exists($attachments[$field_name_3]) ) {
    JFile::move($attachments[$field_name_3], $target_folder.DS.$filename_3);
}
?>


but I think that it would be better to extend it with a while / for cycle:
can somebody check the syntax / code?
I got

Parse error: parse error, unexpected '=', expecting ';' in ...\com_chronocontact\chronocontact.php(533) : eval()'d code on line 4







<?php
// set field names for your form, 3 upload

for(i=0; i<4; i++){
$field_name = 'file_'+string(i);
$select_name = 'select_'+string(i);

// get the folder to save to
$folder = JRequest::getString($select_name, '', 'post');
// set the path to save to
$target_folder = JPATH_SITE.DS.'images'.DS.'stories'.DS.$folder;
// create the target folder if it doesn't exist
if ( !JFolder::exists($target_folder) ) {
    JFolder::create($target_folder);
}
// get the file name
$filename = basename($attachments[$field_name]);
// check that the file exists and move it
if ( JFile::exists($attachments[$field_name]) ) {
    JFile::move($attachments[$field_name], $target_folder.DS.$filename);
}

			
}




?>


And to use a while function, for parsing an array of uploads Untill there are no more files..
kind of that?

while ($attachments[$field_name]==true) {

}
GreyHead 20 Dec, 2008
hi gg4j,

I don't see the error in your code - but it's simpler to write this with arrays and loops
<?php
// set field names for your form
// we assume here that select_1 is linked to file_1
$field_name_array = array('file_1', 'file_2', 'file_3');
$select_name_array = array('select_1', 'select_2', 'select_3');

// loop through the select 
$folder_array = array();
foreach ( $select_field_array as $k => $select_name ) {
    $folder = JRequest::getString($select_name, '', 'post');
    $target_folder[$k] = JPATH_SITE.DS.'images'.DS.'stories'.DS.$folder;
    if ( !JFolder::exists($target_folder) ) {
        JFolder::create($target_folder);
    }
}
// loop through the file list
foreach ( $field_name_array as $k => $field_name ) {
    // get the file name
    $filename = basename($attachments[$field_name]);
    // check that the file exists and move it
    if ( JFile::exists($attachments[$field_name]) ) {
        JFile::move($attachments[$field_name], $target_folder[$k].DS.$filename);
    }
}
?>
NB Not tested and may need debugging

This version will extend for as many files as you like by adding to the arrays at the beginning.

Bob
gg4j 20 Dec, 2008
Awesome, I corrected the code, but I think there is smtg to improve...
here's the code:

<?php
// set field names for your form
// we assume here that select_1 is linked to file_1
$field_name_array = array('file_1', 'file_2', 'file_3');
$select_name_array = array('category_1', 'category_2', 'category_3');

// loop through the select
$folder_array = array();
foreach ( $select_name_array as $k => $select_name ) {
    $folder = JRequest::getString($select_name, '', 'post');
    $target_folder[$k] = JPATH_SITE.DS.'images'.DS.'stories'.DS.$folder;
    if ( !JFolder::exists($target_folder[$k]) ) {
        JFolder::create($target_folder[$k]);
    }
}
// loop through the file list
foreach ( $field_name_array as $k => $field_name ) {
    // get the file name
    $filename = basename($attachments[$field_name]);
    // check that the file exists and move it
    if ( JFile::exists($attachments[$field_name]) ) {
        JFile::move($attachments[$field_name], $target_folder[$k].DS.$filename);
    }
}
?>


but:
like this there are two photos that must be saved in the same target_folder[$K], something goes wrong, and the folder $K is created, but no files are moved in.
So it is currently working only if the three files has three different target folders, that means cannot accept three different select name..

So I changed the loop through the select like this:


<?php
// loop through the select
$folder_array = array();
foreach ( $select_name_array as $k => $select_name ) {
    $folder[$k] = JRequest::getString($select_name, '', 'post');
    $target_folder[$k] = JPATH_SITE.DS.'images'.DS.'stories'.DS.$folder[$k];
    if ( !JFolder::exists($target_folder[$k]) ) {
        JFolder::create($target_folder[$k]);
    }

?>


now the first two images are stored in the select_name folder (where select_name[1,2] are the same), the third folder is created (selected_name[3], but the third image cannot be saved.
Why?

I think I am almost there...
GreyHead 21 Dec, 2008
Hi gg4j,

Sorry, there were a few incorrect indexes. Here's a corrected and tested version of the code:
<?php
// set field names for your form
// we assume here that select_1 is linked to file_1
$field_name_array = array('file_1', 'file_2', 'file_3');
$select_name_array = array('select_1', 'select_2', 'select_3');
// set the base path you want the files moved to 
$base_path = JPATH_SITE.DS.'images'.DS.'stories'.DS;

// loop through the select
$folder_array = array();
foreach ( $select_name_array as $k => $select_name ) {
    $folder = JRequest::getString($select_name, '', 'post');
    $target_folder[$k] = $base_path.$folder;
    if ( !JFolder::exists($target_folder[$k]) ) {
        JFolder::create($target_folder[$k]);
    }
}
// loop through the file list
foreach ( $field_name_array as $k => $field_name ) {
    // check that the file exists and move it
    if ( JFile::exists($attachments[$field_name] ) ) {
        // get the file name
        $filename = basename($attachments[$field_name]);
        JFile::move($attachments[$field_name], $target_folder[$k].DS.$filename);
    }
}
?>

Bob
karmine 07 Feb, 2011
The name of the file has changed from 2008 to today ... and I do not know where to paste the code as it is now I do not work.
I would like to create a folder for each user .... do you think will be very complicated?
🤨
Thank you very much
GreyHead 07 Feb, 2011
Hi karmine,

Because of the order of the ChronoForms workflow you need to upload the files to a temporary folder and then move them into the new user folder.

You can get the list of uploaded file info into the $attachments array with
<?php
$MyForm =& CFChronoForm::getInstance('Your_Form_Name');//Replace with Your Form name
$form_id = $MyForm->formrow->id;
$MyUploads =& CFUploads::getInstance($form_id);
$attachments = $MyUploads->attachments;
?>

Bob
This topic is locked and no more replies can be posted.