Apostrophe in Field element breaks form

ontarget

Active Member
Hi I have a form which is being pre-populated from a URL.
An Admin user fills out a form (called "link generator") they enter a title {___course_title} and a load of other entries.
The user gets the link and some of the entries e.g title {aaa_participant_claim___course_title}
(text elements) in another form (called "my claims") are pre-populated for them as read only fields.

In one of these forms the admin has entered a title: "St Colman's Blah Blah" using an apostrophe
However because of the use of this character the rest of the forms data is null. Removing the apostrophe results in the form working again.
Is there a method of allowing the apostrophe or stripping it from the element {aaa_participant_claim___course_title} without having to send a new link form to all the users again?
 
An Admin user fills out a form (called "link generator") they enter a title {___course_title} and a load of other entries.
The user gets the link and some of the entries e.g title {aaa_participant_claim___course_title}

You've left out how you actually generate the link and send it to the user.

Does the link the user sees have a literal apostrophe in it, or has it been url encoded?

-- hugh
 
Apologies the link is being generated and converted to a bitly link then on clicking the link the user received a prefilled form based on the url ($fullUrl)
Venues are urlencoded e.g &aaa_participant_claim___venue=' . urlencode($ecName).
But titles are not e.g &aaa_participant_claim___course_title=' . '{___course_title}' .

PHP:
$db = JFactory::getDBO();
$tr_table = $db->quoteName('aaa_edcentres');
$eircode = $db->quoteName('eircode');
$ec = '{___venue_education_centre}';
if ($ec == "OTHER") {
  $ecName = '{___venue_other}';
  $ecEircode = '{___venue_other_eircode}';
} else {
  $ecName = '{___venue_education_centre}';
  $query = "SELECT $eircode FROM $tr_table WHERE `edcentre_title` = \"$ec\"";
  $db->setQuery($query);
  $ecEircode = $db->loadResult();
}
//return $ecEircode;




$fullUrl = 'https://mywebsite.com/index.php?option=com_fabrik&view=form&formid=1&aaa_participant_claim___uniqueclaim_id='.'{___course_id}' .' &aaa_participant_claim___category=' . '{___category_raw}' . '&aaa_participant_claim___course_title=' . '{___course_title}' . '&aaa_participant_claim___course_code=' . '{___enter_course_code}' . '&aaa_participant_claim___applysess=' . '{___apply_sess}' . '&aaa_participant_claim___allow_overnight=' . '{___allow_overnight}' . '&aaa_participant_claim___venue=' . urlencode($ecName). '&aaa_participant_claim___course_start_date=' . '{___enter_course_date}' . '&aaa_participant_claim___claim_process=' . '{___edcentre_email}' . '&aaa_participant_claim___edcentre_id=' . '{___edcentreid}' . '&aaa_participant_claim___edcentre_process=' . '{___education_centre}'.'&aaa_participant_claim___venue_ec=' . urlencode($ecEircode);





require_once JPATH_SITE . '/components/com_fabrik/libs/bitly/bitly.php';
         $bitly = new bitly('username', 'xxxxxxxxxxxxxx');
       
         // bitlify it
         $url = (string) $bitly->shorten($fullUrl);
       
         return $url;
       // $link = '~(?:(https?)://([^\s<]+)|(www\.[^\s<]+?\.[^\s<]+))(?<![\.,:])~i';
//$string = preg_replace($link, '<a href="$url" target="_blank" title="$url">$url</a>', $string);
//return $string;
 
Last edited:
Well, I'm guessing that's the problem, that you didn't urlencode it, although I'm surprised bitly doesn't do that for you. If I use their web site to shorten a URL with a quote in it, then visit the URL, it has been correctly encoded.

Do you have an example of one of the affected bitly links? I can't really suggest any mitigations unless I can see what the links are lengthening to.

For future reference, there's a couple of useful helpers in our StringHelper class (aliased to FabrikString), so ...

Code:
$fullUrl = FabrikString::encodeurl($fullUrl);

... will take a full URL with a query string, bust out the query string part, encode the value parts, and put it all back together again. So you don't have to worry about individually encoding values.

If you just have a query string part (everything after the ?), you can do ...

Code:
$qs = FabrikString::encodeqs($qs);

... but don't feed that one a full URL, as it'll encode the schema part as well.

-- hugh
 
Unfortunately, I don't think this is fixable.

The URL's have been encoded with #37 for the quote, so the query string stops right there. PHP doesn't even see the rest of it. It's not in the request array, period, because # has a very specific meaning in URL's, and terminates the query string.

I tested here, to see if we could get the values and massage them into the correct form, but the data just isn't there. Doesn't get passed from the httpd to PHP.

-- hugh
 
Ok thanks for having a look.
When I click the bitly link http://bit.ly/2F28TCC then remove &#039; from the url in the part
&aaa_participant_claim___course_title=PLC%20-%20Banteer,%20St%20Brendan&#039;s &amp; Rahan NS
The read only fields are populated correctly - is there no way of getting the {aaa_participant_claim___course_title} element to ignore or accept characters like #039; ?

Otherwise
How can I prevent apostrophe s being entered in the text element in the admin form in the first place or can they be stripped before submission if entered ?
 
Last edited:
Ok thanks for having a look.
When I click the bitly link http://bit.ly/2F28TCC then remove &#039; from the url in the part
&aaa_participant_claim___course_title=PLC%20-%20Banteer,%20St%20Brendan&#039;s &amp; Rahan NS
The read only fields are populated correctly - is there no way of getting the {aaa_participant_claim___course_title} element to ignore or accept characters like #039; ?

Otherwise
How can I prevent apostrophe s being entered in the text element in the admin form in the first place or can they be stripped before submission if entered ?

As I said in my last post, everything from the # onwards is removed from the request data. It just isn't there, doesn't exist in PHP. Because # is a browser directive (to move between anchors on a page), and is completely ignored by servers. It terminates the query string. So no, we can't fix it, because the data just isn't there.

To avoid this, you need to urlencode your link before bitly'ing it, either by encoding each individual value (like you already do with one of them), or by using the helper function I gave you an example if, to do the whole link at once.

I'll probably go ahead and build a bitly helper function, which includes urlencoding, to help people avoid this pitfall in the future.

Hugh


Sent from my HTC6545LVW using Tapatalk
 
Ok thanks for the explanation - I am trying to create a match regex validation in the title element to prevent users entering such characters
I am using
/^[.,\/#!$%\^&\*;:{}=\-_`~()]$/
see https://regex101.com/r/nkn3SC/1 but it fails in my form even when no such characters are entered is there some special syntax for fabrik?
 
You don't need to. As long as you urlencode the link before bitly'ing, you'll be fine.

But no, we don't do anything special, just regex. And we assume you are surrounding your regex with /.

-- hugh
 
Ok thanks i tried see (//hugh's stuff urlencode then bitlyfy it) that but the problem remains (entering and apostrophe prevents the data being loaded into the remainder of the fields) here is my bitlyfy code:
PHP:
$db = JFactory::getDBO();
$tr_table = $db->quoteName('aaa_edcentres');
$eircode = $db->quoteName('eircode');
$ec = '{___venue_education_centre}';
if ($ec == "OTHER") {
  $ecName = '{___venue_other}';
  $ecEircode = '{___venue_other_eircode}';
} else {
  $ecName = '{___venue_education_centre}';
  $query = "SELECT $eircode FROM $tr_table WHERE `edcentre_title` = \"$ec\"";
  $db->setQuery($query);
  $ecEircode = $db->loadResult();
}
//return $ecEircode;

$fullUrl = 'https://mysite.com/index.php?option=com_fabrik&view=form&formid=1&aaa_participant_claim___uniqueclaim_id='.'{___course_id}' .' &aaa_participant_claim___category=' . '{___category_raw}' . '&aaa_participant_claim___course_title=' . '{___course_title}' . '&aaa_participant_claim___course_code=' . '{___enter_course_code}' . '&aaa_participant_claim___applysess=' . '{___apply_sess}' . '&aaa_participant_claim___allow_overnight=' . '{___allow_overnight}' . '&aaa_participant_claim___venue=' . urlencode($ecName). '&aaa_participant_claim___course_start_date=' . '{___enter_course_date}' . '&aaa_participant_claim___claim_process=' . '{___edcentre_email}' . '&aaa_participant_claim___edcentre_id=' . '{___edcentreid}' . '&aaa_participant_claim___edcentre_process=' . '{___education_centre}'.'&aaa_participant_claim___venue_ec=' . urlencode($ecEircode);

require_once JPATH_SITE . '/components/com_fabrik/libs/bitly/bitly.php';
         $bitly = new bitly('username', 'xxxxxxxxxxxx);
       
        //hugh's stuff urlencode then bitlyfy it
         $encode = FabrikString::encodeurl($fullUrl);
         $url = (string) $bitly->shorten($encode);
          // bitlify it
         //$url = (string) $bitly->shorten($fullUrl);
       
         return $url;
       // $link = '~(?:(https?)://([^\s<]+)|(www\.[^\s<]+?\.[^\s<]+))(?<![\.,:])~i';
//$string = preg_replace($link, '<a href="$url" target="_blank" title="$url">$url</a>', $string);
//return $string;
 
Ha spotted! I'll be encouraging my kids to stop using any kind of grammar and write their essays in lowercase;)
 
I can't replicate that problem. If I use a ', it correctly urlencodes, and fills out the form.

However, thinking about it, you will have to individually encode each value, as they may have &'s in them, which the FabrikString::encodeurl() will intepret as query string separators if you just feed it an entire url, and not encode.

So get rid of my suggestion, and just encode every value ...

Code:
$fullUrl = COM_FABRIK_LIVESITE . 'index.phpoption=com_fabrik&view=form&formid=1' .
   '&aaa_participant_claim___uniqueclaim_id=' . urlencode('{___course_id}') . 
   '&aaa_participant_claim___category=' . urlencode('{___category_raw}') .
   '&aaa_participant_claim___course_title=' . urlencode('{___course_title}') .
   '&aaa_participant_claim___course_code=' . urlencode('{___enter_course_code}') .
   '&aaa_participant_claim___applysess=' . urlencode('{___apply_sess}') .
   '&aaa_participant_claim___allow_overnight=' . urlencode('{___allow_overnight}') .
   '&aaa_participant_claim___venue=' . urlencode($ecName) .
   '&aaa_participant_claim___course_start_date=' . urlencode('{___enter_course_date}') .
   '&aaa_participant_claim___claim_process=' . urlencode('{___edcentre_email}') .
   '&aaa_participant_claim___edcentre_id=' . urlencode('{___edcentreid}') .
   '&aaa_participant_claim___edcentre_process=' . urlencode('{___education_centre}') .
   '&aaa_participant_claim___venue_ec=' . urlencode($ecEircode);

I'm sure some of those don't need encoding, but it won't hurt.

-- hugh
 
Just a coding style thing, it's usually better to bust long concatenation lines like that up into separate lines, and to be liberal with the spacing, for readability. Makes it much easier to see what's going on, and spot potential problems.

And wherever you need to use an absolute link (with site prepended), use the COM_FABRIK_LIVESITE constant, which (for instance) will know whether the page was loaded with http or https, and won't need changing if you have a sandbox on a subdomain, etc.

-- hugh
 
We are in need of some funding.
More details.

Thank you.

Members online

Back
Top