2008-09-29 05:18:23 +02:00
< ? php
2010-07-07 11:17:37 +02:00
2008-09-29 05:18:23 +02:00
/**
2009-04-14 04:06:18 +02:00
* @ package userforms
2008-09-29 05:18:23 +02:00
*/
2009-04-14 04:06:18 +02:00
2016-07-21 07:53:59 +02:00
class UserDefinedForm extends Page
{
2017-04-01 12:02:18 +02:00
2016-07-21 07:53:59 +02:00
/**
* @ var string
*/
private static $icon = 'userforms/images/sitetree_icon.png' ;
/**
* @ var string
*/
private static $description = 'Adds a customizable form.' ;
/**
* @ var string Required Identifier
*/
private static $required_identifier = null ;
/**
* @ var string
*/
private static $email_template_directory = 'userforms/templates/email/' ;
/**
* Should this module automatically upgrade on dev / build ?
*
2016-07-28 15:09:58 +02:00
* @ config
2016-07-21 07:53:59 +02:00
* @ var bool
*/
private static $upgrade_on_build = true ;
2017-04-01 12:02:18 +02:00
/**
* Set this to true to disable automatic inclusion of CSS files
* @ config
* @ var bool
*/
private static $block_default_userforms_css = false ;
/**
* Set this to true to disable automatic inclusion of JavaScript files
* @ config
* @ var bool
*/
private static $block_default_userforms_js = false ;
2016-07-21 07:53:59 +02:00
/**
* Built in extensions required by this page
* @ config
* @ var array
*/
private static $extensions = array (
'UserFormFieldEditorExtension'
);
/**
* @ var array Fields on the user defined form page .
*/
private static $db = array (
" SubmitButtonText " => " Varchar " ,
" ClearButtonText " => " Varchar " ,
" OnCompleteMessage " => " HTMLText " ,
" ShowClearButton " => " Boolean " ,
'DisableSaveSubmissions' => 'Boolean' ,
'EnableLiveValidation' => 'Boolean' ,
'HideFieldLabels' => 'Boolean' ,
'DisplayErrorMessagesAtTop' => 'Boolean' ,
'DisableAuthenicatedFinishAction' => 'Boolean' ,
'DisableCsrfSecurityToken' => 'Boolean'
);
/**
* @ var array Default values of variables when this page is created
*/
private static $defaults = array (
'Content' => '$UserDefinedForm' ,
'DisableSaveSubmissions' => 0 ,
'OnCompleteMessage' => '<p>Thanks, we\'ve received your submission.</p>'
);
/**
* @ var array
*/
private static $has_many = array (
" Submissions " => " SubmittedForm " ,
" EmailRecipients " => " UserDefinedForm_EmailRecipient "
);
/**
* @ var array
* @ config
*/
private static $casting = array (
'ErrorContainerID' => 'Text'
);
/**
* Error container selector which matches the element for grouped messages
*
* @ var string
* @ config
*/
private static $error_container_id = 'error-container' ;
/**
* The configuration used to determine whether a confirmation message is to
* appear when navigating away from a partially completed form .
*
* @ var boolean
* @ config
*/
private static $enable_are_you_sure = true ;
/**
* @ var bool
* @ config
*/
private static $recipients_warning_enabled = false ;
/**
* Temporary storage of field ids when the form is duplicated .
* Example layout : array ( 'EditableCheckbox3' => 'EditableCheckbox14' )
* @ var array
*/
protected $fieldsFromTo = array ();
/**
* @ return FieldList
*/
public function getCMSFields ()
{
Requirements :: css ( USERFORMS_DIR . '/css/UserForm_cms.css' );
$self = $this ;
$this -> beforeUpdateCMSFields ( function ( $fields ) use ( $self ) {
// define tabs
$fields -> findOrMakeTab ( 'Root.FormOptions' , _t ( 'UserDefinedForm.CONFIGURATION' , 'Configuration' ));
$fields -> findOrMakeTab ( 'Root.Recipients' , _t ( 'UserDefinedForm.RECIPIENTS' , 'Recipients' ));
$fields -> findOrMakeTab ( 'Root.Submissions' , _t ( 'UserDefinedForm.SUBMISSIONS' , 'Submissions' ));
// text to show on complete
$onCompleteFieldSet = new CompositeField (
$label = new LabelField ( 'OnCompleteMessageLabel' , _t ( 'UserDefinedForm.ONCOMPLETELABEL' , 'Show on completion' )),
$editor = new HtmlEditorField ( 'OnCompleteMessage' , '' , _t ( 'UserDefinedForm.ONCOMPLETEMESSAGE' , $self -> OnCompleteMessage ))
);
$onCompleteFieldSet -> addExtraClass ( 'field' );
$editor -> setRows ( 3 );
$label -> addExtraClass ( 'left' );
// Define config for email recipients
$emailRecipientsConfig = GridFieldConfig_RecordEditor :: create ( 10 );
$emailRecipientsConfig -> getComponentByType ( 'GridFieldAddNewButton' )
-> setButtonName (
_t ( 'UserDefinedForm.ADDEMAILRECIPIENT' , 'Add Email Recipient' )
);
// who do we email on submission
$emailRecipients = new GridField (
'EmailRecipients' ,
_t ( 'UserDefinedForm.EMAILRECIPIENTS' , 'Email Recipients' ),
$self -> EmailRecipients (),
$emailRecipientsConfig
);
$emailRecipients
-> getConfig ()
-> getComponentByType ( 'GridFieldDetailForm' )
-> setItemRequestClass ( 'UserFormRecipientItemRequest' );
$fields -> addFieldsToTab ( 'Root.FormOptions' , $onCompleteFieldSet );
$fields -> addFieldToTab ( 'Root.Recipients' , $emailRecipients );
$fields -> addFieldsToTab ( 'Root.FormOptions' , $self -> getFormOptions ());
// view the submissions
$submissions = new GridField (
'Submissions' ,
_t ( 'UserDefinedForm.SUBMISSIONS' , 'Submissions' ),
$self -> Submissions () -> sort ( 'Created' , 'DESC' )
);
// make sure a numeric not a empty string is checked against this int column for SQL server
$parentID = ( ! empty ( $self -> ID )) ? ( int ) $self -> ID : 0 ;
// get a list of all field names and values used for print and export CSV views of the GridField below.
$columnSQL = <<< SQL
2016-12-09 00:01:10 +01:00
SELECT " SubmittedFormField " . " Name " as " Name " , COALESCE ( " EditableFormField " . " Title " , " SubmittedFormField " . " Title " ) as " Title " , COALESCE ( " EditableFormField " . " Sort " , 999 ) AS " Sort "
2013-11-13 04:46:13 +01:00
FROM " SubmittedFormField "
LEFT JOIN " SubmittedForm " ON " SubmittedForm " . " ID " = " SubmittedFormField " . " ParentID "
2016-12-08 21:15:44 +01:00
LEFT JOIN " EditableFormField " ON " EditableFormField " . " Name " = " SubmittedFormField " . " Name " AND " EditableFormField " . " ParentID " = '$parentID'
2013-11-13 04:46:13 +01:00
WHERE " SubmittedForm " . " ParentID " = '$parentID'
2016-03-21 11:45:17 +01:00
ORDER BY " Sort " , " Title "
2013-11-13 04:46:13 +01:00
SQL ;
2016-07-21 07:53:59 +02:00
// Sanitise periods in title
$columns = array ();
foreach ( DB :: query ( $columnSQL ) -> map () as $name => $title ) {
$columns [ $name ] = trim ( strtr ( $title , '.' , ' ' ));
}
$config = new GridFieldConfig ();
$config -> addComponent ( new GridFieldToolbarHeader ());
$config -> addComponent ( $sort = new GridFieldSortableHeader ());
$config -> addComponent ( $filter = new UserFormsGridFieldFilterHeader ());
$config -> addComponent ( new GridFieldDataColumns ());
$config -> addComponent ( new GridFieldEditButton ());
$config -> addComponent ( new GridFieldDeleteAction ());
$config -> addComponent ( new GridFieldPageCount ( 'toolbar-header-right' ));
$config -> addComponent ( $pagination = new GridFieldPaginator ( 25 ));
$config -> addComponent ( new GridFieldDetailForm ());
$config -> addComponent ( new GridFieldButtonRow ( 'after' ));
$config -> addComponent ( $export = new GridFieldExportButton ( 'buttons-after-left' ));
$config -> addComponent ( $print = new GridFieldPrintButton ( 'buttons-after-left' ));
2017-01-30 11:24:00 +01:00
// show user form items in the summary tab
$summaryarray = array (
'ID' => 'ID' ,
'Created' => 'Created' ,
'LastEdited' => 'Last Edited'
);
foreach ( EditableFormField :: get () -> filter ( array ( " ParentID " => $parentID )) as $eff ) {
if ( $eff -> ShowInSummary ) {
$summaryarray [ $eff -> Name ] = $eff -> Title ? : $eff -> Name ;
}
}
2017-04-01 12:02:18 +02:00
2017-01-30 11:24:00 +01:00
$config -> getComponentByType ( 'GridFieldDataColumns' ) -> setDisplayFields ( $summaryarray );
2017-04-01 12:02:18 +02:00
2016-07-21 07:53:59 +02:00
/**
* Support for { @ link https :// github . com / colymba / GridFieldBulkEditingTools }
*/
if ( class_exists ( 'GridFieldBulkManager' )) {
$config -> addComponent ( new GridFieldBulkManager ());
}
$sort -> setThrowExceptionOnBadDataType ( false );
$filter -> setThrowExceptionOnBadDataType ( false );
$pagination -> setThrowExceptionOnBadDataType ( false );
// attach every column to the print view form
$columns [ 'Created' ] = 'Created' ;
$filter -> setColumns ( $columns );
// print configuration
$print -> setPrintHasHeader ( true );
$print -> setPrintColumns ( $columns );
// export configuration
$export -> setCsvHasHeader ( true );
$export -> setExportColumns ( $columns );
$submissions -> setConfig ( $config );
$fields -> addFieldToTab ( 'Root.Submissions' , $submissions );
$fields -> addFieldToTab ( 'Root.FormOptions' , new CheckboxField ( 'DisableSaveSubmissions' , _t ( 'UserDefinedForm.SAVESUBMISSIONS' , 'Disable Saving Submissions to Server' )));
});
$fields = parent :: getCMSFields ();
if ( $this -> EmailRecipients () -> Count () == 0 && static :: config () -> recipients_warning_enabled ) {
$fields -> addFieldToTab ( " Root.Main " , new LiteralField ( " EmailRecipientsWarning " ,
" <p class= \" message warning \" > " . _t ( " UserDefinedForm.NORECIPIENTS " ,
" Warning: You have not configured any recipients. Form submissions may be missed. " )
. " </p> " ), " Title " );
}
return $fields ;
}
/**
* Allow overriding the EmailRecipients on a { @ link DataExtension }
* so you can customise who receives an email .
* Converts the RelationList to an ArrayList so that manipulation
* of the original source data isn ' t possible .
*
* @ return ArrayList
*/
public function FilteredEmailRecipients ( $data = null , $form = null )
{
$recipients = new ArrayList ( $this -> EmailRecipients () -> toArray ());
// Filter by rules
$recipients = $recipients -> filterByCallback ( function ( $recipient ) use ( $data , $form ) {
return $recipient -> canSend ( $data , $form );
});
$this -> extend ( 'updateFilteredEmailRecipients' , $recipients , $data , $form );
return $recipients ;
}
/**
* Custom options for the form . You can extend the built in options by
* using { @ link updateFormOptions ()}
*
* @ return FieldList
*/
public function getFormOptions ()
{
$submit = ( $this -> SubmitButtonText ) ? $this -> SubmitButtonText : _t ( 'UserDefinedForm.SUBMITBUTTON' , 'Submit' );
$clear = ( $this -> ClearButtonText ) ? $this -> ClearButtonText : _t ( 'UserDefinedForm.CLEARBUTTON' , 'Clear' );
$options = new FieldList (
new TextField ( " SubmitButtonText " , _t ( 'UserDefinedForm.TEXTONSUBMIT' , 'Text on submit button:' ), $submit ),
new TextField ( " ClearButtonText " , _t ( 'UserDefinedForm.TEXTONCLEAR' , 'Text on clear button:' ), $clear ),
new CheckboxField ( " ShowClearButton " , _t ( 'UserDefinedForm.SHOWCLEARFORM' , 'Show Clear Form Button' ), $this -> ShowClearButton ),
new CheckboxField ( " EnableLiveValidation " , _t ( 'UserDefinedForm.ENABLELIVEVALIDATION' , 'Enable live validation' )),
new CheckboxField ( " HideFieldLabels " , _t ( 'UserDefinedForm.HIDEFIELDLABELS' , 'Hide field labels' )),
new CheckboxField ( " DisplayErrorMessagesAtTop " , _t ( 'UserDefinedForm.DISPLAYERRORMESSAGESATTOP' , 'Display error messages above the form?' )),
new CheckboxField ( 'DisableCsrfSecurityToken' , _t ( 'UserDefinedForm.DISABLECSRFSECURITYTOKEN' , 'Disable CSRF Token' )),
new CheckboxField ( 'DisableAuthenicatedFinishAction' , _t ( 'UserDefinedForm.DISABLEAUTHENICATEDFINISHACTION' , 'Disable Authentication on finish action' ))
);
$this -> extend ( 'updateFormOptions' , $options );
return $options ;
}
/**
* Get the HTML id of the error container displayed above the form .
*
* @ return string
*/
public function getErrorContainerID ()
{
return $this -> config () -> error_container_id ;
}
public function requireDefaultRecords ()
{
parent :: requireDefaultRecords ();
if ( ! $this -> config () -> upgrade_on_build ) {
return ;
}
// Perform migrations
Injector :: inst ()
-> create ( 'UserFormsUpgradeService' )
-> setQuiet ( true )
-> run ();
DB :: alteration_message ( 'Migrated userforms' , 'changed' );
}
/**
* Validate formfields
*/
public function getCMSValidator ()
{
return new UserFormValidator ();
}
2008-09-29 05:18:23 +02:00
}
/**
* Controller for the { @ link UserDefinedForm } page type .
2009-04-14 04:06:18 +02:00
*
2012-10-18 09:01:56 +02:00
* @ package userforms
2008-09-29 05:18:23 +02:00
*/
2009-04-14 04:06:18 +02:00
2016-07-21 07:53:59 +02:00
class UserDefinedForm_Controller extends Page_Controller
{
private static $finished_anchor = '#uff' ;
private static $allowed_actions = array (
'index' ,
'ping' ,
'Form' ,
'finished'
);
public function init ()
{
parent :: init ();
2017-04-01 12:02:18 +02:00
$page = $this -> data ();
// load the css
if ( ! $page -> config () -> block_default_userforms_css ) {
Requirements :: css ( USERFORMS_DIR . '/css/UserForm.css' );
2016-07-21 07:53:59 +02:00
}
2017-04-01 12:02:18 +02:00
// load the jquery
if ( ! $page -> config () -> block_default_userforms_js ) {
$lang = i18n :: get_lang_from_locale ( i18n :: get_locale ());
Requirements :: javascript ( FRAMEWORK_DIR . '/thirdparty/jquery/jquery.js' );
Requirements :: javascript ( USERFORMS_DIR . '/thirdparty/jquery-validate/jquery.validate.min.js' );
Requirements :: add_i18n_javascript ( USERFORMS_DIR . '/javascript/lang' );
Requirements :: javascript ( USERFORMS_DIR . '/javascript/UserForm.js' );
Requirements :: javascript (
USERFORMS_DIR . " /thirdparty/jquery-validate/localization/messages_ { $lang } .min.js "
);
Requirements :: javascript (
USERFORMS_DIR . " /thirdparty/jquery-validate/localization/methods_ { $lang } .min.js "
);
if ( $this -> HideFieldLabels ) {
Requirements :: javascript ( USERFORMS_DIR . '/thirdparty/Placeholders.js/Placeholders.min.js' );
}
// Bind a confirmation message when navigating away from a partially completed form.
if ( $page :: config () -> enable_are_you_sure ) {
Requirements :: javascript ( USERFORMS_DIR . '/thirdparty/jquery.are-you-sure/jquery.are-you-sure.js' );
}
2016-07-21 07:53:59 +02:00
}
}
/**
* Using $UserDefinedForm in the Content area of the page shows
* where the form should be rendered into . If it does not exist
* then default back to $Form .
*
* @ return array
*/
public function index ()
{
if ( $this -> Content && $form = $this -> Form ()) {
$hasLocation = stristr ( $this -> Content , '$UserDefinedForm' );
if ( $hasLocation ) {
$content = preg_replace ( '/(<p[^>]*>)?\\$UserDefinedForm(<\\/p>)?/i' , $form -> forTemplate (), $this -> Content );
return array (
'Content' => DBField :: create_field ( 'HTMLText' , $content ),
'Form' => " "
);
}
}
return array (
'Content' => DBField :: create_field ( 'HTMLText' , $this -> Content ),
'Form' => $this -> Form ()
);
}
/**
* Keep the session alive for the user .
*
* @ return int
*/
public function ping ()
{
return 1 ;
}
/**
* Get the form for the page . Form can be modified by calling { @ link updateForm ()}
* on a UserDefinedForm extension .
*
* @ return Forms
*/
public function Form ()
{
$form = UserForm :: create ( $this );
$this -> generateConditionalJavascript ();
return $form ;
}
/**
* Generate the javascript for the conditional field show / hiding logic .
*
* @ return void
*/
public function generateConditionalJavascript ()
{
$default = " " ;
$rules = " " ;
$watch = array ();
$watchLoad = array ();
if ( $this -> Fields ()) {
foreach ( $this -> Fields () as $field ) {
$holderSelector = $field -> getSelectorHolder ();
// Is this Field Show by Default
if ( ! $field -> ShowOnLoad ) {
$default .= " { $holderSelector } .hide().trigger('userform.field.hide'); \n " ;
}
// Check for field dependencies / default
foreach ( $field -> EffectiveDisplayRules () as $rule ) {
// Get the field which is effected
$formFieldWatch = EditableFormField :: get () -> byId ( $rule -> ConditionFieldID );
// Skip deleted fields
if ( ! $formFieldWatch ) {
continue ;
}
$fieldToWatch = $formFieldWatch -> getSelectorField ( $rule );
$fieldToWatchOnLoad = $formFieldWatch -> getSelectorField ( $rule , true );
// show or hide?
$view = ( $rule -> Display == 'Hide' ) ? 'hide' : 'show' ;
$opposite = ( $view == " show " ) ? " hide " : " show " ;
// what action do we need to keep track of. Something nicer here maybe?
// @todo encapulsation
$action = " change " ;
if ( $formFieldWatch instanceof EditableTextField ) {
$action = " keyup " ;
}
// is this field a special option field
$checkboxField = false ;
$radioField = false ;
if ( in_array ( $formFieldWatch -> ClassName , array ( 'EditableCheckboxGroupField' , 'EditableCheckbox' ))) {
$action = " click " ;
$checkboxField = true ;
} elseif ( $formFieldWatch -> ClassName == " EditableRadioField " ) {
$radioField = true ;
}
// and what should we evaluate
switch ( $rule -> ConditionOption ) {
case 'IsNotBlank' :
$expression = ( $checkboxField || $radioField ) ? '$(this).is(":checked")' : '$(this).val() != ""' ;
break ;
case 'IsBlank' :
$expression = ( $checkboxField || $radioField ) ? '!($(this).is(":checked"))' : '$(this).val() == ""' ;
break ;
case 'HasValue' :
if ( $checkboxField ) {
$expression = '$(this).prop("checked")' ;
} elseif ( $radioField ) {
// We cannot simply get the value of the radio group, we need to find the checked option first.
2017-03-01 23:58:39 +01:00
$expression = '$(this).closest(".field, .control-group").find("input:checked").val()=="' . $rule -> FieldValue . '"' ;
2016-07-21 07:53:59 +02:00
} else {
$expression = '$(this).val() == "' . $rule -> FieldValue . '"' ;
}
break ;
case 'ValueLessThan' :
$expression = '$(this).val() < parseFloat("' . $rule -> FieldValue . '")' ;
break ;
case 'ValueLessThanEqual' :
$expression = '$(this).val() <= parseFloat("' . $rule -> FieldValue . '")' ;
break ;
case 'ValueGreaterThan' :
$expression = '$(this).val() > parseFloat("' . $rule -> FieldValue . '")' ;
break ;
case 'ValueGreaterThanEqual' :
$expression = '$(this).val() >= parseFloat("' . $rule -> FieldValue . '")' ;
break ;
default : // ==HasNotValue
if ( $checkboxField ) {
$expression = '!$(this).prop("checked")' ;
} elseif ( $radioField ) {
// We cannot simply get the value of the radio group, we need to find the checked option first.
$expression = '$(this).parents(".field, .control-group").find("input:checked").val()!="' . $rule -> FieldValue . '"' ;
} else {
$expression = '$(this).val() != "' . $rule -> FieldValue . '"' ;
}
break ;
}
if ( ! isset ( $watch [ $fieldToWatch ])) {
$watch [ $fieldToWatch ] = array ();
}
$watch [ $fieldToWatch ][] = array (
'expression' => $expression ,
'holder_selector' => $holderSelector ,
'view' => $view ,
'opposite' => $opposite ,
'action' => $action
);
$watchLoad [ $fieldToWatchOnLoad ] = true ;
}
}
}
if ( $watch ) {
foreach ( $watch as $key => $values ) {
$logic = array ();
$actions = array ();
foreach ( $values as $rule ) {
// Assign action
$actions [ $rule [ 'action' ]] = $rule [ 'action' ];
// Assign behaviour
$expression = $rule [ 'expression' ];
$holder = $rule [ 'holder_selector' ];
$view = $rule [ 'view' ]; // hide or show
$opposite = $rule [ 'opposite' ];
// Generated javascript for triggering visibility
$logic [] = <<< " EOS "
2015-08-17 00:43:51 +02:00
if ({ $expression }) {
{ $holder }
. { $view }()
. trigger ( 'userform.field.{$view}' );
} else {
{ $holder }
. { $opposite }()
. trigger ( 'userform.field.{$opposite}' );
}
EOS ;
2016-07-21 07:53:59 +02:00
}
2013-02-27 04:05:30 +01:00
2016-07-21 07:53:59 +02:00
$logic = implode ( " \n " , $logic );
$rules .= $key . " .each(function() { \n
2013-02-27 04:05:30 +01:00
$ ( this ) . data ( 'userformConditions' , function () { \n
$logic\n
}); \n
}); \n " ;
2016-07-21 07:53:59 +02:00
foreach ( $actions as $action ) {
$rules .= $key . " . $action (function() {
2013-02-27 04:05:30 +01:00
$ ( this ) . data ( 'userformConditions' ) . call ( this ); \n
}); \n " ;
2016-07-21 07:53:59 +02:00
}
}
}
2013-02-27 04:05:30 +01:00
2016-07-21 07:53:59 +02:00
if ( $watchLoad ) {
foreach ( $watchLoad as $key => $value ) {
$rules .= $key . " .each(function() {
2013-02-27 04:05:30 +01:00
$ ( this ) . data ( 'userformConditions' ) . call ( this ); \n
}); \n " ;
2016-07-21 07:53:59 +02:00
}
}
2013-02-27 04:05:30 +01:00
2016-07-21 07:53:59 +02:00
// Only add customScript if $default or $rules is defined
if ( $default || $rules ) {
Requirements :: customScript ( <<< JS
2012-12-06 17:25:25 +01:00
( function ( $ ) {
$ ( document ) . ready ( function () {
$default
$rules
})
})( jQuery );
2009-04-21 05:44:13 +02:00
JS
2010-09-03 07:06:13 +02:00
, 'UserFormsConditional' );
2016-07-21 07:53:59 +02:00
}
}
/**
* Process the form that is submitted through the site
*
* { @ see UserForm :: validate ()} for validation step prior to processing
*
* @ param array $data
* @ param Form $form
*
* @ return Redirection
*/
public function process ( $data , $form )
{
$submittedForm = Object :: create ( 'SubmittedForm' );
$submittedForm -> SubmittedByID = ( $id = Member :: currentUserID ()) ? $id : 0 ;
$submittedForm -> ParentID = $this -> ID ;
// if saving is not disabled save now to generate the ID
if ( ! $this -> DisableSaveSubmissions ) {
$submittedForm -> write ();
}
$attachments = array ();
$submittedFields = new ArrayList ();
foreach ( $this -> Fields () as $field ) {
if ( ! $field -> showInReports ()) {
continue ;
}
$submittedField = $field -> getSubmittedFormField ();
$submittedField -> ParentID = $submittedForm -> ID ;
$submittedField -> Name = $field -> Name ;
$submittedField -> Title = $field -> getField ( 'Title' );
// save the value from the data
if ( $field -> hasMethod ( 'getValueFromData' )) {
$submittedField -> Value = $field -> getValueFromData ( $data );
} else {
if ( isset ( $data [ $field -> Name ])) {
$submittedField -> Value = $data [ $field -> Name ];
}
}
if ( ! empty ( $data [ $field -> Name ])) {
if ( in_array ( " EditableFileField " , $field -> getClassAncestry ())) {
2017-03-02 00:46:13 +01:00
if ( ! empty ( $_FILES [ $field -> Name ][ 'name' ])) {
2016-07-21 07:53:59 +02:00
$foldername = $field -> getFormField () -> getFolderName ();
// create the file from post data
$upload = new Upload ();
$file = new File ();
$file -> ShowInSearch = 0 ;
try {
$upload -> loadIntoFile ( $_FILES [ $field -> Name ], $file , $foldername );
} catch ( ValidationException $e ) {
$validationResult = $e -> getResult ();
$form -> addErrorMessage ( $field -> Name , $validationResult -> message (), 'bad' );
Controller :: curr () -> redirectBack ();
return ;
}
// write file to form field
$submittedField -> UploadedFileID = $file -> ID ;
// attach a file only if lower than 1MB
if ( $file -> getAbsoluteSize () < 1024 * 1024 * 1 ) {
$attachments [] = $file ;
}
}
}
}
$submittedField -> extend ( 'onPopulationFromField' , $field );
if ( ! $this -> DisableSaveSubmissions ) {
$submittedField -> write ();
}
$submittedFields -> push ( $submittedField );
}
$emailData = array (
" Sender " => Member :: currentUser (),
" Fields " => $submittedFields
);
$this -> extend ( 'updateEmailData' , $emailData , $attachments );
// email users on submit.
if ( $recipients = $this -> FilteredEmailRecipients ( $data , $form )) {
foreach ( $recipients as $recipient ) {
$email = new UserFormRecipientEmail ( $submittedFields );
$mergeFields = $this -> getMergeFieldsMap ( $emailData [ 'Fields' ]);
2017-04-01 12:02:18 +02:00
2016-07-21 07:53:59 +02:00
if ( $attachments ) {
foreach ( $attachments as $file ) {
if ( $file -> ID != 0 ) {
$email -> attachFile (
$file -> Filename ,
$file -> Filename ,
HTTP :: get_mime_type ( $file -> Filename )
);
}
}
}
2017-04-01 12:02:18 +02:00
2016-07-21 07:53:59 +02:00
$parsedBody = SSViewer :: execute_string ( $recipient -> getEmailBodyContent (), $mergeFields );
if ( ! $recipient -> SendPlain && $recipient -> emailTemplateExists ()) {
$email -> setTemplate ( $recipient -> EmailTemplate );
}
$email -> populateTemplate ( $recipient );
$email -> populateTemplate ( $emailData );
$email -> setFrom ( $recipient -> EmailFrom );
$email -> setBody ( $parsedBody );
$email -> setTo ( $recipient -> EmailAddress );
$email -> setSubject ( $recipient -> EmailSubject );
if ( $recipient -> EmailReplyTo ) {
$email -> setReplyTo ( $recipient -> EmailReplyTo );
}
// check to see if they are a dynamic reply to. eg based on a email field a user selected
if ( $recipient -> SendEmailFromField ()) {
$submittedFormField = $submittedFields -> find ( 'Name' , $recipient -> SendEmailFromField () -> Name );
if ( $submittedFormField && is_string ( $submittedFormField -> Value )) {
$email -> setReplyTo ( $submittedFormField -> Value );
}
}
// check to see if they are a dynamic reciever eg based on a dropdown field a user selected
if ( $recipient -> SendEmailToField ()) {
$submittedFormField = $submittedFields -> find ( 'Name' , $recipient -> SendEmailToField () -> Name );
if ( $submittedFormField && is_string ( $submittedFormField -> Value )) {
$email -> setTo ( $submittedFormField -> Value );
}
}
// check to see if there is a dynamic subject
if ( $recipient -> SendEmailSubjectField ()) {
$submittedFormField = $submittedFields -> find ( 'Name' , $recipient -> SendEmailSubjectField () -> Name );
if ( $submittedFormField && trim ( $submittedFormField -> Value )) {
$email -> setSubject ( $submittedFormField -> Value );
}
}
$this -> extend ( 'updateEmail' , $email , $recipient , $emailData );
if ( $recipient -> SendPlain ) {
$body = strip_tags ( $recipient -> getEmailBodyContent ()) . " \n " ;
if ( isset ( $emailData [ 'Fields' ]) && ! $recipient -> HideFormData ) {
foreach ( $emailData [ 'Fields' ] as $Field ) {
$body .= $Field -> Title . ': ' . $Field -> Value . " \n " ;
}
}
$email -> setBody ( $body );
$email -> sendPlain ();
} else {
$email -> send ();
}
}
}
$submittedForm -> extend ( 'updateAfterProcess' );
Session :: clear ( " FormInfo. { $form -> FormName () } .errors " );
Session :: clear ( " FormInfo. { $form -> FormName () } .data " );
$referrer = ( isset ( $data [ 'Referrer' ])) ? '?referrer=' . urlencode ( $data [ 'Referrer' ]) : " " ;
// set a session variable from the security ID to stop people accessing
// the finished method directly.
if ( ! $this -> DisableAuthenicatedFinishAction ) {
if ( isset ( $data [ 'SecurityID' ])) {
Session :: set ( 'FormProcessed' , $data [ 'SecurityID' ]);
} else {
// if the form has had tokens disabled we still need to set FormProcessed
// to allow us to get through the finshed method
if ( ! $this -> Form () -> getSecurityToken () -> isEnabled ()) {
$randNum = rand ( 1 , 1000 );
$randHash = md5 ( $randNum );
Session :: set ( 'FormProcessed' , $randHash );
Session :: set ( 'FormProcessedNum' , $randNum );
}
}
}
if ( ! $this -> DisableSaveSubmissions ) {
Session :: set ( 'userformssubmission' . $this -> ID , $submittedForm -> ID );
}
return $this -> redirect ( $this -> Link ( 'finished' ) . $referrer . $this -> config () -> finished_anchor );
}
/**
* Allows the use of field values in email body .
*
* @ param ArrayList fields
* @ return ArrayData
*/
private function getMergeFieldsMap ( $fields = array ())
{
$data = new ArrayData ( array ());
foreach ( $fields as $field ) {
$data -> setField ( $field -> Name , DBField :: create_field ( 'Text' , $field -> Value ));
}
return $data ;
}
/**
* This action handles rendering the " finished " message , which is
* customizable by editing the ReceivedFormSubmission template .
*
* @ return ViewableData
*/
public function finished ()
{
$submission = Session :: get ( 'userformssubmission' . $this -> ID );
if ( $submission ) {
$submission = SubmittedForm :: get () -> byId ( $submission );
}
$referrer = isset ( $_GET [ 'referrer' ]) ? urldecode ( $_GET [ 'referrer' ]) : null ;
if ( ! $this -> DisableAuthenicatedFinishAction ) {
$formProcessed = Session :: get ( 'FormProcessed' );
if ( ! isset ( $formProcessed )) {
return $this -> redirect ( $this -> Link () . $referrer );
} else {
$securityID = Session :: get ( 'SecurityID' );
// make sure the session matches the SecurityID and is not left over from another form
if ( $formProcessed != $securityID ) {
// they may have disabled tokens on the form
$securityID = md5 ( Session :: get ( 'FormProcessedNum' ));
if ( $formProcessed != $securityID ) {
return $this -> redirect ( $this -> Link () . $referrer );
}
}
}
Session :: clear ( 'FormProcessed' );
}
return $this -> customise ( array (
'Content' => $this -> customise ( array (
'Submission' => $submission ,
'Link' => $referrer
)) -> renderWith ( 'ReceivedFormSubmission' ),
'Form' => '' ,
));
}
2008-09-29 05:18:23 +02:00
}