diff --git a/.toxic.json b/.toxic.json index 3886591fd1110dc7e88a1fed7ab3e2b713cc325e..399c2407acf3e869bb0b08a75784feddd5b21ceb 100644 --- a/.toxic.json +++ b/.toxic.json @@ -32,7 +32,6 @@ "CRM_Contribute_Form_Contribution_Main::formRule()": "toxicAlert", "CRM_Contribute_Form_Contribution_Main::submit()": "toxicAlert", "CRM_Contribute_Form_Task_Invoice::printPDF()": "toxicAlert", - "CRM_Contribute_Import_Parser_Contribution::run()": "toxicAlert", "CRM_Core_BAO_ActionScheduleTest::setUp()": "toxicAlert", "CRM_Core_BAO_CustomField::formatCustomField()": "toxicAlert", "CRM_Core_BAO_CustomGroup::getTree()": "toxicAlert", diff --git a/CRM/Contribute/Import/Form/DataSource.php b/CRM/Contribute/Import/Form/DataSource.php index 36ef3c98845e8667bbf8fe6f71396c4f2198cf84..6de2b35a8d001034a2c8e7c657eafc1756d0c852 100644 --- a/CRM/Contribute/Import/Form/DataSource.php +++ b/CRM/Contribute/Import/Form/DataSource.php @@ -54,20 +54,6 @@ class CRM_Contribute_Import_Form_DataSource extends CRM_Import_Form_DataSource { $this->addContactTypeSelector(); } - /** - * Process the uploaded file. - */ - public function postProcess() { - $this->storeFormValues([ - 'onDuplicate', - 'contactType', - 'dateFormats', - 'savedMapping', - ]); - - $this->submitFileForMapping('CRM_Contribute_Import_Parser_Contribution'); - } - /** * @return \CRM_Contribute_Import_Parser_Contribution */ diff --git a/CRM/Contribute/Import/Form/MapField.php b/CRM/Contribute/Import/Form/MapField.php index 9026f66c5c6c344d39852f27682b279ae3575d2d..ccfcdff34317347aaa8072fb7311a0c3e0b7e91f 100644 --- a/CRM/Contribute/Import/Form/MapField.php +++ b/CRM/Contribute/Import/Form/MapField.php @@ -48,11 +48,11 @@ class CRM_Contribute_Import_Form_MapField extends CRM_Import_Form_MapField { } if ($field == $contactORContributionId) { if (!($weightSum >= $threshold || in_array('external_identifier', $importKeys)) && - $self->_onDuplicate != CRM_Import_Parser::DUPLICATE_UPDATE + !$self->isUpdateExisting() ) { $errors['_qf_default'] .= ts('Missing required contact matching fields.') . " $fieldMessage " . ts('(Sum of all weights should be greater than or equal to threshold: %1).', [1 => $threshold]) . '<br />'; } - elseif ($self->_onDuplicate == CRM_Import_Parser::DUPLICATE_UPDATE && + elseif ($self->isUpdateExisting() && !(in_array('invoice_id', $importKeys) || in_array('trxn_id', $importKeys) || in_array('contribution_id', $importKeys) ) @@ -74,15 +74,10 @@ class CRM_Contribute_Import_Form_MapField extends CRM_Import_Form_MapField { public function preProcess() { parent::preProcess(); - $this->_columnCount = $this->get('columnCount'); - $skipColumnHeader = $this->getSubmittedValue('skipColumnHeader'); - $this->_onDuplicate = $this->getSubmittedValue('onDuplicate'); - $this->assign('skipColumnHeader', $skipColumnHeader); - $highlightedFields = ['financial_type_id', 'total_amount']; //CRM-2219 removing other required fields since for updation only //invoice id or trxn id or contribution id is required. - if ($this->_onDuplicate == CRM_Import_Parser::DUPLICATE_UPDATE) { + if ($this->isUpdateExisting()) { $remove = [ 'contribution_contact_id', 'email', @@ -104,7 +99,7 @@ class CRM_Contribute_Import_Form_MapField extends CRM_Import_Form_MapField { $highlightedFields[] = $key; } } - elseif ($this->_onDuplicate == CRM_Import_Parser::DUPLICATE_SKIP) { + elseif ($this->isSkipExisting()) { unset($this->_mapperFields['contribution_id']); $highlightedFieldsArray = [ 'contribution_contact_id', @@ -155,7 +150,7 @@ class CRM_Contribute_Import_Form_MapField extends CRM_Import_Form_MapField { } $sel1 = $this->_mapperFields; - if (!$this->get('onDuplicate')) { + if (!$this->isUpdateExisting()) { unset($sel1['id']); unset($sel1['contribution_id']); } @@ -178,7 +173,7 @@ class CRM_Contribute_Import_Form_MapField extends CRM_Import_Form_MapField { foreach ($columnHeaders as $i => $columnHeader) { $sel = &$this->addElement('hierselect', "mapper[$i]", ts('Mapper for Field %1', [1 => $i]), NULL); $jsSet = FALSE; - if ($this->get('savedMapping')) { + if ($this->getSubmittedValue('savedMapping')) { [$mappingName, $mappingContactType] = CRM_Core_BAO_Mapping::getMappingFields($savedMappingID); $mappingName = $mappingName[1]; @@ -265,7 +260,7 @@ class CRM_Contribute_Import_Form_MapField extends CRM_Import_Form_MapField { $warning++; } } - if ($warning != 0 && $this->get('savedMapping')) { + if ($warning != 0 && $this->getSubmittedValue('savedMapping')) { $session = CRM_Core_Session::singleton(); $session->setStatus(ts('The data columns in this import file appear to be different from the saved mapping. Please verify that you have selected the correct saved mapping before continuing.')); } @@ -294,7 +289,7 @@ class CRM_Contribute_Import_Form_MapField extends CRM_Import_Form_MapField { public static function formRule($fields, $files, $self) { $errors = []; $fieldMessage = NULL; - $contactORContributionId = $self->_onDuplicate == CRM_Import_Parser::DUPLICATE_UPDATE ? 'contribution_id' : 'contribution_contact_id'; + $contactORContributionId = $self->isUpdateExisting() ? 'contribution_id' : 'contribution_contact_id'; if (!array_key_exists('savedMapping', $fields)) { $importKeys = []; foreach ($fields['mapper'] as $mapperPart) { @@ -327,7 +322,7 @@ class CRM_Contribute_Import_Form_MapField extends CRM_Import_Form_MapField { $errors = self::checkRequiredFields($self, $contactORContributionId, $importKeys, $errors, $weightSum, $threshold, $fieldMessage); //at least one field should be mapped during update. - if ($self->_onDuplicate == CRM_Import_Parser::DUPLICATE_UPDATE) { + if ($self->isUpdateExisting()) { $atleastOne = FALSE; foreach ($self->_mapperFields as $key => $field) { if (in_array($key, $importKeys) && diff --git a/CRM/Contribute/Import/Form/Preview.php b/CRM/Contribute/Import/Form/Preview.php index 3bfc113f7b4ad277c869d6aacb95b86966f36147..85d9bcdf3c1e07b0d3c5213092f13021a5668f4e 100644 --- a/CRM/Contribute/Import/Form/Preview.php +++ b/CRM/Contribute/Import/Form/Preview.php @@ -20,42 +20,6 @@ */ class CRM_Contribute_Import_Form_Preview extends CRM_Import_Form_Preview { - /** - * Set variables up before form is built. - */ - public function preProcess() { - parent::preProcess(); - $invalidRowCount = $this->getRowCount(CRM_Import_Parser::VALID); - - $downloadURL = ''; - if ($invalidRowCount) { - $urlParams = 'type=' . CRM_Import_Parser::ERROR . '&parser=CRM_Contribute_Import_Parser_Contribution'; - $downloadURL = CRM_Utils_System::url('civicrm/export', $urlParams); - } - - $this->setStatusUrl(); - $this->assign('downloadErrorRecordsUrl', $downloadURL); - } - - /** - * Get the mapped fields as an array of labels. - * - * e.g - * ['First Name', 'Employee Of - First Name', 'Home - Street Address'] - * - * @return array - * @throws \API_Exception - * @throws \CRM_Core_Exception - */ - protected function getMappedFieldLabels(): array { - $mapper = []; - $parser = $this->getParser(); - foreach ($this->getSubmittedValue('mapper') as $columnNumber => $mappedField) { - $mapper[$columnNumber] = $parser->getMappedFieldLabel($parser->getMappingFieldFromMapperInput($mappedField, 0, $columnNumber)); - } - return $mapper; - } - /** * @return \CRM_Contribute_Import_Parser_Contribution */ diff --git a/CRM/Contribute/Import/Parser/Contribution.php b/CRM/Contribute/Import/Parser/Contribution.php index c69cd37002805f0cf92f2be23292b2945a8fb3d2..f98f1bc2d161bd8c935dc9996dd0983d7ac50769 100644 --- a/CRM/Contribute/Import/Parser/Contribution.php +++ b/CRM/Contribute/Import/Parser/Contribution.php @@ -110,83 +110,6 @@ class CRM_Contribute_Import_Parser_Contribution extends CRM_Import_Parser { */ protected $_softCreditErrorsFileName; - /** - * @param string $fileName - * @param string $separator - * @param $mapper - * @param bool $skipColumnHeader - * @param int $mode - * @param int $contactType - * @param int $onDuplicate - * @param int $statusID - * - * @return mixed - * @throws Exception - */ - public function run( - $fileName, - $separator, - $mapper, - $skipColumnHeader = FALSE, - $mode = self::MODE_PREVIEW, - $contactType = self::CONTACT_INDIVIDUAL, - $onDuplicate = self::DUPLICATE_SKIP, - $statusID = NULL - ) { - // Since $this->_contactType is still being called directly do a get call - // here to make sure it is instantiated. - $this->getContactType(); - - $this->init(); - - $this->_lineCount = $this->_validSoftCreditRowCount = $this->_validPledgePaymentRowCount = 0; - $this->_invalidRowCount = $this->_validCount = $this->_invalidSoftCreditRowCount = $this->_invalidPledgePaymentRowCount = 0; - $this->_totalCount = 0; - - $this->_errors = []; - $this->_warnings = []; - $this->_pledgePaymentErrors = []; - $this->_softCreditErrors = []; - if ($statusID) { - $this->progressImport($statusID); - $startTimestamp = $currTimestamp = $prevTimestamp = time(); - } - - if ($mode == self::MODE_MAPFIELD) { - $this->_rows = []; - } - else { - $this->_activeFieldCount = count($this->_activeFields); - } - - $dataSource = $this->getDataSourceObject(); - $totalRowCount = $dataSource->getRowCount(['new']); - $dataSource->setStatuses(['new']); - - while ($row = $dataSource->getRow()) { - $values = array_values($row); - $this->_lineCount++; - - $this->_totalCount++; - - if ($mode == self::MODE_MAPFIELD) { - $returnCode = CRM_Import_Parser::VALID; - } - // Note that import summary appears to be unused - elseif ($mode == self::MODE_PREVIEW || $mode == self::MODE_SUMMARY) { - $returnCode = $this->summary($values); - } - elseif ($mode == self::MODE_IMPORT) { - $this->import($values); - if ($statusID && (($this->_lineCount % 50) == 0)) { - $prevTimestamp = $this->progressImport($statusID, FALSE, $startTimestamp, $prevTimestamp, $totalRowCount); - } - } - - } - - } - /** * Get the field mappings for the import. * @@ -274,161 +197,6 @@ class CRM_Contribute_Import_Parser_Contribution extends CRM_Import_Parser { } } - /** - * Store parser values. - * - * @param CRM_Core_Session $store - * - * @param int $mode - */ - public function set($store, $mode = self::MODE_SUMMARY) { - $store->set('totalRowCount', $this->_totalCount); - $store->set('validRowCount', $this->_validCount); - $store->set('invalidRowCount', $this->_invalidRowCount); - - $store->set('invalidSoftCreditRowCount', $this->_invalidSoftCreditRowCount); - $store->set('validSoftCreditRowCount', $this->_validSoftCreditRowCount); - $store->set('invalidPledgePaymentRowCount', $this->_invalidPledgePaymentRowCount); - $store->set('validPledgePaymentRowCount', $this->_validPledgePaymentRowCount); - - switch ($this->_contactType) { - case 'Individual': - $store->set('contactType', CRM_Import_Parser::CONTACT_INDIVIDUAL); - break; - - case 'Household': - $store->set('contactType', CRM_Import_Parser::CONTACT_HOUSEHOLD); - break; - - case 'Organization': - $store->set('contactType', CRM_Import_Parser::CONTACT_ORGANIZATION); - } - - if ($this->_invalidRowCount) { - $store->set('errorsFileName', $this->_errorFileName); - } - if (isset($this->_rows) && !empty($this->_rows)) { - $store->set('dataValues', $this->_rows); - } - - if ($this->_invalidPledgePaymentRowCount) { - $store->set('pledgePaymentErrorsFileName', $this->_pledgePaymentErrorsFileName); - } - - if ($this->_invalidSoftCreditRowCount) { - $store->set('softCreditErrorsFileName', $this->_softCreditErrorsFileName); - } - - if ($mode == self::MODE_IMPORT) { - $store->set('duplicateRowCount', $this->_duplicateCount); - if ($this->_duplicateCount) { - $store->set('duplicatesFileName', $this->_duplicateFileName); - } - } - } - - /** - * Export data to a CSV file. - * - * @param string $fileName - * @param array $header - * @param array $data - */ - public static function exportCSV($fileName, $header, $data) { - $output = []; - $fd = fopen($fileName, 'w'); - - foreach ($header as $key => $value) { - $header[$key] = "\"$value\""; - } - $config = CRM_Core_Config::singleton(); - $output[] = implode($config->fieldSeparator, $header); - - foreach ($data as $datum) { - foreach ($datum as $key => $value) { - if (isset($value[0]) && is_array($value)) { - foreach ($value[0] as $k1 => $v1) { - if ($k1 == 'location_type_id') { - continue; - } - $datum[$k1] = $v1; - } - } - else { - $datum[$key] = "\"$value\""; - } - } - $output[] = implode($config->fieldSeparator, $datum); - } - fwrite($fd, implode("\n", $output)); - fclose($fd); - } - - /** - * Determines the file extension based on error code. - * - * @param int $type - * Error code constant. - * - * @return string - */ - public static function errorFileName($type) { - $fileName = NULL; - if (empty($type)) { - return $fileName; - } - - $config = CRM_Core_Config::singleton(); - $fileName = $config->uploadDir . "sqlImport"; - - switch ($type) { - case self::SOFT_CREDIT_ERROR: - $fileName .= '.softCreditErrors'; - break; - - case self::PLEDGE_PAYMENT_ERROR: - $fileName .= '.pledgePaymentErrors'; - break; - - default: - $fileName = parent::errorFileName($type); - break; - } - - return $fileName; - } - - /** - * Determines the file name based on error code. - * - * @param int $type - * Error code constant. - * - * @return string - */ - public static function saveFileName($type) { - $fileName = NULL; - if (empty($type)) { - return $fileName; - } - - switch ($type) { - case self::SOFT_CREDIT_ERROR: - $fileName = 'Import_Soft_Credit_Errors.csv'; - break; - - case self::PLEDGE_PAYMENT_ERROR: - $fileName = 'Import_Pledge_Payment_Errors.csv'; - break; - - default: - $fileName = parent::saveFileName($type); - break; - } - - return $fileName; - } - /** * The initializer code, called before the processing */ diff --git a/CRM/Export/BAO/Export.php b/CRM/Export/BAO/Export.php index c713eb8ade4e203dcf347d6c3c255f8f5c081ede..6ff9506f45185349ad818e9337f7a41835b06ac7 100644 --- a/CRM/Export/BAO/Export.php +++ b/CRM/Export/BAO/Export.php @@ -251,6 +251,7 @@ INSERT INTO {$componentTable} SELECT distinct gc.contact_id FROM civicrm_group_c if (method_exists($parserName, 'errorFileName') && method_exists($parserName, 'saveFileName') ) { + CRM_Core_Error::deprecatedWarning('unused code'); $errorFileName = $parserName::errorFileName($type); $saveFileName = $parserName::saveFileName($type); if (!empty($errorFileName) && !empty($saveFileName)) { diff --git a/CRM/Import/Forms.php b/CRM/Import/Forms.php index 571ef0f87e8d694acc5c1916769cb547be830d61..0b37ea76b221e8e4ffae146d797c176a319a77a0 100644 --- a/CRM/Import/Forms.php +++ b/CRM/Import/Forms.php @@ -575,7 +575,6 @@ class CRM_Import_Forms extends CRM_Core_Form { * * @return array * @throws \API_Exception - * @throws \CRM_Core_Exception */ protected function getMappedFieldLabels(): array { $mapper = []; @@ -643,4 +642,12 @@ class CRM_Import_Forms extends CRM_Core_Form { return ((int) $this->getSubmittedValue('onDuplicate')) === CRM_Import_Parser::DUPLICATE_UPDATE; } + /** + * Has the user chosen to update existing records. + * @return bool + */ + protected function isSkipExisting(): bool { + return ((int) $this->getSubmittedValue('onDuplicate')) === CRM_Import_Parser::DUPLICATE_SKIP; + } + } diff --git a/tests/phpunit/CRM/Contribute/Import/Parser/ContributionTest.php b/tests/phpunit/CRM/Contribute/Import/Parser/ContributionTest.php index ab39c9a5c5cf8865b61e4748ed89df12bf71ed17..19c11d37dc967d7fc518637f404ac68d101bea31 100644 --- a/tests/phpunit/CRM/Contribute/Import/Parser/ContributionTest.php +++ b/tests/phpunit/CRM/Contribute/Import/Parser/ContributionTest.php @@ -17,6 +17,7 @@ use Civi\Api4\UserJob; */ class CRM_Contribute_Import_Parser_ContributionTest extends CiviUnitTestCase { use CRMTraits_Custom_CustomDataTrait; + use CRMTraits_Import_ParserTrait; /** * Default entity for class. @@ -198,43 +199,6 @@ class CRM_Contribute_Import_Parser_ContributionTest extends CiviUnitTestCase { $this->callAPISuccessGetSingle('PledgePayment', ['pledge_id' => $pledgeID, 'contribution_id' => $contribution['id']]); } - /** - * Import the csv file values. - * - * This function uses a flow that mimics the UI flow. - * - * @param string $csv Name of csv file. - * @param array $fieldMappings - * @param array $submittedValues - */ - protected function importCSV(string $csv, array $fieldMappings, array $submittedValues = []): void { - $submittedValues = array_merge([ - 'uploadFile' => ['name' => __DIR__ . '/data/' . $csv], - 'skipColumnHeader' => TRUE, - 'fieldSeparator' => ',', - 'contactType' => CRM_Import_Parser::CONTACT_INDIVIDUAL, - 'mapper' => $this->getMapperFromFieldMappings($fieldMappings), - 'dataSource' => 'CRM_Import_DataSource_CSV', - 'file' => ['name' => $csv], - 'dateFormats' => CRM_Core_Form_Date::DATE_yyyy_mm_dd, - 'onDuplicate' => CRM_Import_Parser::DUPLICATE_UPDATE, - 'groups' => [], - ], $submittedValues); - $form = $this->getFormObject('CRM_Contribute_Import_Form_DataSource', $submittedValues); - $form->buildForm(); - $form->postProcess(); - $this->userJobID = $form->getUserJobID(); - $form = $this->getFormObject('CRM_Contribute_Import_Form_MapField', $submittedValues); - $form->setUserJobID($this->userJobID); - $form->buildForm(); - $form->postProcess(); - /* @var CRM_Contribute_Import_Form_MapField $form */ - $form = $this->getFormObject('CRM_Contribute_Import_Form_Preview', $submittedValues); - $form->setUserJobID($this->userJobID); - $form->buildForm(); - $form->postProcess(); - } - /** * Test phone is included if it is part of dedupe rule. * diff --git a/tests/phpunit/CRMTraits/Import/ParserTrait.php b/tests/phpunit/CRMTraits/Import/ParserTrait.php new file mode 100644 index 0000000000000000000000000000000000000000..4531d74ccb71b1199f2c99798947bc8c1b48ba68 --- /dev/null +++ b/tests/phpunit/CRMTraits/Import/ParserTrait.php @@ -0,0 +1,107 @@ +<?php +/* + +--------------------------------------------------------------------+ + | Copyright CiviCRM LLC. All rights reserved. | + | | + | This work is published under the GNU AGPLv3 license with some | + | permitted exceptions and without any warranty. For full license | + | and copyright information, see https://civicrm.org/licensing | + +--------------------------------------------------------------------+ + */ + +/** + * Trait ParserTrait + * + * Trait for testing imports. + */ +trait CRMTraits_Import_ParserTrait { + + /** + * Import the csv file values. + * + * This function uses a flow that mimics the UI flow. + * + * @param string $csv Name of csv file. + * @param array $fieldMappings + * @param array $submittedValues + */ + protected function importCSV(string $csv, array $fieldMappings, array $submittedValues = []): void { + $reflector = new ReflectionClass(get_class($this)); + $directory = dirname($reflector->getFileName()); + $submittedValues = array_merge([ + 'uploadFile' => ['name' => $directory . '/data/' . $csv], + 'skipColumnHeader' => TRUE, + 'fieldSeparator' => ',', + 'contactType' => CRM_Import_Parser::CONTACT_INDIVIDUAL, + 'mapper' => $this->getMapperFromFieldMappings($fieldMappings), + 'dataSource' => 'CRM_Import_DataSource_CSV', + 'file' => ['name' => $csv], + 'dateFormats' => CRM_Core_Form_Date::DATE_yyyy_mm_dd, + 'onDuplicate' => CRM_Import_Parser::DUPLICATE_SKIP, + 'groups' => [], + ], $submittedValues); + $form = $this->getDataSourceForm($submittedValues); + $form->buildForm(); + $form->postProcess(); + $this->userJobID = $form->getUserJobID(); + $form = $this->getMapFieldForm($submittedValues); + $form->setUserJobID($this->userJobID); + $form->buildForm(); + $this->assertTrue($form->validate()); + $form->postProcess(); + $form = $this->getPreviewForm($submittedValues); + $form->setUserJobID($this->userJobID); + $form->buildForm(); + $this->assertTrue($form->validate()); + $form->postProcess(); + } + + /** + * Get the import's datasource form. + * + * Defaults to contribution - other classes should override. + * + * @param array $submittedValues + * + * @return \CRM_Contribute_Import_Form_DataSource + * @noinspection PhpUnnecessaryLocalVariableInspection + */ + protected function getDataSourceForm(array $submittedValues): CRM_Contribute_Import_Form_DataSource { + /* @var \CRM_Contribute_Import_Form_DataSource $form */ + $form = $this->getFormObject('CRM_Contribute_Import_Form_DataSource', $submittedValues); + return $form; + } + + /** + * Get the import's mapField form. + * + * Defaults to contribution - other classes should override. + * + * @param array $submittedValues + * + * @return \CRM_Contribute_Import_Form_MapField + * @noinspection PhpUnnecessaryLocalVariableInspection + */ + protected function getMapFieldForm(array $submittedValues): CRM_Contribute_Import_Form_MapField { + /* @var \CRM_Contribute_Import_Form_MapField $form */ + $form = $this->getFormObject('CRM_Contribute_Import_Form_MapField', $submittedValues); + return $form; + } + + /** + * Get the import's preview form. + * + * Defaults to contribution - other classes should override. + * + * @param array $submittedValues + * + * @return \CRM_Contribute_Import_Form_Preview + * @noinspection PhpUnnecessaryLocalVariableInspection + */ + protected function getPreviewForm(array $submittedValues): CRM_Contribute_Import_Form_Preview { + /* @var CRM_Contribute_Import_Form_Preview $form */ + $form = $this->getFormObject('CRM_Contribute_Import_Form_Preview', $submittedValues); + return $form; + } + +}