Application->isAdmin ) { if ( $event->Name == 'OnCreate' ) { // anybody can submit forms on front return true; } } $section = $event->getSection(); $form_id = $this->Application->GetVar('form_id'); $event->setEventParam('PermSection', $section . ':' . $form_id); return parent::CheckPermission($event); } /** * Always allow to view feedback form * * @return void * @access protected * @see kEventHandler::$permMapping */ protected function mapPermissions() { parent::mapPermissions(); $permissions = Array ( 'OnItemBuild' => Array ('self' => true), 'OnEdit' => Array ('self' => 'view', 'subitem' => 'view'), ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * Returns filter block based on field element type * * @param string $element_type * @return string */ function _getFilterBlock($element_type) { $mapping = Array ( 'text' => 'grid_like_filter', 'select' => 'grid_options_filter', 'radio' => 'grid_options_filter', 'checkbox' => 'grid_options_filter', 'password' => 'grid_like_filter', 'textarea' => 'grid_like_filter', 'label' => 'grid_like_filter', 'upload' => 'grid_empty_filter', ); return $mapping[$element_type]; } function OnBuildFormFields($event) { $form_id = $this->Application->GetVar('form_id'); if (!$form_id) return ; $conf_fields = $this->Application->getUnitOption($event->Prefix, 'Fields'); $conf_grids = $this->Application->getUnitOption($event->Prefix, 'Grids'); /** @var InpCustomFieldsHelper $helper */ $helper = $this->Application->recallObject('InpCustomFieldsHelper'); $sql = 'SELECT * FROM ' . TABLE_PREFIX . 'FormFields WHERE FormId = ' . (int)$form_id . ' ORDER BY Priority DESC'; $fields = $this->Conn->Query($sql, 'FormFieldId'); $use_options = Array ('radio', 'select', 'checkbox'); $check_visibility = $this->Application->LoggedIn() && !$this->Application->isAdminUser; foreach ($fields as $field_id => $options) { $field_visible = $check_visibility ? $options['Visibility'] == SubmissionFormField::VISIBILITY_EVERYONE : true; $field_options = Array('type' => 'string', 'default' => $options['DefaultValue']); if ($options['Required'] && $field_visible) { $field_options['required'] = 1; } if ($options['Validation'] == 1) { $field_options['formatter'] = 'kFormatter'; $field_options['regexp'] = '/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i'; } if ($options['DisplayInGrid']) { $title = $options['Prompt']; if (substr($title, 0, 1) == '+') { $this->Application->Phrases->AddCachedPhrase('form_col_title' . $field_id, substr($title, 1)); $title = 'form_col_title' . $field_id; } // Don't HTML-escape, because it's 100% front-end data, that is HTML-escaped in DB. $conf_grids['Default']['Fields']['fld_' . $field_id] = Array ( 'title' => $title, 'no_special' => 1, 'nl2br' => 1, 'first_chars' => 200, 'filter_block' => $this->_getFilterBlock($options['ElementType']) ); if ($options['ElementType'] == 'upload') { $conf_grids['Default']['Fields']['fld_' . $field_id]['data_block'] = 'grid_upload_td'; } if ($options['Validation'] == 1) { $conf_grids['Default']['Fields']['fld_' . $field_id]['data_block'] = 'grid_email_td'; } } if ($options['ElementType'] == 'checkbox' && !$options['ValueList']) { // fix case, when user haven't defined any options for checkbox $options['ValueList'] = '1=la_Yes||0=la_No'; } if (in_array($options['ElementType'], $use_options) && $options['ValueList']) { // field type can have options and user have defined them too $field_options['options'] = $helper->GetValuesHash( $options['ValueList'] ); $field_options['formatter'] = 'kOptionsFormatter'; } if ($options['ElementType'] == 'password') { $field_options['formatter'] = 'kPasswordFormatter'; $field_options['hashing_method'] = PasswordHashingMethod::NONE; $field_options['verify_field'] = 'fld_' . $field_id . '_verify'; } if ($options['ElementType'] == 'upload') { $field_options['formatter'] = 'kUploadFormatter'; $field_options['upload_dir'] = WRITEBALE_BASE . DIRECTORY_SEPARATOR . 'user_files' . DIRECTORY_SEPARATOR . 'form_submissions'; if ( $options['UploadMaxSize'] ) { $field_options['max_size'] = $options['UploadMaxSize'] * 1024; // convert Kbytes to bytes } if ( $options['UploadExtensions'] ) { $field_options['file_types'] = '*.' . implode(';*.', explode(',', $options['UploadExtensions'])); } } $conf_fields['fld_' . $field_id] = $field_options; } $this->Application->setUnitOption($event->Prefix, 'Fields', $conf_fields); $this->Application->setUnitOption($event->Prefix, 'Grids', $conf_grids); } /** * Apply any custom changes to list's sql query * * @param kEvent $event * @return void * @access protected * @see kDBEventHandler::OnListBuild() */ protected function SetCustomQuery(kEvent $event) { parent::SetCustomQuery($event); /** @var kDBList $object */ $object = $event->getObject(); $object->addFilter('form_filter', '%1$s.FormId = ' . (int)$this->Application->GetVar('form_id')); } /** * Allows user to see it's last feedback form data * * @param kEvent $event * @return int * @access public */ public function getPassedID(kEvent $event) { if ( $event->Special == 'last' ) { // allow user to see his last submitted form return $this->Application->RecallVar('last_submission_id'); } if ( $this->Application->isAdminUser ) { // don't check ids in admin return parent::getPassedID($event); } // no way to see other user's form submission by giving it's ID directly in url return 0; } /** * Creates new form submission from Front-End * * @param kEvent $event * @return void * @access protected */ protected function OnCreate(kEvent $event) { parent::OnCreate($event); if ( $event->status != kEvent::erSUCCESS ) { return; } /** @var kDBItem $object */ $object = $event->getObject(); // allows user to view only it's last submission $this->Application->StoreVar('last_submission_id', $object->GetID()); /** @var FormSubmissionHelper $form_submission_helper */ $form_submission_helper = $this->Application->recallObject('FormSubmissionHelper'); $form =& $form_submission_helper->getForm($object); $notify_email = $form->GetDBField('SubmitNotifyEmail'); if ( $notify_email ) { $send_params = Array ( 'to_name' => $notify_email, 'to_email' => $notify_email, ); $this->Application->emailAdmin('FORM.SUBMITTED', null, $send_params); } else { $this->Application->emailAdmin('FORM.SUBMITTED'); } // $this->Application->emailUser('FORM.SUBMITTED', null, Array ('to_email' => '')); $event->SetRedirectParam('opener', 's'); $event->SetRedirectParam('m_cat_id', 0); /** @var kDBItem $theme */ $theme = $this->Application->recallObject('theme.current'); $template = $this->Application->unescapeRequestVariable($this->Application->GetVar('success_template')); $alias_template = $theme->GetField('TemplateAliases', $template); $event->redirect = $alias_template ? $alias_template : $template; } /** * Processes Captcha code * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemCreate(kEvent $event) { parent::OnBeforeItemCreate($event); /** @var kDBItem $object */ $object = $event->getObject(); $object->SetDBField('IPAddress', $this->Application->getClientIp()); if ( !$object->GetDBField('ReferrerURL') ) { $referrer = $this->Application->GetVarDirect('original_referrer', 'Cookie'); if ( !$referrer ) { $base_url = preg_quote($this->Application->BaseURL(), '/'); $referrer = preg_replace('/^' . $base_url . '/', '/', $_SERVER['HTTP_REFERER'], 1); } $object->SetDBField('ReferrerURL', $referrer); } /** @var FormSubmissionHelper $form_submission_helper */ $form_submission_helper = $this->Application->recallObject('FormSubmissionHelper'); $form =& $form_submission_helper->getForm($object); // validate captcha code if ( $form->GetDBField('UseSecurityImage') && !$this->Application->LoggedIn() ) { /** @var kCaptchaHelper $captcha_helper */ $captcha_helper = $this->Application->recallObject('CaptchaHelper'); $captcha_helper->validateCode($event, false); } } /** * Checks, that target submission was selected for merging * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemUpdate(kEvent $event) { parent::OnBeforeItemUpdate($event); /** @var kDBItem $object */ $object = $event->getObject(); $object->setRequired('MergeToSubmission', $object->GetDBField('IsMergeToSubmission')); } /** * Passes form_id, when using "Prev"/"Next" toolbar buttons * * @param kEvent $event * @return void * @access protected */ protected function OnPreSaveAndGo(kEvent $event) { parent::OnPreSaveAndGo($event); if ( $event->status == kEvent::erSUCCESS ) { $event->SetRedirectParam('pass', 'm,form,formsubs'); } } /** * Saves edited item in temp table and goes * to passed tabs, by redirecting to it with OnPreSave event * * @param kEvent $event * @return void * @access protected */ protected function OnPreSaveAndGoToTab(kEvent $event) { parent::OnPreSaveAndGoToTab($event); if ( $event->status == kEvent::erSUCCESS ) { $event->SetRedirectParam('pass', 'm,form,formsubs'); } } /** * Set's new per-page for grid * * @param kEvent $event * @return void * @access protected */ protected function OnSetPerPage(kEvent $event) { parent::OnSetPerPage($event); $event->SetRedirectParam('pass', 'm,form,' . $event->getPrefixSpecial()); } /** * Occurs when page is changed (only for hooking) * * @param kEvent $event * @return void * @access protected */ protected function OnSetPage(kEvent $event) { parent::OnSetPage($event); $event->SetRedirectParam('pass', 'm,form,' . $event->getPrefixSpecial()); } /** * Fills merge-to dropdown * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemLoad(kEvent $event) { parent::OnAfterItemLoad($event); if ($event->Special == 'merge-to') { return ; } /** @var kDBItem $object */ $object = $event->getObject(); $form_id = $object->GetDBField('FormId'); $email_field = $this->getFieldByRole($form_id, SubmissionFormField::COMMUNICATION_ROLE_EMAIL); if (!$email_field) { return ; } /** @var kDBItem $merge_to */ $merge_to = $this->Application->recallObject($event->Prefix . '.merge-to', null, Array ('skip_autoload' => true)); $sql = $merge_to->GetSelectSQL() . ' WHERE (FormId = ' . $form_id . ') AND (' . $email_field . ' = ' . $this->Conn->qstr( $object->GetDBField($email_field) ) . ')'; $submissions = $this->Conn->Query($sql, $object->IDField); // remove this submission unset($submissions[ $object->GetID() ]); if (!$submissions) { return ; } $options = Array (); $name_field = $this->getFieldByRole($form_id, SubmissionFormField::COMMUNICATION_ROLE_NAME); $subject_field = $this->getFieldByRole($form_id, SubmissionFormField::COMMUNICATION_ROLE_SUBJECT); /** @var kDBItem $language */ $language = $this->Application->recallObject('lang.current'); $date_format = $language->GetDBField('DateFormat'); foreach ($submissions as $submission_id => $submission_data) { $option_title = ''; // SenderName (email@address.com) - Subject (06/29/2010) $merge_to->LoadFromHash($submission_data); if ($name_field) { $option_title = $merge_to->GetDBField($name_field) . ' (' . $merge_to->GetDBField($email_field) . ') - '; } else { $option_title = $merge_to->GetDBField($email_field) . ' - '; } if ($subject_field) { $option_title .= $merge_to->GetField($subject_field) . ' (' . $merge_to->GetField('SubmissionTime', $date_format) . ')'; } else { $option_title .= $merge_to->GetField('SubmissionTime', $date_format); } $options[$submission_id] = $option_title; } $object->SetFieldOption('MergeToSubmission', 'options', $options); } /** * Returns submission field name based on given role * * @param int $form_id * @param string $role * @return string */ function getFieldByRole($form_id, $role) { static $cache = Array (); if (!array_key_exists($form_id, $cache)) { $id_field = $this->Application->getUnitOption('formflds', 'IDField'); $table_name = $this->Application->getUnitOption('formflds', 'TableName'); $sql = 'SELECT ' . $id_field . ', EmailCommunicationRole FROM ' . $table_name . ' WHERE FormId = ' . $form_id . ' AND EmailCommunicationRole <> 0'; $cache[$form_id] = $this->Conn->GetCol($sql, 'EmailCommunicationRole'); } // get field name by role return array_key_exists($role, $cache[$form_id]) ? 'fld_' . $cache[$form_id][$role] : false; } /** * Performs submission merge * * @param kEvent $event * @return void * @access protected */ protected function OnUpdate(kEvent $event) { parent::OnUpdate($event); if ($event->status == kEvent::erSUCCESS) { /** @var kDBItem $object */ $object = $event->getObject(); $merge_to = $object->GetDBField('MergeToSubmission'); if (!$merge_to) { return ; } $form_id = $object->GetDBField('FormId'); $sql = 'SELECT * FROM ' . TABLE_PREFIX . 'Forms WHERE FormId = ' . $form_id; $form_info = $this->Conn->GetRow($sql); /** @var kDBItem $reply */ $reply = $this->Application->recallObject('submission-log.merge', null, Array ('skip_autoload' => true)); $email_field = $this->getFieldByRole($form_id, SubmissionFormField::COMMUNICATION_ROLE_EMAIL); $subject_field = $this->getFieldByRole($form_id, SubmissionFormField::COMMUNICATION_ROLE_SUBJECT); $body_field = $this->getFieldByRole($form_id, SubmissionFormField::COMMUNICATION_ROLE_BODY); $reply->SetDBField('FormSubmissionId', $merge_to); if ($email_field) { $reply->SetDBField('FromEmail', $object->GetDBField($email_field)); } $reply->SetDBField('ToEmail', $form_info['ReplyFromEmail']); if ($subject_field) { $reply->SetDBField('Subject', $object->GetDBField($subject_field)); } if ($body_field) { $reply->SetDBField('Message', $object->GetDBField($body_field)); } $reply->SetDBField('SentOn_date', $object->GetDBField('SubmissionTime')); $reply->SetDBField('SentOn_time', $object->GetDBField('SubmissionTime')); $reply->SetDBField('MessageId', $object->GetDBField('MessageId')); $reply->SetDBField('SentStatus', SUBMISSION_LOG_SENT); // as if emails was really received via mailbox $this->Application->SetVar('client_mode', 1); if ($reply->Create()) { // delete submission, since it was merged $object->Delete(); } } } }