CRM-10551: Coding standards
[civicrm-core.git] / CRM / Core / BAO / Block.php
index 64e77630f836bb1671432a209443d7870bc3c499..12c30e1ef74365948ea2e10764b89429a27a9ea8 100644 (file)
@@ -23,7 +23,7 @@
  | GNU Affero General Public License or the licensing of CiviCRM,     |
  | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
  +--------------------------------------------------------------------+
-*/
+ */
 
 /**
  *
@@ -38,7 +38,7 @@
 class CRM_Core_BAO_Block {
 
   /**
-   * Fields that are required for a valid block
+   * Fields that are required for a valid block.
    */
   static $requiredBlockFields = array(
     'email' => array('email'),
@@ -57,8 +57,7 @@ class CRM_Core_BAO_Block {
    *   Input parameters to find object.
    *
    * @return array
-   *   of $block objects.
-   * @static
+   *   Array of $block objects.
    */
   public static function &getValues($blockName, $params) {
     if (empty($params)) {
@@ -85,8 +84,8 @@ class CRM_Core_BAO_Block {
       $count = 1;
       foreach ($blockIds as $blockId) {
         $block = new $BAOString();
-        $block->id        = $blockId['id'];
-        $getBlocks        = self::retrieveBlock($block, $blockName);
+        $block->id = $blockId['id'];
+        $getBlocks = self::retrieveBlock($block, $blockName);
         $blocks[$count++] = array_pop($getBlocks);
       }
     }
@@ -104,8 +103,7 @@ class CRM_Core_BAO_Block {
    *   Name of the above object.
    *
    * @return array
-   *   of $block objects.
-   * @static
+   *   Array of $block objects.
    */
   public static function retrieveBlock(&$block, $blockName) {
     // we first get the primary location due to the order by clause
@@ -128,16 +126,15 @@ class CRM_Core_BAO_Block {
   }
 
   /**
-   * Check if the current block object has any valid data
+   * Check if the current block object has any valid data.
    *
    * @param array $blockFields
    *   Array of fields that are of interest for this object.
    * @param array $params
    *   Associated array of submitted fields.
    *
-   * @return boolean
+   * @return bool
    *   true if the block has data, otherwise false
-   * @static
    */
   public static function dataExists($blockFields, &$params) {
     foreach ($blockFields as $field) {
@@ -149,16 +146,15 @@ class CRM_Core_BAO_Block {
   }
 
   /**
-   * Check if the current block exits
+   * Check if the current block exits.
    *
    * @param string $blockName
    *   Bloack name.
    * @param array $params
    *   Associated array of submitted fields.
    *
-   * @return boolean
+   * @return bool
    *   true if the block exits, otherwise false
-   * @static
    */
   public static function blockExists($blockName, &$params) {
     // return if no data present
@@ -170,7 +166,7 @@ class CRM_Core_BAO_Block {
   }
 
   /**
-   * Get all block ids for a contact
+   * Get all block ids for a contact.
    *
    * @param string $blockName
    *   Block name.
@@ -183,7 +179,6 @@ class CRM_Core_BAO_Block {
    * @return array
    *   formatted array of block ids
    *
-   * @static
    */
   public static function getBlockIds($blockName, $contactId = NULL, $entityElements = NULL, $updateBlankLocInfo = FALSE) {
     $allBlocks = array();
@@ -215,7 +210,7 @@ class CRM_Core_BAO_Block {
   }
 
   /**
-   * Takes an associative array and creates a block
+   * Takes an associative array and creates a block.
    *
    * @param string $blockName
    *   Block name.
@@ -226,17 +221,20 @@ class CRM_Core_BAO_Block {
    *
    * @return object
    *   CRM_Core_BAO_Block object on success, null otherwise
-   * @static
    */
   public static function create($blockName, &$params, $entity = NULL, $contactId = NULL) {
+
     if (!self::blockExists($blockName, $params)) {
       return NULL;
     }
 
-    $name           = ucfirst($blockName);
-    $contactId      = NULL;
-    $isPrimary      = $isBilling = TRUE;
+    // Set up required information / defaults
     $entityElements = $blocks = array();
+    $resetPrimary = $primarySet = $billingSet = FALSE;
+    $contactId = NULL;
+
+    $baoString = 'CRM_Core_BAO_' . ucfirst($blockName);
+    $updateBlankLocInfo = CRM_Utils_Array::value('updateBlankLocInfo', $params, FALSE);
 
     if ($entity) {
       $entityElements = array(
@@ -248,157 +246,137 @@ class CRM_Core_BAO_Block {
       $contactId = $params['contact_id'];
     }
 
-    $updateBlankLocInfo = CRM_Utils_Array::value('updateBlankLocInfo', $params, FALSE);
+    // Get current and submitted values
+    $existingValues = self::getBlockIds($blockName, $contactId, $entityElements, $updateBlankLocInfo);
+    $submittedValues = $params[$blockName];
 
-    //get existsing block ids.
-    $blockIds = self::getBlockIds($blockName, $contactId, $entityElements, $updateBlankLocInfo);
-
-    if (!$updateBlankLocInfo) {
-      $resetPrimaryId = NULL;
-      $primaryId = FALSE;
-      foreach ($params[$blockName] as $count => $value) {
-        $blockId = CRM_Utils_Array::value('id', $value);
-        if ($blockId) {
-          if (is_array($blockIds)
-            && array_key_exists($blockId, $blockIds)
-          ) {
-            unset($blockIds[$blockId]);
-          }
-          else {
-            unset($value['id']);
-          }
-        }
-        //lets allow to update primary w/ more cleanly.
-        if (!$resetPrimaryId && !empty($value['is_primary'])) {
-          $primaryId = TRUE;
-          if (is_array($blockIds)) {
-            foreach ($blockIds as $blockId => $blockValue) {
-              if (!empty($blockValue['is_primary'])) {
-                $resetPrimaryId = $blockId;
-                break;
-              }
-            }
-          }
-          if ($resetPrimaryId) {
-            $baoString = 'CRM_Core_BAO_' . $blockName;
+    // For each submitted value
+    foreach ($submittedValues as $count => $submittedValue) {
+
+      // Set the contact ID
+      $submittedValue['contact_id'] = $contactId;
+
+      // If this is a primary value, and we haven't unset a primary value yet, and there are values on the contact
+      // Then unset any primary value currently on the Contact
+      if (!empty($submittedValue['is_primary']) && !$resetPrimary && is_array($existingValues)) {
+        foreach ($existingValues as $existingValueId => $existingValue) {
+          if (!empty($existingValue['is_primary'])) {
+
+            // @todo Can we refactor this?
             $block = new $baoString();
             $block->selectAdd();
             $block->selectAdd("id, is_primary");
-            $block->id = $resetPrimaryId;
+            $block->id = $existingValue['id'];
             if ($block->find(TRUE)) {
               $block->is_primary = FALSE;
               $block->save();
             }
             $block->free();
+
+            // Stop looping since we found a match
+            $resetPrimary = TRUE;
+            break;
           }
         }
       }
-    }
 
-    foreach ($params[$blockName] as $count => $value) {
-      if (!is_array($value)) {
-        continue;
+      // If there is already an ID passed in
+      if (!empty($submittedValue['id'])) {
+        // If the ID already exists on the contact
+        // Then we don't want to match on it later, so unset it
+        if (array_key_exists($submittedValue['id'], $existingValues)) {
+          unset($existingValues[$existingValueId]);
+        }
+        // Otherwise it is a new value, so ignore the passed in ID
+        else {
+          unset($submittedValue['id']);
+        }
       }
-      $contactFields = array(
-        'contact_id' => $contactId,
-        'location_type_id' => CRM_Utils_Array::value('location_type_id', $value),
-      );
 
-      //check for update
-      if (empty($value['id']) &&
-        is_array($blockIds) && !empty($blockIds)
-      ) {
-        foreach ($blockIds as $blockId => $blockValue) {
-          if ($updateBlankLocInfo) {
-            if (!empty($blockIds[$count])) {
-              $value['id'] = $blockIds[$count]['id'];
-              unset($blockIds[$count]);
-            }
-          }
-          else {
-            if ($blockValue['locationTypeId'] == CRM_Utils_Array::value('location_type_id', $value)) {
-              $valueId = FALSE;
-
-              if ($blockName == 'phone') {
-                $phoneTypeBlockValue = CRM_Utils_Array::value('phoneTypeId', $blockValue);
-                if ($phoneTypeBlockValue == CRM_Utils_Array::value('phone_type_id', $value)) {
-                  $valueId = TRUE;
-                }
-              }
-              elseif ($blockName == 'im') {
-                $providerBlockValue = CRM_Utils_Array::value('providerId', $blockValue);
-                if ($providerBlockValue == $value['provider_id']) {
-                  $valueId = TRUE;
-                }
+      // Otherwise, if there was no ID passed in
+      // Loop through the current values, and find the first match on location type
+      else {
+        foreach ($existingValues as $existingValueId => $existingValue) {
+          if ($existingValue['locationTypeId'] == $submittedValue['location_type_id']) {
+
+            // Also require a match on 'type id' for phone and IM blocks
+            $matchFound = FALSE;
+
+            if ($blockName == 'phone') {
+              if (CRM_Utils_Array::value('phoneTypeId', $existingValue) == CRM_Utils_Array::value('phone_type_id', $submittedValue)) {
+                $matchFound = TRUE;
               }
-              else {
-                $valueId = TRUE;
+            }
+            elseif ($blockName == 'im') {
+              if (CRM_Utils_Array::value('providerId', $existingValue) == CRM_Utils_Array::value('provider_id', $submittedValue)) {
+                $matchFound = TRUE;
               }
+            }
+            else {
+              $matchFound = TRUE;
+            }
 
-              if ($valueId) {
-                //assigned id as first come first serve basis
-                $value['id'] = $blockValue['id'];
-                if (!$primaryId && !empty($blockValue['is_primary'])) {
-                  $value['is_primary'] = $blockValue['is_primary'];
-                }
-                unset($blockIds[$blockId]);
-                break;
+            // If we found a match
+            if ($matchFound) {
+              // Match up the ID
+              $submittedValue['id'] = $existingValue['id'];
+              // If the submitted value is not primary, but the matched value is
+              // Then set the submitted value to be primary
+              if (empty($submittedValue['is_primary']) && !empty($existingValue['is_primary'])) {
+                $submittedValue['is_primary'] = 1;
               }
+              // Remove the original value from the array so we don't match on it again
+              unset($existingValues[$existingValueId]);
+              break;
             }
           }
         }
       }
 
-      $dataExits = self::dataExists(self::$requiredBlockFields[$blockName], $value);
+      // Check if data exists in the submitted value
+      $dataExists = self::dataExists(self::$requiredBlockFields[$blockName], $submittedValue);
 
-      // Note there could be cases when block info already exist ($value[id] is set) for a contact/entity
-      // BUT info is not present at this time, and therefore we should be really careful when deleting the block.
-      // $updateBlankLocInfo will help take appropriate decision. CRM-5969
-      if (!empty($value['id']) && !$dataExits && $updateBlankLocInfo) {
-        //delete the existing record
-        self::blockDelete($blockName, array('id' => $value['id']));
-        continue;
-      }
-      elseif (!$dataExits) {
-        continue;
-      }
+      // If there is data
+      if ($dataExists) {
 
-      if ($isPrimary && !empty($value['is_primary'])) {
-        $contactFields['is_primary'] = $value['is_primary'];
-        $isPrimary = FALSE;
-      }
-      else {
-        $contactFields['is_primary'] = 0;
+        // "There can be only one" primary / billing block
+        if (!$primarySet && !empty($submittedValue['is_primary'])) {
+          $submittedValue['is_primary'] = 1;
+          $primarySet = TRUE;
+        }
+        else {
+          $contactFields['is_primary'] = 0;
+        }
+
+        if (!$billingSet && !empty($submittedValue['is_billing'])) {
+          $submittedValue['is_billing'] = 1;
+          $billingSet = TRUE;
+        }
+        else {
+          $contactFields['is_billing'] = 0;
+        }
+
+        // Add the value to the list of blocks
+        $blocks[] = $baoString::add($submittedValue);
       }
 
-      if ($isBilling && !empty($value['is_billing'])) {
-        $contactFields['is_billing'] = $value['is_billing'];
-        $isBilling = FALSE;
+      // Otherwise, if there is no data, and there is an ID, and we are deleting 'blanked' values
+      // Then delete it
+      elseif (!empty($submittedValue['id']) && $updateBlankLocInfo) {
+        self::blockDelete($blockName, array('id' => $submittedValue['id']));
       }
+
+      // Otherwise we ignore it
       else {
-        $contactFields['is_billing'] = 0;
       }
 
-      $blockFields = array_merge($value, $contactFields);
-      $baoString = 'CRM_Core_BAO_' . $name;
-      $blocks[] = $baoString::add($blockFields);
-    }
-
-    // we need to delete blocks that were deleted during update
-    if ($updateBlankLocInfo && !empty($blockIds)) {
-      foreach ($blockIds as $deleteBlock) {
-        if (empty($deleteBlock['id'])) {
-          continue;
-        }
-        self::blockDelete($blockName, array('id' => $deleteBlock['id']));
-      }
     }
 
     return $blocks;
   }
 
   /**
-   * Delete block
+   * Delete block.
    *
    * @param string $blockName
    *   Block name.
@@ -406,7 +384,6 @@ class CRM_Core_BAO_Block {
    *   Associates array.
    *
    * @return void
-   * @static
    */
   public static function blockDelete($blockName, $params) {
     $name = ucfirst($blockName);
@@ -421,9 +398,8 @@ class CRM_Core_BAO_Block {
     $block = new $baoString();
 
     $block->copyValues($params);
-    /*
-     * CRM-11006 add call to pre and post hook for delete action
-     */
+
+    // CRM-11006 add call to pre and post hook for delete action
     CRM_Utils_Hook::pre('delete', $name, $block->id, CRM_Core_DAO::$_nullArray);
     $block->delete();
     CRM_Utils_Hook::post('delete', $name, $block->id, $block);
@@ -447,7 +423,6 @@ class CRM_Core_BAO_Block {
    * @param $class
    *
    * @throws API_Exception
-   * @static
    */
   public static function handlePrimary(&$params, $class) {
     $table = CRM_Core_DAO_AllCoreTables::getTableForClass($class);
@@ -514,7 +489,7 @@ class CRM_Core_BAO_Block {
   }
 
   /**
-   * Sort location array so primary element is first
+   * Sort location array so primary element is first.
    *
    * @param array $locations
    */
@@ -527,7 +502,7 @@ class CRM_Core_BAO_Block {
    * (sort function for sortPrimaryFirst)
    * @param array $location1
    * @param array $location2
-   * @return number
+   * @return int
    */
   public static function primaryComparison($location1, $location2) {
     $l1 = CRM_Utils_Array::value('is_primary', $location1);
@@ -537,4 +512,5 @@ class CRM_Core_BAO_Block {
     }
     return ($l1 < $l2) ? -1 : 1;
   }
+
 }