file-uploadjoomlajoomla2.5joomla3.0joomla3.3

Joomla! 3/2.5: field "file" upload handler - failed to move file... but moved


I'm working on a content plugin that adds some extra fields to com_content component and one of fields is of type "file" with the following declaration:

  <field
      name="zp_zipupl"
      type="file"
      onchange="jQuery(this).closest('form').attr('enctype','multipart/form-data')"
      label="PLG_CONTENT_CUSTOMFIELDZ_ZP_ZIPUPL"
   />

...and I'm handling the upload process on onContentPrepare content event like this:

function onContentPrepare($context,&$article,&$params,$page){
    $input = new JInputFiles();
    $files = $input->get('jform');

    if($files) foreach ($files as $inputFile) {
        foreach ($inputFile as $file) {
            $tmp_dir = $file['tmp_name'];
            $dest_dir = JPATH_SITE.'/uploads/projects/';
            $file_name_ext = $file['name'];

            JFile::upload($tmp_dir,$dest_dir . $file_name_ext);
        }
    }
}

The problem:
After I save the article I get the error "Warning: Failed to move file", but if I enter the "uploads/project/" directory the file is there, so it worked, but the field value is not stored in the database.

If I remove "onchange" event for this field, the value is stored in the database, but because the form enctype is not specified, the file isn't uploaded (even if I manully edit the com_content article/tmpl/edit view and set the enctype I have the same problem while uploading).

I have adapted the plugin code for J! 2.5 + same onContentPrepare code => same behaviour, but the file isn't uploaded.

*Also, less important, onContentPrepareForm if I want to get the value of some field with $form->getValue('field_name'); it doesn't work...

What could cause this?

Thanks!


Solution

  • [Solution]
    Mainly, I had to use the onContentBeforeSave event to get rid of that warning and the value in the database has to be inserted manually. It works on both J! 3.3 and 2.5.x.
    TO-DO: preserve the stored database values for fields of type 'file' when saving article without uploading new file.

    The code:

    function onContentBeforeSave($context,$article,$isNew){
        //get jform
        $jinput = JFactory::getApplication()->input;
        $jform = $jinput->get('jform', null, null);
    
        //get $_FILES
        $input = new JInputFiles();
        $files = $input->get('jform');
        $uploadDir = $this->params->get('cfz_upload_path');
    
        if( ! empty($files)) foreach ($files as $file) {
            foreach ($file as $fieldName => $fileVals) {
                $tmp_dir = $fileVals['tmp_name'];
                $dest_dir = JPATH_SITE . $uploadDir;
                $file_name_ext = $fileVals['name'];
    
                if(JFile::upload($tmp_dir,$dest_dir . $file_name_ext)){
                    //append input value to jform
                    $jform['attribs'][$fieldName] = $uploadDir . $file_name_ext;
                }
            }
        }
        else{
            //preserve file field value...
        }
    
        //add all attribs to $article
        $article->attribs = json_encode($jform['attribs']);
    }