Merge remote-tracking branch 'upstream/4.6' into 4.6-master-2015-05-28-22-50-49
[civicrm-core.git] / Civi / API / Subscriber / ChainSubscriber.php
index 3d17bf277addcb4797f2dfc627e6e7879aecea03..53566316a472ed5d7d2c2f1e765aec18f08e7723 100644 (file)
@@ -3,7 +3,7 @@
  +--------------------------------------------------------------------+
  | CiviCRM version 4.6                                                |
  +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2014                                |
+ | Copyright CiviCRM LLC (c) 2004-2015                                |
  +--------------------------------------------------------------------+
  | This file is a part of CiviCRM.                                    |
  |                                                                    |
@@ -75,7 +75,7 @@ class ChainSubscriber implements EventSubscriberInterface {
   }
 
   /**
-   * Call any nested api calls
+   * Call any nested api calls.
    *
    * TODO: We don't really need this to be a separate function.
    * @param $params
@@ -86,15 +86,15 @@ class ChainSubscriber implements EventSubscriberInterface {
    * @throws \Exception
    */
   protected function callNestedApi(&$params, &$result, $action, $entity, $version) {
-    $entity = _civicrm_api_get_entity_name_from_camel($entity);
+    $lowercase_entity = _civicrm_api_get_entity_name_from_camel($entity);
 
     // We don't need to worry about nested api in the getfields/getoptions
     // actions, so just return immediately.
-    if (in_array(strtolower($action), array('getfields', 'getoptions'))) {
+    if (in_array($action, array('getfields', 'getfield', 'getoptions'))) {
       return;
     }
 
-    if (strtolower($action) == 'getsingle') {
+    if ($action == 'getsingle') {
       // I don't understand the protocol here, but we don't want
       // $result to be a recursive array
       // $result['values'][0] = $result;
@@ -120,11 +120,11 @@ class ChainSubscriber implements EventSubscriberInterface {
         $subParams = array(
           'debug' => \CRM_Utils_Array::value('debug', $params),
         );
-        $subEntity = $subAPI[1];
+        $subEntity = _civicrm_api_get_entity_name_from_camel($subAPI[1]);
 
         foreach ($result['values'] as $idIndex => $parentAPIValues) {
 
-          if (strtolower($subEntity) != 'contact') {
+          if ($subEntity != 'contact') {
             //contact spits the dummy at activity_id so what else won't it like?
             //set entity_id & entity table based on the parent's id & entity.
             //e.g for something like note if the parent call is contact
@@ -132,13 +132,30 @@ class ChainSubscriber implements EventSubscriberInterface {
             //from the parent call. in this case 'contact_id' will also be
             //set to the parent's id
             $subParams["entity_id"] = $parentAPIValues['id'];
-            $subParams['entity_table'] = 'civicrm_' . _civicrm_api_get_entity_name_from_camel($entity);
-            $subParams[strtolower($entity) . "_id"] = $parentAPIValues['id'];
+            $subParams['entity_table'] = 'civicrm_' . $lowercase_entity;
+
+            $crm16084 = FALSE;
+            if ($subEntity == 'relationship' && $lowercase_entity == 'contact') {
+              // if a relationship call is chained to a contact call, we need
+              // to check whether contact_id_a or contact_id_b for the
+              // relationship is given. If so, don't add an extra subParam
+              // "contact_id" => parent_id.
+              // See CRM-16084.
+              foreach (array_keys($newparams) as $key) {
+                if (substr($key, 0, 11) == 'contact_id_') {
+                  $crm16084 = TRUE;
+                  break;
+                }
+              }
+            }
+            if (!$crm16084) {
+              $subParams[$lowercase_entity . "_id"] = $parentAPIValues['id'];
+            }
           }
-          if (strtolower($entity) != 'contact' && \CRM_Utils_Array::value(strtolower($subEntity . "_id"), $parentAPIValues)) {
+          if ($entity != 'Contact' && \CRM_Utils_Array::value(strtolower($subEntity . "_id"), $parentAPIValues)) {
             //e.g. if event_id is in the values returned & subentity is event
             //then pass in event_id as 'id' don't do this for contact as it
-            //does some wierd things like returning primary email &
+            //does some weird things like returning primary email &
             //thus limiting the ability to chain email
             //TODO - this might need the camel treatment
             $subParams['id'] = $parentAPIValues[$subEntity . "_id"];
@@ -149,7 +166,7 @@ class ChainSubscriber implements EventSubscriberInterface {
           }
           // if we are dealing with the same entity pass 'id' through
           // (useful for get + delete for example)
-          if (strtolower($entity) == strtolower($subEntity)) {
+          if ($lowercase_entity == $subEntity) {
             $subParams['id'] = $result['values'][$idIndex]['id'];
           }
 
@@ -183,7 +200,7 @@ class ChainSubscriber implements EventSubscriberInterface {
         }
       }
     }
-    if (strtolower($action) == 'getsingle') {
+    if ($action == 'getsingle') {
       $result = $result['values'][0];
     }
   }