Move engagement level validation into the validate section
[civicrm-core.git] / CRM / Activity / Import / Parser / Activity.php
index 86186d256cee6367f23ff512b4ca9d2baad62108..7699d2ad01af01f0e5767581bd6e37954acdfb8c 100644 (file)
@@ -24,9 +24,6 @@ class CRM_Activity_Import_Parser_Activity extends CRM_Activity_Import_Parser {
   protected $_mapperKeys;
 
   private $_contactIdIndex;
-  private $_activityTypeIndex;
-  private $_activityLabelIndex;
-  private $_activityDateIndex;
 
   /**
    * Array of successfully imported activity id's
@@ -84,9 +81,6 @@ class CRM_Activity_Import_Parser_Activity extends CRM_Activity_Import_Parser {
 
     // FIXME: we should do this in one place together with Form/MapField.php
     $this->_contactIdIndex = -1;
-    $this->_activityTypeIndex = -1;
-    $this->_activityLabelIndex = -1;
-    $this->_activityDateIndex = -1;
 
     $index = 0;
     foreach ($this->_mapperKeys as $key) {
@@ -95,18 +89,6 @@ class CRM_Activity_Import_Parser_Activity extends CRM_Activity_Import_Parser {
         case 'external_identifier':
           $this->_contactIdIndex = $index;
           break;
-
-        case 'activity_label':
-          $this->_activityLabelIndex = $index;
-          break;
-
-        case 'activity_type_id':
-          $this->_activityTypeIndex = $index;
-          break;
-
-        case 'activity_date_time':
-          $this->_activityDateIndex = $index;
-          break;
       }
       $index++;
     }
@@ -147,61 +129,40 @@ class CRM_Activity_Import_Parser_Activity extends CRM_Activity_Import_Parser {
    *   the result of this processing
    */
   public function summary(&$values) {
-    $erroneousField = NULL;
-    $this->setActiveFieldValues($values, $erroneousField);
-    $index = -1;
+    $this->setActiveFieldValues($values);
+
+    try {
+      // Check required fields if this is not an update.
+      if (!$this->getFieldValue($values, 'activity_id')) {
+        if (!$this->getFieldValue($values, 'activity_label')
+        && !$this->getFieldValue($values, 'activity_type_id')) {
+          throw new CRM_Core_Exception(ts('Missing required fields: Activity type label or Activity type ID'));
+        }
+        if (!$this->getFieldValue($values, 'activity_date_time')) {
+          throw new CRM_Core_Exception(ts('Missing required fields'));
+        }
+      }
 
-    if ($this->_activityTypeIndex > -1 && $this->_activityLabelIndex > -1) {
-      array_unshift($values, ts('Please select either Activity Type ID OR Activity Type Label.'));
-      return CRM_Import_Parser::ERROR;
-    }
-    elseif ($this->_activityLabelIndex > -1) {
-      $index = $this->_activityLabelIndex;
-    }
-    elseif ($this->_activityTypeIndex > -1) {
-      $index = $this->_activityTypeIndex;
-    }
+      $this->validateActivityTypeIDAndLabel($values);
+      if ($this->getFieldValue($values, 'activity_date_time')
+      && !$this->isValidDate($this->getFieldValue($values, 'activity_date_time'))) {
+        throw new CRM_Core_Exception(ts('Invalid Activity Date'));
+      }
 
-    if ($index < 0 or $this->_activityDateIndex < 0) {
-      $errorRequired = TRUE;
-    }
-    else {
-      $errorRequired = !CRM_Utils_Array::value($index, $values) || !CRM_Utils_Array::value($this->_activityDateIndex, $values);
-    }
+      if ($this->getFieldValue($values, 'activity_engagement_level')
+        && !CRM_Utils_Rule::positiveInteger($this->getFieldValue($values, 'activity_engagement_level'))) {
+        throw new CRM_Core_Exception(ts('Activity Engagement Index'));
+      }
 
-    if ($errorRequired) {
-      array_unshift($values, ts('Missing required fields'));
-      return CRM_Import_Parser::ERROR;
+    }
+    catch (CRM_Core_Exception $e) {
+      return $this->addError($values, [$e->getMessage()]);
     }
 
-    $params = &$this->getActiveFieldParams();
+    $params = $this->getActiveFieldParams();
 
     $errorMessage = NULL;
 
-    // For date-Formats
-    $session = CRM_Core_Session::singleton();
-    $dateType = $session->get('dateTypes');
-    if (!isset($params['source_contact_id'])) {
-      $params['source_contact_id'] = $session->get('userID');
-    }
-    foreach ($params as $key => $val) {
-      if ($key == 'activity_date_time') {
-        if ($val) {
-          $dateValue = CRM_Utils_Date::formatDate($val, $dateType);
-          if ($dateValue) {
-            $params[$key] = $dateValue;
-          }
-          else {
-            CRM_Contact_Import_Parser_Contact::addToErrorMsg('Activity date', $errorMessage);
-          }
-        }
-      }
-      elseif ($key == 'activity_engagement_level' && $val &&
-        !CRM_Utils_Rule::positiveInteger($val)
-      ) {
-        CRM_Contact_Import_Parser_Contact::addToErrorMsg('Activity Engagement Index', $errorMessage);
-      }
-    }
     // Date-Format part ends.
 
     // Checking error in custom data.
@@ -229,6 +190,7 @@ class CRM_Activity_Import_Parser_Activity extends CRM_Activity_Import_Parser {
    *
    * @return bool
    *   the result of this processing
+   * @throws \CRM_Core_Exception
    */
   public function import($onDuplicate, &$values) {
     // First make sure this is a valid line
@@ -237,7 +199,7 @@ class CRM_Activity_Import_Parser_Activity extends CRM_Activity_Import_Parser {
     if ($response != CRM_Import_Parser::VALID) {
       return $response;
     }
-    $params = &$this->getActiveFieldParams();
+    $params = $this->getActiveFieldParams();
     $activityLabel = array_search('activity_label', $this->_mapperKeys);
     if ($activityLabel) {
       $params = array_merge($params, ['activity_label' => $values[$activityLabel]]);
@@ -253,20 +215,17 @@ class CRM_Activity_Import_Parser_Activity extends CRM_Activity_Import_Parser {
 
     foreach ($params as $key => $val) {
       if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
-        if ($key == 'activity_date_time' && $val) {
-          $params[$key] = CRM_Utils_Date::formatDate($val, $dateType);
-        }
-        elseif (!empty($customFields[$customFieldID]) && $customFields[$customFieldID]['data_type'] == 'Date') {
+        if (!empty($customFields[$customFieldID]) && $customFields[$customFieldID]['data_type'] == 'Date') {
           CRM_Contact_Import_Parser_Contact::formatCustomDate($params, $params, $dateType, $key);
         }
         elseif (!empty($customFields[$customFieldID]) && $customFields[$customFieldID]['data_type'] == 'Boolean') {
           $params[$key] = CRM_Utils_String::strtoboolstr($val);
         }
       }
-      elseif ($key == 'activity_date_time') {
+      elseif ($key === 'activity_date_time') {
         $params[$key] = CRM_Utils_Date::formatDate($val, $dateType);
       }
-      elseif ($key == 'activity_subject') {
+      elseif ($key === 'activity_subject') {
         $params['subject'] = $val;
       }
     }
@@ -407,4 +366,73 @@ class CRM_Activity_Import_Parser_Activity extends CRM_Activity_Import_Parser {
     return NULL;
   }
 
+  /**
+   *
+   * Get the value for the given field from the row of values.
+   *
+   * @param array $row
+   * @param string $fieldName
+   *
+   * @return null|string
+   */
+  protected function getFieldValue(array $row, string $fieldName) {
+    if (!is_numeric($this->getFieldIndex($fieldName))) {
+      return NULL;
+    }
+    return $row[$this->getFieldIndex($fieldName)] ?? NULL;
+  }
+
+  /**
+   * Get the index for the given field.
+   *
+   * @param string $fieldName
+   *
+   * @return false|int
+   */
+  protected function getFieldIndex(string $fieldName) {
+    return array_search($fieldName, $this->_mapperKeys, TRUE);
+
+  }
+
+  /**
+   * Add an error to the values.
+   *
+   * @param array $values
+   * @param array $error
+   *
+   * @return int
+   */
+  protected function addError(array &$values, array $error): int {
+    array_unshift($values, implode(';', $error));
+    return CRM_Import_Parser::ERROR;
+  }
+
+  /**
+   * Validate that the activity type id does not conflict with the label.
+   *
+   * @param array $values
+   *
+   * @return void
+   * @throws \CRM_Core_Exception
+   */
+  protected function validateActivityTypeIDAndLabel(array $values): void {
+    $activityLabel = $this->getFieldValue($values, 'activity_label');
+    $activityTypeID = $this->getFieldValue($values, 'activity_type_id');
+    if ($activityLabel && $activityTypeID
+      && $activityLabel !== CRM_Core_PseudoConstant::getLabel('CRM_Activity_BAO_Activity', 'activity_type_id', $activityTypeID)) {
+      throw new CRM_Core_Exception(ts('Activity type label and Activity type ID are in conflict'));
+    }
+  }
+
+  /**
+   * Is the supplied date field valid based on selected date format.
+   *
+   * @param string $value
+   *
+   * @return bool
+   */
+  protected function isValidDate(string $value): bool {
+    return (bool) CRM_Utils_Date::formatDate($value, CRM_Core_Session::singleton()->get('dateTypes'));
+  }
+
 }