I'm using contact form 7 to load two different forms into a page and then, in addition to sending the email, dynamically adding that information to a database. Unfortunately, because of the plugin, I can't simply just create all inputs with different names to avoid needing a filter. So, essentially, I'd like to pull the form ID into the action hook and dynamically create the $data variable based on which form is being submitted, but I'm not sure how to get the cf7 form ID. Does anyone know how to accomplish this, or perhaps a more feasible way of doing it?
Form Shortcodes
[contact-form-7 id="221" title="Reg 1"] [contact-form-7 id="112" title="Reg 2"]
PHP Action Hook in functions.php
function save_form( $wpcf7 ) {
global $wpdb;
$form_to_DB = WPCF7_Submission::get_instance();
if($form_to_DB) {
$formData = $form_to_DB->get_posted_data();
}
if("Request a Free Demo" != $formData['demo_request'][0]){
$freeDemo = "yes";}else { $freeDemo = "nope";}
if(THE FORM ID = 221) {
$data = array(
some values from the 112 form
$wpdb->insert( $wpdb->prefix . 'registrations', $data );
);
}elseif(THE FORM ID = 112) {
$data = array(
some other values from the 112 form
$wpdb->insert( $wpdb->prefix . 'registrations_2', $data );
);
}
}
remove_all_filters('wpcf7_before_send_mail');
add_action('wpcf7_before_send_mail', 'save_form' );
I tend to use the "wpcf7_posted_data" action hook (though this might have changed as the question is a bit old now). You don't need to remove all filters.
For example:
function processForm($cf7)
{
$wpcf7 = WPCF7_ContactForm::get_current();
$form_id = $wpcf7->id;
if ($form_id === 221)
{
//Do Stuff
}
else if ($form_id === 112)
{
//Do different stuff
}
}
add_action("wpcf7_posted_data", "processForm");
$wpcf7->idis no longer accessible, use $wpcf7->id() instead.
simply use this:
function save_form( $wpcf7 ) {
if($wpcf7->id == 4711) {
// whatever
}
}
You can use this: $form_id = $_POST['_wpcf7'];
SOLVED:
I wound up just using a logical operator to check if a form specific field was empty or not. If the field "form_2_name" was empty when a form was submitted, then we know that form 1 is being submitted. Simple if statement with that logic did the trick!
Related
I'm trying to redirect to a custom URL after the confirmation in gravity forms, I set this in functions.php but I need to fix what is wrong with the code, I need to do it this way since I have 2 domains sharing the same form.
What I did was set a hidden field in the form with Default Value {referer}, and also allowed the field to be populated dynamically with parameter 'refurl':
add_filter('gform_confirmation', 'conditional_confirmation', 10, 4);
function conditional_confirmation($confirmation, $refurl, $entry, $ajax) {
if ($refurl == 'http://www.example.com') {
$confirmation = array('redirect' => 'http://www.google.com');
}
return $confirmation;
}
When clicking the confirmation button the form doesn't redirect anywhere. Do you guys know what is wrong and how to fix it?
As per the documentation, second argument for the filter is a $form object. So you need to get your hidden input value from the $form object.
Give an input name to that hidden field as 'refUrl' in the gravity field properties.
add_filter('gform_confirmation', 'conditional_confirmation', 10, 4);
function conditional_confirmation($confirmation, $form, $entry, $ajax) {
$input_name = 'refUrl';
foreach ($form['fields'] as $field) {
if (isset($field['inputName']) && $field['inputName'] === $input_name) {
$fieldName = 'input_' . $field['id'];
$refurl = $_POST[$fieldName];
break;
}
}
if ($refurl == 'http://www.example.com') {
$confirmation = array('redirect' => 'http://www.google.com');
}
return $confirmation;
}
I am attempting to edit a form's submission variables before they are submitted to the action URL. I am able to accomplish what I want by changing
$args[ $vars['key'] ] = $value;
in the initial foreach loop of the process() function in action-webhooks.php to
if (is_array ($value)) {
$args[ $vars['key'] ] = implode(';', $value);
}
else {
$args[ $vars['key'] ] = $value;
}
This is obviously a bad solution since this code will be overwritten if the plugin is updated. Is there an action or filter that I can use to accomplish this from my own code? Thanks.
From what I can tell, it looks like using the ninja forms processing method you can set the variables before the form is completely processed.
global $ninja_forms_processing;
//get the form id
$form_id = $ninja_forms_processing->get_form_ID();
//The id of the form you want to check
$form_to_check = 5;
if($form_id == 5)
{
//What the user entered
$user_value = $ninja_forms_processing->get_field_value( 3 );
if(is_array($user_value))
{
//set the value to what it you want it to be
$new_value = implode(';', $user_value);
$ninja_forms_processing->update_field_value( 3, $new_value );
}
}
I am attempting to set the "title" value of a content type before it becomes "required" .
So what happens is the title field becomes hidden based on user name, after filling in the "first name" and "last name" fields I need to take those values and then apply them to the "title" field, before drupal states that the field is required. Here's what I have so far
/**
* Implements hook_form_alter().
*/
function editorhide_form_alter(&$form, &$form_state, $form_id){
global $user;
global $fullTitle;
if($form_id == 'artist_node_form'){
if( $user->name == 'Editor'){
drupal_add_js("jQuery(document).ready(function(){
jQuery('#edit-title').hide();
});","inline");
//adding the form handler
$form['#submit'][] = "editorhide_form_submit_handler";
}
}
}
//submit form handler.
function editorhide_form_submit_handler ($form, &$form_state) {
global $fullTitle;
$fullTitle = $form_state['values']['field_firstname']['und']['0']['value'];
$fullTitle .= ' '. $form_state['values']['field_lastname']['und']['0']['value'];
form_set_value($form['#edit-title'], $fullTitle,$form_state);
}
With my current implementation, it isn't doing quite what I want, as it's throwing the "required field" error.
The problem you are having is that your new submit function never gets executed. A form will go through all validation functions first.
You need to set a new validate function, and make sure it is inserted at the begining of the validation process (so you can set title prior to the node validation):
array_unshift($form['#validate'], "editorhide_form_validate_handler");
Then your validation can do the following (may need to adjust array indexes):
function editorhide_form_validate_handler ($form, &$form_state) {
$fullTitle = $form_state['values']['field_firstname']['und']['0']['value'];
$fullTitle .= ' '. $form_state['values']['field_lastname']['und']['0']['value'];
$form_state['values']['title']['und']['0']['value'] = $fullTitle;
}
I am not a HUGE fan of modifying form_state mid validation, but this should work.
I have following action to display a form
public function showformAction() {
$this->view->form = new Form_MyForm();
$this->view->form->setAction( 'submitform' );
}
above action shows a form successfully with only one textarea and submit button.
And I am using following action to submit above form:
public function submitformAction() {
$form = new Form_MyForm();
$request = $this->getRequest();
if ( $request->isPost() ) {
$values = $form->getValues();
print_r($values);die();
} else {
echo 'Invalid Form';
}
}
Above action is showing following output:
Array ( [myfield] => )
It means it is not posting values correctly and always shows empty array or I am not getting posted values correctly. How to post values to submitformAction().
Thanks
I think you must use the isValid() before accessing the values of a submitted form, because it's right there that the values are checked and valorized
public function submitformAction() {
$form = new Form_MyForm();
$request = $this->getRequest();
if ( $request->isPost() ) {
if ($form->isValid( $request->getPost() )) {
$values = $form->getValues();
print_r($values);die();
}
} else {
echo 'Invalid Form';
}
}
In complement to #VAShhh response. With some more details:
You need to do two things, populate your form fields with the POSTed data and applying security filters and validators to that data. Zend_Form provides one simple function which perform both, it's isValid($data).
So you should:
build your form
test you are in a POST request
populate & filter & validate this data
either handle the fact in can be invalid and re-show the form wich is now
decorated with Errors OR retrieve valid data from the form
So you should get:
function submitformAction() {
$form = new Form_MyForm();
$request = $this->getRequest();
if ( $request->isPost() ) {
if (!$form->isValid($request->getPost())) {
$this->view->form = $form;
// here maybe you could connect to the same view script as your first action
// another solution is to use only one action for showform & submitform actions
// and detect the fact it's not a post to do the showform part
} else {
// values are secure if filters are on each form element
// and they are valid if all validators are set
$securizedvalues = $form->getValues();
// temporary debug
print_r($securizedvalues);die();
// here the nice thing to do at the end, after the job is quite
// certainly a REDIRECT with a code 303 (Redirect after POSt)
$redirector = $this->_helper->getHelper('Redirector');
$redirector->setCode(303)
->setExit(true)
->setGotoSimple('newaction','acontroller','amodule');
$redirector->redirectAndExit();
} else {
throw new Zend_Exception('Invalid Method');
}
}
And as said in the code re-showing the form you shoudl really try to use the same function for both showing and handling POST as a lot of steps are really the same:
building the form
showing it in the view in case of errors
By detecting the request is a POST you can detect you are in the POST handling case.
I've got a Form where the user can check a checkbox "create new address" and can then fill out the fields for this new address in the same form.
Now I want to validate the fields of this new address ONLY if the checkbox has been checked. Otherwise, they should be ignored.
How can I do that using Zend_Form with Zend_Validate?
Thanks!
I think that the best, and more correct way to do this is creating a custom validator.
You can do this validator in two different ways, one is using the second parameter passed to the method isValid, $context, that is the current form being validated, or, inject the Checkbox element, that need to be checked for validation to occur, in the constructor. I prefer the last:
<?php
class RequiredIfCheckboxIsChecked extends Zend_Validate_Abstract {
const REQUIRED = 'required';
protected $element;
protected $_messageTemplates = array(
self::REQUIRED => 'Element required'
);
public function __construct( Zend_Form_Element_Checkbox $element )
{
$this->element = $element;
}
public function isValid( $value )
{
$this->_setValue( $value );
if( $this->element->isChecked() && $value === '' ) {
$this->_error( self::REQUIRED );
return false;
}
return true;
}
}
Usage:
class MyForm extends Zend_Form {
public function init()
{
//...
$checkElement = new Zend_Form_Element_Checkbox( 'checkbox' );
$checkElement->setRequired();
$dependentElement = new Zend_Form_Element_Text( 'text' );
$dependentElement->setAllowEmpty( false )
->addValidator( new RequiredIfCheckboxIsChecked( $checkElement ) );
//...
}
}
I have not tested the code, but I think it should work.
I didn't actually run this, but it should work within reason. I've done something similar before that worked, but couldn't remember where the code was.
<?php
class My_Form extends Zend_Form
{
public function init()
{
$checkbox = new Zend_Form_Element_Checkbox("checkbox");
$checkbox->setValue("checked");
$textField = new Zend_Form_Element_Text("text");
$this->addElements(array("checkbox", "text"));
$checkbox = $this->getElement("checkbox");
if ($checkbox->isChecked() )
{
//get textfield
$textField = $this->getElement("text");
//make fields required and add validations to it.
$textField->setRequired(true);
}
}
}
Here's what I do if I need to validate multiple elements against each other
$f = new Zend_Form();
if($_POST && $f->isValid($_POST)) {
if($f->checkbox->isChecked() && strlen($f->getValue('element')) === 0) {
$f->element->addError('Checkbox checked, but element empty');
$f->markAsError();
}
if(!$f->isErrors()) {
// process
...
...
}
}
I've been wondering how to do that in ZF as well, though never had to implement such form feature.
One idea that comes to mind is to create a custom validator that accepts the checkbox field as a parameter, and run it in a validator chain, as documented. If the checkbox is checked, validator could return failure. Then you can check whether all validations failed and only then treat form as having failed validation.
That level of customization of form validation could be inconvenient, so maybe using form's isValidPartial method would be better.
I created a custom validator that will make your element required based on the value of another zend form element.
Here's the full code. I hope this helps someone.
The idea is to create a custom validator and pass in the name of the conditional element and the value of that conditional element into the constructor. Zend_Validor's isValid method already has access to the value of the element you are attaching the validtor to along with all the form element names and values.
So, inside the isValid method you have all the information you need to determine if your form element should be a required element.
On Zend 1 extend the isValid method, where you set required depending on posted data for example:
public function isValid($data)
{
if (!empty($data['companyCar'])) {
$this->getElement('carValue')->setRequired(true);
}
return parent::isValid($data);
}
Thank you JCM for your good solution.
However 2 things I've noticed:
The isValid method of your validator has to return true in case of success.
The validator will not be executed during form validation without pass the allowEmpty option to false to the text field.