CRM-13234 fix profile to support lcase 'primary' & fix existing test failures
authorEileen <eileen@fuzion.co.nz>
Fri, 13 Sep 2013 09:03:06 +0000 (21:03 +1200)
committerEileen <eileen@fuzion.co.nz>
Fri, 13 Sep 2013 09:03:06 +0000 (21:03 +1200)
api/v3/Profile.php
api/v3/examples/ProfileApply.php
api/v3/examples/ProfileGet.php
api/v3/examples/ProfileGetFields.php
api/v3/examples/ProfileSubmit.php
tests/phpunit/api/v3/ProfileTest.php

index aefd89c317ebf18f2be6a63c25e77fcc6b1a79bf..d3c1d8faca2d1fe51f5a872b1f4f0bf9000c5ed5 100644 (file)
@@ -104,8 +104,11 @@ function civicrm_api3_profile_get($params) {
       }
       else {
         $contactFields[$fieldName] = $field;
+          // we should return 'Primary' with & without capitalisation. it is more consistent with api to not
+          // capitalise, but for form support we need it for now. Hopefully we can move away from it
+          $contactFields[strtolower($fieldName)] = $field;
+        }
       }
-    }
 
     $ufGroupBAO->setProfileDefaults($params['contact_id'], $contactFields, $values[$profileID], TRUE);
 
@@ -115,10 +118,15 @@ function civicrm_api3_profile_get($params) {
   }
   elseif(!empty($params['contact_id'])) {
     $ufGroupBAO->setProfileDefaults($params['contact_id'], $profileFields, $values[$profileID], TRUE);
-  }
-  else{
-    $values[$profileID] = array_fill_keys(array_keys($profileFields), '');
-  }
+      foreach ($values[$profileID] as $fieldName => $field){
+        // we should return 'Primary' with & without capitalisation. it is more consistent with api to not
+        // capitalise, but for form support we need it for now. Hopefully we can move away from it
+        $values[$profileID][strtolower($fieldName)] = $field;
+      }
+    }
+    else{
+      $values[$profileID] = array_fill_keys(array_keys($profileFields), '');
+    }
   }
   if($nonStandardLegacyBehaviour) {
     $result = civicrm_api3_create_success();
@@ -161,18 +169,8 @@ function civicrm_api3_profile_submit($params) {
 
   $contactParams = $activityParams = $missingParams = array();
 
-  $profileFields = CRM_Core_BAO_UFGroup::getFields($profileID,
-    FALSE,
-    NULL,
-    NULL,
-    NULL,
-    FALSE,
-    NULL,
-    TRUE,
-    NULL,
-    CRM_Core_Permission::EDIT
-  );
-
+  $profileFields = civicrm_api3('profile', 'getfields', array('action' => 'submit', 'profile_id' => $profileID));
+  $profileFields = $profileFields['values'];
   if ($isContactActivityProfile) {
     civicrm_api3_verify_mandatory($params, NULL, array('activity_id'));
 
@@ -186,12 +184,6 @@ function civicrm_api3_profile_submit($params) {
   }
 
   foreach ($profileFields as $fieldName => $field) {
-    if (CRM_Utils_Array::value('is_required', $field)) {
-      if (!CRM_Utils_Array::value($fieldName, $params) || empty($params[$fieldName])) {
-        $missingParams[] = $fieldName;
-      }
-    }
-
     if (!isset($params[$fieldName])) {
       continue;
     }
@@ -200,27 +192,27 @@ function civicrm_api3_profile_submit($params) {
     if ($params[$fieldName] && isset($params[$fieldName . '_id'])) {
       $value = $params[$fieldName . '_id'];
     }
-
-    if ($isContactActivityProfile && CRM_Utils_Array::value('field_type', $field) == 'Activity') {
-      $activityParams[$fieldName] = $value;
+    $contactEntities = array('contact', 'individual', 'organization', 'household');
+    $locationEntities = array('email', 'address', 'phone', 'website', 'im');
+
+    $entity = strtolower(CRM_Utils_Array::value('entity', $field));
+    if($entity && !in_array($entity, array_merge($contactEntities, $locationEntities))) {
+      $contactParams['api.' . $entity . '.create'][$fieldName] = $value;
+      if(isset($params[$entity . '_id'])) {
+        //todo possibly declare $entity_id in getfields ?
+        $contactParams['api.' . $entity . '.create']['id'] = $params[$entity . '_id'];
+      }
     }
     else {
-      $contactParams[$fieldName] = $value;
+      $contactParams[_civicrm_api3_profile_translate_fieldnames_for_bao($fieldName)] = $value;
     }
   }
 
-  if (!empty($missingParams)) {
-    throw new API_Exception("Missing required parameters for profile id {$params['profile_id']}: " . implode(', ', $missingParams));
-  }
-
   $contactParams['contact_id'] = CRM_Utils_Array::value('contact_id', $params);
   $contactParams['profile_id'] = $profileID;
   $contactParams['skip_custom'] = 1;
 
   $contactProfileParams = civicrm_api3_profile_apply($contactParams);
-  if (CRM_Utils_Array::value('is_error', $contactProfileParams)) {
-    return $contactProfileParams;
-  }
 
   // Contact profile fields
   $profileParams = $contactProfileParams['values'];
@@ -273,6 +265,20 @@ function civicrm_api3_profile_submit($params) {
   return $result;
 
 }
+
+/**
+ * The api standards expect field names to be lower case but the BAO uses mixed case
+ * so we accept 'email-primary' but pass 'email-Primary' to the BAO
+ * we could make the BAO handle email-primary but this would alter the fieldname seen by hooks
+ * & we would need to consider that change
+ * @param string $fieldName API field name
+ *
+ * @return string BAO Field Name
+ */
+function _civicrm_api3_profile_translate_fieldnames_for_bao($fieldName){
+  $fieldName = str_replace('url', 'URL', $fieldName);
+  return str_replace('primary', 'Primary', $fieldName);
+}
 /**
  * metadata for submit action
  * @param array $params
@@ -314,14 +320,14 @@ function civicrm_api3_profile_set($params) {
  * @deprecated - appears to be an internal function - should not be accessible via api
  * Provide formatted values for profile fields.
  *
- * @param array  $params       Associative array of property name/value
+ * @param array $params       Associative array of property name/value
  *                             pairs to profile field values
  *
+ * @throws API_Exception
  * @return formatted profile field values|CRM_Error
  *
  * @todo add example
  * @todo add test cases
- *
  */
 function civicrm_api3_profile_apply($params) {
 
@@ -454,18 +460,23 @@ function _civicrm_api3_buildprofile_submitfields($profileID, $optionsBehaviour =
   }
   $fields = civicrm_api3('uf_field', 'get', array('uf_group_id' => $profileID));
   $entities = array();
-
   foreach ($fields['values'] as $field) {
     if(!$field['is_active']) {
       continue;
     }
     list($entity, $fieldName) = _civicrm_api3_map_profile_fields_to_entity($field);
-    $profileFields[$profileID][$fieldName] = array(
+    $aliasArray = array();
+    if(strtolower($fieldName) != $fieldName) {
+      $aliasArray['api.aliases'] = array($fieldName);
+      $fieldName = strtolower($fieldName);
+    }
+    $profileFields[$profileID][$fieldName] = array_merge(array(
       'api.required' => $field['is_required'],
       'title' => $field['label'],
       'help_pre' => CRM_Utils_Array::value('help_pre', $field),
       'help_post' => CRM_Utils_Array::value('help_post', $field),
-    );
+      'entity' => $entity,
+    ), $aliasArray);
 
     $realFieldName = $field['field_name'];
     //see function notes
@@ -493,20 +504,28 @@ function _civicrm_api3_buildprofile_submitfields($profileID, $optionsBehaviour =
     $result = civicrm_api3($entity, 'getfields', array('action' => 'create'));
     $entityGetFieldsResult = _civicrm_api3_profile_appendaliases($result['values'], $entity);
     foreach ($entityFields as $entityfield => $realName) {
-      $profileFields[$profileID][$entityfield] = $entityGetFieldsResult[$realName];
+      $profileFields[$profileID][strtolower($entityfield)] = array_merge($profileFields[$profileID][$entityfield], $entityGetFieldsResult[$realName]);
       if($optionsBehaviour && !empty($entityGetFieldsResult[$realName]['pseudoconstant'])) {
         if($optionsBehaviour > 1  || !in_array($realName, array('state_province_id', 'county_id', 'country_id'))) {
           $options = civicrm_api3($entity, 'getoptions', array('field' => $realName));
           $profileFields[$profileID][$entityfield]['options'] = $options['values'];
         }
       }
+
+      if($entityfield != strtolower($entityfield)) {
+        // we will make the mixed case version (e.g. of 'Primary') an aliase
+        if(!isset($profileFields[$profileID][strtolower($entityfield)])) {
+          $profileFields[$profileID][strtolower($entityfield)]['api.aliases'] = array();
+        }
+        $profileFields[$profileID][strtolower($entityfield)]['api.aliases'][] = $entityfield;
+      }
       /**
        * putting this on hold -this would cause the api to set the default - but could have unexpected behaviour
       if(isset($result['values'][$realName]['default_value'])) {
-        //this would be the case for a custom field with a configured default
-        $profileFields[$profileID][$entityfield]['api.default'] = $result['values'][$realName]['default_value'];
+      //this would be the case for a custom field with a configured default
+      $profileFields[$profileID][$entityfield]['api.default'] = $result['values'][$realName]['default_value'];
       }
-      */
+       */
     }
   }
   return $profileFields[$profileID];
@@ -520,6 +539,7 @@ function _civicrm_api3_buildprofile_submitfields($profileID, $optionsBehaviour =
 function _civicrm_api3_map_profile_fields_to_entity(&$field) {
   $entity = $field['field_type'];
   $contactTypes = civicrm_api3('contact', 'getoptions', array('field' => 'contact_type'));
+  $locationFields = array('email' => 'Email');
   if(in_array($entity, $contactTypes['values'])) {
     $entity = 'Contact';
   }
@@ -533,10 +553,15 @@ function _civicrm_api3_map_profile_fields_to_entity(&$field) {
     }
     $fieldName .= '-' . $field['location_type_id'];
   }
+  elseif(array_key_exists($fieldName, $locationFields)) {
+    $fieldName .= '-Primary';
+    $entity = 'Email';
+  }
   if(!empty($field['phone_type_id'])) {
     $fieldName .= '-' . $field['location_type_id'];
     $entity = 'Phone';
   }
+
   // @todo - sort this out!
   //here we do a hard-code list of known fields that don't map to where they are mapped to
   // not a great solution but probably if we looked in the BAO we'd find a scary switch statement
index 24368a7dd57f9049b2f5eb1b1e88a9044f5cd1a5..55c2c59230f8b6eedc918cb3a84451b504f67b29 100644 (file)
@@ -5,8 +5,8 @@
  */
 function profile_apply_example(){
 $params = array(
-  'profile_id' => 25,
-  'contact_id' => 1,
+  'profile_id' => 31,
+  'contact_id' => 2,
   'first_name' => 'abc2',
   'last_name' => 'xyz2',
   'email-Primary' => 'abc2.xyz2@gmail.com',
@@ -41,10 +41,10 @@ function profile_apply_expectedresult(){
   'values' => array(
       'contact_type' => 'Individual',
       'contact_sub_type' => '',
-      'contact_id' => 1,
+      'contact_id' => 2,
       'version' => 3,
       'debug' => 1,
-      'profile_id' => 25,
+      'profile_id' => 31,
       'first_name' => 'abc2',
       'last_name' => 'xyz2',
       'email' => array(
index a3906660003e8e63baefeb13e2d71898a5b9b258..ae90235bbb5d9843ef0162ded4095a059da789db 100644 (file)
@@ -6,11 +6,11 @@
 function profile_get_example(){
 $params = array(
   'profile_id' => array(
-      '0' => 25,
+      '0' => 14,
       '1' => 1,
       '2' => 'Billing',
     ),
-  'contact_id' => 1,
+  'contact_id' => 2,
 );
 
 try{
@@ -37,14 +37,15 @@ function profile_get_expectedresult(){
   'version' => 3,
   'count' => 3,
   'values' => array(
-      '25' => array(
-          'first_name' => 'abc1',
-          'last_name' => 'xyz1',
-          'email-Primary' => 'abc1.xyz1@yahoo.com',
-          'phone-1-1' => '021 512 755',
-          'country-1' => '1228',
-          'state_province-1' => '1021',
+      '14' => array(
           'postal_code-1' => '90210',
+          'state_province-1' => '1021',
+          'country-1' => '1228',
+          'phone-1-1' => '021 512 755',
+          'email-Primary' => 'abc1.xyz1@yahoo.com',
+          'last_name' => 'xyz1',
+          'first_name' => 'abc1',
+          'email-primary' => 'abc1.xyz1@yahoo.com',
         ),
       '1' => array(
           'first_name' => 'abc1',
index 4ec751934410cd8a8aa38876739682f5fea17623..b7984ab8d3ddec276c49e78852379374193129fe 100644 (file)
@@ -6,7 +6,7 @@
 function profile_getfields_example(){
 $params = array(
   'action' => 'submit',
-  'profile_id' => 25,
+  'profile_id' => 27,
 );
 
 try{
@@ -34,9 +34,13 @@ function profile_getfields_expectedresult(){
   'count' => 9,
   'values' => array(
       'first_name' => array(
+          'api.required' => '1',
+          'title' => 'First Name',
+          'help_pre' => '',
+          'help_post' => '',
+          'entity' => 'Contact',
           'name' => 'first_name',
           'type' => 2,
-          'title' => 'First Name',
           'maxlength' => 64,
           'size' => 30,
           'import' => true,
@@ -46,9 +50,13 @@ function profile_getfields_expectedresult(){
           'export' => true,
         ),
       'last_name' => array(
+          'api.required' => '1',
+          'title' => 'Last Name',
+          'help_pre' => '',
+          'help_post' => '',
+          'entity' => 'Contact',
           'name' => 'last_name',
           'type' => 2,
-          'title' => 'Last Name',
           'maxlength' => 64,
           'size' => 30,
           'import' => true,
@@ -57,11 +65,18 @@ function profile_getfields_expectedresult(){
           'dataPattern' => '/^\w+(\s\w+)?+$/',
           'export' => true,
         ),
-      'email' => array(
+      'email-primary' => array(
+          'api.required' => 1,
+          'title' => 'Email',
+          'help_pre' => '',
+          'help_post' => '',
+          'entity' => 'Email',
+          'api.aliases' => array(
+              '0' => 'email-Primary',
+            ),
           'name' => 'email',
           'type' => 2,
-          'title' => 'Email',
-          'maxlength' => 64,
+          'maxlength' => 254,
           'size' => 20,
           'import' => true,
           'where' => 'civicrm_email.email',
@@ -69,12 +84,15 @@ function profile_getfields_expectedresult(){
           'dataPattern' => '/^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/',
           'export' => true,
           'rule' => 'email',
-          'api.required' => 1,
         ),
       'phone-1-1' => array(
+          'api.required' => 1,
+          'title' => 'Phone',
+          'help_pre' => '',
+          'help_post' => '',
+          'entity' => 'Phone',
           'name' => 'phone',
           'type' => 2,
-          'title' => 'Phone',
           'maxlength' => 32,
           'size' => 20,
           'import' => true,
@@ -82,12 +100,15 @@ function profile_getfields_expectedresult(){
           'headerPattern' => '/phone/i',
           'dataPattern' => '/^[\d\(\)\-\.\s]+$/',
           'export' => true,
-          'api.required' => 1,
         ),
       'country-1' => array(
+          'api.required' => '1',
+          'title' => 'Country',
+          'help_pre' => '',
+          'help_post' => '',
+          'entity' => 'Address',
           'name' => 'country_id',
           'type' => 1,
-          'title' => 'Country',
           'FKClassName' => 'CRM_Core_DAO_Country',
           'pseudoconstant' => array(
               'table' => 'civicrm_country',
@@ -97,9 +118,13 @@ function profile_getfields_expectedresult(){
             ),
         ),
       'state_province-1' => array(
+          'api.required' => '1',
+          'title' => 'State',
+          'help_pre' => '',
+          'help_post' => '',
+          'entity' => 'Address',
           'name' => 'state_province_id',
           'type' => 1,
-          'title' => 'State',
           'FKClassName' => 'CRM_Core_DAO_StateProvince',
           'pseudoconstant' => array(
               'table' => 'civicrm_state_province',
@@ -108,9 +133,13 @@ function profile_getfields_expectedresult(){
             ),
         ),
       'postal_code-1' => array(
+          'api.required' => 0,
+          'title' => 'Postal Code',
+          'help_pre' => '',
+          'help_post' => '',
+          'entity' => 'Address',
           'name' => 'postal_code',
           'type' => 2,
-          'title' => 'Postal Code',
           'maxlength' => 12,
           'size' => 12,
           'import' => true,
@@ -120,6 +149,11 @@ function profile_getfields_expectedresult(){
           'export' => true,
         ),
       'custom_1' => array(
+          'api.required' => '1',
+          'title' => 'first_name',
+          'help_pre' => '',
+          'help_post' => '',
+          'entity' => 'Contact',
           'label' => '_addCustomFieldToProfile',
           'groupTitle' => '_addCustomFie',
           'data_type' => 'String',
index 0562485f370cb0e54fa177acc9ea57f49a4fc47e..156ac6552b919a0ad77a5f8d9e6c45bfd9562205 100644 (file)
@@ -5,11 +5,11 @@
  */
 function profile_submit_example(){
 $params = array(
-  'profile_id' => 25,
-  'contact_id' => 1,
+  'profile_id' => 29,
+  'contact_id' => 2,
   'first_name' => 'abc2',
   'last_name' => 'xyz2',
-  'email-Primary' => 'abc2.xyz2@gmail.com',
+  'email-primary' => 'abc2.xyz2@gmail.com',
   'phone-1-1' => '022 321 826',
   'country-1' => '1013',
   'state_province-1' => '1000',
@@ -38,10 +38,10 @@ function profile_submit_expectedresult(){
   'is_error' => 0,
   'version' => 3,
   'count' => 1,
-  'id' => 1,
+  'id' => 2,
   'values' => array(
-      '1' => array(
-          'id' => '1',
+      '2' => array(
+          'id' => '2',
           'contact_type' => 'Individual',
           'contact_sub_type' => '',
           'do_not_email' => 0,
@@ -65,6 +65,7 @@ function profile_submit_expectedresult(){
           'first_name' => 'abc2',
           'middle_name' => 'J.',
           'last_name' => 'xyz2',
+          'suffix_id' => '3',
           'email_greeting_id' => '1',
           'email_greeting_custom' => '',
           'email_greeting_display' => 'Dear abc1',
index a77247a29cac905a71f0e6ac911aec3e7726b4f1..555dffd5a1da5d2162065ea502993ab12091e0ca 100644 (file)
@@ -549,8 +549,8 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
       'activity_status_id' => '2',
     );
     $profileParams = array_merge($params, $updateParams);
-    $profile       = $this->callAPISuccess('profile', 'submit', $profileParams);
-    $result        = $this->callAPISuccess('profile', 'get', $params);
+    $this->callAPISuccess('profile', 'submit', $profileParams);
+    $result = $this->callAPISuccess('profile', 'get', $params);
 
     foreach ($updateParams as $profileField => $value) {
       $this->assertEquals($value, CRM_Utils_Array::value($profileField, $result['values']), "In line " . __LINE__ . " error message: " . "missing/mismatching value for {$profileField}"