diff --git a/Jenkinsfile b/Jenkinsfile index 36ce3da4f31..efb0e72ffb7 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.12.0 --url $WEBURL --admin-pass $ADMIN_PASS" // Get target and PR branches name def prBranch = env.CHANGE_BRANCH diff --git a/com.civicrm.hrjobroles/hrjobroles.php b/com.civicrm.hrjobroles/hrjobroles.php index 6bdd456a055..ca090bc0626 100644 --- a/com.civicrm.hrjobroles/hrjobroles.php +++ b/com.civicrm.hrjobroles/hrjobroles.php @@ -125,6 +125,7 @@ function hrjobroles_civicrm_tabset($tabsetName, &$tabs, $context) { $tabs[] = array( 'id' => 'hrjobroles', 'url' => $url, 'title' => 'Job Roles', + 'icon' => 'crm-i fa-list-alt', 'weight' => -180, ); } diff --git a/contactsummary/contactsummary.php b/contactsummary/contactsummary.php index 0fe22fd666c..712783e5119 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() @@ -157,6 +157,7 @@ function contactsummary_civicrm_tabset($tabsetName, &$tabs, $context) { 'id' => 'contactsummary', 'url' => CRM_Utils_System::url('civicrm/contact-summary'), 'title' => ts('Contact Summary'), + 'icon' => 'crm-i fa-user', 'weight' => -200, ); } diff --git a/hrbank/hrbank.php b/hrbank/hrbank.php index 502f0583b39..23cf41c8145 100644 --- a/hrbank/hrbank.php +++ b/hrbank/hrbank.php @@ -104,3 +104,22 @@ function hrbank_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { function hrbank_civicrm_managed(&$entities) { return _hrbank_civix_civicrm_managed($entities); } + +/** + * Implementation of hook_civicrm_tabset + * + * @param string $tabsetName + * @param array $tabs + * @param mixed $context + */ +function hrbank_civicrm_tabset($tabsetName, &$tabs, $context) { + if ($tabsetName != 'civicrm/contact/view') { + return; + } + + foreach ($tabs as $i => $tab) { + if ($tab['title'] == 'Bank Details') { + $tabs[$i]['icon'] = 'crm-i fa-bank'; + } + } +} diff --git a/hrcareer/hrcareer.php b/hrcareer/hrcareer.php index b4ccc91b659..4e91a13f41e 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'), @@ -192,3 +192,22 @@ function hrcareer_civicrm_pageRun($page) { ->addScriptFile('org.civicrm.hrcareer', 'js/dist/hrcareer.min.js', 1010); } } + +/** + * Implementation of hook_civicrm_tabset + * + * @param string $tabsetName + * @param array $tabs + * @param mixed $context + */ +function hrcareer_civicrm_tabset($tabsetName, &$tabs, $context) { + if ($tabsetName != 'civicrm/contact/view') { + return; + } + + foreach ($tabs as $i => $tab) { + if ($tab['title'] == 'Career History') { + $tabs[$i]['icon'] = 'crm-i fa-history'; + } + } +} 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/hrjobcontract/CRM/Export/BAO/Export.php b/hrjobcontract/CRM/Export/BAO/Export.php index 2ed08db6325..856babfc3fa 100644 --- a/hrjobcontract/CRM/Export/BAO/Export.php +++ b/hrjobcontract/CRM/Export/BAO/Export.php @@ -3,7 +3,7 @@ +--------------------------------------------------------------------+ | CiviCRM version 5 | +--------------------------------------------------------------------+ - | Copyright CiviCRM LLC (c) 2004-2018 | + | Copyright CiviCRM LLC (c) 2004-2019 | +--------------------------------------------------------------------+ | This file is a part of CiviCRM. | | | @@ -28,7 +28,7 @@ /** * * @package CRM - * @copyright CiviCRM LLC (c) 2004-2018 + * @copyright CiviCRM LLC (c) 2004-2019 */ /** @@ -41,50 +41,6 @@ class CRM_Export_BAO_Export { // CRM-7675 const EXPORT_ROW_COUNT = 100000; - /** - * Get Querymode based on ExportMode - * - * @param int $exportMode - * Export mode. - * - * @return string $Querymode - * Query Mode - */ - public static function getQueryMode($exportMode) { - $queryMode = CRM_Contact_BAO_Query::MODE_CONTACTS; - - switch ($exportMode) { - case CRM_Export_Form_Select::CONTRIBUTE_EXPORT: - $queryMode = CRM_Contact_BAO_Query::MODE_CONTRIBUTE; - break; - - case CRM_Export_Form_Select::EVENT_EXPORT: - $queryMode = CRM_Contact_BAO_Query::MODE_EVENT; - break; - - case CRM_Export_Form_Select::MEMBER_EXPORT: - $queryMode = CRM_Contact_BAO_Query::MODE_MEMBER; - break; - - case CRM_Export_Form_Select::PLEDGE_EXPORT: - $queryMode = CRM_Contact_BAO_Query::MODE_PLEDGE; - break; - - case CRM_Export_Form_Select::CASE_EXPORT: - $queryMode = CRM_Contact_BAO_Query::MODE_CASE; - break; - - case CRM_Export_Form_Select::GRANT_EXPORT: - $queryMode = CRM_Contact_BAO_Query::MODE_GRANT; - break; - - case CRM_Export_Form_Select::ACTIVITY_EXPORT: - $queryMode = CRM_Contact_BAO_Query::MODE_ACTIVITY; - break; - } - return $queryMode; - } - /** * Get default return property for export based on mode * @@ -157,10 +113,8 @@ public static function exportComponent($exportMode) { /** * Get Query Group By Clause - * @param int $exportMode + * @param \CRM_Export_BAO_ExportProcessor $processor * Export Mode - * @param string $queryMode - * Query Mode * @param array $returnProperties * Return Properties * @param object $query @@ -169,8 +123,10 @@ public static function exportComponent($exportMode) { * @return string $groupBy * Group By Clause */ - public static function getGroupBy($exportMode, $queryMode, $returnProperties, $query) { - $groupBy = ''; + public static function getGroupBy($processor, $returnProperties, $query) { + $groupBy = NULL; + $exportMode = $processor->getExportMode(); + $queryMode = $processor->getQueryMode(); // @custom HRJobContract extension override by PCHR-1409. // We don't want to group Contacts by their ID as it doesn't allow // to export Job Contracts and their revisions. So the block below @@ -188,7 +144,7 @@ public static function getGroupBy($exportMode, $queryMode, $returnProperties, $q $groupBy = 'civicrm_contribution.id'; if (CRM_Contribute_BAO_Query::isSoftCreditOptionEnabled()) { // especial group by when soft credit columns are included - $groupBy = array('contribution_search_scredit_combined.id', 'contribution_search_scredit_combined.scredit_id'); + $groupBy = ['contribution_search_scredit_combined.id', 'contribution_search_scredit_combined.scredit_id']; } break; @@ -211,61 +167,7 @@ public static function getGroupBy($exportMode, $queryMode, $returnProperties, $q $groupBy = array('contact_a.id', 'hrjobcontract.id'); } - if (!empty($groupBy)) { - if (!Civi::settings()->get('searchPrimaryDetailsOnly')) { - CRM_Core_DAO::disableFullGroupByMode(); - } - $groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($query->_select, $groupBy); - } - - return $groupBy; - } - - /** - * Define extra properties for the export based on query mode - * - * @param string $queryMode - * Query Mode - * @return array $extraProperties - * Extra Properties - */ - public static function defineExtraProperties($queryMode) { - switch ($queryMode) { - case CRM_Contact_BAO_Query::MODE_EVENT: - $paymentFields = TRUE; - $paymentTableId = 'participant_id'; - $extraReturnProperties = array(); - break; - - case CRM_Contact_BAO_Query::MODE_MEMBER: - $paymentFields = TRUE; - $paymentTableId = 'membership_id'; - $extraReturnProperties = array(); - break; - - case CRM_Contact_BAO_Query::MODE_PLEDGE: - $extraReturnProperties = CRM_Pledge_BAO_Query::extraReturnProperties($queryMode); - $paymentFields = TRUE; - $paymentTableId = 'pledge_payment_id'; - break; - - case CRM_Contact_BAO_Query::MODE_CASE: - $extraReturnProperties = CRM_Case_BAO_Query::extraReturnProperties($queryMode); - $paymentFields = FALSE; - $paymentTableId = ''; - break; - - default: - $paymentFields = FALSE; - $paymentTableId = ''; - $extraReturnProperties = array(); - } - $extraProperties = array( - 'paymentFields' => $paymentFields, - 'paymentTableId' => $paymentTableId, - 'extraReturnProperties' => $extraReturnProperties, - ); - return $extraProperties; + return $groupBy ? ' GROUP BY ' . implode(', ', (array) $groupBy) : ''; } /** @@ -318,49 +220,18 @@ public static function exportComponents( $queryOperator = 'AND' ) { - $returnProperties = array(); - $paymentFields = $selectedPaymentFields = FALSE; - - $phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id'); - // Warning - this imProviders var is used in a somewhat fragile way - don't rename it - // without manually testing the export of IM provider still works. - $imProviders = CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'); - $contactRelationshipTypes = CRM_Contact_BAO_Relationship::getContactRelationshipType( - NULL, - NULL, - NULL, - NULL, - TRUE, - 'name', - FALSE + $isPostalOnly = ( + isset($exportParams['postal_mailing_export']['postal_mailing_export']) && + $exportParams['postal_mailing_export']['postal_mailing_export'] == 1 ); - $queryMode = self::getQueryMode($exportMode); + $processor = new CRM_Export_BAO_ExportProcessor($exportMode, $fields, $queryOperator, $mergeSameHousehold, $isPostalOnly); + $returnProperties = array(); if ($fields) { - //construct return properties - $locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id'); - $locationTypeFields = array( - 'street_address', - 'supplemental_address_1', - 'supplemental_address_2', - 'supplemental_address_3', - 'city', - 'postal_code', - 'postal_code_suffix', - 'geo_code_1', - 'geo_code_2', - 'state_province', - 'country', - 'phone', - 'email', - 'im', - ); - foreach ($fields as $key => $value) { - $relationField = NULL; - $relationshipTypes = $fieldName = CRM_Utils_Array::value(1, $value); - if (!$fieldName) { + $fieldName = CRM_Utils_Array::value(1, $value); + if (!$fieldName || $processor->isHouseholdMergeRelationshipTypeKey($fieldName)) { continue; } @@ -368,63 +239,19 @@ public static function exportComponents( $returnProperties['contact_id'] = 1; } - if (array_key_exists($relationshipTypes, $contactRelationshipTypes) && (!empty($value[2]) || !empty($value[4]))) { - $relPhoneTypeId = $relIMProviderId = NULL; - if (!empty($value[2])) { - $relationField = CRM_Utils_Array::value(2, $value); - if (trim(CRM_Utils_Array::value(3, $value))) { - $relLocTypeId = CRM_Utils_Array::value(3, $value); - } - else { - $relLocTypeId = 'Primary'; - } - - if ($relationField == 'phone') { - $relPhoneTypeId = CRM_Utils_Array::value(4, $value); - } - elseif ($relationField == 'im') { - $relIMProviderId = CRM_Utils_Array::value(4, $value); - } - } - elseif (!empty($value[4])) { - $relationField = CRM_Utils_Array::value(4, $value); - $relLocTypeId = CRM_Utils_Array::value(5, $value); - if ($relationField == 'phone') { - $relPhoneTypeId = CRM_Utils_Array::value(6, $value); - } - elseif ($relationField == 'im') { - $relIMProviderId = CRM_Utils_Array::value(6, $value); - } - } - if (in_array($relationField, $locationTypeFields) && is_numeric($relLocTypeId)) { - if ($relPhoneTypeId) { - $returnProperties[$relationshipTypes]['location'][$locationTypes[$relLocTypeId]]['phone-' . $relPhoneTypeId] = 1; - } - elseif ($relIMProviderId) { - $returnProperties[$relationshipTypes]['location'][$locationTypes[$relLocTypeId]]['im-' . $relIMProviderId] = 1; - } - else { - $returnProperties[$relationshipTypes]['location'][$locationTypes[$relLocTypeId]][$relationField] = 1; - } - } - else { - $returnProperties[$relationshipTypes][$relationField] = 1; - } - } - - if ($relationField) { - // already handled. + if ($processor->isRelationshipTypeKey($fieldName) && (!empty($value[2]) || !empty($value[4]))) { + $returnProperties[$fieldName] = $processor->setRelationshipReturnProperties($value, $fieldName); } elseif (is_numeric(CRM_Utils_Array::value(2, $value))) { - $locTypeId = $value[2]; + $locationName = CRM_Core_PseudoConstant::getName('CRM_Core_BAO_Address', 'location_type_id', $value[2]); if ($fieldName == 'phone') { - $returnProperties['location'][$locationTypes[$locTypeId]]['phone-' . CRM_Utils_Array::value(3, $value)] = 1; + $returnProperties['location'][$locationName]['phone-' . CRM_Utils_Array::value(3, $value)] = 1; } elseif ($fieldName == 'im') { - $returnProperties['location'][$locationTypes[$locTypeId]]['im-' . CRM_Utils_Array::value(3, $value)] = 1; + $returnProperties['location'][$locationName]['im-' . CRM_Utils_Array::value(3, $value)] = 1; } else { - $returnProperties['location'][$locationTypes[$locTypeId]][$fieldName] = 1; + $returnProperties['location'][$locationName][$fieldName] = 1; } } else { @@ -433,14 +260,6 @@ public static function exportComponents( if ($fieldName == 'event_id') { $returnProperties['event_id'] = 1; } - elseif ( - $exportMode == CRM_Export_Form_Select::EVENT_EXPORT && - array_key_exists($fieldName, self::componentPaymentFields()) - ) { - $selectedPaymentFields = TRUE; - $paymentTableId = 'participant_id'; - $returnProperties[$fieldName] = 1; - } else { $returnProperties[$fieldName] = 1; } @@ -452,56 +271,11 @@ public static function exportComponents( } } else { - $primary = TRUE; - $fields = CRM_Contact_BAO_Contact::exportableFields('All', TRUE, TRUE); - foreach ($fields as $key => $var) { - if ($key && (substr($key, 0, 6) != 'custom')) { - //for CRM=952 - $returnProperties[$key] = 1; - } - } - - if ($primary) { - $returnProperties['location_type'] = 1; - $returnProperties['im_provider'] = 1; - $returnProperties['phone_type_id'] = 1; - $returnProperties['provider_id'] = 1; - $returnProperties['current_employer'] = 1; - } - - $extraProperties = self::defineExtraProperties($queryMode); - $paymentFields = $extraProperties['paymentFields']; - $extraReturnProperties = $extraProperties['extraReturnProperties']; - $paymentTableId = $extraProperties['paymentTableId']; - - if ($queryMode != CRM_Contact_BAO_Query::MODE_CONTACTS) { - $componentReturnProperties = CRM_Contact_BAO_Query::defaultReturnProperties($queryMode); - if ($queryMode == CRM_Contact_BAO_Query::MODE_CONTRIBUTE) { - // soft credit columns are not automatically populated, because contribution search doesn't require them by default - $componentReturnProperties = array_merge( - $componentReturnProperties, - CRM_Contribute_BAO_Query::softCreditReturnProperties(TRUE)); - } - $returnProperties = array_merge($returnProperties, $componentReturnProperties); - - if (!empty($extraReturnProperties)) { - $returnProperties = array_merge($returnProperties, $extraReturnProperties); - } - - // unset non exportable fields for components - $nonExpoFields = array( - 'groups', - 'tags', - 'notes', - 'contribution_status_id', - 'pledge_status_id', - 'pledge_payment_status_id', - ); - foreach ($nonExpoFields as $value) { - unset($returnProperties[$value]); - } - } + $returnProperties = $processor->getDefaultReturnProperties(); } + // @todo - we are working towards this being entirely a property of the processor + $processor->setReturnProperties($returnProperties); + $paymentTableId = $processor->getPaymentTableID(); if ($mergeSameAddress) { //make sure the addressee fields are selected @@ -564,113 +338,17 @@ public static function exportComponents( CRM_Contact_BAO_ProximityQuery::fixInputParams($params); } - $query = new CRM_Contact_BAO_Query($params, $returnProperties, NULL, - FALSE, FALSE, $queryMode, - FALSE, TRUE, TRUE, NULL, $queryOperator - ); - - //sort by state - //CRM-15301 - $query->_sort = $order; - list($select, $from, $where, $having) = $query->query(); + list($query, $select, $from, $where, $having) = $processor->runQuery($params, $order, $returnProperties); if ($mergeSameHousehold == 1) { if (empty($returnProperties['id'])) { $returnProperties['id'] = 1; } - //also merge Head of Household - $relationKeyMOH = CRM_Utils_Array::key('Household Member of', $contactRelationshipTypes); - $relationKeyHOH = CRM_Utils_Array::key('Head of Household for', $contactRelationshipTypes); - - foreach ($returnProperties as $key => $value) { - if (!array_key_exists($key, $contactRelationshipTypes)) { - $returnProperties[$relationKeyMOH][$key] = $value; - $returnProperties[$relationKeyHOH][$key] = $value; - } - } - - unset($returnProperties[$relationKeyMOH]['location_type']); - unset($returnProperties[$relationKeyMOH]['im_provider']); - unset($returnProperties[$relationKeyHOH]['location_type']); - unset($returnProperties[$relationKeyHOH]['im_provider']); + $processor->setHouseholdMergeReturnProperties(array_diff_key($returnProperties, array_fill_keys(['location_type', 'im_provider'], 1))); } - $allRelContactArray = $relationQuery = array(); - - foreach ($contactRelationshipTypes as $rel => $dnt) { - if ($relationReturnProperties = CRM_Utils_Array::value($rel, $returnProperties)) { - $allRelContactArray[$rel] = array(); - // build Query for each relationship - $relationQuery[$rel] = new CRM_Contact_BAO_Query(NULL, $relationReturnProperties, - NULL, FALSE, FALSE, $queryMode - ); - list($relationSelect, $relationFrom, $relationWhere, $relationHaving) = $relationQuery[$rel]->query(); - - list($id, $direction) = explode('_', $rel, 2); - // identify the relationship direction - $contactA = 'contact_id_a'; - $contactB = 'contact_id_b'; - if ($direction == 'b_a') { - $contactA = 'contact_id_b'; - $contactB = 'contact_id_a'; - } - if ($exportMode == CRM_Export_Form_Select::CONTACT_EXPORT) { - $relIDs = $ids; - } - elseif ($exportMode == CRM_Export_Form_Select::ACTIVITY_EXPORT) { - $sourceID = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_ActivityContact', 'record_type_id', 'Activity Source'); - $dao = CRM_Core_DAO::executeQuery(" - SELECT contact_id FROM civicrm_activity_contact - WHERE activity_id IN ( " . implode(',', $ids) . ") AND - record_type_id = {$sourceID} - "); - - while ($dao->fetch()) { - $relIDs[] = $dao->contact_id; - } - } - else { - $component = self::exportComponent($exportMode); - - if ($exportMode == CRM_Export_Form_Select::CASE_EXPORT) { - $relIDs = CRM_Case_BAO_Case::retrieveContactIdsByCaseId($ids); - } - else { - $relIDs = CRM_Core_DAO::getContactIDsFromComponent($ids, $component); - } - } - - $relationshipJoin = $relationshipClause = ''; - if (!$selectAll && $componentTable) { - $relationshipJoin = " INNER JOIN {$componentTable} ctTable ON ctTable.contact_id = {$contactA}"; - } - elseif (!empty($relIDs)) { - $relID = implode(',', $relIDs); - $relationshipClause = " AND crel.{$contactA} IN ( {$relID} )"; - } - - $relationFrom = " {$relationFrom} - INNER JOIN civicrm_relationship crel ON crel.{$contactB} = contact_a.id AND crel.relationship_type_id = {$id} - {$relationshipJoin} "; - - //check for active relationship status only - $today = date('Ymd'); - $relationActive = " AND (crel.is_active = 1 AND ( crel.end_date is NULL OR crel.end_date >= {$today} ) )"; - $relationWhere = " WHERE contact_a.is_deleted = 0 {$relationshipClause} {$relationActive}"; - $relationGroupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($relationQuery[$rel]->_select, "crel.{$contactA}"); - $relationSelect = "{$relationSelect}, {$contactA} as refContact "; - $relationQueryString = "$relationSelect $relationFrom $relationWhere $relationHaving $relationGroupBy"; - - $allRelContactDAO = CRM_Core_DAO::executeQuery($relationQueryString); - while ($allRelContactDAO->fetch()) { - //FIX Me: Migrate this to table rather than array - // build the array of all related contacts - $allRelContactArray[$rel][$allRelContactDAO->refContact] = clone($allRelContactDAO); - } - $allRelContactDAO->free(); - } - } + self::buildRelatedContactArray($selectAll, $ids, $processor, $componentTable); // make sure the groups stuff is included only if specifically specified // by the fields param (CRM-1969), else we limit the contacts outputted to only @@ -715,7 +393,7 @@ public static function exportComponents( $queryString = "$select $from $where $having"; - $groupBy = self::getGroupBy($exportMode, $queryMode, $returnProperties, $query); + $groupBy = self::getGroupBy($processor, $returnProperties, $query); $queryString .= $groupBy; @@ -737,31 +415,34 @@ public static function exportComponents( $addPaymentHeader = FALSE; - $paymentDetails = array(); - if ($paymentFields || $selectedPaymentFields) { + list($outputColumns, $metadata) = self::getExportStructureArrays($returnProperties, $processor); + if (!empty($exportParams['merge_same_address']['temp_columns'])) { + // @todo - this is a temp fix - ideally later we don't set stuff only to unset it. + // test exists covering this... + foreach (array_keys($exportParams['merge_same_address']['temp_columns']) as $field) { + $processor->setColumnAsCalculationOnly($field); + } + } + + $paymentDetails = []; + if ($processor->isExportPaymentFields()) { // get payment related in for event and members $paymentDetails = CRM_Contribute_BAO_Contribution::getContributionDetails($exportMode, $ids); //get all payment headers. // If we haven't selected specific payment fields, load in all the // payment headers. - if (!$selectedPaymentFields) { - $paymentHeaders = self::componentPaymentFields(); + if (!$processor->isExportSpecifiedPaymentFields()) { if (!empty($paymentDetails)) { $addPaymentHeader = TRUE; + foreach (array_keys($processor->getPaymentHeaders()) as $paymentField) { + $processor->addOutputSpecification($paymentField); + } } } - // If we have selected specific payment fields, leave the payment headers - // as an empty array; the headers for each selected field will be added - // elsewhere. - else { - $paymentHeaders = array(); - } - $nullContributionDetails = array_fill_keys(array_keys($paymentHeaders), NULL); } $componentDetails = array(); - $setHeader = TRUE; $rowCount = self::EXPORT_ROW_COUNT; $offset = 0; @@ -770,15 +451,16 @@ public static function exportComponents( $count = -1; - // for CRM-3157 purposes - $i18n = CRM_Core_I18n::singleton(); - - list($outputColumns, $headerRows, $sqlColumns, $metadata) = self::getExportStructureArrays($returnProperties, $query, $contactRelationshipTypes, $relationQuery, $selectedPaymentFields); - + $headerRows = $processor->getHeaderRows(); + $sqlColumns = $processor->getSQLColumns(); + $exportTempTable = self::createTempTable($sqlColumns); $limitReached = FALSE; + while (!$limitReached) { $limitQuery = "{$queryString} LIMIT {$offset}, {$rowCount}"; + CRM_Core_DAO::disableFullGroupByMode(); $iterationDAO = CRM_Core_DAO::executeQuery($limitQuery); + CRM_Core_DAO::reenableFullGroupByMode(); // If this is less than our limit by the end of the iteration we do not need to run the query again to // check if some remain. $rowsThisIteration = 0; @@ -786,176 +468,9 @@ public static function exportComponents( while ($iterationDAO->fetch()) { $count++; $rowsThisIteration++; - $row = array(); - $query->convertToPseudoNames($iterationDAO); - - //first loop through output columns so that we return what is required, and in same order. - foreach ($outputColumns as $field => $value) { - - // add im_provider to $dao object - if ($field == 'im_provider' && property_exists($iterationDAO, 'provider_id')) { - $iterationDAO->im_provider = $iterationDAO->provider_id; - } - - //build row values (data) - $fieldValue = NULL; - if (property_exists($iterationDAO, $field)) { - $fieldValue = $iterationDAO->$field; - // to get phone type from phone type id - if ($field == 'phone_type_id' && isset($phoneTypes[$fieldValue])) { - $fieldValue = $phoneTypes[$fieldValue]; - } - elseif ($field == 'provider_id' || $field == 'im_provider') { - $fieldValue = CRM_Utils_Array::value($fieldValue, $imProviders); - } - elseif (strstr($field, 'master_id')) { - $masterAddressId = NULL; - if (isset($iterationDAO->$field)) { - $masterAddressId = $iterationDAO->$field; - } - // get display name of contact that address is shared. - $fieldValue = CRM_Contact_BAO_Contact::getMasterDisplayName($masterAddressId); - } - } - - if ($field == 'id') { - $row[$field] = $iterationDAO->contact_id; - // special case for calculated field - } - elseif ($field == 'source_contact_id') { - $row[$field] = $iterationDAO->contact_id; - } - elseif ($field == 'pledge_balance_amount') { - $row[$field] = $iterationDAO->pledge_amount - $iterationDAO->pledge_total_paid; - // special case for calculated field - } - elseif ($field == 'pledge_next_pay_amount') { - $row[$field] = $iterationDAO->pledge_next_pay_amount + $iterationDAO->pledge_outstanding_amount; - } - elseif (array_key_exists($field, $contactRelationshipTypes)) { - $relDAO = CRM_Utils_Array::value($iterationDAO->contact_id, $allRelContactArray[$field]); - $relationQuery[$field]->convertToPseudoNames($relDAO); - self::fetchRelationshipDetails($relDAO, $value, $field, $row); - } - elseif (isset($fieldValue) && - $fieldValue != '' - ) { - //check for custom data - if ($cfID = CRM_Core_BAO_CustomField::getKeyID($field)) { - $row[$field] = CRM_Core_BAO_CustomField::displayValue($fieldValue, $cfID); - } - - elseif (in_array($field, array( - 'email_greeting', - 'postal_greeting', - 'addressee', - ))) { - //special case for greeting replacement - $fldValue = "{$field}_display"; - $row[$field] = $iterationDAO->$fldValue; - } - else { - //normal fields with a touch of CRM-3157 - switch ($field) { - case 'country': - case 'world_region': - $row[$field] = $i18n->crm_translate($fieldValue, array('context' => 'country')); - break; - - case 'state_province': - $row[$field] = $i18n->crm_translate($fieldValue, array('context' => 'province')); - break; - - case 'gender': - case 'preferred_communication_method': - case 'preferred_mail_format': - case 'communication_style': - $row[$field] = $i18n->crm_translate($fieldValue); - break; - - default: - if (isset($metadata[$field])) { - // No I don't know why we do it this way & whether we could - // make better use of pseudoConstants. - if (!empty($metadata[$field]['context'])) { - $row[$field] = $i18n->crm_translate($fieldValue, $metadata[$field]); - break; - } - if (!empty($metadata[$field]['pseudoconstant'])) { - // This is not our normal syntax for pseudoconstants but I am a bit loath to - // call an external function until sure it is not increasing php processing given this - // may be iterated 100,000 times & we already have the $imProvider var loaded. - // That can be next refactor... - // Yes - definitely feeling hatred for this bit of code - I know you will beat me up over it's awfulness - // but I have to reach a stable point.... - $varName = $metadata[$field]['pseudoconstant']['var']; - $labels = $$varName; - $row[$field] = $labels[$fieldValue]; - break; - } - - } - $row[$field] = $fieldValue; - break; - } - } - } - elseif ($selectedPaymentFields && array_key_exists($field, self::componentPaymentFields())) { - $paymentData = CRM_Utils_Array::value($iterationDAO->$paymentTableId, $paymentDetails); - $payFieldMapper = array( - 'componentPaymentField_total_amount' => 'total_amount', - 'componentPaymentField_contribution_status' => 'contribution_status', - 'componentPaymentField_payment_instrument' => 'pay_instru', - 'componentPaymentField_transaction_id' => 'trxn_id', - 'componentPaymentField_received_date' => 'receive_date', - ); - $row[$field] = CRM_Utils_Array::value($payFieldMapper[$field], $paymentData, ''); - } - else { - // if field is empty or null - $row[$field] = ''; - } - } - - // add payment headers if required - if ($addPaymentHeader && $paymentFields) { - // @todo rather than do this for every single row do it before the loop starts. - // where other header definitions take place. - $headerRows = array_merge($headerRows, $paymentHeaders); - foreach (array_keys($paymentHeaders) as $paymentHdr) { - self::sqlColumnDefn($query, $sqlColumns, $paymentHdr); - } - } - - if ($setHeader) { - $exportTempTable = self::createTempTable($sqlColumns); - } - - //build header only once - $setHeader = FALSE; - - // If specific payment fields have been selected for export, payment - // data will already be in $row. Otherwise, add payment related - // information, if appropriate. - if ($addPaymentHeader) { - if (!$selectedPaymentFields) { - if ($paymentFields) { - $paymentData = CRM_Utils_Array::value($row[$paymentTableId], $paymentDetails); - if (!is_array($paymentData) || empty($paymentData)) { - $paymentData = $nullContributionDetails; - } - $row = array_merge($row, $paymentData); - } - elseif (!empty($paymentDetails)) { - $row = array_merge($row, $nullContributionDetails); - } - } - } - //remove organization name for individuals if it is set for current employer - if (!empty($row['contact_type']) && - $row['contact_type'] == 'Individual' && array_key_exists('organization_name', $row) - ) { - $row['organization_name'] = ''; + $row = $processor->buildRow($query, $iterationDAO, $outputColumns, $metadata, $paymentDetails, $addPaymentHeader, $paymentTableId); + if ($row === FALSE) { + continue; } // add component info @@ -977,36 +492,22 @@ public static function exportComponents( if ($exportTempTable) { self::writeDetailsToTable($exportTempTable, $componentDetails, $sqlColumns); - // if postalMailing option is checked, exclude contacts who are deceased, have - // "Do not mail" privacy setting, or have no street address - if (isset($exportParams['postal_mailing_export']['postal_mailing_export']) && - $exportParams['postal_mailing_export']['postal_mailing_export'] == 1 - ) { - self::postalMailingFormat($exportTempTable, $headerRows, $sqlColumns, $exportMode); - } - // do merge same address and merge same household processing if ($mergeSameAddress) { - self::mergeSameAddress($exportTempTable, $headerRows, $sqlColumns, $exportParams); - } - - // merge the records if they have corresponding households - if ($mergeSameHousehold) { - self::mergeSameHousehold($exportTempTable, $headerRows, $sqlColumns, $relationKeyMOH); - self::mergeSameHousehold($exportTempTable, $headerRows, $sqlColumns, $relationKeyHOH); + self::mergeSameAddress($exportTempTable, $sqlColumns, $exportParams); } // call export hook - CRM_Utils_Hook::export($exportTempTable, $headerRows, $sqlColumns, $exportMode); + CRM_Utils_Hook::export($exportTempTable, $headerRows, $sqlColumns, $exportMode, $componentTable, $ids); // In order to be able to write a unit test against this function we need to suppress // the csv writing. In future hopefully the csv writing & the main processing will be in separate functions. if (empty($exportParams['suppress_csv_for_testing'])) { - self::writeCSVFromTable($exportTempTable, $headerRows, $sqlColumns, $exportMode); + self::writeCSVFromTable($exportTempTable, $headerRows, $sqlColumns, $processor); } else { - // return tableName and sqlColumns in test context - return array($exportTempTable, $sqlColumns); + // return tableName sqlColumns headerRows in test context + return array($exportTempTable, $sqlColumns, $headerRows, $processor); } // delete the export temp table and component table @@ -1021,45 +522,6 @@ public static function exportComponents( } } - /** - * Name of the export file based on mode. - * - * @param string $output - * Type of output. - * @param int $mode - * Export mode. - * - * @return string - * name of the file - */ - public static function getExportFileName($output = 'csv', $mode = CRM_Export_Form_Select::CONTACT_EXPORT) { - switch ($mode) { - case CRM_Export_Form_Select::CONTACT_EXPORT: - return ts('CiviCRM Contact Search'); - - case CRM_Export_Form_Select::CONTRIBUTE_EXPORT: - return ts('CiviCRM Contribution Search'); - - case CRM_Export_Form_Select::MEMBER_EXPORT: - return ts('CiviCRM Member Search'); - - case CRM_Export_Form_Select::EVENT_EXPORT: - return ts('CiviCRM Participant Search'); - - case CRM_Export_Form_Select::PLEDGE_EXPORT: - return ts('CiviCRM Pledge Search'); - - case CRM_Export_Form_Select::CASE_EXPORT: - return ts('CiviCRM Case Search'); - - case CRM_Export_Form_Select::GRANT_EXPORT: - return ts('CiviCRM Grant Search'); - - case CRM_Export_Form_Select::ACTIVITY_EXPORT: - return ts('CiviCRM Activity Search'); - } - } - /** * Handle import error file creation. */ @@ -1146,140 +608,16 @@ public static function exportCustom($customSearchClass, $formValues, $order) { $rows[] = $row; } - CRM_Core_Report_Excel::writeCSVFile(self::getExportFileName(), $header, $rows); + CRM_Core_Report_Excel::writeCSVFile(ts('CiviCRM Contact Search'), $header, $rows); CRM_Utils_System::civiExit(); } - /** - * @param $query - * @param $sqlColumns - * @param $field - */ - public static function sqlColumnDefn($query, &$sqlColumns, $field) { - if (substr($field, -4) == '_a_b' || substr($field, -4) == '_b_a') { - return; - } - - $fieldName = CRM_Utils_String::munge(strtolower($field), '_', 64); - if ($fieldName == 'id') { - $fieldName = 'civicrm_primary_id'; - } - - // early exit for master_id, CRM-12100 - // in the DB it is an ID, but in the export, we retrive the display_name of the master record - // also for current_employer, CRM-16939 - if ($fieldName == 'master_id' || $fieldName == 'current_employer') { - $sqlColumns[$fieldName] = "$fieldName varchar(128)"; - return; - } - - if (substr($fieldName, -11) == 'campaign_id') { - // CRM-14398 - $sqlColumns[$fieldName] = "$fieldName varchar(128)"; - return; - } - - $lookUp = array('prefix_id', 'suffix_id'); - // set the sql columns - if (isset($query->_fields[$field]['type'])) { - switch ($query->_fields[$field]['type']) { - case CRM_Utils_Type::T_INT: - case CRM_Utils_Type::T_BOOLEAN: - if (in_array($field, $lookUp)) { - $sqlColumns[$fieldName] = "$fieldName varchar(255)"; - } - else { - $sqlColumns[$fieldName] = "$fieldName varchar(16)"; - } - break; - - case CRM_Utils_Type::T_STRING: - if (isset($query->_fields[$field]['maxlength'])) { - $sqlColumns[$fieldName] = "$fieldName varchar({$query->_fields[$field]['maxlength']})"; - } - else { - $sqlColumns[$fieldName] = "$fieldName varchar(255)"; - } - break; - - case CRM_Utils_Type::T_TEXT: - case CRM_Utils_Type::T_LONGTEXT: - case CRM_Utils_Type::T_BLOB: - case CRM_Utils_Type::T_MEDIUMBLOB: - $sqlColumns[$fieldName] = "$fieldName longtext"; - break; - - case CRM_Utils_Type::T_FLOAT: - case CRM_Utils_Type::T_ENUM: - case CRM_Utils_Type::T_DATE: - case CRM_Utils_Type::T_TIME: - case CRM_Utils_Type::T_TIMESTAMP: - case CRM_Utils_Type::T_MONEY: - case CRM_Utils_Type::T_EMAIL: - case CRM_Utils_Type::T_URL: - case CRM_Utils_Type::T_CCNUM: - default: - $sqlColumns[$fieldName] = "$fieldName varchar(32)"; - break; - } - } - else { - if (substr($fieldName, -3, 3) == '_id') { - $sqlColumns[$fieldName] = "$fieldName varchar(255)"; - } - elseif (substr($fieldName, -5, 5) == '_note') { - $sqlColumns[$fieldName] = "$fieldName text"; - } - else { - $changeFields = array( - 'groups', - 'tags', - 'notes', - ); - - if (in_array($fieldName, $changeFields)) { - $sqlColumns[$fieldName] = "$fieldName text"; - } - else { - // set the sql columns for custom data - if (isset($query->_fields[$field]['data_type'])) { - - switch ($query->_fields[$field]['data_type']) { - case 'String': - // May be option labels, which could be up to 512 characters - $length = max(512, CRM_Utils_Array::value('text_length', $query->_fields[$field])); - $sqlColumns[$fieldName] = "$fieldName varchar($length)"; - break; - - case 'Country': - case 'StateProvince': - case 'Link': - $sqlColumns[$fieldName] = "$fieldName varchar(255)"; - break; - - case 'Memo': - $sqlColumns[$fieldName] = "$fieldName text"; - break; - - default: - $sqlColumns[$fieldName] = "$fieldName varchar(255)"; - break; - } - } - else { - $sqlColumns[$fieldName] = "$fieldName text"; - } - } - } - } - } - /** * @param string $tableName * @param $details * @param $sqlColumns */ - public static function writeDetailsToTable($tableName, &$details, &$sqlColumns) { + public static function writeDetailsToTable($tableName, $details, $sqlColumns) { if (empty($details)) { return; } @@ -1296,10 +634,10 @@ public static function writeDetailsToTable($tableName, &$details, &$sqlColumns) $sqlClause = array(); - foreach ($details as $dontCare => $row) { + foreach ($details as $row) { $id++; $valueString = array($id); - foreach ($row as $dontCare => $value) { + foreach ($row as $value) { if (empty($value)) { $valueString[] = "''"; } @@ -1326,16 +664,14 @@ public static function writeDetailsToTable($tableName, &$details, &$sqlColumns) * * @return string */ - public static function createTempTable(&$sqlColumns) { + public static function createTempTable($sqlColumns) { //creating a temporary table for the search result that need be exported - $exportTempTable = CRM_Core_DAO::createTempTableName('civicrm_export', TRUE); + $exportTempTable = CRM_Utils_SQL_TempTable::build()->setDurable()->setCategory('export')->setUtf8(); // also create the sql table - $sql = "DROP TABLE IF EXISTS {$exportTempTable}"; - CRM_Core_DAO::executeQuery($sql); + $exportTempTable->drop(); $sql = " -CREATE TABLE {$exportTempTable} ( id int unsigned NOT NULL AUTO_INCREMENT, "; $sql .= implode(",\n", array_values($sqlColumns)); @@ -1358,21 +694,16 @@ public static function createTempTable(&$sqlColumns) { } } - $sql .= " -) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci -"; - - CRM_Core_DAO::executeQuery($sql); - return $exportTempTable; + $exportTempTable->createWithColumns($sql); + return $exportTempTable->getName(); } /** * @param string $tableName - * @param $headerRows * @param $sqlColumns * @param array $exportParams */ - public static function mergeSameAddress($tableName, &$headerRows, &$sqlColumns, $exportParams) { + public static function mergeSameAddress($tableName, &$sqlColumns, $exportParams) { // check if any records are present based on if they have used shared address feature, // and not based on if city / state .. matches. $sql = " @@ -1465,11 +796,12 @@ public static function mergeSameAddress($tableName, &$headerRows, &$sqlColumns, } // unset temporary columns that were added for postal mailing format + // @todo - this part is pretty close to ready to be removed.... if (!empty($exportParams['merge_same_address']['temp_columns'])) { $unsetKeys = array_keys($sqlColumns); foreach ($unsetKeys as $headerKey => $sqlColKey) { if (array_key_exists($sqlColKey, $exportParams['merge_same_address']['temp_columns'])) { - unset($sqlColumns[$sqlColKey], $headerRows[$headerKey]); + unset($sqlColumns[$sqlColKey]); } } } @@ -1648,101 +980,14 @@ public static function _buildMasterCopyArray($sql, $exportParams, $sharedAddress return $merge; } - /** - * Merge household record into the individual record - * if exists - * - * @param string $exportTempTable - * Temporary temp table that stores the records. - * @param array $headerRows - * Array of headers for the export file. - * @param array $sqlColumns - * Array of names of the table columns of the temp table. - * @param string $prefix - * Name of the relationship type that is prefixed to the table columns. - */ - public static function mergeSameHousehold($exportTempTable, &$headerRows, &$sqlColumns, $prefix) { - $prefixColumn = $prefix . '_'; - $allKeys = array_keys($sqlColumns); - $replaced = array(); - $headerRows = array_values($headerRows); - - // name map of the non standard fields in header rows & sql columns - $mappingFields = array( - 'civicrm_primary_id' => 'id', - 'contact_source' => 'source', - 'current_employer_id' => 'employer_id', - 'contact_is_deleted' => 'is_deleted', - 'name' => 'address_name', - 'provider_id' => 'im_service_provider', - 'phone_type_id' => 'phone_type', - ); - - //figure out which columns are to be replaced by which ones - foreach ($sqlColumns as $columnNames => $dontCare) { - if ($rep = CRM_Utils_Array::value($columnNames, $mappingFields)) { - $replaced[$columnNames] = CRM_Utils_String::munge($prefixColumn . $rep, '_', 64); - } - else { - $householdColName = CRM_Utils_String::munge($prefixColumn . $columnNames, '_', 64); - - if (!empty($sqlColumns[$householdColName])) { - $replaced[$columnNames] = $householdColName; - } - } - } - $query = "UPDATE $exportTempTable SET "; - - $clause = array(); - foreach ($replaced as $from => $to) { - $clause[] = "$from = $to "; - unset($sqlColumns[$to]); - if ($key = CRM_Utils_Array::key($to, $allKeys)) { - unset($headerRows[$key]); - } - } - $query .= implode(",\n", $clause); - $query .= " WHERE {$replaced['civicrm_primary_id']} != ''"; - - CRM_Core_DAO::executeQuery($query); - - //drop the table columns that store redundant household info - $dropQuery = "ALTER TABLE $exportTempTable "; - foreach ($replaced as $householdColumns) { - $dropClause[] = " DROP $householdColumns "; - } - $dropQuery .= implode(",\n", $dropClause); - - CRM_Core_DAO::executeQuery($dropQuery); - - // also drop the temp table if exists - $sql = "DROP TABLE IF EXISTS {$exportTempTable}_temp"; - CRM_Core_DAO::executeQuery($sql); - - // clean up duplicate records - $query = " -CREATE TABLE {$exportTempTable}_temp SELECT * -FROM {$exportTempTable} -GROUP BY civicrm_primary_id "; - - CRM_Core_DAO::executeQuery($query); - - $query = "DROP TABLE $exportTempTable"; - CRM_Core_DAO::executeQuery($query); - - $query = "ALTER TABLE {$exportTempTable}_temp RENAME TO {$exportTempTable}"; - CRM_Core_DAO::executeQuery($query); - } - /** * @param $exportTempTable * @param $headerRows * @param $sqlColumns - * @param $exportMode - * @param null $saveFile - * @param string $batchItems + * @param \CRM_Export_BAO_ExportProcessor $processor */ - public static function writeCSVFromTable($exportTempTable, $headerRows, $sqlColumns, $exportMode, $saveFile = NULL, $batchItems = '') { + public static function writeCSVFromTable($exportTempTable, $headerRows, $sqlColumns, $processor) { + $exportMode = $processor->getExportMode(); $writeHeader = TRUE; $offset = 0; $limit = self::EXPORT_ROW_COUNT; @@ -1768,103 +1013,25 @@ public static function writeCSVFromTable($exportTempTable, $headerRows, $sqlColu } $componentDetails[] = $row; } - if ($exportMode == 'financial') { - $getExportFileName = 'CiviCRM Contribution Search'; - } - else { - $getExportFileName = self::getExportFileName('csv', $exportMode); - } - $csvRows = CRM_Core_Report_Excel::writeCSVFile($getExportFileName, + CRM_Core_Report_Excel::writeCSVFile($processor->getExportFileName(), $headerRows, $componentDetails, NULL, - $writeHeader, - $saveFile); - - if ($saveFile && !empty($csvRows)) { - $batchItems .= $csvRows; - } + $writeHeader + ); $writeHeader = FALSE; $offset += $limit; } } - /** - * Manipulate header rows for relationship fields. - * - * @param $headerRows - * @param $contactRelationshipTypes - */ - public static function manipulateHeaderRows(&$headerRows, $contactRelationshipTypes) { - foreach ($headerRows as & $header) { - $split = explode('-', $header); - if ($relationTypeName = CRM_Utils_Array::value($split[0], $contactRelationshipTypes)) { - $split[0] = $relationTypeName; - $header = implode('-', $split); - } - } - } - - /** - * Exclude contacts who are deceased, have "Do not mail" privacy setting, - * or have no street address - * @param $exportTempTable - * @param $headerRows - * @param $sqlColumns - * @param $exportParams - */ - public static function postalMailingFormat($exportTempTable, &$headerRows, &$sqlColumns, $exportParams) { - $whereClause = array(); - - if (array_key_exists('is_deceased', $sqlColumns)) { - $whereClause[] = 'is_deceased = 1'; - } - - if (array_key_exists('do_not_mail', $sqlColumns)) { - $whereClause[] = 'do_not_mail = 1'; - } - - if (array_key_exists('street_address', $sqlColumns)) { - $addressWhereClause = " ( (street_address IS NULL) OR (street_address = '') ) "; - - // check for supplemental_address_1 - if (array_key_exists('supplemental_address_1', $sqlColumns)) { - $addressOptions = CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, - 'address_options', TRUE, NULL, TRUE - ); - if (!empty($addressOptions['supplemental_address_1'])) { - $addressWhereClause .= " AND ( (supplemental_address_1 IS NULL) OR (supplemental_address_1 = '') ) "; - // enclose it again, since we are doing an AND in between a set of ORs - $addressWhereClause = "( $addressWhereClause )"; - } - } - - $whereClause[] = $addressWhereClause; - } - - if (!empty($whereClause)) { - $whereClause = implode(' OR ', $whereClause); - $query = " -DELETE -FROM $exportTempTable -WHERE {$whereClause}"; - CRM_Core_DAO::singleValueQuery($query); - } - - // unset temporary columns that were added for postal mailing format - if (!empty($exportParams['postal_mailing_export']['temp_columns'])) { - $unsetKeys = array_keys($sqlColumns); - foreach ($unsetKeys as $headerKey => $sqlColKey) { - if (array_key_exists($sqlColKey, $exportParams['postal_mailing_export']['temp_columns'])) { - unset($sqlColumns[$sqlColKey], $headerRows[$headerKey]); - } - } - } - } - /** * Build componentPayment fields. + * + * This is no longer used by export but BAO_Mapping still calls it & we + * should find a generic way to handle this or move this to that class. + * + * @deprecated */ public static function componentPaymentFields() { static $componentPaymentFields; @@ -1880,115 +1047,6 @@ public static function componentPaymentFields() { return $componentPaymentFields; } - /** - * Set the definition for the header rows and sql columns based on the field to output. - * - * @param string $field - * @param array $headerRows - * @param array $sqlColumns - * Columns to go in the temp table. - * @param CRM_Contact_BAO_Query $query - * @param array|string $value - * @param array $phoneTypes - * @param array $imProviders - * @param array $contactRelationshipTypes - * @param string $relationQuery - * @param array $selectedPaymentFields - * @return array - */ - public static function setHeaderRows($field, $headerRows, $sqlColumns, $query, $value, $phoneTypes, $imProviders, $contactRelationshipTypes, $relationQuery, $selectedPaymentFields) { - - // Split campaign into 2 fields for id and title - if (substr($field, -14) == 'campaign_title') { - $headerRows[] = ts('Campaign Title'); - } - elseif (substr($field, -11) == 'campaign_id') { - $headerRows[] = ts('Campaign ID'); - } - elseif (isset($query->_fields[$field]['title'])) { - $headerRows[] = $query->_fields[$field]['title']; - } - elseif ($field == 'phone_type_id') { - $headerRows[] = ts('Phone Type'); - } - elseif ($field == 'provider_id') { - $headerRows[] = ts('IM Service Provider'); - } - elseif (substr($field, 0, 5) == 'case_' && $query->_fields['case'][$field]['title']) { - $headerRows[] = $query->_fields['case'][$field]['title']; - } - elseif (array_key_exists($field, $contactRelationshipTypes)) { - foreach ($value as $relationField => $relationValue) { - // below block is same as primary block (duplicate) - if (isset($relationQuery[$field]->_fields[$relationField]['title'])) { - if ($relationQuery[$field]->_fields[$relationField]['name'] == 'name') { - $headerName = $field . '-' . $relationField; - } - else { - if ($relationField == 'current_employer') { - $headerName = $field . '-' . 'current_employer'; - } - else { - $headerName = $field . '-' . $relationQuery[$field]->_fields[$relationField]['name']; - } - } - - $headerRows[] = $headerName; - - self::sqlColumnDefn($query, $sqlColumns, $headerName); - } - elseif ($relationField == 'phone_type_id') { - $headerName = $field . '-' . 'Phone Type'; - $headerRows[] = $headerName; - self::sqlColumnDefn($query, $sqlColumns, $headerName); - } - elseif ($relationField == 'provider_id') { - $headerName = $field . '-' . 'Im Service Provider'; - $headerRows[] = $headerName; - self::sqlColumnDefn($query, $sqlColumns, $headerName); - } - elseif ($relationField == 'state_province_id') { - $headerName = $field . '-' . 'state_province_id'; - $headerRows[] = $headerName; - self::sqlColumnDefn($query, $sqlColumns, $headerName); - } - elseif (is_array($relationValue) && $relationField == 'location') { - // fix header for location type case - foreach ($relationValue as $ltype => $val) { - foreach (array_keys($val) as $fld) { - $type = explode('-', $fld); - - $hdr = "{$ltype}-" . $relationQuery[$field]->_fields[$type[0]]['title']; - - if (!empty($type[1])) { - if (CRM_Utils_Array::value(0, $type) == 'phone') { - $hdr .= "-" . CRM_Utils_Array::value($type[1], $phoneTypes); - } - elseif (CRM_Utils_Array::value(0, $type) == 'im') { - $hdr .= "-" . CRM_Utils_Array::value($type[1], $imProviders); - } - } - $headerName = $field . '-' . $hdr; - $headerRows[] = $headerName; - self::sqlColumnDefn($query, $sqlColumns, $headerName); - } - } - } - } - self::manipulateHeaderRows($headerRows, $contactRelationshipTypes); - } - elseif ($selectedPaymentFields && array_key_exists($field, self::componentPaymentFields())) { - $headerRows[] = CRM_Utils_Array::value($field, self::componentPaymentFields()); - } - else { - $headerRows[] = $field; - } - - self::sqlColumnDefn($query, $sqlColumns, $field); - - return array($headerRows, $sqlColumns); - } - /** * Get the various arrays that we use to structure our output. * @@ -1999,10 +1057,8 @@ public static function setHeaderRows($field, $headerRows, $sqlColumns, $query, $ * as a step on the refactoring path rather than how it should be. * * @param array $returnProperties - * @param CRM_Contact_BAO_Contact $query - * @param array $contactRelationshipTypes - * @param string $relationQuery - * @param array $selectedPaymentFields + * @param \CRM_Export_BAO_ExportProcessor $processor + * * @return array * - outputColumns Array of columns to be exported. The values don't matter but the key must match the * alias for the field generated by BAO_Query object. @@ -2019,15 +1075,31 @@ public static function setHeaderRows($field, $headerRows, $sqlColumns, $query, $ * - b) this code is old & outdated. Submit your answers to circular bin or better * yet find a way to comment them for posterity. */ - public static function getExportStructureArrays($returnProperties, $query, $contactRelationshipTypes, $relationQuery, $selectedPaymentFields) { - $metadata = $headerRows = $outputColumns = $sqlColumns = array(); - $phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id'); - $imProviders = CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'); - + public static function getExportStructureArrays($returnProperties, $processor) { + $outputColumns = $metadata = array(); + $queryFields = $processor->getQueryFields(); foreach ($returnProperties as $key => $value) { - if ($key != 'location' || !is_array($value)) { + if (($key != 'location' || !is_array($value)) && !$processor->isRelationshipTypeKey($key)) { $outputColumns[$key] = $value; - list($headerRows, $sqlColumns) = self::setHeaderRows($key, $headerRows, $sqlColumns, $query, $value, $phoneTypes, $imProviders, $contactRelationshipTypes, $relationQuery, $selectedPaymentFields); + $processor->addOutputSpecification($key); + } + elseif ($processor->isRelationshipTypeKey($key)) { + $outputColumns[$key] = $value; + foreach ($value as $relationField => $relationValue) { + // below block is same as primary block (duplicate) + if (isset($queryFields[$relationField]['title'])) { + $processor->addOutputSpecification($relationField, $key); + } + elseif (is_array($relationValue) && $relationField == 'location') { + // fix header for location type case + foreach ($relationValue as $ltype => $val) { + foreach (array_keys($val) as $fld) { + $type = explode('-', $fld); + $processor->addOutputSpecification($type[0], $key, $ltype, CRM_Utils_Array::value(1, $type)); + } + } + } + } } else { foreach ($value as $locationType => $locationFields) { @@ -2035,36 +1107,19 @@ public static function getExportStructureArrays($returnProperties, $query, $cont $type = explode('-', $locationFieldName); $actualDBFieldName = $type[0]; - $outputFieldName = $locationType . '-' . $query->_fields[$actualDBFieldName]['title']; $daoFieldName = CRM_Utils_String::munge($locationType) . '-' . $actualDBFieldName; if (!empty($type[1])) { $daoFieldName .= "-" . $type[1]; - if ($actualDBFieldName == 'phone') { - $outputFieldName .= "-" . CRM_Utils_Array::value($type[1], $phoneTypes); - } - elseif ($actualDBFieldName == 'im') { - $outputFieldName .= "-" . CRM_Utils_Array::value($type[1], $imProviders); - } - } - if ($type[0] == 'im_provider') { - // Warning: shame inducing hack. - $metadata[$daoFieldName]['pseudoconstant']['var'] = 'imProviders'; - } - self::sqlColumnDefn($query, $sqlColumns, $outputFieldName); - list($headerRows, $sqlColumns) = self::setHeaderRows($outputFieldName, $headerRows, $sqlColumns, $query, $value, $phoneTypes, $imProviders, $contactRelationshipTypes, $relationQuery, $selectedPaymentFields); - if ($actualDBFieldName == 'country' || $actualDBFieldName == 'world_region') { - $metadata[$daoFieldName] = array('context' => 'country'); - } - if ($actualDBFieldName == 'state_province') { - $metadata[$daoFieldName] = array('context' => 'province'); } + $processor->addOutputSpecification($actualDBFieldName, NULL, $locationType, CRM_Utils_Array::value(1, $type)); + $metadata[$daoFieldName] = $processor->getMetaDataForField($actualDBFieldName); $outputColumns[$daoFieldName] = TRUE; } } } } - return array($outputColumns, $headerRows, $sqlColumns, $metadata); + return array($outputColumns, $metadata); } /** @@ -2079,6 +1134,8 @@ private static function fetchRelationshipDetails($relDAO, $value, $field, &$row) $phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id'); $imProviders = CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'); $i18n = CRM_Core_I18n::singleton(); + $field = $field . '_'; + foreach ($value as $relationField => $relationValue) { if (is_object($relDAO) && property_exists($relDAO, $relationField)) { $fieldValue = $relDAO->$relationField; @@ -2109,7 +1166,6 @@ private static function fetchRelationshipDetails($relDAO, $value, $field, &$row) else { $fieldValue = ''; } - $field = $field . '_'; $relPrefix = $field . $relationField; if (is_object($relDAO) && $relationField == 'id') { @@ -2117,6 +1173,10 @@ private static function fetchRelationshipDetails($relDAO, $value, $field, &$row) } elseif (is_array($relationValue) && $relationField == 'location') { foreach ($relationValue as $ltype => $val) { + // If the location name has a space in it the we need to handle that. This + // is kinda hacky but specifically covered in the ExportTest so later efforts to + // improve it should be secure in the knowled it will be caught. + $ltype = str_replace(' ', '_', $ltype); foreach (array_keys($val) as $fld) { $type = explode('-', $fld); $fldValue = "{$ltype}-" . $type[0]; @@ -2181,4 +1241,117 @@ private static function fetchRelationshipDetails($relDAO, $value, $field, &$row) } } + /** + * Get the ids that we want to get related contact details for. + * + * @param array $ids + * @param int $exportMode + * + * @return array + */ + protected static function getIDsForRelatedContact($ids, $exportMode) { + if ($exportMode == CRM_Export_Form_Select::CONTACT_EXPORT) { + return $ids; + } + if ($exportMode == CRM_Export_Form_Select::ACTIVITY_EXPORT) { + $relIDs = []; + $sourceID = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_ActivityContact', 'record_type_id', 'Activity Source'); + $dao = CRM_Core_DAO::executeQuery(" + SELECT contact_id FROM civicrm_activity_contact + WHERE activity_id IN ( " . implode(',', $ids) . ") AND + record_type_id = {$sourceID} + "); + + while ($dao->fetch()) { + $relIDs[] = $dao->contact_id; + } + return $relIDs; + } + $component = self::exportComponent($exportMode); + + if ($exportMode == CRM_Export_Form_Select::CASE_EXPORT) { + return CRM_Case_BAO_Case::retrieveContactIdsByCaseId($ids); + } + else { + return CRM_Core_DAO::getContactIDsFromComponent($ids, $component); + } + } + + /** + * @param $selectAll + * @param $ids + * @param \CRM_Export_BAO_ExportProcessor $processor + * @param $componentTable + */ + protected static function buildRelatedContactArray($selectAll, $ids, $processor, $componentTable) { + $allRelContactArray = $relationQuery = array(); + $queryMode = $processor->getQueryMode(); + $exportMode = $processor->getExportMode(); + + foreach ($processor->getRelationshipReturnProperties() as $relationshipKey => $relationReturnProperties) { + $allRelContactArray[$relationshipKey] = array(); + // build Query for each relationship + $relationQuery = new CRM_Contact_BAO_Query(NULL, $relationReturnProperties, + NULL, FALSE, FALSE, $queryMode + ); + list($relationSelect, $relationFrom, $relationWhere, $relationHaving) = $relationQuery->query(); + + list($id, $direction) = explode('_', $relationshipKey, 2); + // identify the relationship direction + $contactA = 'contact_id_a'; + $contactB = 'contact_id_b'; + if ($direction == 'b_a') { + $contactA = 'contact_id_b'; + $contactB = 'contact_id_a'; + } + $relIDs = self::getIDsForRelatedContact($ids, $exportMode); + + $relationshipJoin = $relationshipClause = ''; + if (!$selectAll && $componentTable) { + $relationshipJoin = " INNER JOIN {$componentTable} ctTable ON ctTable.contact_id = {$contactA}"; + } + elseif (!empty($relIDs)) { + $relID = implode(',', $relIDs); + $relationshipClause = " AND crel.{$contactA} IN ( {$relID} )"; + } + + $relationFrom = " {$relationFrom} + INNER JOIN civicrm_relationship crel ON crel.{$contactB} = contact_a.id AND crel.relationship_type_id = {$id} + {$relationshipJoin} "; + + //check for active relationship status only + $today = date('Ymd'); + $relationActive = " AND (crel.is_active = 1 AND ( crel.end_date is NULL OR crel.end_date >= {$today} ) )"; + $relationWhere = " WHERE contact_a.is_deleted = 0 {$relationshipClause} {$relationActive}"; + CRM_Core_DAO::disableFullGroupByMode(); + $relationSelect = "{$relationSelect}, {$contactA} as refContact "; + $relationQueryString = "$relationSelect $relationFrom $relationWhere $relationHaving GROUP BY crel.{$contactA}"; + + $allRelContactDAO = CRM_Core_DAO::executeQuery($relationQueryString); + CRM_Core_DAO::reenableFullGroupByMode(); + + while ($allRelContactDAO->fetch()) { + $relationQuery->convertToPseudoNames($allRelContactDAO); + $row = []; + // @todo pass processor to fetchRelationshipDetails and set fields directly within it. + self::fetchRelationshipDetails($allRelContactDAO, $relationReturnProperties, $relationshipKey, $row); + foreach (array_keys($relationReturnProperties) as $property) { + if ($property === 'location') { + // @todo - simplify location in self::fetchRelationshipDetails - remove handling here. Or just call + // $processor->setRelationshipValue from fetchRelationshipDetails + foreach ($relationReturnProperties['location'] as $locationName => $locationValues) { + foreach (array_keys($locationValues) as $locationValue) { + $key = str_replace(' ', '_', $locationName) . '-' . $locationValue; + $processor->setRelationshipValue($relationshipKey, $allRelContactDAO->refContact, $key, $row[$relationshipKey . '__' . $key]); + } + } + } + else { + $processor->setRelationshipValue($relationshipKey, $allRelContactDAO->refContact, $property, $row[$relationshipKey . '_' . $property]); + } + } + } + } + } + } 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 diff --git a/hrjobcontract/CRM/Hrjobcontract/Dedupe/Merger.php b/hrjobcontract/CRM/Hrjobcontract/Dedupe/Merger.php index e3f85ff3f3c..e47bcdb82ef 100644 --- a/hrjobcontract/CRM/Hrjobcontract/Dedupe/Merger.php +++ b/hrjobcontract/CRM/Hrjobcontract/Dedupe/Merger.php @@ -3,7 +3,7 @@ +--------------------------------------------------------------------+ | CiviCRM version 5 | +--------------------------------------------------------------------+ - | Copyright CiviCRM LLC (c) 2004-2018 | + | Copyright CiviCRM LLC (c) 2004-2019 | +--------------------------------------------------------------------+ | This file is a part of CiviCRM. | | | @@ -28,7 +28,7 @@ /** * * @package CRM - * @copyright CiviCRM LLC (c) 2004-2018 + * @copyright CiviCRM LLC (c) 2004-2019 */ class CRM_Hrjobcontract_Dedupe_Merger { @@ -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); } @@ -630,8 +619,11 @@ public static function retrieveFields($main, $other) { } $key1 = CRM_Utils_Array::value($key, $mainEvs); $key2 = CRM_Utils_Array::value($key, $otherEvs); - // CRM-17556 Get all non-empty fields, to make comparison easier - if (!empty($key1) || !empty($key2)) { + // We wish to retain '0' as it has a different meaning than NULL on a checkbox. + // However I can't think of a case where an empty string is more meaningful than null + // or where it would be FALSE or something else nullish. + $valuesToIgnore = [NULL, '', []]; + if (!in_array($key1, $valuesToIgnore, TRUE) || !in_array($key2, $valuesToIgnore, TRUE)) { $result['custom'][] = $key; } } @@ -1441,7 +1433,16 @@ public static function getRowsElementsAndInfo($mainId, $otherId, $checkPermissio } } if ($name == 'rel_table_memberships') { - $elements[] = array('checkbox', "operation[move_{$name}][add]", NULL, ts('add new')); + //Enable 'add new' checkbox if main contact does not contain any membership similar to duplicate contact. + $attributes = ['checked' => 'checked']; + $otherContactMemberships = CRM_Member_BAO_Membership::getAllContactMembership($otherId); + foreach ($otherContactMemberships as $membership) { + $mainMembership = CRM_Member_BAO_Membership::getContactMembership($mainId, $membership['membership_type_id'], FALSE); + if ($mainMembership) { + $attributes = []; + } + } + $elements[] = array('checkbox', "operation[move_{$name}][add]", NULL, ts('add new'), $attributes); $migrationInfo["operation"]["move_{$name}"]['add'] = 1; } } @@ -1457,7 +1458,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 +2018,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 +2058,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 +2108,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 +2401,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(); } } diff --git a/hrjobcontract/CRM/Hrjobcontract/Form/Merge.php b/hrjobcontract/CRM/Hrjobcontract/Form/Merge.php index 5dda31f9d95..f9fc7f29f4c 100644 --- a/hrjobcontract/CRM/Hrjobcontract/Form/Merge.php +++ b/hrjobcontract/CRM/Hrjobcontract/Form/Merge.php @@ -3,7 +3,7 @@ +--------------------------------------------------------------------+ | CiviCRM version 5 | +--------------------------------------------------------------------+ - | Copyright CiviCRM LLC (c) 2004-2018 | + | Copyright CiviCRM LLC (c) 2004-2019 | +--------------------------------------------------------------------+ | This file is a part of CiviCRM. | | | @@ -28,7 +28,7 @@ /** * * @package CRM - * @copyright CiviCRM LLC (c) 2004-2018 + * @copyright CiviCRM LLC (c) 2004-2019 */ /** diff --git a/hrjobcontract/CRM/Hrjobcontract/Import/Parser.php b/hrjobcontract/CRM/Hrjobcontract/Import/Parser.php index 6452efdc63e..db58ae3dc97 100644 --- a/hrjobcontract/CRM/Hrjobcontract/Import/Parser.php +++ b/hrjobcontract/CRM/Hrjobcontract/Import/Parser.php @@ -313,9 +313,9 @@ function addField($name, $title, $type = CRM_Utils_Type::T_INT, $headerPattern = } /** - * @param $elements + * @param array $elements */ - function setActiveFieldLocationTypes($elements) { + function setActiveFieldLocationTypes(Array $elements) { for ($i = 0; $i < count($elements); $i++) { $this->_activeFields[$i]->_hasLocationType = $elements[$i]; } diff --git a/hrjobcontract/CRM/Hrjobcontract/Import/Parser/Api.php b/hrjobcontract/CRM/Hrjobcontract/Import/Parser/Api.php index 3c38f7a876f..5e8489321a4 100755 --- a/hrjobcontract/CRM/Hrjobcontract/Import/Parser/Api.php +++ b/hrjobcontract/CRM/Hrjobcontract/Import/Parser/Api.php @@ -568,7 +568,7 @@ private function validateField($key, $value) { switch($key) { case 'HRJobContractRevision-jobcontract_id': $contractDetails = CRM_Hrjobcontract_BAO_HRJobContract::checkContract($value); - if ($contractDetails == 0) { + if (!$contractDetails) { $errorMessage = "{$this->_fields[$key]->_title} is not found"; } break; diff --git a/hrjobcontract/CRM/Hrjobcontract/Import/Parser/BaseClass.php b/hrjobcontract/CRM/Hrjobcontract/Import/Parser/BaseClass.php index 00b89a6afee..4c0a411046f 100755 --- a/hrjobcontract/CRM/Hrjobcontract/Import/Parser/BaseClass.php +++ b/hrjobcontract/CRM/Hrjobcontract/Import/Parser/BaseClass.php @@ -82,8 +82,10 @@ function init() { $field['headerPattern'] = CRM_Utils_Array::value('headerPattern', $field, '//'); $this->addField($name, CRM_Utils_Array::value('title', $field, $name), $field['type'], $field['headerPattern'], $field['dataPattern']); } + + $mapperLocType = !empty($this->_mapperLocType) ? $this->_mapperLocType : []; $this->setActiveFields($this->_mapperKeys); - $this->setActiveFieldLocationTypes($this->_mapperLocType); + $this->setActiveFieldLocationTypes($mapperLocType); // Fetch select list options from the database and cache them $this->_optionsList['HRJobHour-hours_type'] = CRM_Hrjobcontract_SelectValues::buildDbOptions('hrjc_hours_type'); diff --git a/hrjobcontract/hrjobcontract.php b/hrjobcontract/hrjobcontract.php index e3f60f4c2e3..8f58fe580b3 100644 --- a/hrjobcontract/hrjobcontract.php +++ b/hrjobcontract/hrjobcontract.php @@ -288,6 +288,7 @@ function hrjobcontract_civicrm_tabset($tabsetName, &$tabs, $context) { 'id' => 'hrjobcontract', 'url' => CRM_Utils_System::url('civicrm/contact/view/hrjobcontract', array('cid' => $context['contact_id'])), 'title' => ts('Job Contract'), + 'icon' => 'crm-i fa-file-o', 'weight' => -190, ); } diff --git a/hrjobcontract/templates/CRM/Hrjobcontract/Form/Merge.hlp b/hrjobcontract/templates/CRM/Hrjobcontract/Form/Merge.hlp index 1898e57360a..3062af37036 100644 --- a/hrjobcontract/templates/CRM/Hrjobcontract/Form/Merge.hlp +++ b/hrjobcontract/templates/CRM/Hrjobcontract/Form/Merge.hlp @@ -2,7 +2,7 @@ +--------------------------------------------------------------------+ | CiviCRM version 5 | +--------------------------------------------------------------------+ - | Copyright CiviCRM LLC (c) 2004-2018 | + | Copyright CiviCRM LLC (c) 2004-2019 | +--------------------------------------------------------------------+ | This file is a part of CiviCRM. | | | diff --git a/hrjobcontract/templates/CRM/Hrjobcontract/Form/Merge.tpl b/hrjobcontract/templates/CRM/Hrjobcontract/Form/Merge.tpl index 022e555f687..89f75b0784a 100644 --- a/hrjobcontract/templates/CRM/Hrjobcontract/Form/Merge.tpl +++ b/hrjobcontract/templates/CRM/Hrjobcontract/Form/Merge.tpl @@ -2,7 +2,7 @@ +--------------------------------------------------------------------+ | CiviCRM version 5 | +--------------------------------------------------------------------+ - | Copyright CiviCRM LLC (c) 2004-2018 | + | Copyright CiviCRM LLC (c) 2004-2019 | +--------------------------------------------------------------------+ | This file is a part of CiviCRM. | | | @@ -67,9 +67,9 @@