2

I am hooking into _buildForm for CRM_Contact_Form_Task_Email to add a hidden input called "order_id" that I will need for some token logic. This part is working great. But when I click Send Email, my _tokenValues hook fires and the &$values array is missing order_id.

Does Civi remove things from the $_POST array before building $values? Is this a bug or by design? I'm currently working around it by setting and getting my own session variables, but that means I have to create a session object in buildForm and again in tokenValues ($this->set() doesn't seem to work within an extension).

This code creates my extra input. I have verified that the input is written in the form when I view source in the browser. But doesn't make it to tokenValues:

function invoicetoken_civicrm_buildForm($formName, &$form) {
  if($formName == 'CRM_Contact_Form_Task_Email') {
        if (CRM_Utils_Request::retrieve('order_id', 'String')) {
           $order_id = CRM_Utils_Request::retrieve('order_id', 'String');
           $form->addElement('hidden','order_id', $order_id);
        }
  }
}

Edit: Based on Lobo's answer, I tried using $form->get(), but something still isn't working:

function invoicetoken_civicrm_buildForm($formName, &$form) {
  //add order_id to our form
  if($formName == 'CRM_Contact_Form_Task_Email') {
    //buildForm runs on get and post. this line re-adds the input during post
    if ($form->get('order_id')) {
        $order_id = $form->get('order_id');
        $form->addElement('hidden','order_id', $order_id);
    }
    //this line adds the input on initial load of the form
    elseif (CRM_Utils_Request::retrieve('order_id', 'String')) {
      $order_id = CRM_Utils_Request::retrieve('order_id', 'String');
        $form->addElement('hidden','order_id', $order_id);
    }
  }
}

No matter what I do, the input doesn't make it over to tokenValues; when I log the $form object, 'order_id' field appears in ['_submitValues']. I have tried $form->set(), $form->setVar, and any other combination I could think of. In the end, the only thing that works is to use a session var.

1

Most likely you are not adding order_id when the form is being posted back to the server

the quickform package basically filters out all variables that have not been added to the form. The buildForm hook is called even when the form is posted, so you might want to ensure that order_id is also added there. In most cases this happens automatically, however if we are using ajax for build parts of the form, it gets a bit trickier

$_GET['pid'] is available only during the first GET request. The POST request sends a very minimal set of GET variables. Try using this variation:`

function invoicetoken_civicrm_buildForm($formName, &$form) {
  //add order_id to our form
  if($formName == 'CRM_Contact_Form_Task_Email') {
    $order_id = CRM_Utils_Request::retrieve('order_id', 'String', $form);
    $form->addElement('hidden','order_id', $order_id);
  }
}`
  • I've added my code that shows the input being added, and verified that it does appear on the form. Interesting that you mention ajax, as the standard Send Email task that I'm calling does open and send in a modal. – Nicholai May 10 '15 at 21:06
  • I've modified my response in response to your modification :) – Donald Lobo May 10 '15 at 21:09
  • I've modified my response to your response to my response. Working code is at the bottom of the question. Thanks again! – Nicholai May 10 '15 at 21:38
  • i dont think u need the elsif. I suspect it never gets executed. Civi stuff all the GET variables into the form session, and hence line 1 will be valid for both GET and POST – Donald Lobo May 10 '15 at 22:24
  • 1
    ok, i re-read your original post and seemed to have missed the "_tokenValues" hook. The "values" array in tokenValues does not really have anything to do with the submitted form elements. Its a mixture of multiple things including lots of values from the db – Donald Lobo May 14 '15 at 3:20
1

There isn't a connection between form elements and tokens, so no matter how you customize the form, it will not be added to the $values array for tokens. The correct way to do this is via PHP session variables.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.