save and display for files in user profile in Moodle - php

I'm trying to create a moodle profile field plugin for file upload.
my edit_field_add in field.class is:
function edit_field_add(&$mform) {
$maxlength = 1024*1024;
$fieldtype = $this->field->param2;
/// Create the form field
$mform->addElement('filepicker', $this->inputname, format_string($this->field->name), null,
array('maxbytes' => $maxlength, 'accepted_types' => $fieldtype));
$mform->setType($this->inputname,PARAM_FILE);
}
This shows and saves file correctly but
Saves a number in data field of plugin (e.g. 766686554)
How can I find the URL to the uploaded file to make a link to it by display_data in 'field.class` ?
EDIT
I'm saving the file by this:
function edit_save_data_preprocess($data, &$datarecord) {
$draftitemid=file_get_submitted_draft_itemid($this->inputname);
if (empty($entry->id)) {
$entry = new stdClass;
$entry->id = 0;
}
$context = context_user::instance($this->userid);
file_save_draft_area_files($draftitemid, $context->id, 'profile_field_fileupload', $this->inputname,$entry->id);
return $draftitemid;
}
But draft still exists and I cant find how to retrieve saved file!

Assuming you have saved the file after the form has been posted -http://docs.moodle.org/dev/Using_the_File_API_in_Moodle_forms#filepicker
Then you can use the File API to retrieve the file(s) - http://docs.moodle.org/dev/File_API#Serving_files_to_users
eg to display links to all files for the plugin:
$out = array();
$fs = get_file_storage();
$files = $fs->get_area_files($contextid, $pluginname, $pluginfolder);
foreach ($files as $file) {
$filename = $file->get_filename();
$url = moodle_url::make_file_url('/pluginfile.php', array(
$file->get_contextid(),
$pluginname,
$pluginfolder,
$file->get_itemid(),
$file->get_filepath(), $filename)
);
$out[] = html_writer::link($url, $filename);
}
$br = html_writer::empty_tag('br');
echo implode($br, $out);

Related

Dynamic Input Array with Image/file in Laravel 8

i am trying to do an update using dynamic for "education history" but there is an image also, i use eloquent to update too, for some reason the data is saved in the database but the image just tmp and cannot find in the folder.
//count array data inputed
for($incs=0; $incs < count($data_detail_user['institution_names']); $incs++) {
// update education
foreach( $data_detail_user['institution_names'] as $key => $file ){
// get old photo thumbnail
$get_photo = Educations::where('id', $key)->first();
// store photo
$path = $file->store(
'assets/education/thumbnail', 'public'
);
$education_user = Educations::find($incs);
$education_user->detail_user_id = $detail_user['id'];
$education_user->name = $data_detail_user['institution_names'][$incs];
$education_user->course = $data_detail_user['education_courses'][$incs];
$education_user->start = $data_detail_user['education_starts'][$incs];
$education_user->graduate = $data_detail_user['education_graduates'][$incs];
$education_user->address = $data_detail_user['education_addresses'][$incs];
$education_user->regencies = $data_detail_user['education_regencies'][$incs];
$education_user->provinces = $data_detail_user['education_provinces'][$incs];
$education_user->country = $data_detail_user['education_countries'][$incs];
$education_user->zip_code = $data_detail_user['education_zips'][$incs];
$education_user->certificate = $data_detail_user['education_certificates'][$incs][$path];
$education_user->save();
$data_detail_user = 'storage/' .$get_photo['certificate'];
if (File::exists($data_detail_user)) {
File::delete($data_detail_user);
} else {
File::delete('storage/app/public/' .$get_photo['certificate']);
}
}
}
[the error show Call to a member function store() on string]
this is the screenshoot of the error
[1]: https://i.stack.imgur.com/l96sm.png
$path = $request->file('path')->store('public/post');
I assume you have a directory where the image is suppose to be stored that's why i created the post directory after public.

How to insert Multiple Uploaded files to database

I'm working on a mobile application, and I'm handling database and APIs.
Android developer is sending me images and I'm using file function to get its data.
I have written this code:
public function addalbum($baseurl)
{
$images = array();
if(isset($_FILES['image'])){
//echo "hellow";exit;
//$pathToUpload = '../media/gallary/';
$count = count($_FILES['image']['name']);
//echo $count;exit;
$imagepaths = '';
$imagetepaths = '';
$images = '';
for($i=0;$i<$count;$i++){
$imageurls[$i] = $baseurl."../media/gallary/".$_FILES['image']['name'];
$imagepaths = '../media/gallary/'.$_FILES['image']['name'][$i];
$images[$i] = $_FILES['image']['name'][$i];
$imagetepaths = $_FILES['image']['tmp_name'][$i];
move_uploaded_file($imagetepaths , $imagepaths);
}
}
$data=array(
'image' => ($images != '') ? implode(',',$imageurls) : '',
'email'=>$this->input->post('email'),
'name'=>$this->input->post('name'),
'type'=>$this->input->post('type')
);
//print_r($data);exit;
$this->db->insert('album',$data);
}
But from the bunch of images, only the last one is being inserted in the database.
any help will be very much appreciated.
Thanks
$_FILES['image'] is the field name of 1 uploaded file. If multiple files should be posted you would require different names for each field. Just think how will you upload multiple files from an html form.
For example: $_FILES['image1'], $_FILES['image2'], $_FILES['image3']
You could use something like this:
if(is_array($_FILES)) {
foreach($_FILES as $fileKey => $fileVal){
if($fileVal[name]) {
move_uploaded_file($_FILES["uploaded_file"]["tmp_name"],$target_path.$fileVal[name]);
}
}
}
Checkout this example where a maximum of 3 files are uploaded from android using php.

Add File Uploader to Joomla Admin Component

I made Joomla admin component according to Joomla guide - http://docs.joomla.org/Developing_a_Model-View-Controller_Component/2.5/Developing_a_Basic_Component
In that i need to have file uploader which let user to upload single file.
In administrator\components\com_invoicemanager\models\forms\invoicemanager.xml i have defined
<field name="invoice" type="file"/>
In the controller administrator\components\com_invoicemanager\controllers\invoicemanager.php im trying to retrieve that file like below. But its not working (can't retrieve file)
Where am i doing it wrong ?
How can i get file and save it on disk ?
class InvoiceManagerControllerInvoiceManager extends JControllerForm
{
function save(){
$file = JRequest::getVar( 'invoice', '', 'files', 'array' );
var_dump($file);
exit(0);
}
}
make sure that you have included enctype="multipart/form-data" in the form that the file is being submitting. This is a common mistake
/// Get the file data array from the request.
$file = JRequest::getVar( 'Filedata', '', 'files', 'array' );
/// Make the file name safe.
jimport('joomla.filesystem.file');
$file['name'] = JFile::makeSafe($file['name']);
/// Move the uploaded file into a permanent location.
if (isset( $file['name'] )) {
/// Make sure that the full file path is safe.
$filepath = JPath::clean( $somepath.'/'.strtolower( $file['name'] ) );
/// Move the uploaded file.
JFile::upload( $file['tmp_name'], $filepath );}
Think i found the solution :)
$file = JRequest::getVar('jform', null, 'files', 'array');
Saving part is mentioned here - http://docs.joomla.org/Secure_coding_guidelines
For uploading the file from your component, you need to write your code in the controller file and you can extend the save() method. check the code given below -
public function save($data = array(), $key = 'id')
{
// Neccesary libraries and variables
jimport('joomla.filesystem.file');
//Debugging
ini_set("display_error" , 1);
error_reporting(E_ALL);
// Get input object
$jinput = JFactory::getApplication()->input;
// Get posted data
$data = $jinput->get('jform', null, 'raw');
$file = $jinput->files->get('jform');
// renaming the file
$file_ext=explode('.',JFile::makeSafe($file['invoice']['name'])); // invoice - file handler name
$filename = round(microtime(true)) . '.' . strtolower(end($file_ext));
// Move the uploaded file into a permanent location.
if ( $filename != '' ) {
// Make sure that the full file path is safe.
$filepath = JPath::clean( JPATH_ROOT."/media/your_component_name/files/". $filename );
// Move the uploaded file.
if (JFile::upload( $file['invoice']['tmp_name'], $filepath )) {
echo "success :)";
} else {
echo "failed :(";
}
$data['name'] = $filename ; // getting file name
$data['path'] = $filepath ; // getting file path
$data['size'] = $file['invoice']['size'] ; // getting file size
}
JRequest::setVar('jform', $data, 'post');
$return = parent::save($data);
return $return;
}
Joomla 2.5 & 3 style:
$app = JFactory::getApplication();
$input = $app->input;
$file= $input->files->get('file');
if(isset($file['name']))
{
jimport('joomla.filesystem.file');
$file['name'] = strtolower(JFile::makeSafe($file['name']));
$fileRelativePath = '/pathToTheRightFolder/'.$file['name'];
$fileAbsolutePath = JPath::clean( JPATH_ROOT.$fileRelativePath);
JFile::upload( $file['tmp_name'], $fileAbsolutePath );
}
http://docs.joomla.org/How_to_use_the_filesystem_package
has a full upload sample.
Little sample where admin choose the file type or all, enter the users to access the form upload. Folder to upload files in Joomla directory or with absolute path. Only selected users access the form upload.

multi picture upload in zend framework, how to?

i have an issue with uploading multiple files to disk. here is my code.
i have a request with 2 pictures that gets sent to a upload function. the 2 pictures are in a var called $multiUpload
$folderPath = '/var/www/';
if (is_array($multiUpload)){
$file = array();
$filename = array();
foreach($multiUpload as $key=>$val){
// get the file extension
$file[] = explode('.',$val);
// create custom file name
$filename[] = time().'.'.$file[$key][1];
//send to the upload function
$this->uploadToDisk($folderPath, $filename[$key]);
// sleep 1 sec so that the pic names will be different
sleep(1);
}
return $filename;
}
public function uploadToDisk($folderPath, $filename)
{
$adapter = new Zend_File_Transfer_Adapter_Http();
$adapter->setDestination($folderPath);
$adapter->addFilter( 'Rename',array(
'target' => $folderPath."/".$filename,
'overwrite' => true
) );
if ($adapter->receive()) {
$message = "success";
} else {
$message = "fail";
}
return $message;
}
this will return
Array
(
[0] => Array
(
[0] => 1332977938.jpg
[1] => 1332977939.jpg
)
)
but only array[0][0] or 1332977938.jpg will actually get saves to the disk.
Why are they now both get saved? wired
any ideas?
I suspect the second call to uploadToDisk is returning fail because you can only call Zend_File_Transfer_Adapter_Http::receive() once for each file. Since you are not specifying a file when calling receive, it is receiving all of the files the first time you call uploadToDisk and subsequently is failing with a File Upload Attack error.
Here is some code you can try. This tries to receive each file individually and then save them one at a time with each call to uploadToDisk.
A few notes about the code:
The first parameter to uploadToDisk ($val) may need to be changed as I am not sure what the original values are. It should correspond to one of the element names used for the file upload (See Zend_File_Transfer_Adapter_Http::getFileInfo()) for a list of the files.
I changed the method for generating a unique filename so you don't have to sleep(1)
Zend_File_Transfer_Adapter_Abstract::setDestination() is deprecated and will go away in the future. Instead, just use the Rename filter. When using Rename, setDestination() has no effect.
And here it is...
<?php
$folderPath = '/var/www/';
if (is_array($multiUpload)){
$filenames = array();
foreach($multiUpload as $key => $val){
// get the file extension
$ext = explode('.', $val);
$ext = $ext[sizeof($ext) - 1];
// create custom file name
do {
$filename = uniqid(time()) . '.' . $ext;
$diskPath = $folderPath . $filename;
} while (file_exists($diskPath));
$filenames[$key] = $filename;
//send to the upload function
// $val is the file to receive, $diskPath is where it will be moved to
$this->uploadToDisk($val, $diskPath);
}
return $filename;
}
public function uploadToDisk($file, $filename)
{
// create the transfer adapter
// note that setDestination is deprecated, instead use the Rename filter
$adapter = new Zend_File_Transfer_Adapter_Http();
$adapter->addFilter('Rename', array(
'target' => $filename,
'overwrite' => true
));
// try to receive one file
if ($adapter->receive($file)) {
$message = "success";
} else {
$message = "fail";
}
return $message;
}

Drupal 6 Node Creation PHP Script with File upload not working

I've got this PHP script I'm working on to import pay-stubs into Drupal. It's doing everything the way I want except the script is not attaching the uploaded PDF file to the node.
A few notes; Drupal's filesystem is set to private, not sure if this makes a difference or not. Second, the pdf files are already in the correct location 'paystubs/[uid]/paystub_1.pdf' so I think my problem is that the file is not being associated to the node correctly.
Here is the code
function create_drupal_node($employeeID, $employeeDate, $drupalUid, $file2) {
$sourcePDF = "/var/www/html/mgldev.************.com/burst_pdfs/pdfs/" . $file2;
$destinationPDF = '/paystubs/' . $drupalUid . '/' . $file2;
$destination = '/paystubs/' . $drupalUid . '/';
if (!file_check_directory($destination, TRUE)){
echo "Failed to check dir, does it exist?";
mkdir($destination);
echo "trying to drupal mkdir...";
}
// Copy the file to the Drupal files directory
if (file_exists($sourcePDF)) {
if(!rename($sourcePDF, $destinationPDF)) {
echo "Failed to move file\n";
}
}
//Create node and attach file uplaod
$file_drupal_path = "paystubs/" . $drupalUid . "/" . $file2;
$mime = 'pdf/application';
$file = new stdClass();
$file->filename = $file2;
$file->filepath = $file_drupal_path;
$file->filemime = $mime;
$file->filesize = filesize($file_drupal_path);
$file->uid = $drupalUid;
$file->status = FILE_STATUS_PERMANENT;
$file->timestamp = time();
drupal_write_record('files', $file);
$node = new StdClass();
$node->type = 'paystub';
$node->body = $employeeID;
$node->title = $employeeDate;
$node->field_paystub_upload = array(
array(
'fid' => $file->fid,
'title' => $file2,
'filename' => $file->filename,
'filepath' => $file->filepath,
'filesize' => $file->filesize,
'mimetype' => $mime,
'data' => array(
'description' => $file2,
),
'list' => 1,
),
);
$node->uid = $drupalUid;
$node->status = 1;
$node->active = 1;
$node->promote = 1;
node_save($node);
}
The node is created and the title and body of the node have the right values. When I look at the node using Devel module I can see that the 'field_paystub_upload' array is null. So for some reason its doing everything right except attaching the file to the node and that is what I've been banging my head on for days. Best response gets on free internet?
Drupal's file.inc file_save_upload uses $_FILES, which is a global, magically set by PHP. Drupal expects an uploaded file, not a file that exists locally.
You best just call a custom file-saver method, to process local files. Make sure its path up in the files database-table too. file_save_upload will be valuable for creating such a helper method.
Big thanks to berkes for helping me solve this problem. Turns out that since the files were already on the drupal webserver and not being uploaded to PHP $_FILES global variable, I was unable to programmatically upload the file correctly.
This was causing every other way I've tried to fail. I tried using Drupals defualt upload module and I also tried using CCK's fielfield module both were not working. Thanks to berkes suggestion I found a function that comes with CCK's filefield widget to save uploaded files that are already on the server. Hopefully this helps someone else.
This is the function I found that can save a file thats already on the web-server.
Here is the working code I used to create the node and attach the file after calling field_file_save_file.
function create_drupal_node($employeeID, $employeeDate, $drupalUid, $file2){
$file_remove_html_extention = substr($file2, 0, -7);
$file_pdf = $file_remove_html_extention . '.pdf';
$node = new stdClass();
$node->type = 'paystub';
$node->status = 1;
$node->uid = $drupalUid;
$node->title = $employeeDate . ' - eStub';
$node->body = $employeeID;
$node->created = time();
$node->changed = $node->created;
$node->promote = 1;
$node->sticky = 0;
$node->format = 1;
$node->language = 'en';
$file = '/var/www/html/mgldev.foobar.com/burst_pdfs/pdfs/' . $file_pdf;
// Get the path to your Drupal site's files directory
$dest_folder = '/paystubs/' . $drupalUid;
$dest = 'paystubs/' . $drupalUid . '/' . $file_pdf;
if (!file_check_directory($dest_folder, TRUE)){
mkdir($dest_folder);
}
// Load the CCK field
$field = content_fields('field_paystub_upload', 'paystub');
// Load the appropriate validators
$validators = array_merge(filefield_widget_upload_validators($field));
// Create the file object
$file = field_file_save_file($file, $validators, $dest_folder);
// Apply the file to the field, this sets the first file only, could be looped
// if there were more files
$node->field_paystub_upload = array(0 => $file);
// The file has been copied in the appropriate directory, so it can be
// removed from the import directory
unlink($file);
// change file status to permanent
file_set_status($file,1);
node_save($node);
}
</pre></code>
Thanks again berkes

Categories