Merge pull request #17187 from alexymik/recur_contribution_source
[civicrm-core.git] / tests / phpunit / CRMTraits / Custom / CustomDataTrait.php
index 6830c8a517dce6e6757187d697a8fe9dde35ceaf..23f26fa62cd12e90fe28dd81148c978595f0d618 100644 (file)
@@ -9,6 +9,8 @@
  +--------------------------------------------------------------------+
  */
 
+use Civi\Api4\CustomGroup;
+
 /**
  * Trait Custom Data trait.
  *
@@ -20,6 +22,9 @@ trait CRMTraits_Custom_CustomDataTrait {
    * Create a custom group with fields of multiple types.
    *
    * @param array $groupParams
+   *
+   * @throws \API_Exception
+   * @throws \Civi\API\Exception\UnauthorizedException
    */
   public function createCustomGroupWithFieldsOfAllTypes($groupParams = []) {
     $this->createCustomGroup($groupParams);
@@ -32,6 +37,9 @@ trait CRMTraits_Custom_CustomDataTrait {
    * @param array $params
    *
    * @return int
+   *
+   * @throws \API_Exception
+   * @throws \Civi\API\Exception\UnauthorizedException
    */
   public function createCustomGroup($params = []) {
     $params = array_merge([
@@ -42,7 +50,7 @@ trait CRMTraits_Custom_CustomDataTrait {
       'max_multiple' => 0,
     ], $params);
     $identifier = $params['name'] ?? $params['title'];
-    $this->ids['CustomGroup'][$identifier] = $this->callAPISuccess('CustomGroup', 'create', $params)['id'];
+    $this->ids['CustomGroup'][$identifier] = CustomGroup::create()->setCheckPermissions(FALSE)->setValues($params)->execute()->first()['id'];
     return $this->ids['CustomGroup'][$identifier];
   }
 
@@ -73,38 +81,46 @@ trait CRMTraits_Custom_CustomDataTrait {
    * Create a custom group with a single field.
    *
    * @param array $groupParams
+   *   Params for the group to be created.
    * @param string $customFieldType
    *
    * @param string $identifier
    *
+   * @throws \API_Exception
    * @throws \CRM_Core_Exception
+   * @throws \Civi\API\Exception\UnauthorizedException
    */
   public function createCustomGroupWithFieldOfType($groupParams = [], $customFieldType = 'text', $identifier = NULL) {
-    $supported = ['text', 'select', 'date', 'int'];
+    $supported = ['text', 'select', 'date', 'int', 'contact_reference'];
     if (!in_array($customFieldType, $supported, TRUE)) {
       throw new CRM_Core_Exception('we have not yet extracted other custom field types from createCustomFieldsOfAllTypes, Use consistent syntax when you do');
     }
     $groupParams['title'] = empty($groupParams['title']) ? $identifier . 'Group with field ' . $customFieldType : $groupParams['title'];
     $groupParams['name'] = $identifier ?? 'Custom Group';
     $this->createCustomGroup($groupParams);
+    $reference = &$this->ids['CustomField'][$identifier . $customFieldType];
+    $fieldParams = ['custom_group_id' => $this->ids['CustomGroup'][$groupParams['name']]];
     switch ($customFieldType) {
       case 'text':
-        $customField = $this->createTextCustomField(['custom_group_id' => $this->ids['CustomGroup'][$groupParams['name']]]);
-        break;
+        $reference = $this->createTextCustomField($fieldParams)['id'];
+        return;
 
       case 'select':
-        $customField = $this->createSelectCustomField(['custom_group_id' => $this->ids['CustomGroup'][$groupParams['name']]]);
-        break;
+        $reference = $this->createSelectCustomField($fieldParams)['id'];
+        return;
 
       case 'int':
-        $customField = $this->createIntCustomField(['custom_group_id' => $this->ids['CustomGroup'][$groupParams['name']]]);
-        break;
+        $reference = $this->createIntCustomField($fieldParams)['id'];
+        return;
 
       case 'date':
-        $customField = $this->createDateCustomField(['custom_group_id' => $this->ids['CustomGroup'][$groupParams['name']]]);
-        break;
+        $reference = $this->createDateCustomField($fieldParams)['id'];
+        return;
+
+      case 'contact_reference':
+        $reference = $this->createContactReferenceCustomField($fieldParams)['id'];
+        return;
     }
-    $this->ids['CustomField'][$identifier . $customFieldType] = $customField['id'];
   }
 
   /**
@@ -113,53 +129,18 @@ trait CRMTraits_Custom_CustomDataTrait {
   public function createCustomFieldsOfAllTypes() {
     $customGroupID = $this->ids['CustomGroup']['Custom Group'];
     $ids = [];
-    $customField = $this->createTextCustomField(['custom_group_id' => $customGroupID]);
-    $ids['text'] = $customField['id'];
-
-    if ((!empty($this->entity) && $this->entity !== 'Contribution') || empty($this->entity)) {
-      $customField = $this->createSelectCustomField(['custom_group_id' => $customGroupID]);
-      $ids['select_string'] = $customField['id'];
-    }
-
-    $customField = $this->createDateCustomField(['custom_group_id' => $customGroupID]);
-    $ids['select_date'] = $customField['id'];
-
-    $customField = $this->createIntCustomField(['custom_group_id' => $customGroupID]);
-    $ids['int'] = $customField['id'];
-
-    $params = [
-      'custom_group_id' => $customGroupID,
-      'name' => 'test_link',
-      'label' => 'test_link',
-      'html_type' => 'Link',
-      'data_type' => 'Link',
-      'default_value' => 'http://civicrm.org',
-      'weight' => 4,
-      'is_required' => 1,
-      'is_searchable' => 0,
-      'is_active' => 1,
-    ];
-
-    $customField = $this->callAPISuccess('custom_field', 'create', $params);
-
-    $ids['link'] = $customField['id'];
-    $fileField = $this->customFieldCreate([
-      'custom_group_id' => $customGroupID,
-      'data_type' => 'File',
-      'html_type' => 'File',
-      'default_value' => '',
-    ]);
-
-    $ids['file'] = $fileField['id'];
-    $ids['country'] = $this->customFieldCreate([
-      'custom_group_id' => $customGroupID,
-      'data_type' => 'Country',
-      'html_type' => 'Select Country',
-      'default_value' => '',
-      'label' => 'Country',
-      'option_type' => 0,
-    ])['id'];
-
+    $ids['text'] = (int) $this->createTextCustomField(['custom_group_id' => $customGroupID])['id'];
+    $ids['select_string'] = (int) $this->createSelectCustomField(['custom_group_id' => $customGroupID])['id'];
+    $ids['select_date'] = (int) $this->createDateCustomField(['custom_group_id' => $customGroupID])['id'];
+    $ids['int'] = (int) $this->createIntCustomField(['custom_group_id' => $customGroupID])['id'];
+    $ids['link'] = (int) $this->createLinkCustomField(['custom_group_id' => $customGroupID])['id'];
+    $ids['file'] = (int) $this->createFileCustomField(['custom_group_id' => $customGroupID])['id'];
+    $ids['country'] = (int) $this->createCountryCustomField(['custom_group_id' => $customGroupID])['id'];
+    $ids['multi_country'] = (int) $this->createMultiCountryCustomField(['custom_group_id' => $customGroupID])['id'];
+    $ids['contact_reference'] = $this->createContactReferenceCustomField(['custom_group_id' => $customGroupID])['id'];
+    $ids['state'] = (int) $this->createStateCustomField(['custom_group_id' => $customGroupID])['id'];
+    $ids['multi_state'] = (int) $this->createMultiStateCustomField(['custom_group_id' => $customGroupID])['id'];
+    $ids['boolean'] = (int) $this->createBooleanCustomField(['custom_group_id' => $customGroupID])['id'];
     return $ids;
   }
 
@@ -202,21 +183,36 @@ trait CRMTraits_Custom_CustomDataTrait {
    * @return array
    */
   protected function createIntCustomField($params = []) {
-    $params = array_merge([
-      'label' => 'Enter integer here',
-      'html_type' => 'Text',
-      'data_type' => 'Int',
-      'default_value' => '4',
-      'weight' => 1,
-      'is_required' => 1,
-      'sequential' => 1,
-      'is_searchable' => 1,
-      'is_search_range' => 1,
-    ], $params);
+    $params = array_merge($this->getFieldsValuesByType('Int'), $params);
+    return $this->callAPISuccess('CustomField', 'create', $params)['values'][0];
+  }
 
+  /**
+   * Create a custom text fields.
+   *
+   * @param array $params
+   *   Parameter overrides, must include custom_group_id.
+   *
+   * @return array
+   */
+  protected function createBooleanCustomField($params = []) {
+    $params = array_merge($this->getFieldsValuesByType('Boolean'), $params);
     return $this->callAPISuccess('CustomField', 'create', $params)['values'][0];
   }
 
+  /**
+   * Create a custom text fields.
+   *
+   * @param array $params
+   *   Parameter overrides, must include custom_group_id.
+   *
+   * @return array
+   */
+  protected function createContactReferenceCustomField($params = []) {
+    $params = array_merge($this->getFieldsValuesByType('ContactReference'), $params);
+    return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
+  }
+
   /**
    * Create a custom text fields.
    *
@@ -226,64 +222,99 @@ trait CRMTraits_Custom_CustomDataTrait {
    * @return array
    */
   protected function createTextCustomField($params = []) {
-    $params = array_merge([
-      'label' => 'Enter text here',
-      'html_type' => 'Text',
-      'data_type' => 'String',
-      'default_value' => 'xyz',
-      'weight' => 1,
-      'is_required' => 1,
-      'sequential' => 1,
-      'is_searchable' => 1,
-      'text_length' => 300,
-    ], $params);
+    $params = array_merge($this->getFieldsValuesByType('String'), $params);
+    return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
+  }
 
-    return $this->callAPISuccess('CustomField', 'create', $params)['values'][0];
+  /**
+   * Create a custom text fields.
+   *
+   * @param array $params
+   *   Parameter overrides, must include custom_group_id.
+   *
+   * @return array
+   */
+  protected function createLinkCustomField($params = []) {
+    $params = array_merge($this->getFieldsValuesByType('Link'), $params);
+    return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
   }
 
   /**
-   * Create custom select field.
+   * Create a custom country fields.
    *
    * @param array $params
    *   Parameter overrides, must include custom_group_id.
    *
    * @return array
    */
-  protected function createSelectCustomField(array $params): array {
-    $optionValue = [
-      [
-        'label' => 'Red',
-        'value' => 'R',
-        'weight' => 1,
-        'is_active' => 1,
-      ],
-      [
-        'label' => 'Yellow',
-        'value' => 'Y',
-        'weight' => 2,
-        'is_active' => 1,
-      ],
-      [
-        'label' => 'Green',
-        'value' => 'G',
-        'weight' => 3,
-        'is_active' => 1,
-      ],
-    ];
+  protected function createCountryCustomField($params = []) {
+    $params = array_merge($this->getFieldsValuesByType('Country'), $params);
+    return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
+  }
 
-    $params = array_merge([
-      'label' => 'Pick Color',
-      'html_type' => 'Select',
-      'data_type' => 'String',
-      'weight' => 2,
-      'is_required' => 1,
-      'is_searchable' => 0,
-      'is_active' => 1,
-      'option_values' => $optionValue,
-    ], $params);
+  /**
+   * Create a custom multi select country fields.
+   *
+   * @param array $params
+   *   Parameter overrides, must include custom_group_id.
+   *
+   * @return array
+   */
+  protected function createMultiCountryCustomField($params = []) {
+    $params = array_merge($this->getFieldsValuesByType('Country', 'Multi-Select Country'), $params);
+    return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
+  }
+
+  /**
+   * Create a custom state fields.
+   *
+   * @param array $params
+   *   Parameter overrides, must include custom_group_id.
+   *
+   * @return array
+   */
+  protected function createStateCustomField($params = []) {
+    $params = array_merge($this->getFieldsValuesByType('StateProvince'), $params);
+    return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
+  }
 
-    $customField = $this->callAPISuccess('custom_field', 'create', $params);
-    return $customField['values'][$customField['id']];
+  /**
+   * Create a custom multi select state fields.
+   *
+   * @param array $params
+   *   Parameter overrides, must include custom_group_id.
+   *
+   * @return array
+   */
+  protected function createMultiStateCustomField($params = []) {
+    $params = array_merge($this->getFieldsValuesByType('StateProvince', 'Multi-Select State/Province'), $params);
+    return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
+  }
+
+  /**
+   * Create a custom text fields.
+   *
+   * @param array $params
+   *   Parameter overrides, must include custom_group_id.
+   *
+   * @return array
+   */
+  protected function createFileCustomField($params = []) {
+    $params = array_merge($this->getFieldsValuesByType('File'), $params);
+    return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
+  }
+
+  /**
+   * Create custom select field.
+   *
+   * @param array $params
+   *   Parameter overrides, must include custom_group_id.
+   *
+   * @return array
+   */
+  protected function createSelectCustomField(array $params): array {
+    $params = array_merge($this->getFieldsValuesByType('String', 'Select'), $params);
+    return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
   }
 
   /**
@@ -294,20 +325,396 @@ trait CRMTraits_Custom_CustomDataTrait {
    * @return array
    */
   protected function createDateCustomField($params): array {
-    $params = array_merge([
-      'name' => 'test_date',
-      'label' => 'Test Date',
-      'html_type' => 'Select Date',
-      'data_type' => 'Date',
-      'default_value' => '20090711',
-      'weight' => 3,
+    $params = array_merge($this->getFieldsValuesByType('Date'), $params);
+    return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
+  }
+
+  /**
+   * Get default field values for the type of field.
+   *
+   * @param $dataType
+   * @param string $htmlType
+   *
+   * @return mixed
+   */
+  public function getFieldsValuesByType($dataType, $htmlType = 'default') {
+    $values = $this->getAvailableFieldCombinations()[$dataType];
+    return array_merge([
       'is_searchable' => 1,
-      'is_search_range' => 1,
-      'time_format' => 1,
-    ], $params);
+      'sequential' => 1,
+      'default_value' => '',
+      'is_required' => 0,
+    ], array_merge($values['default'], $values[$htmlType])
+    );
+  }
 
-    $customField = $this->callAPISuccess('custom_field', 'create', $params);
-    return $customField['values'][$customField['id']];
+  /**
+   * Get data available for custom fields.
+   *
+   * The 'default' key holds general values. Where more than one html type is an option
+   * then the any values that  differ to the defaults are keyed by html key.
+   *
+   * The order below is consistent with the UI.
+   *
+   * @return array
+   */
+  protected function getAvailableFieldCombinations() {
+    return [
+      'String' => [
+        'default' => [
+          'label' => 'Enter text here',
+          'html_type' => 'Text',
+          'data_type' => 'String',
+          'default_value' => 'xyz',
+          'text_length' => 300,
+        ],
+        'Select' => [
+          'label' => 'Pick Color',
+          'html_type' => 'Select',
+          'data_type' => 'String',
+          'text_length' => '',
+          'default_value' => '',
+          'option_values' => [
+            [
+              'label' => 'Red',
+              'value' => 'R',
+              'weight' => 1,
+              'is_active' => 1,
+            ],
+            [
+              'label' => 'Yellow',
+              'value' => 'Y',
+              'weight' => 2,
+              'is_active' => 1,
+            ],
+            [
+              'label' => 'Green',
+              'value' => 'G',
+              'weight' => 3,
+              'is_active' => 1,
+            ],
+          ],
+        ],
+        'Radio' => [
+          'label' => 'Pick Color',
+          'html_type' => 'Radio',
+          'data_type' => 'String',
+          'text_length' => '',
+          'default_value' => '',
+          'option_values' => [
+            [
+              'label' => 'Red',
+              'value' => 'R',
+              'weight' => 1,
+              'is_active' => 1,
+            ],
+            [
+              'label' => 'Yellow',
+              'value' => 'Y',
+              'weight' => 2,
+              'is_active' => 1,
+            ],
+            [
+              'label' => 'Green',
+              'value' => 'G',
+              'weight' => 3,
+              'is_active' => 1,
+            ],
+          ],
+        ],
+        'CheckBox' => [
+          'label' => 'Pick Color',
+          'html_type' => 'Checkbox',
+          'data_type' => 'String',
+          'text_length' => '',
+          'default_value' => '',
+          'option_values' => [
+            [
+              'label' => 'Red',
+              'value' => 'R',
+              'weight' => 1,
+              'is_active' => 1,
+            ],
+            [
+              'label' => 'Yellow',
+              'value' => 'Y',
+              'weight' => 2,
+              'is_active' => 1,
+            ],
+            [
+              'label' => 'Green',
+              'value' => 'G',
+              'weight' => 3,
+              'is_active' => 1,
+            ],
+          ],
+        ],
+        'Multi-Select' => [
+          'label' => 'Pick Color',
+          'html_type' => 'Multi-Select',
+          'data_type' => 'String',
+          'text_length' => '',
+          'default_value' => '',
+          'option_values' => [
+            [
+              'label' => 'Red',
+              'value' => 'R',
+              'weight' => 1,
+              'is_active' => 1,
+            ],
+            [
+              'label' => 'Yellow',
+              'value' => 'Y',
+              'weight' => 2,
+              'is_active' => 1,
+            ],
+            [
+              'label' => 'Green',
+              'value' => 'G',
+              'weight' => 3,
+              'is_active' => 1,
+            ],
+          ],
+        ],
+        'Autocomplete-Select' => [
+          'label' => 'Pick Color',
+          'html_type' => 'Autocomplete-Select',
+          'data_type' => 'String',
+          'text_length' => '',
+          'default_value' => '',
+          'option_values' => [
+            [
+              'label' => 'Red',
+              'value' => 'R',
+              'weight' => 1,
+              'is_active' => 1,
+            ],
+            [
+              'label' => 'Yellow',
+              'value' => 'Y',
+              'weight' => 2,
+              'is_active' => 1,
+            ],
+            [
+              'label' => 'Green',
+              'value' => 'G',
+              'weight' => 3,
+              'is_active' => 1,
+            ],
+          ],
+        ],
+      ],
+      'Int' => [
+        'default' => [
+          'label' => 'Enter integer here',
+          'html_type' => 'Text',
+          'data_type' => 'Int',
+          'default_value' => '4',
+          'is_search_range' => 1,
+        ],
+        'Select' => [
+          'label' => 'Integer select',
+          'html_type' => 'Select',
+          'option_values' => [
+            [
+              'label' => '50',
+              'value' => 3,
+              'weight' => 1,
+              'is_active' => 1,
+            ],
+            [
+              'label' => '100',
+              'value' => 4,
+              'weight' => 2,
+              'is_active' => 1,
+            ],
+          ],
+        ],
+        'Radio' => [
+          'label' => 'Integer radio',
+          'html_type' => 'Radio',
+          'option_values' => [
+            [
+              'label' => '50',
+              'value' => 3,
+              'weight' => 1,
+              'is_active' => 1,
+            ],
+            [
+              'label' => '100',
+              'value' => 4,
+              'weight' => 2,
+              'is_active' => 1,
+            ],
+          ],
+        ],
+      ],
+      'Date' => [
+        'default' => [
+          'name' => 'test_date',
+          'label' => 'Test Date',
+          'html_type' => 'Select Date',
+          'data_type' => 'Date',
+          'default_value' => '20090711',
+          'weight' => 3,
+          'is_search_range' => 1,
+          'time_format' => 1,
+        ],
+      ],
+      'Float' => [
+        'default' => [
+          'label' => 'Number',
+          'html_type' => 'Text',
+          'data_type' => 'Float',
+        ],
+        'Select' => [
+          'label' => 'Number select',
+          'html_type' => 'Select',
+          'option_values' => [
+            [
+              'label' => '50',
+              'value' => 3,
+              'weight' => 1,
+              'is_active' => 1,
+            ],
+            [
+              'label' => '100',
+              'value' => 4,
+              'weight' => 2,
+              'is_active' => 1,
+            ],
+          ],
+        ],
+        'Radio' => [
+          'label' => 'Number radio',
+          'html_type' => 'Radio',
+          'option_values' => [
+            [
+              'label' => '50',
+              'value' => 3,
+              'weight' => 1,
+              'is_active' => 1,
+            ],
+            [
+              'label' => '100',
+              'value' => 4,
+              'weight' => 2,
+              'is_active' => 1,
+            ],
+          ],
+        ],
+      ],
+      'Money' => [
+        'default' => [
+          'label' => 'Money',
+          'html_type' => 'Text',
+          'data_type' => 'Money',
+        ],
+        'Select' => [
+          'label' => 'Money select',
+          'html_type' => 'Select',
+          'option_values' => [
+            [
+              'label' => '50',
+              'value' => 3,
+              'weight' => 1,
+              'is_active' => 1,
+            ],
+            [
+              'label' => '100',
+              'value' => 4,
+              'weight' => 2,
+              'is_active' => 1,
+            ],
+          ],
+        ],
+        'Radio' => [
+          'label' => 'Money radio',
+          'html_type' => 'Radio',
+          'option_values' => [
+            [
+              'label' => '50',
+              'value' => 3,
+              'weight' => 1,
+              'is_active' => 1,
+            ],
+            [
+              'label' => '100',
+              'value' => 4,
+              'weight' => 2,
+              'is_active' => 1,
+            ],
+          ],
+        ],
+      ],
+      'Memo' => [
+        'default' => [
+          'label' => 'Memo',
+          'html_type' => 'TextArea',
+          'data_type' => 'Memo',
+          'attributes' => 'rows=4, cols=60',
+        ],
+        'RichTextEditor' => [
+          'label' => 'Memo Rich Text Editor',
+          'html_type' => 'Memo',
+        ],
+      ],
+      'Boolean' => [
+        'default' => [
+          'data_type' => 'Boolean',
+          'html_type' => 'Radio',
+          'label' => 'Yes No',
+        ],
+      ],
+      'StateProvince' => [
+        'default' => [
+          'data_type' => 'StateProvince',
+          'html_type' => 'Select State/Province',
+          'label' => 'State',
+          'option_type' => 0,
+        ],
+        'Multi-Select State/Province' => [
+          'html_type' => 'Multi-Select State/Province',
+          'label' => 'State-multi',
+        ],
+      ],
+      'Country' => [
+        'default' => [
+          'data_type' => 'Country',
+          'html_type' => 'Select Country',
+          'label' => 'Country',
+          'option_type' => 0,
+        ],
+        'Multi-Select Country' => [
+          'html_type' => 'Multi-Select Country',
+          'label' => 'Country-multi',
+          'option_type' => 0,
+        ],
+      ],
+      'File' => [
+        'default' => [
+          'label' => 'My file',
+          'data_type' => 'File',
+          'html_type' => 'File',
+        ],
+      ],
+      'Link' => [
+        'default' => [
+          'name' => 'test_link',
+          'label' => 'test_link',
+          'html_type' => 'Link',
+          'data_type' => 'Link',
+          'default_value' => 'http://civicrm.org',
+        ],
+      ],
+      'ContactReference' => [
+        'default' => [
+          'label' => 'Contact reference field',
+          'html_type' => 'Autocomplete-Select',
+          'data_type' => 'ContactReference',
+        ],
+      ],
+    ];
   }
 
 }