From 96167e1b4ea22b40bfda240ba36cfe0e0557f71c Mon Sep 17 00:00:00 2001 From: Davi Alexandre Date: Wed, 1 Aug 2018 16:38:33 -0300 Subject: [PATCH 01/23] PCHR-3681: Remove unnecessary store param in calls to CRM_Utils_Request::retrieve() The main reason for this is that `$this` was being passed as the store param in places that we didn't have a context object (i.e. outside of a instance method). Up to PHP 7.0, this would work without a problem, but starting from PHP 7.1, this now results in an error: https://3v4l.org/QXYLB In a few places, instead of $this, `CRM_Core_DAO::$_nullObject` was being used. This is a risky approach, as it's possible for $_nullObject to not be null (it is just an public static property of the DAO class). This has been removed as well --- contactsummary/contactsummary.php | 6 +++--- hrcareer/hrcareer.php | 4 ++-- hrident/hrident.php | 4 ++-- hrmed/hrmed.php | 4 ++-- hrqual/hrqual.php | 6 +++--- hrstaffdir/hrstaffdir.php | 2 +- hrui/hrui.php | 2 +- hrvisa/hrvisa.php | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/contactsummary/contactsummary.php b/contactsummary/contactsummary.php index 0fe22fd666c..6db6eac90c5 100644 --- a/contactsummary/contactsummary.php +++ b/contactsummary/contactsummary.php @@ -128,9 +128,9 @@ function contactsummary_civicrm_alterSettingsFolders(&$metaDataFolders = NULL) { function contactsummary_civicrm_pageRun($page) { if ($page instanceof CRM_Contact_Page_View_Summary) { CRM_Core_Resources::singleton() - ->addSetting(array( - 'tabSettings' => array('active' => CRM_Utils_Request::retrieve('selectedChild', 'String', $this, FALSE, 'contactsummary')), - )) + ->addSetting([ + 'tabSettings' => ['active' => CRM_Utils_Request::retrieve('selectedChild', 'String') ?: 'contactsummary'], + ]) ->addVars('leaveAndAbsences', [ 'baseURL' => CRM_Core_Resources::singleton()->getUrl('uk.co.compucorp.civicrm.hrleaveandabsences'), 'attachmentToken' => CRM_Core_Page_AJAX_Attachment::createToken() diff --git a/hrcareer/hrcareer.php b/hrcareer/hrcareer.php index b4ccc91b659..6ecb62e219c 100644 --- a/hrcareer/hrcareer.php +++ b/hrcareer/hrcareer.php @@ -149,7 +149,7 @@ function hrcareer_getUFGroupID() { */ function hrcareer_civicrm_buildProfile($name) { if ($name == 'hrcareer_tab') { - $isDialog = ('multiProfileDialog' == CRM_Utils_Request::retrieve('context', 'String', CRM_Core_DAO::$_nullObject)); + $isDialog = ('multiProfileDialog' == CRM_Utils_Request::retrieve('context', 'String')); // To fix validation alert issue $smarty = CRM_Core_Smarty::singleton(); @@ -167,7 +167,7 @@ function hrcareer_civicrm_buildProfile($name) { $config = CRM_Core_Config::singleton(); if ($config->logging && ! $isDialog) { - $contactID = CRM_Utils_Request::retrieve('id', 'Positive', $this); + $contactID = CRM_Utils_Request::retrieve('id', 'Positive'); CRM_Core_Region::instance('profile-form-hrcareer_tab')->add(array( 'template' => 'CRM/common/logButton.tpl', 'instance_id' => CRM_Report_Utils_Report::getInstanceIDForValue('logging/contact/summary'), diff --git a/hrident/hrident.php b/hrident/hrident.php index 64756d8839e..5c193e5a0c3 100644 --- a/hrident/hrident.php +++ b/hrident/hrident.php @@ -140,8 +140,8 @@ function hrident_civicrm_buildProfile($name) { $smarty->assign('urlIsPublic', FALSE); $config = CRM_Core_Config::singleton(); - if ($config->logging && 'multiProfileDialog' !== CRM_Utils_Request::retrieve('context', 'String', CRM_Core_DAO::$_nullObject)) { - $contactID = CRM_Utils_Request::retrieve('id', 'Positive', $this); + if ($config->logging && 'multiProfileDialog' !== CRM_Utils_Request::retrieve('context', 'String')) { + $contactID = CRM_Utils_Request::retrieve('id', 'Positive'); CRM_Core_Region::instance('profile-form-hrident_tab')->add(array( 'template' => 'CRM/common/logButton.tpl', 'instance_id' => CRM_Report_Utils_Report::getInstanceIDForValue('logging/contact/summary'), diff --git a/hrmed/hrmed.php b/hrmed/hrmed.php index d1633938a91..2a8ff68308e 100644 --- a/hrmed/hrmed.php +++ b/hrmed/hrmed.php @@ -141,8 +141,8 @@ function hrmed_civicrm_buildProfile($name) { $smarty->assign('urlIsPublic', FALSE); $config = CRM_Core_Config::singleton(); - if ($config->logging && 'multiProfileDialog' !== CRM_Utils_Request::retrieve('context', 'String', CRM_Core_DAO::$_nullObject)) { - $contactID = CRM_Utils_Request::retrieve('id', 'Positive', $this); + if ($config->logging && 'multiProfileDialog' !== CRM_Utils_Request::retrieve('context', 'String')) { + $contactID = CRM_Utils_Request::retrieve('id', 'Positive'); CRM_Core_Region::instance('profile-form-hrmed_tab')->add(array( 'template' => 'CRM/common/logButton.tpl', 'instance_id' => CRM_Report_Utils_Report::getInstanceIDForValue('logging/contact/summary'), diff --git a/hrqual/hrqual.php b/hrqual/hrqual.php index 7d6d8f84ae3..14ffa1add9c 100644 --- a/hrqual/hrqual.php +++ b/hrqual/hrqual.php @@ -36,7 +36,7 @@ function hrqual_civicrm_buildProfile($name) { $smarty = CRM_Core_Smarty::singleton(); $smarty->assign('urlIsPublic', FALSE); - $action = CRM_Utils_Request::retrieve('multiRecord', 'String', $this); + $action = CRM_Utils_Request::retrieve('multiRecord', 'String'); // display the select box only in add and update mode if (in_array($action, array("add", "update"))) { $regionParams = array( @@ -46,8 +46,8 @@ function hrqual_civicrm_buildProfile($name) { } $config = CRM_Core_Config::singleton(); - if ($config->logging && 'multiProfileDialog' !== CRM_Utils_Request::retrieve('context', 'String', CRM_Core_DAO::$_nullObject)) { - $contactID = CRM_Utils_Request::retrieve('id', 'Positive', $this); + if ($config->logging && 'multiProfileDialog' !== CRM_Utils_Request::retrieve('context', 'String')) { + $contactID = CRM_Utils_Request::retrieve('id', 'Positive'); CRM_Core_Region::instance('profile-form-hrqual_tab')->add(array( 'template' => 'CRM/common/logButton.tpl', 'instance_id' => CRM_Report_Utils_Report::getInstanceIDForValue('logging/contact/summary'), diff --git a/hrstaffdir/hrstaffdir.php b/hrstaffdir/hrstaffdir.php index 82535652f92..57c2e035076 100644 --- a/hrstaffdir/hrstaffdir.php +++ b/hrstaffdir/hrstaffdir.php @@ -50,7 +50,7 @@ function hrstaffdir_civicrm_searchColumns($objectName, &$headers, &$values, &$se if ($objectName == 'profile') { $profileId = hrstaffdir_getUFGroupID(); $session = CRM_Core_Session::singleton(); - $gid = CRM_Utils_Request::retrieve('gid', 'Positive', CRM_Core_DAO::$_nullObject); + $gid = CRM_Utils_Request::retrieve('gid', 'Positive'); // Note: This protocol is not safe when concurrently browsing multiple profile-listings, but // that doesn't work anyway, so we can't implement/test a better protocol. if ($gid) { diff --git a/hrui/hrui.php b/hrui/hrui.php index 76f4a424ec1..b97a73d62f8 100644 --- a/hrui/hrui.php +++ b/hrui/hrui.php @@ -72,7 +72,7 @@ function hrui_civicrm_buildForm($formName, &$form) { } if ($formName == 'CRM_Admin_Form_Extensions') { - $extensionKey= CRM_Utils_Request::retrieve('key', 'String', $this); + $extensionKey= CRM_Utils_Request::retrieve('key', 'String'); if ($extensionKey == 'uk.co.compucorp.civicrm.hrsampledata') { $title = ts("Be Careful"); $message = ts("Installing/Uninstalling this extension will remove all existing data, so make sure to create a backup first !"); diff --git a/hrvisa/hrvisa.php b/hrvisa/hrvisa.php index 711e681bbe5..50f46136989 100644 --- a/hrvisa/hrvisa.php +++ b/hrvisa/hrvisa.php @@ -36,10 +36,10 @@ function hrvisa_civicrm_buildProfile($name) { $smarty = CRM_Core_Smarty::singleton(); $smarty->assign('urlIsPublic', FALSE); - $contactID = CRM_Utils_Request::retrieve('id', 'Positive', $this); + $contactID = CRM_Utils_Request::retrieve('id', 'Positive'); $config = CRM_Core_Config::singleton(); - if ($config->logging && 'multiProfileDialog' !== CRM_Utils_Request::retrieve('context', 'String', CRM_Core_DAO::$_nullObject)) { + if ($config->logging && 'multiProfileDialog' !== CRM_Utils_Request::retrieve('context', 'String')) { CRM_Core_Region::instance('profile-form-hrvisa_tab')->add(array( 'template' => 'CRM/common/logButton.tpl', 'instance_id' => CRM_Report_Utils_Report::getInstanceIDForValue('logging/contact/summary'), From 90c2df094e21745e012925eecdfbf2fdaa934b97 Mon Sep 17 00:00:00 2001 From: Davi Alexandre Date: Tue, 23 Oct 2018 11:52:52 -0300 Subject: [PATCH 02/23] PCHR-4346: Run tests on CiviCRM 5.7 --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 36ce3da4f31..2c64f90bedf 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -49,7 +49,7 @@ pipeline { steps { script { // Build site with CV Buildkit - sh "civibuild create ${params.CIVIHR_BUILDNAME} --type drupal-clean --civi-ver 5.3.1 --url $WEBURL --admin-pass $ADMIN_PASS" + sh "civibuild create ${params.CIVIHR_BUILDNAME} --type drupal-clean --civi-ver 5.7 --url $WEBURL --admin-pass $ADMIN_PASS" // Get target and PR branches name def prBranch = env.CHANGE_BRANCH From 1e26062741a211a7a55b4854c68fd976e19cdc61 Mon Sep 17 00:00:00 2001 From: Davi Alexandre Date: Tue, 23 Oct 2018 15:38:33 -0300 Subject: [PATCH 03/23] PCHR-4346: Fix undefined index error when using the HRJobContract.getFullDetails API This API call is an optimized way to fetch all the information for a Job Contract, which is stored in multiple different database tables. It does that by running a single SQL query, joining all the tables and the necessary fields. In the resultset, in order to differentiate which field belongs to which entity, each field is prefixed with the entity name (examplei: details__). After the data is fetched from the database, the `HRJobContractRevision::normalizeFullDetailsResult()` was used to loop through all the fields in the resultset, detect to which entity they belong to and organize the data in a proper way. Besides the fields returned by the query, the resultset object also contains some internal fields. In the past, all of these fields were prefixed with an underscore, but on https://github.com/civicrm/civicrm-core/pull/12276 a new `resultCopies` field was added, and since it does not start with an underscore, the logic to filter out the internal fields stopped working. To fix that, instead of looping through all of the fields from the resultset, we call the `toArray()` method which will return a list of fields and values containing only those returned by the SQL query. --- .../CRM/Hrjobcontract/BAO/HRJobContractRevision.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/hrjobcontract/CRM/Hrjobcontract/BAO/HRJobContractRevision.php b/hrjobcontract/CRM/Hrjobcontract/BAO/HRJobContractRevision.php index 5882f849763..3d2322d574d 100755 --- a/hrjobcontract/CRM/Hrjobcontract/BAO/HRJobContractRevision.php +++ b/hrjobcontract/CRM/Hrjobcontract/BAO/HRJobContractRevision.php @@ -335,10 +335,9 @@ private static function buildEntityQueryArray($entity, $revision, $query) { protected static function normalizeFullDetailsResult($result) { $normalized = []; - foreach ($result as $key => $value) { - if ($key[0] == '_' || $key == 'N') { continue; } // ignores "internal" fields - - list($entity, $field) = explode('__', $key); + $allFields = $result->toArray(); + foreach ($allFields as $entityField => $value) { + list($entity, $field) = explode('__', $entityField); // This is necessary because some fields are stored in the DB as strings // although the content is actually a JSON. It is done automatically when From 6d079d32e073a744e1d58bd3ef8f7f2d8f3686a3 Mon Sep 17 00:00:00 2001 From: Davi Alexandre Date: Wed, 24 Oct 2018 09:46:53 -0300 Subject: [PATCH 04/23] PCHR-4346: Sync CRM_Hrjobcontract_Dedupe_Merger with Civi 5.7.0 --- .../CRM/Hrjobcontract/Dedupe/Merger.php | 57 ++++--------------- 1 file changed, 12 insertions(+), 45 deletions(-) diff --git a/hrjobcontract/CRM/Hrjobcontract/Dedupe/Merger.php b/hrjobcontract/CRM/Hrjobcontract/Dedupe/Merger.php index e3f85ff3f3c..c13c8eef2c0 100644 --- a/hrjobcontract/CRM/Hrjobcontract/Dedupe/Merger.php +++ b/hrjobcontract/CRM/Hrjobcontract/Dedupe/Merger.php @@ -203,35 +203,23 @@ public static function getActiveRelTables($cid) { /** * Get array tables and fields that reference civicrm_contact.id. * - * This includes core tables, custom group tables, tables added by the merge - * hook and (somewhat randomly) the entity_tag table. + * This function calls the merge hook and only exists to wrap the DAO function to support that deprecated call. + * The entityTypes hook is the recommended way to add tables to this result. * - * Refer to CRM-17454 for information on the danger of querying the information - * schema to derive this. - * - * This function calls the merge hook but the entityTypes hook is the recommended - * way to add tables to this result. + * I thought about adding another hook to alter tableReferences but decided it was unclear if there + * are use cases not covered by entityTables and instead we should wait & see. */ public static function cidRefs() { if (isset(\Civi::$statics[__CLASS__]) && isset(\Civi::$statics[__CLASS__]['contact_references'])) { return \Civi::$statics[__CLASS__]['contact_references']; } - $contactReferences = array(); - $coreReferences = CRM_Core_DAO::getReferencesToTable('civicrm_contact'); - foreach ($coreReferences as $coreReference) { - if (!is_a($coreReference, 'CRM_Core_Reference_Dynamic')) { - $contactReferences[$coreReference->getReferenceTable()][] = $coreReference->getReferenceKey(); - } - } - self::addCustomTablesExtendingContactsToCidRefs($contactReferences); - // FixME for time being adding below line statically as no Foreign key constraint defined for table 'civicrm_entity_tag' - $contactReferences['civicrm_entity_tag'][] = 'entity_id'; + $contactReferences = $coreReferences = CRM_Core_DAO::getReferencesToContactTable(); - // Allow hook_civicrm_merge() to adjust $cidRefs. - // Note that if entities are registered using the entityTypes hook there - // is no need to use this hook. CRM_Utils_Hook::merge('cidRefs', $contactReferences); + if ($contactReferences !== $coreReferences) { + Civi::log()->warning("Deprecated hook ::merge in context of 'cidRefs. Use entityTypes instead.", array('civi.tag' => 'deprecated')); + } \Civi::$statics[__CLASS__]['contact_references'] = $contactReferences; return \Civi::$statics[__CLASS__]['contact_references']; } @@ -486,7 +474,8 @@ public static function moveContactBelongings($mainId, $otherId, $tables = FALSE, // getting all custom tables $customTables = array(); if ($customTableToCopyFrom !== NULL) { - self::addCustomTablesExtendingContactsToCidRefs($customTables); + // @todo this duplicates cidRefs? + CRM_Core_DAO::appendCustomTablesExtendingContacts($customTables); $customTables = array_keys($customTables); } @@ -1457,7 +1446,6 @@ public static function getRowsElementsAndInfo($mainId, $otherId, $checkPermissio $otherTree = CRM_Core_BAO_CustomGroup::getTree($main['contact_type'], NULL, $otherId, -1, CRM_Utils_Array::value('contact_sub_type', $other), NULL, TRUE, NULL, TRUE, $checkPermissions ); - CRM_Core_DAO::freeResult(); foreach ($otherTree as $gid => $group) { $foundField = FALSE; @@ -2018,26 +2006,6 @@ public static function addMembershipToRealtedContacts($contactID) { } } - /** - * Add custom tables that extend contacts to the list of contact references. - * - * CRM_Core_BAO_CustomGroup::getAllCustomGroupsByBaseEntity seems like a safe-ish - * function to be sure all are retrieved & we don't miss subtypes or inactive or multiples - * - the down side is it is not cached. - * - * Further changes should be include tests in the CRM_Core_MergerTest class - * to ensure that disabled, subtype, multiple etc groups are still captured. - * - * @param array $cidRefs - */ - public static function addCustomTablesExtendingContactsToCidRefs(&$cidRefs) { - $customValueTables = CRM_Core_BAO_CustomGroup::getAllCustomGroupsByBaseEntity('Contact'); - $customValueTables->find(); - while ($customValueTables->fetch()) { - $cidRefs[$customValueTables->table_name] = array('entity_id'); - } - } - /** * Create activities tracking the merge on affected contacts. * @@ -2078,6 +2046,7 @@ public static function createMergeActivities($mainId, $otherId) { * @param int $rule_group_id * @param int $group_id * @param bool $reloadCacheIfEmpty + * Should the cache be reloaded if empty - this must be false when in a dedupe action! * @param int $batchLimit * @param bool $isSelected * Limit to selected pairs. @@ -2127,7 +2096,7 @@ public static function getDuplicatePairs($rule_group_id, $group_id, $reloadCache */ public static function getMergeCacheKeyString($rule_group_id, $group_id, $criteria = array(), $checkPermissions = TRUE) { $contactType = CRM_Dedupe_BAO_RuleGroup::getContactTypeForRuleGroup($rule_group_id); - $cacheKeyString = "merge {$contactType}"; + $cacheKeyString = "merge_{$contactType}"; $cacheKeyString .= $rule_group_id ? "_{$rule_group_id}" : '_0'; $cacheKeyString .= $group_id ? "_{$group_id}" : '_0'; $cacheKeyString .= !empty($criteria) ? md5(serialize($criteria)) : '_0'; @@ -2420,8 +2389,6 @@ protected static function dedupePair(&$migrationInfo, &$resultStats, &$deletedCo // pair may have been flipped, so make sure we delete using both orders CRM_Core_BAO_PrevNextCache::deletePair($mainId, $otherId, $cacheKeyString, TRUE); } - - CRM_Core_DAO::freeResult(); } } From ebc2f44d13222366fc92b255590d6f8f38a3b18c Mon Sep 17 00:00:00 2001 From: Davi Alexandre Date: Wed, 24 Oct 2018 10:00:58 -0300 Subject: [PATCH 05/23] PCHR-4346: Sync templates/CRM/Hrjobcontract/Form/Merge.tpl with Civi 5.7.0 --- hrjobcontract/templates/CRM/Hrjobcontract/Form/Merge.tpl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hrjobcontract/templates/CRM/Hrjobcontract/Form/Merge.tpl b/hrjobcontract/templates/CRM/Hrjobcontract/Form/Merge.tpl index 022e555f687..510c9745d90 100644 --- a/hrjobcontract/templates/CRM/Hrjobcontract/Form/Merge.tpl +++ b/hrjobcontract/templates/CRM/Hrjobcontract/Form/Merge.tpl @@ -67,9 +67,9 @@