• Hello Fabrik Community

    Fabrik is now in the hands of the development team that brought you Fabrik for Joomla 4. We have recently transitioned the Fabrik site over to a new server and are busy trying to clean it up. We have upgraded the site to Joomla 4 and are running the latest version of Fabrik 4. We have also upgraded the Xenforo forum software to the latest version. Many of the widgets you might have been used to on the forum are no longer operational, many abandoned by the developers. We hope to bring back some of the important ones as we have time.

    Exciting times to be sure.

    The Fabrik 4.0 Official release is now available. In addition, the Fabrik codebase is now available in a public repository. See the notices about these in the announcements section

    We wish to shout out a very big Thank You to all of you who have made donations. They have really helped. But we can always use more...wink..wink..

    Also a big Thank You to those of you who have been assisting others in the forum. This takes a very big burden off of us as we work on bugs, the website and the future of Fabrik.

Question about upsert value of empty form field

Here's my situation and the functionality I'm looking to accomplish:
- I have a form that uses the upsert plugin to copy the form data to a second table.
- For one specific field, I only want it to overwrite the second table's data if the form field contains a value.
- If the form field is empty, I want the data that's already in the second table's field to remain untouched.

I've tried using just the placeholder as well as several versions of code to check if the form field contains data, but what continues to happen is this:
- When the form field contains a value, the field in the second table is successfully updated with the form field's value.
- When the form field is empty, the field in the second table is updated, but it's blank... I'm assuming because the form field was left blank.

Here's what I've tried. This code is being inserted into the "Value" field in the Upsert plugin and evaluated as PHP (obviously except for when I tried just the placeholder.)

Placeholder
Code:
{tablename___elementname}

Example 1
Code:
$formField = $formModel->fullFormData['tablename___elementname'];
if(!empty($formField)):
    return $formField;
endif;

Example 2
Code:
$formField = $formModel->fullFormData['tablename___elementname'];
if(isset($formField)):
    return $formField;
endif;

Example 3
Code:
$formField = $formModel->fullFormData['tablename___elementname'];
if(isset($formField) && !empty($formField)):
    return $formField;
endif;

Example 4
Code:
$formField = $formModel->fullFormData['tablename___elementname'];
if($formField != ''):
    return $formField;
endif;

This feels like it should be pretty simple, but for some reason I can't figure out what I'm missing.

Thanks!
 
Yeah, the way it works at the moment is if the value is empty, we use the default.

What you could try is edit ...

plugins/fabrik_form/upsert/upsert.php

... at line 165, modify the code to check to see if the returned value is false ...

Code:
            if ($upsert->upsert_eval_value[$i] === '1')
            {
                $res = FabrikHelperHTML::isDebug() ? eval($v) : @eval($v);
                FabrikWorker::logEval($res, 'Eval exception : upsert : ' . $v . ' : %s');

                // if the eval'ed code returned false, skip this
                if ($res === false)
                {
                     continue;
                }

                $v = $res;
            }

I'm not 100% what would happen if this is the only field being updated, so we wind up with no values to update, but this would at least be a start, even if it needs to be tweaked a little.

Then in your eval'ed code, return false if you don't want to update.

if this works, I'll implement it in github.
 
Thank you hugh!
This worked perfectly.

I made the code change to upsert.php

And changed my upsert value to:

Code:
$formField = $formModel->fullFormData['tablename___elementname'];
if(!empty($formField)):
    return $formField;
else:
   return false;
endif;

I'm updating more than one field, so I can't speak to how it would work with only one field, but it does exactly what I needed in my case.

Thank you!!
 
Ok.

My form has quite a few plugins going on, so I created a copy of my site to test upserting a single field with this method.

I turned off all other form plugins and removed all fields from the Upsert plugin except for this one.

I tested editing the record with a value in the form field and with the form field left empty.

When there's a value in the form field, the record in the upserted table is updated as expected.

When the form field is empty, the record in the upserted table is not updated, which is expected. I can see the correct value in the database. But, there is an error thrown on the screen.

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE `upsertedtablename`.`foreign_key_element` = '###'' at line 3

Hope this helps!
 
Thanks.

Yeah, I thought that might be the case. If there's no fields to update, it'll try and execute a query like "UPDATE foo WHERE fk=123" or "INSERT foo", with no "SET something=whatever".

I think I can work round that.

-- hugh
 
OK, at line 82, add this test ...

Code:
        $fields = $this->upsertData($upsertRowExists);

        // make sure we have at least one field to upsert
        if (empty($fields))
        {
            return true;
        }

-- hugh
 
Tested the additional code on both forms, with only a single field upserted and with multiple fields upserted.

Everything works as expected and no errors thrown.
 
So, I seem to be experiencing a weird issue with this again.

I did some testing and I believe the issue is only happening when the logged in user belongs to the Super Administrator group.

When a user not in the Super Administrator group edits a record, the upserted field behaves as expected: when the form field is empty return false so the data in the upserted table is not overwritten.
When a user in the Super Administrator group edits a record, the upserted field is overwritten when the form field is empty.

Any thoughts on that?
 
Hey - sorry about the delay, I was on a much needed vacation with no Internet for a week.

Looking at the code now, see if I can see anything obvious.

-- hugh
 
I can't see anything obvious in the upsert code, we don't check ACL's anywhere.

Is your code still the simple stuff you quoted previously?

Can you put a 'dump' in there ...

Code:
$formField = $formModel->fullFormData['tablename___elementname'];
var_dump($formField);exit;
if(!empty($formField)):
    return $formField;
else:
   return false;
endif;

... and make sure it runs your code, and you get an otherwise blank screen with the expected field value dumped.

-- hugh
 
Yes, the code is still what I posted before. Other things have changed in the application since the original post was resolved, but nothing that I can think of that would affect this and unfortunately I couldn't tell you exactly what changes have been made. I didn't think to test users with different access levels in the initial resolution so I can't say if it was happening before or not. I just happened to notice it when I was working on other parts of the application. It definitely only happens when a user is assigned to the Super Admin group. I've got a "Site Administrator" group which can do most things in the site except for the really technical stuff. I even tested having a Super Admin in both groups thinking maybe I could just add my Super Admins to the Site Admin group as a work around, but the issue still occurred.

I tried the dump. Here's what it gave me.

With a blank form field: string(0) ""
With a non-blank form field: string(11) "XXXXXXXX999" - which is the correct value I entered
 
Hmmm, well I'm baffled then. When that field is an empty string (string(0) "") your code will then return false, and I don't see anything in the upsert plugin code that would behave any different for different group memberships - there literally is nowhere in that code that even looks at access levels or group membership.

Try moving the var_dump ...

Code:
$formField = $formModel->fullFormData['tablename___elementname'];
if(!empty($formField)):
    return $formField;
else:
   var_dump($formField);exit;
   return false;
endif;

... and make sure the dump now only triggers when the field is empty.

-- hugh
 
So, I had some other items I needed to focus on for a bit, but I'm still stuck on this one.
I moved the var_dump so it only triggers when the field is empty and it returned: string(0) ""

It's quite possible I changed something elsewhere along the way between when this was first working and when I noticed the issue with editing a record as a Super User that would affect the functionality, I just don't know what that would be. I know... that's super helpful, right?
 
Do you have any other plugins running on this form?

I've double checked the plugin code, and still don't see anything that would change depending on group membership.

It calls upsertData() here ...

https://github.com/Fabrik/fabrik/blob/master/plugins/fabrik_form/upsert/upsert.php#L82

... and in upsertData(), if the eval'ed code returns false, we skip that field ...

https://github.com/Fabrik/fabrik/blob/master/plugins/fabrik_form/upsert/upsert.php#L177

... and hence don't add it to the array of field names to be change, later in that loop ...

https://github.com/Fabrik/fabrik/blob/master/plugins/fabrik_form/upsert/upsert.php#L231

So ... I guess the next debug test is to see what the actual field array and the generated query is, so add ...

Code:
var_dump($fields, (string)$query);exit;

... at line 107, before we set and execute the query ...

https://github.com/Fabrik/fabrik/blob/master/plugins/fabrik_form/upsert/upsert.php#L108

That should show you the exact array of fields to be changed created by the upsertData() function, and the query the plugin will execute.

If that line doesn't trigger the dump/exit, then that means $fields was empty, and the plugin returned at line 87.

-- hugh
 
Hey hugh,
I've done some more testing and it seems this issue is bigger than just the one field I'm trying to not update when the form field is blank. When I'm editing this form as a superuser, much of the custom code I have as values in the upsert plugin is not working correctly. I'm pretty sure I'm just going to re-do the plugin on this form to see if that helps. I've avoided doing that because I'm updating about 40 fields.

It's something to do with this specific form, because I'm using the upsert plugin with similar code as the value in other forms and I don't experience the issue.

I do have other plugins in this form. In this order:
  • juser
  • redirect - submission message
  • redirect (unpublished) - submission message
  • email - sends an email based on a checkbox on the form
  • autofill
  • upsert
  • php - code to deleted related records when the current record is deleted.

Just curious... does it matter what order the form plugins are in? Probably depends on what I'm trying to do?
 
We are in need of some funding.
More details.

Thank you.

Members online

Back
Top