I use Zend Framework 1.12 for some file upload system. And using Zend_File_Transfer_Adapter_Http in a form, for upload of two files.
There are two form elements for those two files.
$file1 = new Zend_Form_Element_File('file1');
// other options like setLabel etc.
$this->addElement($file1, 'file1');
$file2 = new Zend_Form_Element_File('file2');
// other options like setLabel etc.
$this->addElement($file2, 'file2');
and I handle the upload process in my controller like this:
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
$adapter = new Zend_File_Transfer_Adapter_Http();
$adapter->setDestination($dirname);
$files = $adapter->getFileInfo();
foreach ($files as $file => $fileInfo) {
if (!$adapter->receive($file)) {
$messages = $adapter->getMessages();
echo implode("\n", $messages);
} else {
$location = $adapter->getFileName($file, true);
$filename = $adapter->getFileName($file, false);
// taking location and file names to save in database..
}
}
}
With these, I can manage upload of two files. But I don't know how to take location of files which is uploaded with the specific Zend_Form_Element_File. For example, i need to know which file is uploaded to $file1 (element in form) and I will save its location to a table in database, and which file is uploaded to $file2 and save its location to another table.
I do not like to use Zend_File_Transfer_Adapter_Http.
I prefer to use code like this:
in application.ini:
data_tmp = APPLICATION_PATH "/../data/tmp"
in Bootstrap:
$options = $this->getOptions();
define('DATA_TMP', $options['data_tmp']);
in form:
$elementFoo = new Zend_Form_Element_File('foo');
$elementFoo->setLabel('Upload File 1:')->setDestination(DATA_TMP);
$elementBar = new Zend_Form_Element_File('bar');
$elementBar->setLabel('Upload File 2:')->setDestination(DATA_TMP);
in controller:
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
$values = $form->getValues();
$filenameFoo = $values['foo'];
$filenameBar = $values['bar'];
//at this point you know the name of the individual filename
$filePathFoo = DATA_TMP . DIRECTORY_SEPARATOR . $filenameFoo;
$filePathBar = DATA_TMP . DIRECTORY_SEPARATOR . $filenameBar;
//now you have even the physical path of the files
// taking location and file names to save in database..
}
}
my 2 cent.
Related
I have a modal that stores an image, and i have to store this inside my img/items folder. However I get this error "Unable to write in the "img/items" directory".
I already used enctype="multipart/form-data" in my form
This is my function to save the photo
public function Photo(Request $request){
$id = $request->id;
$item = Items::find($id);
$path = $request->file('photo');
$image = $item->ItemName.'_'.Carbon::now().'.'.$path->getClientOriginalExtension();
$path = $request->file('photo')->move('img/items', $image);
$item->Photo = $image;
$item->update();
return back()->with('success','Successfully Added Photo!');
}
I have created a form in drupal 7 and it has a field to upload file (csv file only ) now how to display uploaded csv file into table on form submit ?
Not sure about theme function, but you can do it on your own.
I.e. use:
http://php.net/manual/en/function.file-get-contents.php
To read the file and then:
http://php.net/manual/en/function.str-getcsv.php
to parse CSV.
Or, maybe:
http://php.net/manual/en/function.fgetcsv.php
to read row by row. Anyway, you'll end up with looping trough rows so just print values the way you want, add markup around the values...
After go through various code exercises i have come up with solution which is as follows :
`function display_table($filename, $head=false) {
$handle = fopen($filename, "r");
$all_rows = array();
$header = null;
while ($row = fgetcsv($handle)) {
if ($header === null) {
$header = $row;
continue;
}
$all_rows[] = array_combine($header, $row);
}
$table = theme('table', array('header' => $header, 'rows' => $all_rows));
return $table;
}`
Hope it would be helpful to others as well !
Does anybody knows a working example to receive multiple files, store them in a folder and the names in a mysql table? Some days already with no luck at all, something always missing, and before putting those questions, well , maybe i can find the right one!
maybe?
i am learning using zend 1.11
thanks
pablo
EDIT:
i add the code for clearness:
in the form:
$element = new Zend_Form_Element_File('images');
$element->setLabel('Upload bis 3 Bilder (máx. 200kb each):')
->setMultiFile(3)
->setValueDisabled(true)
->addValidator(new Zend_Validate_File_Size('2MB'))
->addValidator('Count', false, array('min'=>0,'max' => 3));
in the controller:
$adapter = $form->images->getTransferAdapter();
//create directory where files would be hold
if (!file_exists(UPLOADDIR))
mkdir(UPLOADDIR, 0777, 1);
$i=0;
$images="";
//loop uploaded files
foreach ($adapter->getFileInfo() as $info)
{
//rename file how you like and move it to given destination
$fileName = time().$i.'.'.$this->getExtension($info['name']);
$adapter->addFilter('Rename', array('target'=>UPLOADDIR.$fileName, 'overwrite'=>true));
//if something goes wrong print errors in screen
if (!$adapter->receive($info['name']))
{
die(print_r($adapter->getMessages(),1));
}else{
if ($info['name']!==""){
$images .= $fileName.",";
}
}
$i++;
}
I think you should use setFilters() instead of addFilter on the adapter, because the current code will add a new Rename filter on each iteration of the foreach loop.
Try replacing:
$adapter->addFilter('Rename', array('target'=>UPLOADDIR.$fileName, 'overwrite'=>true));
with
$adapter->setFilters(array(new Zend_Filter_File_Rename(array('target'=>UPLOADDIR.$fileName, 'overwrite'=>true))));
For an application I'd like to create some kind of setup-steps. In one of the steps the database configuration is written to the application.ini file. This all works, but something very strange happens: All the paths to the directories (library, layout, ...) are changed from paths with APPLICATION_PATH . to full paths. As you can imagine, this isn't very systemfriendly. Any idea how I can prevent that?
I update the application.ini with this code:
# read existing configuration
$config = new Zend_Config_Ini(
$location,
null,
array('skipExtends' => true,
'allowModifications' => true));
# add new values
$config->production->doctrine->connection = array();
$config->production->doctrine->connection->host = $data['server'];
$config->production->doctrine->connection->user = $data['username'];
$config->production->doctrine->connection->password = $data['password'];
$config->production->doctrine->connection->database = $data['database'];
# write new configuration
$writer = new Zend_Config_Writer_Ini(
array(
'config' => $config,
'filename' => $location));
$writer->write();
Since Zend_Config_Ini uses the default ini scanning mode (INI_SCANNER_NORMAL), it will parse all options and replace constants with their respective values. What you could do, is call parse_ini_file directly, using the INI_SCANNER_RAW mode, so the options aren't parsed.
ie. use
$config = parse_ini_file('/path/to/your.ini', TRUE, INI_SCANNER_RAW);
You will get an associative array that you can manipulate as you see fit, and afterwards you can write that back with the following snippet (from the comments):
function write_ini_file($assoc_arr, $path, $has_sections=FALSE) {
$content = "";
if ($has_sections) {
foreach ($assoc_arr as $key=>$elem) {
$content .= "[".$key."]\n";
foreach ($elem as $key2=>$elem2) {
if(is_array($elem2))
{
for($i=0;$i<count($elem2);$i++)
{
$content .= $key2."[] = ".$elem2[$i]."\n";
}
}
else if($elem2=="") $content .= $key2." = \n";
else $content .= $key2." = ".$elem2."\n";
}
}
}
else {
foreach ($assoc_arr as $key=>$elem) {
if(is_array($elem))
{
for($i=0;$i<count($elem);$i++)
{
$content .= $key2."[] = ".$elem[$i]."\n";
}
}
else if($elem=="") $content .= $key2." = \n";
else $content .= $key2." = ".$elem."\n";
}
}
if (!$handle = fopen($path, 'w')) {
return false;
}
if (!fwrite($handle, $content)) {
return false;
}
fclose($handle);
return true;
}
ie. call it with :
write_ini_file($config, '/path/to/your.ini', TRUE);
after manipulating the $config array. Just make sure you add double quotes to the option values where needed...
Or alternatively - instead of using that function - you could try writing it back using Zend_Config_Writer_Ini, after converting the array back to a Zend_Config object, I guess that should work as well...
I'm guess you could iterate over the values, checking for a match between the value of APPLICATION_PATH, and replacing it with string literal APPLICATION_PATH.
That is if you know that APPLICATION_PATH contains the string '/home/david/apps/myapp/application' and you find a config value '/home/david/apps/myapp/application/views/helpers', then you do some kind of replacement of the leading string '/home/david/apps/myapp/application' with the string 'APPLICATION_PATH', ending up with 'APPLICATION_PATH "/views/helpers"'.
Kind of a kludge, but something like that might work.
This is a long shot - but have you tried running your Zend_Config_Writer_Ini code while the APPLICATION_PATH constant is not defined? It should interpret it as the literal string 'APPLICATION_PATH' and could possibly work.
The code says Zend_Form_element_File::setDestination() is deprecated and to use the rename filter. However the rename filter is currently codes such that when path is set, only temporary name is given. Original filename is lost.
<?php
$file = new Zend_Form_Element_File();
$file->setDestination('/var/www/project/public');
?>
vs
<?php
$file = new Zend_Form_Element_File();
$file->addFilter('Rename', array('target' => '/var/www/project/public'));
?>
Any solution to upload files so that it preserves original filename structure but checks for existing file and appends _1.ext or _2.ext?
You need to query the name of the file after upload and then add the Rename filter then. Eg:
if ($form->file->isUploaded()) {
$fileinfo = $form->file->getFileInfo();
$filename = $fileinfo['file']['name'];
$extn = pathinfo($filename,PATHINFO_EXTENSION);
$uploadname = $this->_makeFilename($formData, $extn);
$uploadfilepath = UPLOADED_FILES_PATH . '/' . $uploadname;
$form->file->addFilter('Rename', $uploadfilepath);
$receiveStatus = $form->file->receive();
}
After submitting the form you can inspect the $_FILES['file_element']['name'] check for existing files and then set the rename filter on your form element before calling the :
$form->getValues()/isValid() or $form->file_element->receive().