Answers.Body: <p>In <a href="https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_pre/" rel="nofollow noreferrer"><code>hook_civicrm_pre</code></a>, the params passed to your function include <code>qfKey</code> and <code>entryURL</code> &mdash; at least sometimes. The entry URL is in a format that's pretty obvious, but it seems like depending on URL parsing would make for brittle code. So what about <code>qfKey</code>?</p>
  
  <p><a href="https://github.com/civicrm/civicrm-core/blob/5.16.2/CRM/Core/Key.php#L84" rel="nofollow noreferrer"><code>qfKey</code></a> is a form key based on form name, the current user session ID, a private key unique to the current user session, and optionally a sequence number to distinguish between multiple instances of the same form in the same session. The form name might give you the context information you need! But it is encrypted, so your extension can't just use a simple comparison operator on it.</p>
  
  <p>To find out whether an entity was created in the context of a given form, you need to use <code>CRM_Core_Key::validate()</code>. For example:</p>
  
  
  
  <pre><code>function myextension_civicrm_pre($op, $objectName, $id, &amp;$params) {
    if (CRM_Core_Key::validate($params['qfKey'], 'CRM_Contribute_Form_Contribution', TRUE)) {
      // This entity is being created in the context of the back-office contribution form.
      // Do stuff.
    }
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-08-22T05:56:53.487Z
Answers.LastActivityDate: 2019-08-22T05:56:53.487Z
Answers.UserDisplayName: Noah Miller
Body: <p>I'm creating an extension. It should:</p>
  
  <ul>
  <li>intervene when a Contribution is created, and make some changes to the data</li>
  <li>only intervene if the Contribution was created via a public-facing Contribution Page, <em>or</em> via the Import Contributions UI</li>
  <li><em>not</em> intervene if the contribution was created through the back-office UI, batch data entry, a public-facing event registration form, or any other method.</li>
  </ul>
  
  <p>My plan was to use <code>hook_civicrm_pre</code> or <code>hook_civicrm_post</code> to intercept the Contribution at the time of its creation... but I need to know which context the Contribution is being created/updated in, so I can make sure I'm only modifying the data in the desired contexts.</p>
  
  <p>How can I determine, within my hook implementations, what context the Contribution is being created in?</p>
  
  <p>(Bonus points for determining contexts other than the ones I listed above. For example, CLI or REST API.)</p>
  
Tags: <civicontribute><extension><contributions><forms><hooks>
Title: Ways for an extension to determine how (by which form/screen/API) a Contribution was created?
ThreadText: # Ways for an extension to determine how (by which form/screen/API) a Contribution was created?
  
  (Asked by: username_0 on 2019-08-22)
  
  I'm creating an extension. It should:
  
  * intervene when a Contribution is created, and make some changes to the data
  * only intervene if the Contribution was created via a public-facing Contribution Page, *or* via the Import Contributions UI
  * *not* intervene if the contribution was created through the back-office UI, batch data entry, a public-facing event registration form, or any other method.
  
  My plan was to use `hook_civicrm_pre` or `hook_civicrm_post` to intercept the Contribution at the time of its creation... but I need to know which context the Contribution is being created/updated in, so I can make sure I'm only modifying the data in the desired contexts.
  
  How can I determine, within my hook implementations, what context the Contribution is being created in?
  
  (Bonus points for determining contexts other than the ones I listed above. For example, CLI or REST API.)
  
  **Tags:** civicontribute, extension, contributions, forms, hooks
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2019-08-22. Score: 3
  
  In hook_civicrm_pre, the params passed to your function include qfKey and entryURL — at least sometimes. The entry URL is in a format that's pretty obvious, but it seems like depending on URL parsing would make for brittle code. So what about qfKey?
  qfKey is a form key based on form name, the current user session ID, a private key unique to the current user session, and optionally a sequence number to distinguish between multiple instances of the same form in the same session. The form name might give you the context information you need! But it is encrypted, so your extension can't just use a simple comparison operator on it.
  To find out whether an entity was created in the context of a given form, you need to use CRM_Core_Key::validate(). For example:
  function myextension_civicrm_pre($op, $objectName, $id, &$params) {
    if (CRM_Core_Key::validate($params['qfKey'], 'CRM_Contribute_Form_Contribution', TRUE)) {
      // This entity is being created in the context of the back-office contribution form.
      // Do stuff.
    }
  }
  
  
  ---
  
  