Joomla 3.3 MVC file/pdf upload in custom component backend - file-upload

I want to upload a pdf from a custom component from backend in the edit mode.
the state now is,
1.- either the pdf is uploaded correctly but the file name is not written in the database,
2.- or the file name is written in the data base, but the pdf is not seen by JFactory::getApplication()->input;
I found out is has with enctype="multipart/form-data" to do.
In case 1.- enctype="multipart/form-data" is in and the pdf is uploaded
in case 2.- the pdf file name is written in the data base.
What to do know ? I need both, of course.
Here so code, it is a little component com_job with MVC structure under Joomla! 3.3:
here just the part file administrator/components/com_job/views/tmpl/edit.php
with the enctype="multipart/form-data"
<form method="post" action="<?php echo JRoute::_('index.php?option=com_job&layout=edit&id='.(int) $this->item->id); ?>" id="adminForm" name="adminForm" enctype="multipart/form-data">
<fieldset class="adminform">
<legend><?php echo JText::_( 'Details' ); ?></legend>
<div class="control-group">
<div class="control-label">
<?php echo $this->form->getLabel('title'); ?>
</div>
<div class="controls">
<?php echo $this->form->getInput('title'); ?>
</div>
</div>
....
<div class="control-group">
<div class="control-label">
<?php echo $this->form->getLabel('upload_pdf'); ?>
</div>
<div class="controls">
<?php echo $this->form->getInput('upload_pdf'); ?>
</div>
</div>
........
here a part of the xml file administrator/components/com_job/models/forms/job.xml
<?xml version="1.0" encoding="utf-8"?>
...
<field
id="title"
name="title"
type="text"
required="true"
label="Title"
description="title_Desc"
class="inputbox"
size="40"/>
<field
id="upload_pdf"
name="upload_pdf"
type="file"
required="false"
label="Upload_pdf"
description="upload_pdf_Desc"
class="inputbox"
size="40"
accept="application/pdf"/>
.....
here the controller administrator/components/com_job/controllers/job.php
jimport('joomla.application.component.controlleradmin');
jimport('joomla.application.component.controllerform');
jimport('joomla.filesystem.file');
jimport('joomla.filesystem.folder');
class JobControllerJob extends JControllerForm
{
public function save()
{
$jinput = JFactory::getApplication()->input;
$files = $jinput->files->get('jform', null);
$files['upload_pdf']['name'] = JFile::makeSafe($files['upload_pdf']['name']);
if (!empty($files['upload_pdf']['name'])) {
$pdf_path = JPATH_ROOT . '/images/upload_pdf';
if (!JFolder::exists($pdf_path)) {
$status = JFolder::create($pdf_path);
if (!$status) {
JError::raiseWarning(100, JText::_('could not create directory pdf'), '');
}
}
$file_path = JPath::clean($pdf_path . '/' . strtolower($files['upload_pdf']['name']));
$status = JFile::upload($files['upload_pdf']['tmp_name'], $file_path);
if (!$status) {
JError::raiseWarning(100, JText::_('could not copy pdf'), '');
}
}
return parent::save();
}
}
where is the error ? I tried to put enctype="multipart/form-data" in the form in job.xml (models), but it didn't work.
I found a temporally solution, in the save function in the controller, I add this code:
//$jform = $jinput->get(jform, null);
$pdf_filename = JFile::makeSafe($files['upload_pdf']['name']);
$jform = $_POST['jform'];
$tmp_pdf_filename = array('upload_pdf' => $pdf_filename);
$merged_jform = array_merge($jform,$tmp_pdf_filename);
$jinput->post->set('jform',$merged_jform);
the first line with $jinput didn't work. I tried many ways with $jinput, but nothing worked. So finally I used directly $_POST. Of course, it is not the right way, but at least it works.
here the full function save:
public function save()
{
$jinput = JFactory::getApplication()->input;
$files = $jinput->files->get('jform', null);
$pdf_filename = JFile::makeSafe($files['upload_pdf']['name']);
if (!empty($pdf_filename)) {
$pdf_path = JPATH_ROOT . '/images/upload_pdf';
if (!JFolder::exists($pdf_path)) {
$status = JFolder::create($pdf_path);
if (!$status) {
JError::raiseWarning(100, JText::_('could not create directory pdf'), '');
}
}
$file_path = JPath::clean($pdf_path . '/' . strtolower($files['upload_pdf']['name']));
$status = JFile::upload($files['upload_pdf']['tmp_name'], $file_path);
if ($status) {
//$jform = $jinput->get(jform, null);
$jform = $_POST['jform'];
$tmp_pdf_filename = array('upload_pdf' => $pdf_filename);
$merged_jform = array_merge($jform,$tmp_pdf_filename);
$jinput->post->set('jform',$merged_jform);
} else {
JError::raiseWarning(100, JText::_('could not copy pdf'), '');
}
}
return parent::save();
}

$jinput = JFactory::getApplication()->input;
$files = $jinput->files->get('jform');
$file = $files['upload_pdf'];
Try this...it is true method!!!
That should do the trick. The $file array then holds the following keys:
error
name
size
tmp_name
type

Related

Insert Multiple Rows in Laravel (Image Upload Issues)

In my application, I have faced several issues when I try to insert multiple rows of data into a database in laravel 8. Basically this issues is related to image upload. I have add related code to get help.
Controller View:
foreach($request->param_img as $key => $param_img){
$data = new PortfolioParam;
$data->param_desc = $request->param_desc[$key];
if($request->hasfile('param_img')){
$file = $request->file('param_img');
$extension = $file->getClientOriginalExtension();
$filename = time().'.'.$extension;
$file->move('upload/portfolio_param/', $filename);
$portfolio->param_img = $filename;
}
$data->portfolio_id = $portfolio->id;
$data->save();
}
Blade View:
<td class="pl-0 border-0">
<textarea class="form-control" name="param_desc[]" id="" cols="30" rows="3"></textarea>
</td>
<td class="border-0">
<input type="file" class="form-control" name="param_img[]">
</td>
Error
Call to a member function getClientOriginalExtension() on array
How can I get rid of this problems??
You have looped through the image but you have not used it in your image uploading code. You are still using the request data. Check this out, hopefully it helps.
// $file = $request->file('param_img');
$file = $param_img;
$extension = $file->getClientOriginalExtension();
$filename = time().'.'.$extension;
$file->move('upload/portfolio_param/', $filename);
$portfolio->param_img = $filename;

Empty post value : CodeIgniter

While uploading the file through codeigniter, I am getting the following error:
My file upload result is:
My Controller function is below:
public function Upload files($data='')
{
ini_set("display_errors",1); // I added so it would help me show errors
error_reporting(E_ALL);
print_r($_POST);exit('I am in the tp');
$config['upload_path'] = 'assets/images/uploads/';
//$config['allowed_types'] = 'gif|jpg|png';
//$config['max_size'] = 100;
//$config['max_width'] = 1024;
//$config['max_height'] = 768;
$this->load->library('upload', $config);
$this->upload->initialize($config);
if ( ! $this->upload->do_upload('userfile'))
{
$error = array('error' => $this->upload->display_errors());
print_r($error);exit('The first loop');
$this->load->view('upload_form', $error);
}
else
{
$data = array('upload_data' => $this->upload->data());
print_r($data);exit();
$this->load->view('upload_success', $data);
}
}
And my view file:
<div id="Upload_div">
<?php //echo $error;?>
<form action="<?php echo site_url() ?>/Admin/Upload_files/" method="POST" enctype="multipart/form-data">
<label for="myfile">Select a file:</label>
<input type="file" id="myfile" name="userfile"><br><br>
<input type="submit" name="submit" value="submit">
</form>
</div>
Can anyone help me figure out why post value is empty?
Thanks
$_POST does not contain any file data.
Remove the line
print_r($_POST);exit('I am in the tp');
And then tell us what happens.

prestashop 1.7 new module

I have a problem in prestashop 1.7, when I load the form.tpl in my module I can not do a setAction. What I need is that when I continue in the payment I open a new sale with a payment platform and in prestashop in platform carge the validation I leave the code. help please
main file of the prestashop module
public function hookPaymentOptions($params) {
if (!$this->active) {
return;
}
$this->smarty->assign(
$this->getPaymentApiVars()
);
$apiPayement = new PaymentOption();
$apiPayement->setModuleName($this->name)
->setLogo($this->context->link->getBaseLink().'/modules/hhpayment/views/img/pago.jpg')
// ->setCallToActionText($this->l(''))
//Définition d'un formulaire personnalisé
->setForm($this->fetch('module:hhpayment/views/templates/hook/payment_api_form.tpl'))
->setAdditionalInformation($this->fetch('module:hhpayment/views/templates/hook/displayPaymentApi.tpl'))
->setAction($this->context->link->getModuleLink($this->name, 'validation', array(), true));
return [$apiPayement];
}
this is the form.tpl that I charge this without the method but it is by tests
<form action="{$payment_url}" target="_blank" >
<div class="form-group">
{* choix du mode de carte *}
{l s='please choose your card type' mod='hhpayment'}
<div class="radio">
<label>
<input type="radio" name="cb_type" value="mastercard" id="cb_type1" checked="checked" /> Pago internacional
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="cb_type" id="cb_type2" value="visa"/> Pago Nacional
</label>
</div>
</div>
{* Informations pour l'api *}
<input type="hidden" name="success_url" value="{$success_url}" />
<input type="hidden" name="error_url" value="{$error_url}" />
<input type="hidden" name="id_cart" value="{$id_cart}" />
<input type="hidden" name="cart_total" value="{$cart_total}" />
<input type="hidden" name="id_customer" value="{$id_customer}" />
</form>
and this is the validation file
class hhpaymentvalidationModuleFrontController extends ModuleFrontController
{
/**
* Validation du paiement standard
* Puis redirection vers la page de succès de commande
*/
public function postProcess()
{
$cart = $this->context->cart;
$this->abrir("http://davivienda.com");
if ($cart->id_customer == 0 || $cart->id_address_delivery == 0 || $cart->id_address_invoice == 0 || !$this->module->active) {
Tools::redirect('index.php?controller=order&step=1');
}
$customer = new Customer($cart->id_customer);
if (!Validate::isLoadedObject($customer)) {
Tools::redirect('index.php?controller=order&step=1');
}
$currency = $this->context->currency;
$total = (float)$cart->getOrderTotal(true, Cart::BOTH);
//La command passe directement en statut payé
$this->module->validateOrder((int)$cart->id, Configuration::get('PS_OS_PAYMENT'), $total, $this->module->displayName, null, array(), (int)$currency->id, false, $customer->secure_key);
Tools::redirect('index.php?controller=order-confirmation&id_cart='.(int)$cart->id.'&id_module='.(int)$this->module->id.'&id_order='.$this->module->currentOrder.'&key='.$customer->secure_key);
}
public function abrir($param)
{
echo" <script> window.open(URL,'ventana1,'width=300,height=300,scrollbars=NO')</script> ";
}
}
I was able to find a solution to this problem, I don't know if it is the correct one, but it already works for me:
The postProcess method passes it to the main and the validation.php file passes it to the same folder where the main file is.
Then it is time to modify the validation.php file which was changed to the same directory as main, this file should be as follows.
It should be imported
require_once dirname(__FILE__) . '/config/config.inc.php';
require_once dirname(__FILE__) . '/main.php';
Then to avoid a kernel error the following code snippet must be implemented
global $kernel;
if(!$kernel){
require_once _PS_ROOT_DIR_.'/app/AppKernel.php';
$kernel = new \AppKernel('prod', false);
$kernel->boot();
}
After this, it is necessary to implement the logic and receive the parameters by get that the payment screen will return to us after the payment is made, once this data is received, the cart must be recovered and the data sent to the function that was migrated to the main file
ob_start();
$context = Context::getContext();
if (is_null($context->cart)) {
$context->cart = new Cart($context->cookie->id_cart);
}
if (is_null($context->cart->id_currency)) {
$context->cart->id_currency = $context->cookie->id_currency;
}
$cart = $context->cart;
$customer = new Customer($cart->id_customer);
$currency = $cart->id_currency;
$total = (float)$cart->getOrderTotal(true, Cart::BOTH);
$object = new filemain();
$order = $object->methodCreateInMain($cart->id, Configuration::get('PS_OS_PAYMENT'), $total, $currency, $customer->secure_key);
Basically the previous code in validation.php retrieves the cart data and sends it by parameter to the function that was passed to main, where the order will be validated and created.
It should be noted that the return url after payment must be ulrCommerce/module/validation.php
The above worked perfectly for me and is a solution based on various blogs and forums viewed

How to get file tmp_name using JInput

I'm a bit stuck with this. I have this bit of code which manages to get the filename of my file:
class AControllerA extends JControllerForm
{
function save()
{
//Upload file
jimport('joomla.filesystem.file');
$jinput = JFactory::getApplication()->input;
$store_form = $jinput->get('jform', null, 'array');
$file = $store_form['img_url'];
echo $file;
}
}
*The file field has a name of jform[img_url];
However I cannot seem to get the 'tmp_name' for the file. Anyone know what I'm missing out? I'm a bit confused as to how jinput works...jrequest worked quite easily. Thanks!
models/forms/a.xml
<form enctype="multipart/form-data">
<fieldset>
<field
name="img_url"
type="file"
label=""
description=""
size="40"
class="inputbox"
default=""
/>
</fieldset>
</form>
How about like this:
$files = $input->files->get('jform', null);
$filename = $files['img_url']['tmp_name'];
echo $filename;
Check out documentation for Retrieving file data using JInput
Supposing you are using JForm and the file input type, then you can access the file using this:
$files = $jinput->files->get('jform');
$file = $files['img_url']['tmp_name']
Also make sure your form has the enctype="multipart/form-data" set, otherwise it will not work.
In your model you should have sth like this
public function getForm($data = array(), $loadData = false)
{
/**
* Get the Form
*/
$form = $this->loadForm('com_mycomponent.mycomponent', 'mycomponent',
array('control' => false, 'load_data' => $loadData));
if (empty($form)) {
return false;
}
return $form;
}
Note that $loaddata and 'control' is set to false, when 'control' is false you can get file parameters as according to the name specified in your xml i.e the output form is like:
<input name="name in xml file" type="file" />
If 'control' => 'jform'
<input name="jform[name in xml file]" type="file" />
$loaddata= false means you dont need to fetch any data from the database to the form.
in your view.html.php you should have sth like this
public function display($tpl = null)
{
$this->formData = $this->get('Form');
$this->addToolbar();
parent::display($tpl);
}
Lets suppose I'll receive the requested file in "upload" method of "mycomponent" controller then it should have sth like this:
class MycomponentControllerMycomponent extends JControllerAdmin
{
public function upload()
{
//Retrieve file details from uploaded file, sent from upload form
$file = JFactory::getApplication()->input->files->get('name in xml
**$tmp_name** = $file['tmp_name'];
}
}
$tmp_name is Your required name

virtuemart 2 product pdf does not display custom fields

I'm using VirtueMart 2.0.10 with Joomla! 2.5.6 and my problem is the autogenerated pdf documents for each product don't include my custom fields. I'm no php expert but I think theese lines in file /components/com_virtuemart/views/productdetails/tmpl/default_pdf.php has something to do with it, starting at line 145:
<?php // Product custom_fields TODO relation to Childs
if (!empty($this->product->customfields)) { ?>
<div class="product-fields">
<?php
$custom_title = null ;
foreach ($this->product->customfields as $field){
?><div style="display:inline-block;" class="product-field product-field-type-<?php echo $field->field_type ?>">
<?php if ($field->custom_title != $custom_title) { ?>
<span class="product-fields-title" ><strong><?php echo JText::_($field->custom_title); ?></strong></span>
<?php //echo JHTML::tooltip($field->custom_tip, $field->custom_title, 'tooltip.png');
} ?>
<span class="product-field-display"><?php echo $field->display ?></span>
<span class="product-field-desc"><?php echo jText::_($field->custom_field_desc) ?></span>
</div>
<?php
$custom_title = $field->custom_title;
} ?>
</div>
<?php
} // Product custom_fields END ?>
I tested adding an else statement echoing some text after the above if statement and it executetd. So apperently there are no custom fields... but there really are...
I haven't found anyone else experiencing this problem wich I think is weird, but I don't think I have screwed something up. I HAVE made a few changes in the /components/com_virtuemart/views/productdetails/tmpl/default.php file.
I removed all the code that I entered in my question and replaced it with the following code from the file /components/com_virtuemart/views/productdetails/tmpl/default.php:
<?php
$custom_title = null;
foreach ($this->product->customfieldsSorted['normal'] as $field) { // I set the position to normal
if ( $field->is_hidden )
continue;
if ($field->display) {
?>
<?php if ($field->custom_title != $custom_title) { ?>
<b><?php echo JText::_($field->custom_title); ?></b><br />
<?php
if ($field->custom_tip)
echo JHTML::tooltip($field->custom_tip, JText::_($field->custom_title), 'tooltip.png');
}
?>
<?php echo $field->display ?><br />
<?php echo jText::_($field->custom_field_desc) ?><br />
<?php
$custom_title = $field->custom_title;
}
}
?>
I'm no expert but this worked for me. The PDF now includes the custom fields.
As you see in the comment in the code I changed the position to 'normal'. The other positions seems to be 'ontop' and 'onbot'. But I won't change that setting so I leave it be.
EDIT: I forgot to mention I added some other html-code to that segment, like <br /> and <b> just for apperences. So nothing major, just to clarify that the code isn't EXACTLY like it is in the file default.php