Access files from custom field in my plugin

141 views
Skip to first unread message

Lirim Imeri

unread,
Feb 25, 2021, 3:32:31 AM2/25/21
to Joomla! General Development
Hi.

I'm trying to make a payment plugin, this plugin has some custom fields I added manually in example.xml file.

Here is the code how I added.

1.png

How it displays:

2.png
So far, everything is fine.

My problem is with last 3 fields, I can't accessing them correctly.
Access to the fields above them works perfectly, but with files it doesn't.


Using this code:
$input = JFactory::getApplication()->input;
$input->get('caTest');
shows me only the name of the file I entered.


The question is how can i get the entire file or path where the file is stored added there? I need the file and its content to make request.

Hope I was clear.
Regards.  

Glenn Arkell

unread,
Feb 25, 2021, 4:34:09 AM2/25/21
to Joomla! General Development
I've not done anything like this in a plugin but this is what I do in a component controller so I'm assuming it would be similar.

$files = Factory::getApplication()->input->files->get(' caTest ');

I hope this helps in some way.  Cheers.
Glenn
Message has been deleted

Lirim Imeri

unread,
Feb 25, 2021, 9:11:17 AM2/25/21
to Joomla! General Development
Thanks for your response Glenn.

Unfortunately, this method doesn't worked.

Roger Creagh

unread,
Feb 25, 2021, 10:28:07 AM2/25/21
to joomla-de...@googlegroups.com
Now I look back at how I did it in a component that worked fine, it seems like you are only doing half the job. Maybe my code is overcomplex (it is from a while back) but as Glen says you need to do ->input->files->get() but in my case this is used like this:

$importfile = Factory::getApplication()->input->files->get('jform', null, 'files', 'array' );

I think at this point it has been uploaded to a temp space on the server with a temporary name.

$importfile is an array of arrays of all the files controls on the form, each containing the original filename (name.ext only, not path) ['name']  and the temporary filename on the server ['tmp_name'] (which includes the path on the server)

You then have to sanitise the original filename you have been given (if you are keeping the same filename once it is upload) in case it has dodgy characters in the name that your server won't like:

$filename =JFile::makeSafe($importfile['file2import']['name']

where 'file2import' is the name of the control on your form (eg 'caTest'). You might have more than one files control on the form.
Of course you can use your own filename instead if there may be uploads with the same name. 

You then get the temporary filename and also set the destination filename you want to use

$src = $importfile['file2import']['tmp_name'];
$dest = JPATH_COMPONENT_ADMINISTRATOR ."/uploads/". $filename;

(obviously you'll need to adjust the destination to somewhere your plugin can access)

you  then transfer the temporary file to the destination

JFile::upload($src, $dest);

where you can do what you like with it. Or I suppose you might be able to play directly with $importfile['file2import']['tmp_name'] if you didn't want to keep it on the server?

I think these days we are supposed to be using "\Joomla\CMS\Filesystem\File" in place of JFile but I'm not sure about that.

Hope this helps and someone more knowledgeable can say whether it is correct or best. It certainly works for me in a component.

RogerCO
--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-gene...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/joomla-dev-general/5775403f-76ad-4ad2-acde-f7e0e58577c0n%40googlegroups.com.

Lirim Imeri

unread,
Mar 4, 2021, 10:05:44 AM3/4/21
to Joomla! General Development
Hi Roger,

I still could not solve the problem.

I don't know if the files is being upload correctly, where these files should be located, or can I specify the path to locate these files or anything like that to access them?

Thanks in advance,
Lirim.

Roger Creagh

unread,
Mar 4, 2021, 3:14:44 PM3/4/21
to joomla-de...@googlegroups.com
On Thu, 2021-03-04 at 07:05 -0800, Lirim Imeri wrote:
I don't know if the files is being upload correctly, where these files should be located, or can I specify the path to locate these files or anything like that to access them?

Yes you specify the destination where you want them to end up.  In my example below I have already created a folder in my component's admin area where the files will arrive. (In this case it was created by the install xml file for the component by including it in the <administration><files> section of the xml)

Glenn Arkell

unread,
Mar 4, 2021, 6:35:09 PM3/4/21
to Joomla! General Development
Try this (untested).

        $files = Factory::getApplication()->input->files->get('jform', '', 'array');

        foreach ($files as $file) {
            if (file_exists('file://'.$file['tmp_name'])) {
                $fileName = File::makeSafe($file['name']);
                $fileName = str_replace(' ', '_', $fileName);
                $src = $file['tmp_name'];
                $fileName = 'images/foldername/'.$fileName;
    
                $destfile = Path::clean( JPATH_SITE . '/' . $fileName );
    
                File::upload($src, $destfile, false, false, array('jpg','png'));
            }
        }

Glenn

Lirim Imeri

unread,
Mar 5, 2021, 4:57:43 AM3/5/21
to Joomla! General Development
Hi Glenn,

Unfortunately it's not working.

I think only way I can access these files is via URL (path).

Let me know where Joomla stores these files .

Viper

unread,
Mar 5, 2021, 7:12:26 AM3/5/21
to Joomla! General Development
Temporary uploaded files stored not under Joomla folder. They are located in folder from PHP ini value https://www.php.net/manual/en/ini.core.php#ini.upload-tmp-dir

Do something^

if (!empty($_FILES))
{
    if ($files['error'] || !is_uploaded_file($files['tmp_name']))
    {
        header('HTTP/1.0 500 Server error', true, 500);

        jexit();
    }

    // Read binary input stream and append it to temp file
    if (!$in = @fopen($files['tmp_name'], "rb"))
    {
        header('HTTP/1.0 500 Server error', true, 500);

        jexit();
    }
}
else
{
    if (!$in = @fopen("php://input", "rb"))
    {
        header('HTTP/1.0 500 Server error', true, 500);

        jexit();
    }
}

while ($buff = fread($in, 4096))
{
    fwrite($out, $buff);
}

@fclose($out);
@fclose($in);

Mathew Lenning

unread,
Mar 7, 2021, 7:18:08 PM3/7/21
to Joomla! General Development
I'm pretty sure the reason you're having trouble accessing the files is because the file data isn't being saved when it is submitted. 
Your plugin's config is stored by the com_plugin component and so your plugin never actually touches it when the config is saved.

As far as I can tell Joomla doesn't automatically process multi-part form data in the controller or the model (at least not for plugins). It just json_encodes the config values and stores it in the params field.
Since com_plugin's plugin controller is empty you can look at \Joomla\CMS\MVC\Controller\FormController::save method to see what is happening there.
  
You might be able to capture/save the file using either the 'onContentNormaliseRequestData' event  or 'onExtensionBeforeSave' event as the former is called before form validation and the latter is called just before the model saves the data.

Hope this helps. 



Vesa Ademi

unread,
Mar 9, 2021, 8:12:31 AM3/9/21
to Joomla! General Development

Hello,

I am a beginner in Joomla, now I have just worked on a plugin that extends hikashopPaymentPlugin. My question is: when I am uploading the file and pressing the save button the file is not saved and the file name is disappearing, I wanted to ask you where to put the part of the code for file upload, do I have to write inside a specific function and if yes what is that function, or should I extend any class?

Thanks,
Vesa

Mathew Lenning

unread,
Mar 11, 2021, 8:43:55 AM3/11/21
to Joomla! General Development
It depends if your plugin is a system plugin or a hikashop specific plugin. 

If it is a system plugin then you can add a public function called either "onContentNormaliseRequestData" or "onExtensionBeforeSave"  

Looking something like this

public function onContentNormaliseRequestData($context, $dataObject, $form)
{
      if($context !== 'com_plugin.plugin')
      {
            return true;
      }

     $files = JFactory::getApplication()->input->files->get($formControl, array(), 'raw');

     // save the file where you want it and do whatever else you need to do.
}

It is pretty much the same with onExtensionBeforeSave, but the signature is a little different. 

public function onExtensionBeforeSave($context, $table, $isNew, $data)

Hope this helps. 
Reply all
Reply to author
Forward
0 new messages