X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FCore%2FBAO%2FBlock.php;h=12c30e1ef74365948ea2e10764b89429a27a9ea8;hb=8ded2b4dfdf2bf072fa1f555afe09605d9c8b99f;hp=e477c5291514003307e3d1afeb26f13c373b4939;hpb=11df99209d13885aaf45a5c94612bdc65eb490ff;p=civicrm-core.git diff --git a/CRM/Core/BAO/Block.php b/CRM/Core/BAO/Block.php index e477c52915..12c30e1ef7 100644 --- a/CRM/Core/BAO/Block.php +++ b/CRM/Core/BAO/Block.php @@ -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,32 +38,33 @@ 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'), 'phone' => array('phone'), 'im' => array('name'), - 'openid' => array('openid') + 'openid' => array('openid'), ); /** * Given the list of params in the params array, fetch the object * and store the values in the values array * - * @param string $blockName name of the above object - * @param array $params input parameters to find object + * @param string $blockName + * Name of the above object. + * @param array $params + * Input parameters to find object. * - * @return array of $block objects. - * @access public - * @static + * @return array + * Array of $block objects. */ - static function &getValues($blockName, $params) { + public static function &getValues($blockName, $params) { if (empty($params)) { return NULL; } $BAOString = 'CRM_Core_BAO_' . $blockName; - $block = new $BAOString( ); + $block = new $BAOString(); $blocks = array(); if (!isset($params['entity_table'])) { @@ -82,9 +83,9 @@ class CRM_Core_BAO_Block { $count = 1; foreach ($blockIds as $blockId) { - $block = new $BAOString( ); - $block->id = $blockId['id']; - $getBlocks = self::retrieveBlock($block, $blockName); + $block = new $BAOString(); + $block->id = $blockId['id']; + $getBlocks = self::retrieveBlock($block, $blockName); $blocks[$count++] = array_pop($getBlocks); } } @@ -96,14 +97,15 @@ class CRM_Core_BAO_Block { * Given the list of params in the params array, fetch the object * and store the values in the values array * - * @param Object $block typically a Phone|Email|IM|OpenID object - * @param string $blockName name of the above object + * @param Object $block + * Typically a Phone|Email|IM|OpenID object. + * @param string $blockName + * Name of the above object. * - * @return array of $block objects. - * @access public - * @static + * @return array + * Array of $block objects. */ - static function retrieveBlock(&$block, $blockName) { + public static function retrieveBlock(&$block, $blockName) { // we first get the primary location due to the order by clause $block->orderBy('is_primary desc, id'); $block->find(); @@ -124,16 +126,17 @@ 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 + * @param array $blockFields + * Array of fields that are of interest for this object. + * @param array $params + * Associated array of submitted fields. * - * @return boolean true if the block has data, otherwise false - * @access public - * @static + * @return bool + * true if the block has data, otherwise false */ - static function dataExists($blockFields, &$params) { + public static function dataExists($blockFields, &$params) { foreach ($blockFields as $field) { if (CRM_Utils_System::isNull(CRM_Utils_Array::value($field, $params))) { return FALSE; @@ -143,16 +146,17 @@ 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 + * @param string $blockName + * Bloack name. + * @param array $params + * Associated array of submitted fields. * - * @return boolean true if the block exits, otherwise false - * @access public - * @static + * @return bool + * true if the block exits, otherwise false */ - static function blockExists($blockName, &$params) { + public static function blockExists($blockName, &$params) { // return if no data present if (empty($params[$blockName]) || !is_array($params[$blockName])) { return FALSE; @@ -162,20 +166,21 @@ class CRM_Core_BAO_Block { } /** - * Get all block ids for a contact + * Get all block ids for a contact. * - * @param string $blockName block name - * @param int $contactId contact id + * @param string $blockName + * Block name. + * @param int $contactId + * Contact id. * * @param null $entityElements * @param bool $updateBlankLocInfo * - * @return array $contactBlockIds formatted array of block ids + * @return array + * formatted array of block ids * - * @access public - * @static */ - static function getBlockIds($blockName, $contactId = NULL, $entityElements = NULL, $updateBlankLocInfo = FALSE) { + public static function getBlockIds($blockName, $contactId = NULL, $entityElements = NULL, $updateBlankLocInfo = FALSE) { $allBlocks = array(); $name = ucfirst($blockName); @@ -194,37 +199,42 @@ class CRM_Core_BAO_Block { // e.g $bao = new $baoString; // $bao->getAllBlocks() $baoFunction = 'all' . $name . 's'; - $allBlocks = $baoString::$baoFunction( $contactId, $updateBlankLocInfo ); + $allBlocks = $baoString::$baoFunction($contactId, $updateBlankLocInfo); } elseif (!empty($entityElements) && $blockName != 'openid') { $baoFunction = 'allEntity' . $name . 's'; - $allBlocks = $baoString::$baoFunction( $entityElements ); + $allBlocks = $baoString::$baoFunction($entityElements); } return $allBlocks; } /** - * Takes an associative array and creates a block + * Takes an associative array and creates a block. * - * @param string $blockName block name - * @param array $params (reference ) an assoc array of name/value pairs + * @param string $blockName + * Block name. + * @param array $params + * (reference ) an assoc array of name/value pairs. * @param null $entity * @param int $contactId * - * @return object CRM_Core_BAO_Block object on success, null otherwise - * @access public - * @static + * @return object + * CRM_Core_BAO_Block object on success, null otherwise */ - static function create($blockName, &$params, $entity = NULL, $contactId = NULL) { + 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( @@ -236,165 +246,146 @@ 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; - $block = new $baoString( ); + // 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 - * @param int $params associates array + * @param string $blockName + * Block name. + * @param int $params + * Associates array. * * @return void - * @static */ - static function blockDelete($blockName, $params) { + public static function blockDelete($blockName, $params) { $name = ucfirst($blockName); if ($blockName == 'im') { $name = 'IM'; @@ -404,12 +395,11 @@ class CRM_Core_BAO_Block { } $baoString = 'CRM_Core_DAO_' . $name; - $block = new $baoString( ); + $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); @@ -433,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); @@ -460,7 +449,7 @@ class CRM_Core_BAO_Block { $sql = "UPDATE $table SET is_primary = 0 WHERE contact_id = %1"; $sqlParams = array(1 => array($contactId, 'Integer')); // we don't want to create unecessary entries in the log_ tables so exclude the one we are working on - if(!empty($params['id'])){ + if (!empty($params['id'])) { $sql .= " AND id <> %2"; $sqlParams[2] = array($params['id'], 'Integer'); } @@ -483,7 +472,7 @@ class CRM_Core_BAO_Block { * is_primary to 1 * CRM-10451 */ - if ( $existingEntities->N == 1 && $existingEntities->id == CRM_Utils_Array::value( 'id', $params ) ) { + if ($existingEntities->N == 1 && $existingEntities->id == CRM_Utils_Array::value('id', $params)) { $params['is_primary'] = 1; return; } @@ -500,23 +489,22 @@ class CRM_Core_BAO_Block { } /** - * Sort location array so primary element is first + * Sort location array so primary element is first. * * @param array $locations - * */ - static function sortPrimaryFirst(&$locations){ + public static function sortPrimaryFirst(&$locations) { uasort($locations, 'self::primaryComparison'); } -/** - * compare 2 locations to see which should go first based on is_primary - * (sort function for sortPrimaryFirst) - * @param array $location1 - * @param array $location2 - * @return number - */ - static function primaryComparison($location1, $location2){ + /** + * compare 2 locations to see which should go first based on is_primary + * (sort function for sortPrimaryFirst) + * @param array $location1 + * @param array $location2 + * @return int + */ + public static function primaryComparison($location1, $location2) { $l1 = CRM_Utils_Array::value('is_primary', $location1); $l2 = CRM_Utils_Array::value('is_primary', $location2); if ($l1 == $l2) { @@ -524,5 +512,5 @@ class CRM_Core_BAO_Block { } return ($l1 < $l2) ? -1 : 1; } -} +}