*/
public $sourceDigest;
+ /**
+ * Should the specification be allowed to echo output.
+ *
+ * @var bool
+ */
+ protected $verbose = TRUE;
+
+ /**
+ * @param bool $verbose
+ *
+ * @return CRM_Core_CodeGen_Main
+ */
+ public function setVerbose(bool $verbose): CRM_Core_CodeGen_Main {
+ $this->verbose = $verbose;
+ return $this;
+ }
+
/**
* @param $CoreDAOCodePath
* @param $sqlCodePath
public function init() {
if (!$this->database || !$this->tables) {
$specification = new CRM_Core_CodeGen_Specification();
- $specification->parse($this->schemaPath, $this->buildVersion);
+ $specification->parse($this->schemaPath, $this->buildVersion, $this->verbose);
$this->database = $specification->database;
$this->tables = $specification->tables;
}
return $this->getUserJob()['metadata']['DataSource']['column_headers'];
}
+ /**
+ * Get the field names of the fields holding data in the import tracking table.
+ *
+ * @return array
+ * @throws \API_Exception
+ * @throws \CRM_Core_Exception
+ */
+ public function getDataFieldNames(): array {
+ $result = CRM_Core_DAO::executeQuery(
+ 'SHOW FIELDS FROM ' . $this->getTableName() . "
+ WHERE Field NOT LIKE '\_%'");
+ $fields = [];
+ while ($result->fetch()) {
+ $fields[] = $result->Field;
+ }
+ return $fields;
+ }
+
/**
* Get an array of column headers, if any.
*
* @return string
*/
private function getSelectClause(): string {
- return $this->getSelectFields() ? implode(', ', $this->getSelectFields()) : '*';
+ return $this->getSelectFields() ? '`' . implode('`, `', $this->getSelectFields()) . '`' : '*';
}
/**
$strtolower = function_exists('mb_strtolower') ? 'mb_strtolower' : 'strtolower';
$columns = array_map($strtolower, $firstrow);
+ $columns = array_map('trim', $columns);
$columns = str_replace(' ', '_', $columns);
$columns = preg_replace('/[^a-z_]/', '', $columns);
$tableName = $table->getName();
$table->createWithQuery($this->getSubmittedValue('sqlQuery'));
- // Get the names of the fields to be imported. Any fields starting with an
- // underscore are considered to be internal to the import process)
+ // Get the names of the fields to be imported.
$columnsResult = CRM_Core_DAO::executeQuery(
- 'SHOW FIELDS FROM ' . $tableName . "
- WHERE Field NOT LIKE '\_%'");
+ 'SHOW FIELDS FROM ' . $tableName);
$columnNames = [];
while ($columnsResult->fetch()) {
*/
protected function getOutputRows($statuses = [], int $limit = 0) {
$statuses = (array) $statuses;
- return $this->getDataSourceObject()->setLimit($limit)->setStatuses($statuses)
- ->setSelectFields(array_merge(['_id', '_status_message'], $this->getColumnHeaders()))
- ->setStatuses($statuses)->getRows();
+ $dataSource = $this->getDataSourceObject()->setLimit($limit)->setStatuses($statuses)->setStatuses($statuses);
+ $dataSource->setSelectFields(array_merge(['_id', '_status_message'], $dataSource->getDataFieldNames()));
+ return $dataSource->getRows();
}
/**
*/
public static function outputCSV(): void {
$userJobID = CRM_Utils_Request::retrieveValue('user_job_id', 'Integer', NULL, TRUE);
- $status = CRM_Utils_Request::retrieveValue('status', 'String', NULL, TRUE);
+ $status = (int) CRM_Utils_Request::retrieveValue('status', 'String', NULL, TRUE);
$saveFileName = CRM_Import_Parser::saveFileName($status);
$form = new CRM_Import_Forms();
$writer = Writer::createFromFileObject(new SplTempFileObject());
$headers = $form->getOutputColumnsHeaders();
$writer->insertOne($headers);
- // Note this might be more inefficient that iterating the result
+ // Note this might be more inefficient by iterating the result
// set & doing insertOne - possibly something to explore later.
$writer->insertAll($form->getOutputRows($status));
-
- CRM_Utils_System::setHttpHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0');
- CRM_Utils_System::setHttpHeader('Content-Description', 'File Transfer');
- CRM_Utils_System::setHttpHeader('Content-Type', 'text/csv; charset=UTF-8');
$writer->output($saveFileName);
CRM_Utils_System::civiExit();
}
/**
* Determines the file name based on error code.
*
- * @var $type error code constant
+ * @var int $type code constant
* @return string
*/
public static function saveFileName($type) {
if (!isset(self::$singletons['codeGen'])) {
$civiRoot = str_replace(DIRECTORY_SEPARATOR, '/', dirname(__DIR__));
$codeGen = new \CRM_Core_CodeGen_Main("$civiRoot/CRM/Core/DAO", "$civiRoot/sql", $civiRoot, "$civiRoot/templates", NULL, "UnitTests", NULL, "$civiRoot/xml/schema/Schema.xml", NULL);
+ $codeGen->setVerbose(FALSE);
$codeGen->init();
self::$singletons['codeGen'] = $codeGen;
}
--- /dev/null
+FIRSTNAME,LASTNAME,ID,IND/ORG,Do Not Mail,Valid Address
+Mary,Jones,1,Individual,0,Yes
*
* @throws \API_Exception
* @throws \CRM_Core_Exception
+ * @throws \League\Csv\CannotInsertRecord
*/
- public function testImport($csv, $mapper, $expectedError, $expectedOutcomes = [], $submittedValues = []): void {
+ public function testImport($csv, $mapper, $expectedOutcomes = [], $submittedValues = []): void {
$this->importCSV($csv, $mapper, $submittedValues);
$dataSource = new CRM_Import_DataSource_CSV(UserJob::get(FALSE)->setSelect(['id'])->execute()->first()['id']);
foreach ($expectedOutcomes as $outcome => $count) {
$this->assertEquals($dataSource->getRowCount([$outcome]), $count);
}
+ ob_start();
+ $_REQUEST['user_job_id'] = $dataSource->getUserJobID();
+ $_REQUEST['status'] = array_key_first($expectedOutcomes);
+ try {
+ CRM_Import_Forms::outputCSV();
+ }
+ catch (CRM_Core_Exception_PrematureExitException $e) {
+ // For now just check it got this far without error.
+ ob_end_clean();
+ return;
+ }
+ ob_end_clean();
+ $this->fail('Should have resulted in a premature exit exception');
}
/**
*/
public function importDataProvider(): array {
return [
+ 'column_names_casing.csv' => [
+ 'csv' => 'column_names_casing.csv',
+ 'mapper' => [['first_name'], ['last_name'], ['do_not_import'], ['do_not_import'], ['do_not_import'], ['do_not_import']],
+ 'expected_outcomes' => [CRM_Import_Parser::VALID => 1],
+ ],
'individual_unicode.csv' => [
'csv' => 'individual_unicode.csv',
'mapper' => [['first_name'], ['last_name'], ['url', 1], ['country', 1]],
- 'expected_error' => '',
'expected_outcomes' => [CRM_Import_Parser::VALID => 1],
],
'individual_invalid_sub_type' => [
'csv' => 'individual_invalid_contact_sub_type.csv',
'mapper' => [['first_name'], ['last_name'], ['contact_sub_type']],
- 'expected_error' => '',
'expected_outcomes' => [CRM_Import_Parser::ERROR => 1],
],
//Record duplicates multiple contacts
'organization_multiple_duplicates_invalid' => [
'csv' => 'organization_multiple_duplicates_invalid.csv',
'mapper' => [['organization_name'], ['email']],
- 'expected_error' => '',
'expected_outcomes' => [
CRM_Import_Parser::VALID => 2,
CRM_Import_Parser::ERROR => 1,
'individual_invalid_external_identifier_email_mismatch' => [
'csv' => 'individual_invalid_external_identifier_email_mismatch.csv',
'mapper' => [['first_name'], ['last_name'], ['email'], ['external_identifier']],
- 'expected_error' => '',
'expected_outcomes' => [
CRM_Import_Parser::VALID => 2,
CRM_Import_Parser::ERROR => 1,