Answers.Body: <p>There is no target contact ID stored in the $form, however...</p>
  
  <p>As ErikH mentioned, most of the time the logged-in user fills in the form themselves. In that case, you could retrieve the <code>contact ID</code> like this:</p>
  
  <pre><code>$session = CRM_Core_Session::singleton();
  $contactId = $session-&gt;get('userID');
  </code></pre>
  
  <p>If another user or admin is filling in the form for another contact, the URL should have something like cid=xxx specified. It's true for participant registration and profile editing.</p>
  
  <p>There is still the case of a new contact, either with cid=0, either if not logged in (session does not contains userID).</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-04-01T13:24:30.330Z
Answers.LastActivityDate: 2015-04-02T13:12:21.240Z
Answers.LastEditDate: 2015-04-02T13:12:21.240Z
Answers.UserDisplayName: samuelsov
Answers.Body: <p>Not sure about them, but you can at least always retrieve the logged in user? Like so: </p>
  
  <pre><code>$session = CRM_Core_Session::singleton();
  $userId = $session-&gt;get('userID');
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-31T14:59:10.090Z
Answers.Text: Thanks Erik, unfortunately this doesn't help in the case where an administrator is updating a user's profile.
Answers.UserDisplayName: John
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-31T15:03:01.543Z
Answers.Text: True enough :-). Have you checked the entryUrl to see if there is anything valuable in there?
Answers.UserDisplayName: ErikH - CiviCooP
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-31T15:09:40.247Z
Answers.Text: Which form are you catching in your buildForm hook? Is it not easier to use the civicrm_post hook on the Participant entity? Just thinking out loud here.....
Answers.UserDisplayName: ErikH - CiviCooP
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-31T15:11:03.363Z
Answers.Text: So we're particularly interested in the event registration form, and the profile update form.
  
  There is nothing in the entryURL for either. I've done some searching in the $form for 'my' contact ID and nothing is coming up, so I guess this isn't possible - at least not in a 'generic' way.
Answers.UserDisplayName: John
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-31T15:18:12.537Z
Answers.Text: What are you trying to achieve? Could you solve it with the civicrm_post or civicrm_pre hook? If for example I get a Participant entity in the post hook, I can then check if field X exists for the participant?
Answers.UserDisplayName: ErikH - CiviCooP
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-31T15:42:24.737Z
Answers.Text: Hi Erik. I've outlined what we are trying to achieve in my original question. Ideally we would be able to freeze certain fields on the form when they are not empty (easy enough); but only when the contact in question has a certain value on their record (not so easy!).
Answers.UserDisplayName: John
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-31T15:46:37.993Z
Answers.Text: Yes, I got that. But what is the situation? Is the profile also used for event registration? Is the user logged in or is the admin logged in? Your question is too generic for me to really help you further than I have? I can not describe how to influence 'certain' fields on 'certain' forms? You have to give me a little more if you want me to help you? There are certainly forms where the target contact ID resideds, and there are those where they do not as you have noticed :-)
Answers.UserDisplayName: ErikH - CiviCooP
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-31T15:48:12.637Z
Answers.Text: If someone fill a form for someone else, the url should contains the contact id, otherwise the session seems the good option. ex: civicrm/event/register?cid=7032&reset=1&id=64 vs civicrm/event/register?reset=1&id=64
Answers.UserDisplayName: samuelsov
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-31T15:57:06.643Z
Answers.Text: Thanks Erik. I'm afraid the use-case is fairly generic. The fields might be exposed on a profile update form, event registration, donation form. We would want to freeze the fields based on a value on the target contact, ie: the contact the form will affect, regardless of whether the user themselves or an administrator is completing the form. I suppose the short answer to my original question is 'No, not in the $form, but...'
  
  Samuelsoc, that could work, checking if the cid is set in the URL and if not then using the contact ID of the currently logged-in user. You could post that as an answer?
Answers.UserDisplayName: John
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-31T16:27:46.760Z
Answers.Text: Even if it is fairly generic, I as a user would have to mention somewhere on the form who I am registering? Or whom I am recording a contribution for? So the data will be somewhere in the object, either in the _defaultValues array or perhaps in the _elements, which you can access via the _elementIndex?  Or am I missing the point?
Answers.UserDisplayName: ErikH - CiviCooP
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-31T22:56:02.277Z
Answers.Text: Sorry Erik, I've probably explained it badly. Thanks for your patience. We can fairly easily 'disable a field if it has a default value', as you say we can check _defaultValues for that, and then freeze() the appropriate element on the form. However, I only want this to happen if the user the default values are coming from (ie: normally the logged in user, but it could be registering on behalf of someone else perhaps) has 'Yes' in a custom field on their profile. Finding the contact ID that the _defaultValues are coming from, so we can look up the field on their profile, is the trick.
Answers.UserDisplayName: John
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-04-02T07:10:50.697Z
Answers.Text: I would expect thought that if you are registering on behalf of someone else the contact_id of the person you are registering for will be somewhere in the form? Do you know of more cases where you get in trouble?
Answers.UserDisplayName: ErikH - CiviCooP
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-31T14:58:15.763Z
Answers.LastActivityDate: 2015-03-31T14:58:15.763Z
Answers.UserDisplayName: ErikH - CiviCooP
Answers.Body: <p>Just in case, alternative solution via hook in Drupal module: </p>
  
  <pre><code>function MYMODULENAME_civicrm_buildForm($formName, &amp;$form) {
  # Form we work with, print_r($formName) for name;
    if ($formName == 'CRM_Profile_Form_Edit') {
       $curr_user_civiID = $_SESSION['CiviCRM']['userID']; 
  # Check if it matches current user's civicrm contactID via print_r($curr_user_civiID);
   }
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-12-17T13:04:36.500Z
Answers.LastActivityDate: 2015-12-17T13:04:36.500Z
Answers.UserDisplayName: yurg
Answers.Body: <p>It really depends on the entity you are processing I guess....if you are working on the activity form, you can get the activity id and with that id retrieve the target it from the API? 
  Or from the table civicrm_activity_contact directly using CRM_Core_DAO::executeQuery?</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-31T14:54:50.317Z
Answers.Text: I'm particularly focusing on the profile update form and the event registration form - neither of these seem to have the associated contact ID in the $form when someone is logged in?
Answers.UserDisplayName: John
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-31T14:56:07.253Z
Answers.Text: Not sure about them, but you can at least always retrieve the logged in user? Like so:
Answers.UserDisplayName: ErikH - CiviCooP
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-03-31T14:46:01.607Z
Answers.LastActivityDate: 2015-03-31T14:46:01.607Z
Answers.UserDisplayName: ErikH - CiviCooP
Body: <p><strong>Summary</strong></p>
  
  <p>Is it possible to extract the target contact ID of a form during <a href="http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_buildForm" rel="nofollow">hook_civicrm_buildForm</a>?</p>
  
  <p><strong>Details</strong></p>
  
  <p>We are trying to manipulate a wide range of fields across the site, ones that might be present in event registration forms, contact profile forms, etc.</p>
  
  <p>We want to disable editing of the field if there is a value in it, and the contact has a certain value on their record.</p>
  
  <p>The workflow we have in mind is...</p>
  
  <ul>
  <li>Is 'Field A' on the form?</li>
  <li>If yes, does 'Field A' have a value already?</li>
  <li>If yes, is there a 'target contact' for the form (ie: a logged in user is registering for an event, or updating their profile)</li>
  <li>If yes, fire an API call to get the value of 'Field X' from the record of the target contact.</li>
  <li>If 'Field X' is 'Yes' then disable editing of 'Field A' on the form.</li>
  </ul>
  
  <p>We understand that not all forms will have a target contact ID, and we would only want to go through this logic if there was one. So it wouldn't do any of this if an anonymous user was signing up to an event; but would if a logged-in user was.</p>
  
  <p>The logic itself isn't the problem, but we can't seem to find the target contact ID stored anywhere at this point.</p>
  
  <p>Thanks in advance!</p>
  
Tags: <hooks><forms>
Title: Can I find the target contact ID in hook_civicrm_buildForm?
ThreadText: # Can I find the target contact ID in hook_civicrm_buildForm?
  
  (Asked by: username_0 on 2015-03-31)
  
  **Summary**
  
  Is it possible to extract the target contact ID of a form during [hook\_civicrm\_buildForm](http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_buildForm)?
  
  **Details**
  
  We are trying to manipulate a wide range of fields across the site, ones that might be present in event registration forms, contact profile forms, etc.
  
  We want to disable editing of the field if there is a value in it, and the contact has a certain value on their record.
  
  The workflow we have in mind is...
  
  * Is 'Field A' on the form?
  * If yes, does 'Field A' have a value already?
  * If yes, is there a 'target contact' for the form (ie: a logged in user is registering for an event, or updating their profile)
  * If yes, fire an API call to get the value of 'Field X' from the record of the target contact.
  * If 'Field X' is 'Yes' then disable editing of 'Field A' on the form.
  
  We understand that not all forms will have a target contact ID, and we would only want to go through this logic if there was one. So it wouldn't do any of this if an anonymous user was signing up to an event; but would if a logged-in user was.
  
  The logic itself isn't the problem, but we can't seem to find the target contact ID stored anywhere at this point.
  
  Thanks in advance!
  
  **Tags:** hooks, forms
  
  
  ---
  
  ## 4 answers
  
  ### Answer by username_1 on 2015-04-01. Score: 1 | Accepted answer
  
  There is no target contact ID stored in the $form, however...
  As ErikH mentioned, most of the time the logged-in user fills in the form themselves. In that case, you could retrieve the contact ID like this:
  $session = CRM_Core_Session::singleton();
  $contactId = $session->get('userID');
  
  If another user or admin is filling in the form for another contact, the URL should have something like cid=xxx specified. It's true for participant registration and profile editing.
  There is still the case of a new contact, either with cid=0, either if not logged in (session does not contains userID).
  
  
  ---
  
  ### Answer by username_2 on 2015-03-31. Score: 1
  
  Not sure about them, but you can at least always retrieve the logged in user? Like so: 
  $session = CRM_Core_Session::singleton();
  $userId = $session->get('userID');
  
  > **Comments:**
  > **username_0**: Thanks Erik, unfortunately this doesn't help in the case where an administrator is updating a user's profile.  
  > **username_2**: True enough :-). Have you checked the entryUrl to see if there is anything valuable in there?  
  > **username_2**: Which form are you catching in your buildForm hook? Is it not easier to use the civicrm_post hook on the Participant entity? Just thinking out loud here.....  
  > **username_0**: So we're particularly interested in the event registration form, and the profile update form.  There is nothing in the entryURL for either. I've done some searching in the $form for 'my' contact ID and nothing is coming up, so I guess this isn't possible - at least not in a 'generic' way.  
  > **username_2**: What are you trying to achieve? Could you solve it with the civicrm_post or civicrm_pre hook? If for example I get a Participant entity in the post hook, I can then check if field X exists for the participant?  
  > **username_0**: Hi Erik. I've outlined what we are trying to achieve in my original question. Ideally we would be able to freeze certain fields on the form when they are not empty (easy enough); but only when the contact in question has a certain value on their record (not so easy!).  
  > **username_2**: Yes, I got that. But what is the situation? Is the profile also used for event registration? Is the user logged in or is the admin logged in? Your question is too generic for me to really help you further than I have? I can not describe how to influence 'certain' fields on 'certain' forms? You have to give me a little more if you want me to help you? There are certainly forms where the target contact ID resideds, and there are those where they do not as you have noticed :-)  
  > **username_1**: If someone fill a form for someone else, the url should contains the contact id, otherwise the session seems the good option. ex: civicrm/event/register?cid=7032&reset=1&id=64 vs civicrm/event/register?reset=1&id=64  
  > **username_0**: Thanks Erik. I'm afraid the use-case is fairly generic. The fields might be exposed on a profile update form, event registration, donation form. We would want to freeze the fields based on a value on the target contact, ie: the contact the form will affect, regardless of whether the user themselves or an administrator is completing the form. I suppose the short answer to my original question is 'No, not in the $form, but...'  Samuelsoc, that could work, checking if the cid is set in the URL and if not then using the contact ID of the currently logged-in user. You could post that as an answer?  
  > **username_2**: Even if it is fairly generic, I as a user would have to mention somewhere on the form who I am registering? Or whom I am recording a contribution for? So the data will be somewhere in the object, either in the _defaultValues array or perhaps in the _elements, which you can access via the _elementIndex?  Or am I missing the point?  
  > **username_0**: Sorry Erik, I've probably explained it badly. Thanks for your patience. We can fairly easily 'disable a field if it has a default value', as you say we can check _defaultValues for that, and then freeze() the appropriate element on the form. However, I only want this to happen if the user the default values are coming from (ie: normally the logged in user, but it could be registering on behalf of someone else perhaps) has 'Yes' in a custom field on their profile. Finding the contact ID that the _defaultValues are coming from, so we can look up the field on their profile, is the trick.  
  > **username_2**: I would expect thought that if you are registering on behalf of someone else the contact_id of the person you are registering for will be somewhere in the form? Do you know of more cases where you get in trouble?  
  
  ---
  
  ### Answer by username_3 on 2015-12-17. Score: 0
  
  Just in case, alternative solution via hook in Drupal module: 
  function MYMODULENAME_civicrm_buildForm($formName, &$form) {
  # Form we work with, print_r($formName) for name;
    if ($formName == 'CRM_Profile_Form_Edit') {
       $curr_user_civiID = $_SESSION['CiviCRM']['userID']; 
  # Check if it matches current user's civicrm contactID via print_r($curr_user_civiID);
   }
  }
  
  
  ---
  
  ### Answer by username_2 on 2015-03-31. Score: 0
  
  It really depends on the entity you are processing I guess....if you are working on the activity form, you can get the activity id and with that id retrieve the target it from the API?
  Or from the table civicrm\_activity\_contact directly using CRM\_Core\_DAO::executeQuery?
  
  > **Comments:**
  > **username_0**: I'm particularly focusing on the profile update form and the event registration form - neither of these seem to have the associated contact ID in the $form when someone is logged in?  
  > **username_2**: Not sure about them, but you can at least always retrieve the logged in user? Like so:  
  
  ---
  
  