Add wrapper class for importProcessor
authoreileen <emcnaughton@wikimedia.org>
Tue, 13 Aug 2019 10:46:49 +0000 (22:46 +1200)
committereileen <emcnaughton@wikimedia.org>
Tue, 13 Aug 2019 23:53:00 +0000 (11:53 +1200)
With the export cleanup creating a new sensible class & migrating code to it turned out to be a good approach.

This adds a class that wraps around the Importer Object, taking the mapping_field db format of fields
as a format - this is also where we wound up with the Export - using that format as it is what is saed.

There is a gap as I noted in https://lab.civicrm.org/dev/core/issues/1172 around the schema's adequacy.

That is not such an issue for this - in that we are not dealing with Contribution import and
this is really just exposing the wrapper for the unit tests at this stage - the only change to
'live' code is a little less php v4 support - we have removed a bunch of these from the constructor of the
other objects already with no observed issues

CRM/Contact/Import/Parser/Contact.php
CRM/Import/ImportProcessor.php [new file with mode: 0644]
tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php

index a93dfc1ae4000f210e5beca1a4bb3c5abd02f15a..086e35fa0473a5213f1ebbaa9363cee615dfea6b 100644 (file)
@@ -122,11 +122,11 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Contact_Import_Parser {
    * @param array $mapperRelatedContactWebsiteType
    */
   public function __construct(
-    &$mapperKeys, $mapperLocType = [], $mapperPhoneType = [], $mapperImProvider = [], $mapperRelated = [], $mapperRelatedContactType = [], $mapperRelatedContactDetails = [], $mapperRelatedContactLocType = [], $mapperRelatedContactPhoneType = [], $mapperRelatedContactImProvider = [],
+    $mapperKeys, $mapperLocType = [], $mapperPhoneType = [], $mapperImProvider = [], $mapperRelated = [], $mapperRelatedContactType = [], $mapperRelatedContactDetails = [], $mapperRelatedContactLocType = [], $mapperRelatedContactPhoneType = [], $mapperRelatedContactImProvider = [],
     $mapperWebsiteType = [], $mapperRelatedContactWebsiteType = []
   ) {
     parent::__construct();
-    $this->_mapperKeys = &$mapperKeys;
+    $this->_mapperKeys = $mapperKeys;
     $this->_mapperLocType = &$mapperLocType;
     $this->_mapperPhoneType = &$mapperPhoneType;
     $this->_mapperWebsiteType = $mapperWebsiteType;
diff --git a/CRM/Import/ImportProcessor.php b/CRM/Import/ImportProcessor.php
new file mode 100644 (file)
index 0000000..ffd38c5
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+
+/**
+ * Class CRM_Import_ImportProcessor.
+ *
+ * Import processor class. This is intended to provide a sanitising wrapper around
+ * the form-oriented import classes. In particular it is intended to provide a clear translation
+ * between the saved mapping field format and the quick form & parser formats.
+ *
+ * In the first instance this is only being used in unit tests but the intent is to migrate
+ * to it on a trajectory similar to the ExportProcessor so it is not in the tests.
+ */
+class CRM_Import_ImportProcessor {
+
+  /**
+   * An array of fields in the format used in the table civicrm_mapping_field.
+   *
+   * @var array
+   */
+  protected $mappingFields = [];
+
+  /**
+   * Get contact type being imported.
+   *
+   * @var string
+   */
+  protected $contactType;
+
+  /**
+   * @return string
+   */
+  public function getContactType(): string {
+    return $this->contactType;
+  }
+
+  /**
+   * @param string $contactType
+   */
+  public function setContactType(string $contactType) {
+    $this->contactType = $contactType;
+  }
+
+  /**
+   * @return array
+   */
+  public function getMappingFields(): array {
+    return $this->mappingFields;
+  }
+
+  /**
+   * @param array $mappingFields
+   */
+  public function setMappingFields(array $mappingFields) {
+    $this->mappingFields = CRM_Utils_Array::rekey($mappingFields, 'column_number');
+    ksort($this->mappingFields);
+    $this->mappingFields = array_values($this->mappingFields);
+  }
+
+  /**
+   * Get the names of the mapped fields.
+   */
+  public function getFieldNames() {
+    return CRM_Utils_Array::collect('name', $this->getMappingFields());
+  }
+
+  /**
+   * Get the location types of the mapped fields.
+   */
+  public function getFieldLocationTypes() {
+    return CRM_Utils_Array::collect('location_type_id', $this->getMappingFields());
+  }
+
+  /**
+   * Get the phone types of the mapped fields.
+   */
+  public function getFieldPhoneTypes() {
+    return CRM_Utils_Array::collect('phone_type_id', $this->getMappingFields());
+  }
+
+  /**
+   * Get the names of the im_provider fields.
+   */
+  public function getFieldIMProviderTypes() {
+    return CRM_Utils_Array::collect('im_provider_id', $this->getMappingFields());
+  }
+
+  /**
+   * Get the names of the website fields.
+   */
+  public function getFieldWebsiteTypes() {
+    return CRM_Utils_Array::collect('im_provider_id', $this->getMappingFields());
+  }
+
+  /**
+   * Get an instance of the importer object.
+   *
+   * @return CRM_Contact_Import_Parser_Contact
+   */
+  public function getImporterObject() {
+    $importer = new CRM_Contact_Import_Parser_Contact(
+      $this->getFieldNames(),
+      $this->getFieldLocationTypes(),
+      $this->getFieldPhoneTypes(),
+      $this->getFieldIMProviderTypes(),
+      // @todo - figure out related mappings.
+      // $mapperRelated = [], $mapperRelatedContactType = [], $mapperRelatedContactDetails = [], $mapperRelatedContactLocType = [], $mapperRelatedContactPhoneType = [], $mapperRelatedContactImProvider = [],
+      [],
+      [],
+      [],
+      [],
+      [],
+      [],
+      $this->getFieldWebsiteTypes()
+      // $mapperRelatedContactWebsiteType = []
+    );
+    $importer->init();
+    $importer->_contactType = $this->getContactType();
+    return $importer;
+  }
+
+}
index ff4e11c6c9ef64bfc2624ea51031de8124525174..b7fe612e49882fe3fde620ec5ee09aef6406ea1b 100644 (file)
@@ -333,6 +333,40 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase {
     $this->callAPISuccessGetSingle('Contact', $contactValues);
   }
 
+  /**
+   * Test prefix & suffix work when you specify the label.
+   *
+   * There is an expectation that you can import by label here.
+   *
+   * @throws \CRM_Core_Exception
+   * @throws \CiviCRM_API3_Exception
+   */
+  public function testPrefixLabel() {
+    $this->callAPISuccess('OptionValue', 'create', ['option_group_id' => 'individual_prefix', 'name' => 'new_one', 'label' => 'special', 'value' => 70]);
+    $mapping = [
+      ['name' => 'first_name', 'column_number' => 1],
+      ['name' => 'last_name', 'column_number' => 2],
+      ['name' => 'email', 'column_number' => 3, 'location_type_id' => CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_Email', 'location_type_id', 'Home')],
+      ['name' => 'prefix_id', 'column_number' => 5],
+      ['name' => 'suffix_id', 'column_number' => 4],
+    ];
+    $processor = new CRM_Import_ImportProcessor();
+    $processor->setMappingFields($mapping);
+    $processor->setContactType('Individual');
+    $importer = $processor->getImporterObject();
+
+    $contactValues = [
+      'Bill',
+      'Gates',
+      'bill.gates@microsoft.com',
+      'III',
+      'special',
+    ];
+    $importer->import(CRM_Import_Parser::DUPLICATE_NOCHECK, $contactValues);
+
+    $contact = $this->callAPISuccessGetSingle('Contact', ['first_name' => 'Bill', 'prefix_id' => 'new_one', 'suffix_id' => 'III']);
+  }
+
   /**
    * Test that labels work for importing custom data.
    *