Answers.Body: <p>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.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-05-19T12:37:30.970Z
Answers.LastActivityDate: 2015-05-19T12:37:30.970Z
Answers.UserDisplayName: Nicholai
Answers.Body: <p>Most likely you are not adding order_id when the form is being posted back to the server</p>
  
  <p>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</p>
  
  <p>$_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:`</p>
  
  <pre><code>function invoicetoken_civicrm_buildForm($formName, &amp;$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-&gt;addElement('hidden','order_id', $order_id);
    }
  }`
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-05-10T21:06:22.920Z
Answers.Text: 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.
Answers.UserDisplayName: Nicholai
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-05-10T21:09:17.093Z
Answers.Text: I've modified my response in response to your modification :)
Answers.UserDisplayName: Donald Lobo
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-05-10T21:38:30.223Z
Answers.Text: I've modified my response to your response to my response. Working code is at the bottom of the question. Thanks again!
Answers.UserDisplayName: Nicholai
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-05-10T22:24:17.170Z
Answers.Text: 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
Answers.UserDisplayName: Donald Lobo
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-05-10T22:48:49.557Z
Answers.Text: It actually didn't work until I added that. On the first form load, $form->addElement('hidden','pid', $form->get('pid')) would create the input with no value so it had to come from GET on the first load.
Answers.UserDisplayName: Nicholai
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-05-13T13:52:05.753Z
Answers.Text: After further testing, it appears that form->get() didn't actually work for me. I've clarified the question further, and I'm temporarily unmarking the answer as accepted in case there are any other ideas. Thanks!
Answers.UserDisplayName: Nicholai
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-05-14T02:44:21.140Z
Answers.Text: ok, another stab at it, check code snippet above
Answers.UserDisplayName: Donald Lobo
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-05-14T02:57:53.873Z
Answers.Text: I tried the function and got the same result, unfortunately. I'm setting my tokenvalue to print_r($values,true) to debug, and order_id doesn't appear in the array when I look at the email that is sent. But everything works fine when using a session variable.
Answers.UserDisplayName: Nicholai
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-05-14T03:20:13.443Z
Answers.Text: 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
Answers.UserDisplayName: Donald Lobo
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-05-10T20:56:19.670Z
Answers.LastActivityDate: 2015-05-14T02:44:05.313Z
Answers.LastEditDate: 2015-05-14T02:44:05.313Z
Answers.UserDisplayName: Donald Lobo
Body: <p>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 &amp;$values array is missing order_id. </p>
  
  <p>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).</p>
  
  <p>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:</p>
  
  <pre><code>function invoicetoken_civicrm_buildForm($formName, &amp;$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-&gt;addElement('hidden','order_id', $order_id);
          }
    }
  }
  </code></pre>
  
  <p>Edit: Based on Lobo's answer, I tried using $form->get(), but something still isn't working:</p>
  
  <pre><code>function invoicetoken_civicrm_buildForm($formName, &amp;$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-&gt;get('order_id')) {
          $order_id = $form-&gt;get('order_id');
          $form-&gt;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-&gt;addElement('hidden','order_id', $order_id);
      }
    }
  }
  </code></pre>
  
  <p>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 <code>$form-&gt;set()</code>, <code>$form-&gt;setVar</code>, and any other combination I could think of. In the end, the only thing that works is to use a session var.</p>
  
Tags: <extension><tokens><forms>
Title: Custom form input field missing from &$values when hooking into tokenValues
ThreadText: # Custom form input field missing from &$values when hooking into tokenValues
  
  (Asked by: username_0 on 2015-05-10)
  
  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 username_1'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.
  
  **Tags:** extension, tokens, forms
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_0 on 2015-05-19. Score: 1 | Accepted answer
  
  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.
  
  
  ---
  
  ### Answer by username_1 on 2015-05-10. Score: 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);
    }
  }`
  
  ```
  
  > **Comments:**
  > **username_0**: 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.  
  > **username_1**: I've modified my response in response to your modification :)  
  > **username_0**: I've modified my response to your response to my response. Working code is at the bottom of the question. Thanks again!  
  > **username_1**: 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  
  > **username_0**: It actually didn't work until I added that. On the first form load, $form->addElement('hidden','pid', $form->get('pid')) would create the input with no value so it had to come from GET on the first load.  
  > **username_0**: After further testing, it appears that form->get() didn't actually work for me. I've clarified the question further, and I'm temporarily unmarking the answer as accepted in case there are any other ideas. Thanks!  
  > **username_1**: ok, another stab at it, check code snippet above  
  > **username_0**: I tried the function and got the same result, unfortunately. I'm setting my tokenvalue to print_r($values,true) to debug, and order_id doesn't appear in the array when I look at the email that is sent. But everything works fine when using a session variable.  
  > **username_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  
  
  ---
  
  