How to properly user JFormFieldFile???

402 views
Skip to first unread message

Daniel D. / compojoom

unread,
Mar 23, 2012, 11:39:22 AM3/23/12
to joomla-...@googlegroups.com
Hey Guys,
For the last hour I've been trying to figure out how to use a JFormFieldFile field that is set to required.

The thing is when I save the form data, the save function complains that the file field is empty and because it is required -> the validation function returns false...

I went around this by overriding the whole save function in the JControllerForm. (I just checked if the  $_Files array contains the file and added it to the $data array.) But this approach feels really stupid for me??? I basically have the same save function + 3 lines that handle the file field.

Is there any other way to let JForm know that we have a field that is not in the post array? Preprocess form in the controller or something?

Regards,
Daniel

elin

unread,
Mar 23, 2012, 5:27:04 PM3/23/12
to joomla-...@googlegroups.com
I'm not sure I understand what is happening. Maybe you could show us your code or xml?


Are you saying that the field has been filled out but the validation is saying it is empty? 
 

Elin

Daniel D. / compojoom

unread,
Mar 24, 2012, 7:47:15 AM3/24/12
to joomla-...@googlegroups.com
I just realized that I've posted this maybe in the wrong group (general joomla dev would have been a better match, maybe).

Thanks for the reply Elin. Of course I can share a little bit of code:

so here is the form:

<?xml version="1.0" encoding="utf-8"?>
<form>
    <fieldset>
        <field name="hotspots_kml_id" type="text" default="0" label="JGLOBAL_FIELD_ID_LABEL"
            readonly="true" class="readonly"
            description="JGLOBAL_FIELD_ID_DESC"/>

        ....


        <field name="kml_file" type="file" label="COM_HOTSPOTS_KML_FILE"
               description="COM_HOTSPOTS_KML_FILE_DESC" required="true"/>

        ....


    </fieldset>

</form>

my edit.php layout file:

<form enctype="multipart/form-data" action="<?php echo JRoute::_('index.php?option=com_hotspots&view=kml&hotspots_kml_id=' . (int)$this->item->hotspots_kml_id); ?>" method="post" class="form" name="adminForm" id="adminForm" >
    <div class="width-60 fltlft">
        <fieldset class="adminform">
            <legend><?php echo empty($this->item->hotspots_kml_id) ? JText::_('COM_HOTSPOTS_NEW_KML') : JText::sprintf('COM_HOTSPOTS_EDIT_KML', $this->item->hotspots_kml_id); ?></legend>
            <ul class="adminformlist">
                ....
                <li>
                    <?php echo $this->form->getLabel('hotspots_kml_id'); ?>
                    <?php echo $this->form->getInput('hotspots_kml_id'); ?>
                </li>
        ....
       
                <li>
                    <?php echo $this->form->getLabel('kml_file'); ?>
                    <?php echo $this->form->getInput('kml_file'); ?>
                </li>
            </ul>

            .....

    <input type="hidden" name="task" value=""/>
    <?php echo JHTML::_('form.token'); ?>
</form>

So when you  click on save, we go in the kml controller that extends JControllerForm:
class HotspotsControllerKml extends JControllerForm {
....
}

If I don't override the save function, then we use the parent function which looks like this:

public function save($key = null, $urlVar = null)
    {

        // Check for request forgeries.
        JRequest::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

        // Initialise variables.
        $app = JFactory::getApplication();
        $lang = JFactory::getLanguage();
        $model = $this->getModel();
        $table = $model->getTable();
        $data = JRequest::getVar('jform', array(), 'post', 'array');
        $checkin = property_exists($table, 'checked_out');
        $context = "$this->option.edit.$this->context";
        $task = $this->getTask();

.....



// Validate the posted data.
        // Sometimes the form needs some posted data, such as for plugins and modules.
        $form = $model->getForm($data, false);

        if (!$form)
        {
            $app->enqueueMessage($model->getError(), 'error');

            return false;
        }

        // Test whether the data is valid.
        $validData = $model->validate($form, $data);

.....

        if ($validData === false)
        {
....

}

As you can see in this function we do:
$data = JRequest::getVar('jform', array(), 'post', 'array');

and this is all ok, but the file is not sent in the post array, but it is in the $_FILES array.

And because of this the validation in the model fails.

So as I said, I overwrote the save function and added a $data['kml_file'] = true; if the user has submitted a file.

The question is - should I overwrite this function? Or should I do the checks in the validate function?

Since the validate function expects to receive the $form and the $data I think that we should not do any interactions with the $_POST and $_FILES arrays there, right?

Am I doing something wrong here? Is there a better approach to this???

Thanks in advance!
Daniel

elin

unread,
Mar 24, 2012, 3:02:44 PM3/24/12
to joomla-...@googlegroups.com
I have to say that field has always been a mystery to me. It has never saved and I guess you have figured out why but  it's not clear what it should even save. I think of it more like the field in the installer that you use to find the zip file but you don't ever actually store that information.
 Usually the fields  like the media or imagelist or filelist fields would just save the reference to the name and location of the file. 

I have always thought that what you should do is extend it to make a custom field that is actually useful for the file types you want.

Elin

Sam Moffatt

unread,
Mar 24, 2012, 10:30:58 PM3/24/12
to joomla-...@googlegroups.com
You have to write something in your model to process and save it. This
is primarily a PHP side effect that it'll be jammed into $_FILES and
you have to use move_uploaded_file (or JFile::upload) to shift it
somewhere on disk where you want to use it.

No idea why the required thing isn't working, possibly a bug but you
shouldn't need to subclass, just pick it up in the model when you save
to shift the file on disk somewhere.

Cheers,

Sam Moffatt
http://pasamio.id.au

> --
> You received this message because you are subscribed to the Google Groups
> "Joomla! CMS Development" group.
> To view this discussion on the web, visit
> https://groups.google.com/d/msg/joomla-dev-cms/-/Nc8IpWwUHz8J.
>
> To post to this group, send an email to joomla-...@googlegroups.com.
> To unsubscribe from this group, send email to
> joomla-dev-cm...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/joomla-dev-cms?hl=en-GB.

Daniel D. / compojoom

unread,
Mar 25, 2012, 4:57:55 AM3/25/12
to joomla-...@googlegroups.com
hey guys!
I think that I haven't explained that good enough.
Yes I overwrote the save function in the model and I upload the KML files myself - no issue here.

The problem is -> to get to the save function in the model, one needs to go in the save function of the controller.

If I override the save function in the controller and trick the $data to include the file field than everything is fine.
I was just wondering if this is the correct way to do it, or if there is an easier one.

Btw - if I don't set the formField to be required then the validation function doesn't complain and one lands in the model's save function :)

So it is really just the issue with having this field required and failing the validation after that. ( I understand why it fails - if anyone else will have better ideas how to trick this thing - or to solve this nuisances once and forever :))

Cheers,
Daniel

elin

unread,
Mar 25, 2012, 8:41:25 AM3/25/12
to joomla-...@googlegroups.com

Required is not working because it assumes that you are going to save something from $data in a field. 
So the issue I think is in how required is attempting to validate in this case.  It needs to check  $_FILES not $data.

If the field is  not going to save something in a manner typical of other fields the required is going to fail unless it is overriding that.   

So ... possibly the field needs to handle validation for required itself. Or you could make a custom rule that handles file validation including dealing correctly with required.

 
Elin 

On Saturday, Marc)odel when you save

to shift the file on disk somewhere.htCheers,

Sam Moffatt
http://pasamio.id.au

> To post to this group, send an email to joomla-dev-cms@googlegroups.​com.


> To unsubscribe from this group, send email to


> For more options, visit this group at
> http://groups.google.com/​group/joomla-dev-cms?hl=en-GB.

> To post to this group, send an email to joomla-dev-cms@googlegroups.​com.


> To unsubscribe from this group, send email to

> joomla-dev-cms+unsubscribe@​googlegroups.com.

Reply all
Reply to author
Forward
0 new messages