[Typo3-dev] formmail, locationData and TemplaVoila! A Fix and a Workaround.

Georg Rehfeld georg.rehfeld at gmx.de
Wed Jan 19 06:11:35 CET 2005


Hi all,

while using TemplaVoila! and trying to have a contact mail form on every
page on my site I seem to have discovered a bug in Typo3
( typo3/sysext/cms/tslib/class.tslib_fe.php, function locDataCheck() ).

My form was derived from the css_styled_content one visible in the
"TypoScript Object Browser" under "tt_content.mailform.20" by copying
and modifying it a little as of the TS snippets below.

Also I had a normal mail form on some page, which did it's job just
perfectly: sent a nicely HTML formatted email to the configured
recipient.

However, the "on every page" form, though showing up and redirecting me
to a "Thank you" page, as the normal form, refused to send the mail
without any notice (<rant>like a typical M$ product</rant>)! Also the
XHTML of both forms was identical (except of formatting, as you might
guess).

The Admin Panel then gave a first hint: it had a message telling me:
| LocationData Error: Location data (42:_NO_TABLE:) record pointed to
| was not accessible.

Looking for that message in the sources revealed the mentioned function.
That functions purpose is to assure, that the email sender is on some
valid page of the site (at least; more checks are done in the function
and elsewhere, to avoid abuse by spammers). My proposed change to this
function follows (similar to a context diff, sorry for the confusing
formatting due to Mozilla and Typo3.org reformatting to HTML):

   /**
     * Checks if a formmail submission can be sent as email
+   * The given locationData is of the form: [page id]:[current record 
table]:[current record id] .
+   * At least the [page_id] must be given and be a valid page UID.
     *
     * @param       string          The input from $_POST['locationData']
-   * @return      void
+   * @return      boolean         True, when email may be sent, false 
otherwise
     * @access private
     * @see checkDataSubmission()
+   * @see TSRef, FORM.locationData
     */
   function locDataCheck($locationData)    {
       $locData = explode(':',$locationData);
-     if (!$locData[1] || 
$this->sys_page->checkRecord($locData[1],$locData[2],1)) {
+     if (!$locData[1] || 
!$this->sys_page->checkRecord($locData[1],$locData[2],1)) {
           if (count($this->sys_page->getPage($locData[0]))) {
               // $locData[1] -check means that a record is checked only 
if the locationData has a value for a record else than the page.
               return 1;
-         } else $GLOBALS['TT']->setTSlogMessage('LocationData Error: 
The page pointed to by location data ('.$locationData.') was not 
accessible.',2);
+         }
-     } else $GLOBALS['TT']->setTSlogMessage('LocationData Error: 
Location data ('.$locationData.') record pointed to was not accessible.',2);
+     }
+     // fall through == error. Saves 2 else statements :-)
+     $GLOBALS['TT']->setTSlogMessage('LocationData Error: Location data 
('.$locationData.') record pointed to was not accessible.',2);
   }

Someone with more insigth PLEASE check the change, to not introduce
any spam flaws into Typo3! Then please apply the change.

My config:
- typo3                 version 3.7.0
- templavoila           version 0.3.0
- css_styled_content    version 0.2.2


My TS (TypoScript), essentials, "lib.contactform" was configured via
TemplaVoila as the receiver of the following at an appropriate spot:

### Email form on every page
lib.contactform < tt_content.mailform.20
lib.contactform {
   layout = <div class= ... [formatting tailored for pure CSS layout]
   ...
   ### have a constant for the recipient(s) of the email instead of some
   ### page field. Comma seperated list of (valid) email addresses.
   recipient.field >
   recipient = {$contact.email.recipient}
   ...
   ### get the form itself from a constant too, same format as
   ### documented in TSRef.FORM.data. Easily gotten from a
   ### form on some test page. Just replace any linebreak with '||'
   ### and set it into the constant contact.email.formdata.
   data.field >
   data = {$contact.email.formdata}
   ...
   ### get the UID of the 'thanks' page as a constant instead of some
   ### page field
   redirect.field >
   redirect.listNum >
   redirect = {$contact.email.thanks}
}

This setup together with my patch works well.

If you can't (or dont like to) patch the Typo3 source, here is the
workaround:

lib.contactform < tt_content.mailform.20
lib.contactform {
   ...
   [statements to configure your formmail, see above or do your own]
   ...
   ### Shut off auto generation of the hidden field 'locationData',
   ### which seems to be broken.
   locationData = 0
   ### generate an acceptable hidden field 'locationData' manually
   hiddenFields.locationData = TEXT
   hiddenFields.locationData {
   value = {page:uid}
     insertData = 1
   }
   ...
   [other stuff]
}

Just my 2 cents, regards

Georg
-- 
  ___   ___
| + | |__    Georg Rehfeld      Woltmanstr. 12     20097 Hamburg
|_|_\ |___   georg.rehfeld.nospam at gmx.de    +49 (40) 23 53 27 10





More information about the TYPO3-dev mailing list