Basic image upload in Joomla custom component - php

I am trying to add image upload function to my view where I am creating model. I tried many sample codes here but I can't get to full path to file. My code looks like this:
public function submit() {
jimport ( 'joomla.filesystem.file' );
// Check for request forgeries.
JRequest::checkToken () or jexit ( JText::_ ( 'JINVALID_TOKEN' ) );
// Initialise variables.
$app = JFactory::getApplication ();
$model = $this->getModel ( 'createaction' );
// Get the data from the form POST
$data = JRequest::getVar ( 'jform', array (), 'post', 'array' );
echo $data['image']; <-- here
$createdItem = $model->createItem ( $data );
if ($createdItem) {
$redirect = JRoute::_ ( 'index.php?option=com_akcehned&view=actions', false );
$this->setRedirect ( $redirect, "Akce byla vytvořena" );
} else {
echo "<h2>Omlouváme se, ale něco se stalo špatně</h2>";
}
return true;
}
Part of file input in xml:
<field
name="image"
type="file"
description="COM_AKCEHNED_FORM_DESC_CREATEACTION_IMAGE"
label="COM_AKCEHNED_FORM_LBL_CREATEACTION_IMAGE"
size="10"
accept="image/*" />
Where I tried to echo file file input I get just name (image_name.jpg and so) but I need fullpath right? I saw examples with ['tmp_name'] but It's not working for me.
I tried code like this:
$jinput = $app->input;
$files = $jinput->files->get('jform');
$file = $files['image'];
echo $file;
echo $file['tmp_name'];
But it's not working for me either. I just get empty values. Can someone give me working block of code where I get data from other inputs and fullpath to file for upload? It's for joomla 2.5, Thanks

You need to make sure the the form tag contains enctype attribute and that it is set to "multipart/form-data" if your are going to upload files.
eg
<form action="" method="post" enctype="multipart/form-data">
Also see: What does enctype='multipart/form-data' mean?

Did you try DPAttachments, it takes only three lines of code to integrate attachment support into your component.
if (JLoader::import('components.com_dpattachments.libraries.dpattachments.core', JPATH_ADMINISTRATOR)) {
echo DPAttachmentsCore::render('com_demo.item', $object->id);
}
Drag and drop and copy paste from your clipboard (no need to save the file to your hard disk) is supported. Perhaps you want to give it a try. If not here is a link to the Github repo how the upload function is implemented:
https://github.com/Digital-Peak/DPAttachments/blob/master/com_dpattachments/admin/models/attachment.php#L50
[I'm the author of this component]

Related

How to upload multiple files from single form input in Laravel?

I'm trying to upload multiple pdf files using Laravel. I've made the form using simple HTML and enabled the multiple attribute in the input field. I've tried many other methods mentioned in the stack community but they didn't work for me.
In the controller, I've the following to check whether the files are being uploaded or not. The foreach loop will return the path of the files uploaded.
Controller Code
if ($request->hasFile('corpfile')) {
$file = $request->file('corpfile');
// dd($file);
foreach ($file as $attachment) {
$path = $attachment->store('corporate');
dd($path);
}
HTML Form Code
<input type="file" name='corpfile[]' accept=".xls, .xlsx, .xlsm, .pdf" multiple>
The dd($file) is returning an array with all the files uploaded but the dd($path) is returning only one file's path.
I don't know what the issue is. Any help is appreciated.
you're diying the loop with dd
if you want to store the path in array , you should do that
$path = [];
if ($request->hasFile('corpfile')) {
$file = $request->file('corpfile');
// dd($file);
foreach ($file as $attachment) {
$path[] = $attachment->store('corporate');
}
}

Retrieving image from MySQL Database with CodeIgniter without using the upload library. Is it possible?

What I want to do is upload an image to my sql database using an html form and then retrieving it from the database to display it. I`ll show you some code so you can understand what I am trying to do.
1st EDIT: Just linking an image to show the database table I am uploading the image to. The row type is blob --> https://imgur.com/a/KBlNWWN in the code below I edited out the other rows of the DB table, but code for them is actually in.
This is the form that is uploading the image:
<form method="POST" action="/~gd339/ci/index.php/Add/postEvent/<?php echo $societyId ?>" enctype="multipart/form-data">
Event image: <input type="file" name="image"/> <br>
<input type="submit" name="POST" value="Post Event!" class = "unique"/>
What it does is that it posts the data to the postEvent controller:
public function postEvent($society_id) {
$this->load->model('Events_model');
$image = file_get_contents($_FILES['image']['tmp_name']);
$this->Events_model->addEvent($image);
}
Note that to get the image from the form, I am using $image = file_get_contents($_FILES['image']['tmp_name']); data retrieved using post is then sent to addEvent in my model:
public function addEvent ($image) {
$image1 = $this->db->escape($image);
$sql = "INSERT INTO events (event_image) VALUES ($image1)";
$query = $this->db->query($sql);
}
To retrieve the image I am using an image tag with a src that calls a function in the controller:
<img src="http://dragon.maple.as.re/~gd339/ci/index.php/add/getEventImage/<?php echo $row['event_id'] ?>">
public function getEventImage($event_id){
$this->load->model('Societies_model');
$image = $this->Societies_model->getEventImage($event_id);
header("Content-type: image/jpeg");
print($image);
}
code for getEventImage:
public function getEventImage($event_id) {
$data = '';
$sql = "SELECT event_image FROM events WHERE event_id = $event_id";
$query = $this->db->query($sql);
if ($query->num_rows()) {
$data = $query->row_array();
$data = $data['MA_PHOTO'];
$query->free_result();
}
return $data;
}
This results in the image just not showing up. I have been reading other examples here on stackoverflow and all of them, except for 1, use the CI upload library to do what I am trying to do. Is the library the only way to retrieve images using CI or is there something wrong in my code preventing the images to appear when called?
Thanks a lot to whoever will have the patience to go through my code. I know it is a lot but it is the first time I am using CI so im still learning.
I have done a similar process without using CI_Upload.
A useful debug is, using some db tool, save the blob to a file and try to display it (using mspaint, image viewer, etc...)
Before I save the image on database, I use the following function to resize (as I don't need it big) and convert(ensure) that it is a jpeg.
private function get_image_resized($data){
$data = smart_resize_image (
null,
$data,
250,
0,
true,
'return');
$temp_file = tempnam(sys_get_temp_dir(), 'ImageResize');
imagejpeg($data, $temp_file, 100);
$data = file_get_contents($temp_file);
unlink($temp_file);
return $data;
}
smart_resize_image can be found here:
To display the image
function imagem($cd_produto){
$im_produto = $this->produto_model->get_imagem ( $cd_produto );
header ( "Content-type:image/jpeg" );
echo $im_produto;
}
Hope it helps.

Slim Image Cropper With Codeigniter

View
<form method="post" enctype='multipart/form-data' action="<?php base_url();?>edituserpic" name="form_editpic" id="form_editpic" class="avatar">
<div class="slim"
data-label="Drop your avatar here"
data-size="240,240"
data-ratio="1:1">
<input type="file" name="avatar" required />
</div>
<button type="submit">Upload now!</button>
</form>
Controller
public function edit_user_pic() {
$data['baseurl'] = $this->config->item('base_url');
// Pass Slim's getImages the name of your file input, and since we only care about one image, postfix it with the first array key
$image = $this->slim->getImages('avatar')[0];
*/
// Grab the ouput data (data modified after Slim has done its thing)
if ( isset($image['output']['data']) )
{
// Original file name
$name = $image['output']['name'];
// Base64 of the image
$data = $image['output']['data'];
}
}
I'm just stuck in server side how to save to get output image and save to database.
I am getting $name undefined. This mean output is empty.
If anyone used it and able to help that would be great.
If you've setup to use a different name than "slim", pass it along.
$images = Slim::getImages('avatar');
$image = $images[0];
It works for me.

custom validation rule for joomla file upload

I am trying to validate a file upload as below using a custom validation rule but its not working.
class JFormRuleResume extends JFormRule
{
public function test(&$element, $value, $group = null, &$input = null, &$form = null)
{
jimport('joomla.filesystem.file');
jimport('joomla.filesystem.folder');
$jinput = JFactory::getApplication()->input;
$fileInput = new JInput($_FILES);
$file = $fileInput->get('jform', null, 'files', 'array');
//$files = $jinput->files->get('jform');
//$file = $files['resume'];
$filename = JFile::makeSafe($file['name']['resume']);
$filesize = $file['size'];
if (strtolower(JFile::getExt($filename))!='pdf') {
$element->addAttribute('message', strtolower(JFile::getExt($filename)));
return false;
}
if($filesize<2000000){
$element->addAttribute('message', "File size bigger than 2MB");
return false;
}
//var_dump($files);
return true;
}
}
Whether I upload a pdf file or other files with different extension, the error "Invalid file type" is returned.
Please enlighten me what the problem is?
My field looks like this:
<field
name="resume"
type="file"
label="Resume"
description=""
size="40"
accept="application/pdf"
validate="resume"
required="true"
/>
UPDATE
This is an update to what i've discovered so far. The post data
$requestData = JRequest::getVar('jform', null, 'post', 'array');
do not fetch the file input value. It is therefore, i've to add the following code in the controller action before i validate the form $data = $model->validate($form, $requestData);
$requestData = JRequest::getVar('jform', null, 'post', 'array');
// Get the file data array from the request.
$jinput = JFactory::getApplication()->input;
$fileInput = new JInput($_FILES);
$file = $fileInput->get('jform', null, 'files', 'array');
// Make the file name safe.
$filename = JFile::makeSafe($file['name']['resume']);
$requestData['resume'] = strtolower($filename);
JRequest::setVar('jform', $requestData );
$form = $model->getForm();
if (!$form) {
JError::raiseError(500, $model->getError());
return false;
}
$data = $model->validate($form, $requestData);
This way i am able to inject the file input value to the post array. But the problem still lies somewhere because the above validation works only partially. The validation works correctly only for files like docx, png, htm, php, txt .... and if i submit doc, pdf (larger than 2MB), zip files the validation do not work at all, instead i am displayed back the form without data and with the validation warning that all the fields are missing.
This is very strange, i desperately need some help.
Finally made through with the problem of form being redisplayed when file of bigger size is uploaded. It was a server problem, had to change the following in php.ini of my wamp server
upload_max_filesize = 100M
post_max_size = 100M
And regarding the second issue for file upload value not being in post was a new thing to me which i didn't know. Had to upload the file seperately first, then get the name by which the file was saved and then use that name to be inserted in the database.

Zend Framework: image upload

I want to upload an image with Zend Framework version 1.9.6. The uploading itself works fine, but I want a couple of other things as well ... and I'm completely stuck.
Error messages for failing to upload an image won't show up.
If a user doesn't enter all the required fields but has uploaded an image then I want to display the uploaded image in my form. Either as an image or as a link to the image. Just some form of feedback to the user.
I want to use Zend_ Validate_ File_ IsImage. But it doesn't seem to do anything.
And lastly; is there some automatic renaming functionality?
All ideas and suggestions are very welcome. I've been struggling for two days now.
These are simplified code snippets:
myform.ini
method = "post"
elements.title.type = "text"
elements.title.options.label = "Title"
elements.title.options.attribs.size = 40
elements.title.options.required = true
elements.image.type = "file"
elements.image.options.label = "Image"
elements.image.options.validators.isimage.validator = "IsImage"
elements.submit.type = "submit"
elements.submit.options.label = "Save"
TestController
<?php
class Admin_TestController extends Zend_Controller_Action
{
public function testAction ()
{
$config = new Zend_Config_Ini(MY_SECRET_PATH . 'myform.ini');
$f = new Zend_Form($config);
if ($this->_request->isPost())
{
$data = $this->_request->getPost();
$imageElement = $f->getElement('image');
$imageElement->receive();
//$imageElement->getValue();
if ($f->isValid($data))
{
//save data
$this->_redirect('/admin');
}
else
{
$f->populate($data);
}
}
$this->view->form = $f;
}
}
?>
My view just echo's the 'form' variable.
First, put this at the start of your script:
error_reporting(E_ALL);//this should show all php errors
I think the error messages are missing from the form because you re-populate the form before you display it. I think that wipes out any error messages. To fix that, remove this part:
else
{
$f->populate($data);
}
To show the uploaded image in the form, just add a div to your view template, like this:
<div style="float:right"><?=$this->image?></div>
If the image uploaded ok, then populate $view->image with an img tag.
As for automatic re-naming, no, it's not built in, but it's very easy. I'll show you how below.
Here's how I handle my image uploads:
$form = new Zend_Form();
$form->setEnctype(Zend_Form::ENCTYPE_MULTIPART);
$image = new Zend_Form_Element_File('image');
$image->setLabel('Upload an image:')
->setDestination($config->paths->upload)
->setRequired(true)
->setMaxFileSize(10240000) // limits the filesize on the client side
->setDescription('Click Browse and click on the image file you would like to upload');
$image->addValidator('Count', false, 1); // ensure only 1 file
$image->addValidator('Size', false, 10240000); // limit to 10 meg
$image->addValidator('Extension', false, 'jpg,jpeg,png,gif');// only JPEG, PNG, and GIFs
$form->addElement($image);
$this->view->form = $form;
if($this->getRequest()->isPost())
{
if(!$form->isValid($this->getRequest()->getParams()))
{
return $this->render('add');
}
if(!$form->image->receive())
{
$this->view->message = '<div class="popup-warning">Errors Receiving File.</div>';
return $this->render('add');
}
if($form->image->isUploaded())
{
$values = $form->getValues();
$source = $form->image->getFileName();
//to re-name the image, all you need to do is save it with a new name, instead of the name they uploaded it with. Normally, I use the primary key of the database row where I'm storing the name of the image. For example, if it's an image of Person 1, I call it 1.jpg. The important thing is that you make sure the image name will be unique in whatever directory you save it to.
$new_image_name = 'someNameYouInvent';
//save image to database and filesystem here
$image_saved = move_uploaded_file($source, '/www/yoursite/images/'.$new_image_name);
if($image_saved)
{
$this->view->image = '<img src="/images/'.$new_image_name.'" />';
$form->reset();//only do this if it saved ok and you want to re-display the fresh empty form
}
}
}
First, have a look at the Quick Start tutorial. Note how it has an ErrorController.php that will display error messages for you. Also note how the application.ini has these lines to cause PHP to emit error messages, but make sure you're in the "development" environment to see them (which is set in public/.htaccess).
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
Second, ZF has a renaming filter for file uploads:
$upload_elt = new Zend_Form_Element_File('upload');
$upload_elt
->setRequired(true)
->setLabel('Select the file to upload:')
->setDestination($uploadDir)
->addValidator('Count', false, 1) // ensure only 1 file
->addValidator('Size', false, 2097152) // limit to 2MB
->addValidator('Extension', false, 'doc,txt')
->addValidator('MimeType', false,
array('application/msword',
'text/plain'))
->addFilter('Rename', implode('_',
array($this->_user_id,
$this->_upload_category,
date('YmdHis'))))
->addValidator('NotExists', false, $uploadDir)
;
Some of the interesting things above:
mark the upload as required (which your .ini doesn't seem to do)
put all the uploads in a special directory
limit file size and acceptable mime types
rename upload to myuser_category_timestamp
don't overwrite an existing file (unlikely, given our timestamp scheme, but let's make sure anyway)
So, the above goes in your form. In the controller/action that receives the upload, you could do this:
$original_filename = $form->upload->getFileName(null, false);
if ($form->upload->receive()) {
$model->saveUpload(
$this->_identity, $form->upload->getFileName(null, false),
$original_filename
);
}
Note how we capture the $original_filename (if you need it) before doing receive(). After we receive(), we do getFileName() to get the thing that the rename filter picked as the new filename.
Finally, in the model->saveUpload method you could store whatever stuff to your database.
Make sure your view also outputs any error messages that you generate in the controller: loading errors, field validation, file validation. Renaming would be your job, as would other post processing such as by image-magick convert.
When following lo_fye's listing I experienced problems with custom decorators.
I do not have the default File Decorator set and got the following exception:
Warning: Exception caught by form: No file decorator found... unable to render file element Stack Trace:
The Answer to this is that one of your decrators must implement the empty interface Zend_Form_Decorator_Marker_File_Interface
Also sometimes it happens to bug when using an ajax request. Try it without an ajax request and don't forget the multipart form.

Categories