Merge pull request #22312 from mlutfy/eventPhpTweak
authorTim Otten <totten@civicrm.org>
Fri, 24 Dec 2021 01:02:41 +0000 (17:02 -0800)
committerGitHub <noreply@github.com>
Fri, 24 Dec 2021 01:02:41 +0000 (17:02 -0800)
Event Registration: initialize array

12 files changed:
CRM/Core/BAO/Address.php
CRM/Core/BAO/CustomValueTable.php
CRM/Core/DAO/CustomField.php
CRM/Core/DAO/CustomGroup.php
api/v3/MailingContact.php
api/v3/utils.php
ext/search_kit/Civi/Api4/Action/SearchDisplay/AbstractRunAction.php
ext/search_kit/Civi/Search/Display.php
tests/phpunit/CRM/Contact/BAO/ContactType/ContactSearchTest.php
tests/phpunit/api/v3/AddressTest.php
xml/schema/Core/CustomField.xml
xml/schema/Core/CustomGroup.xml

index f7c8ca8ecc3ca461c11eae347b489dbfafb50f95..e2644ab53905ff5879c27884943e001e6f1e100d 100644 (file)
@@ -78,7 +78,7 @@ class CRM_Core_BAO_Address extends CRM_Core_DAO_Address {
     if ($address->id) {
       // first get custom field from master address if any
       if (isset($params['master_id']) && !CRM_Utils_System::isNull($params['master_id'])) {
-        $address->copyCustomFields($params['master_id'], $address->id);
+        $address->copyCustomFields($params['master_id'], $address->id, $hook);
       }
 
       if (isset($params['custom'])) {
index 8556c4ec217b11812661f23ce4725864a2da51f2..555de5f9f9f5e00550dee1c6a30b0d9a988ba367 100644 (file)
@@ -376,6 +376,13 @@ class CRM_Core_BAO_CustomValueTable {
         if (!empty($customValue['id'])) {
           $cvParam['id'] = $customValue['id'];
         }
+        elseif (empty($cvParam['is_multiple']) && !empty($entityID)) {
+          // dev/core#3000 Ensure that if we are not dealing with multiple record custom data and for some reason have got here without getting the id of the record in the custom table for this entityId let us give it one last shot
+          $rowId = CRM_Core_DAO::singleValueQuery("SELECT id FROM {$cvParam['table_name']} WHERE entity_id = %1", [1 => [$entityID, 'Integer']]);
+          if (!empty($rowId)) {
+            $cvParam['id'] = $rowId;
+          }
+        }
         if (!array_key_exists($customValue['table_name'], $cvParams)) {
           $cvParams[$customValue['table_name']] = [];
         }
index 758beb4cf98b0b7f795284ead6d09d96e08c940e..0e2cb68355b8575e0a28431481362d06e72e87bb 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Generated from xml/schema/CRM/Core/CustomField.xml
  * DO NOT EDIT.  Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:b53a928be3c87ec7da4f88da3ec825b8)
+ * (GenCodeChecksum:c093cac865bba7796c2c7deda6579f40)
  */
 
 /**
@@ -37,6 +37,19 @@ class CRM_Core_DAO_CustomField extends CRM_Core_DAO {
    */
   public static $_log = TRUE;
 
+  /**
+   * Paths for accessing this entity in the UI.
+   *
+   * @var string[]
+   */
+  protected static $_paths = [
+    'add' => 'civicrm/admin/custom/group/field/add?reset=1&action=add&gid=[custom_group_id]',
+    'update' => 'civicrm/admin/custom/group/field/update?action=update&reset=1&id=[id]&gid=[custom_group_id]',
+    'preview' => 'civicrm/admin/custom/group/field?action=preview&reset=1&id=[id]&gid=[custom_group_id]',
+    'delete' => 'civicrm/admin/custom/group/field?action=delete&reset=1&id=[id]&gid=[custom_group_id]',
+    'move' => 'civicrm/admin/custom/group/field/move?reset=1&fid=[id]',
+  ];
+
   /**
    * Unique Custom Field ID
    *
index 02989e424adba16454db38fc3a12318c9122bf14..a57c659aae3a4812e92362941a06f6d850c60a34 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Generated from xml/schema/CRM/Core/CustomGroup.xml
  * DO NOT EDIT.  Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:27a1b80ba9d2696e97dd1df33468caff)
+ * (GenCodeChecksum:57ebfb396e58116709f9d883a46edfa7)
  */
 
 /**
@@ -37,6 +37,18 @@ class CRM_Core_DAO_CustomGroup extends CRM_Core_DAO {
    */
   public static $_log = TRUE;
 
+  /**
+   * Paths for accessing this entity in the UI.
+   *
+   * @var string[]
+   */
+  protected static $_paths = [
+    'add' => 'civicrm/admin/custom/group?action=add&reset=1',
+    'update' => 'civicrm/admin/custom/group?action=update&reset=1&id=[id]',
+    'preview' => 'civicrm/admin/custom/group?action=preview&reset=1&id=[id]',
+    'delete' => 'civicrm/admin/custom/group?action=delete&reset=1&id=[id]',
+  ];
+
   /**
    * Unique Custom Group ID
    *
index b3f2d8bb2608234716260d5a95d40f343820564c..4875e79340423624cab3d2cd4c7f953c492fe076 100644 (file)
@@ -43,6 +43,9 @@ function _civicrm_api3_mailing_contact_getresults($params, $count) {
   }
   $options  = _civicrm_api3_get_options_from_params($params, TRUE, 'contribution', 'get');
   $fnName = '_civicrm_api3_mailing_contact_get_' . strtolower($params['type']);
+  if (!function_exists($fnName)) {
+    throw new API_Exception('Invalid mailing type: ' . $params['type']);
+  }
   return $fnName(
       $params['contact_id'],
       $options['offset'],
index 93b899b5e0c72add30db491a3876d7e2cec18f66..3272066ef75adfc181636cb22deb3773e0528006 100644 (file)
@@ -1498,7 +1498,7 @@ function _civicrm_api3_validate($entity, $action, $params) {
   foreach ($finalfields as $fieldInfo) {
     $fieldName = $fieldInfo['name'];
     try {
-      _civicrm_api3_validate_switch_cases($fieldName, $fieldInfo, $entity, $params);
+      _civicrm_api3_validate_switch_cases($fieldName, $fieldInfo, $entity, $params, $action);
     }
     catch (Exception $e) {
       $errors[$fieldName] = [
@@ -1517,11 +1517,12 @@ function _civicrm_api3_validate($entity, $action, $params) {
  * @param array $fieldInfo
  * @param string $entity
  * @param array $params
+ * @param string $action
  *
  * @throws API_Exception
  * @throws Exception
  */
-function _civicrm_api3_validate_switch_cases($fieldName, $fieldInfo, $entity, $params) {
+function _civicrm_api3_validate_switch_cases($fieldName, $fieldInfo, $entity, $params, $action) {
   switch (CRM_Utils_Array::value('type', $fieldInfo)) {
     case CRM_Utils_Type::T_INT:
       _civicrm_api3_validate_integer($params, $fieldName, $fieldInfo, $entity);
@@ -1536,7 +1537,7 @@ function _civicrm_api3_validate_switch_cases($fieldName, $fieldInfo, $entity, $p
 
     case CRM_Utils_Type::T_TEXT:
     case CRM_Utils_Type::T_STRING:
-      _civicrm_api3_validate_string($params, $fieldName, $fieldInfo, $entity);
+      _civicrm_api3_validate_string($params, $fieldName, $fieldInfo, $entity, $action);
       break;
 
     case CRM_Utils_Type::T_MONEY:
@@ -1605,7 +1606,7 @@ function _civicrm_api3_validate_fields($entity, $action, &$params, $fields) {
 
       case CRM_Utils_Type::T_TEXT:
       case CRM_Utils_Type::T_STRING:
-        _civicrm_api3_validate_string($params, $fieldName, $fieldInfo, $entity);
+        _civicrm_api3_validate_string($params, $fieldName, $fieldInfo, $entity, $action);
         break;
 
       case CRM_Utils_Type::T_MONEY:
@@ -2225,11 +2226,13 @@ function _civicrm_api3_validate_html(&$params, &$fieldName, $fieldInfo) {
  * @param array $fieldInfo
  *   Array of fields from getfields function.
  * @param string $entity
+ * @param string $action
  *
  * @throws API_Exception
  * @throws Exception
  */
-function _civicrm_api3_validate_string(&$params, &$fieldName, &$fieldInfo, $entity) {
+function _civicrm_api3_validate_string(&$params, &$fieldName, &$fieldInfo, $entity, $action) {
+  $isGet = substr($action, 0, 3) === 'get';
   list($fieldValue, $op) = _civicrm_api3_field_value_check($params, $fieldName, 'String');
   if (strpos($op, 'NULL') !== FALSE || strpos($op, 'EMPTY') !== FALSE || CRM_Utils_System::isNull($fieldValue)) {
     return;
@@ -2250,7 +2253,15 @@ function _civicrm_api3_validate_string(&$params, &$fieldName, &$fieldInfo, $enti
     }
   }
   if (!empty($fieldInfo['pseudoconstant']) || !empty($fieldInfo['options'])) {
-    _civicrm_api3_api_match_pseudoconstant($fieldValue, $entity, $fieldName, $fieldInfo, $op);
+    try {
+      _civicrm_api3_api_match_pseudoconstant($fieldValue, $entity, $fieldName, $fieldInfo, $op);
+    }
+    catch (API_Exception $e) {
+      // For get operations, allow any string
+      if (!$isGet) {
+        throw $e;
+      }
+    }
   }
   // Check our field length
   elseif (is_string($fieldValue) && !empty($fieldInfo['maxlength']) && strlen(utf8_decode($fieldValue)) > $fieldInfo['maxlength']) {
index e49b718f73943674d78657cb39afa7893639bd36..0ed8a5642c8c627ee162aebf35d97a002c72e36d 100644 (file)
@@ -404,12 +404,13 @@ abstract class AbstractRunAction extends \Civi\Api4\Generic\AbstractAction {
       }
       // Check access for edit/update links
       // (presumably if a record is shown in SearchKit the user already has view access, and the check is expensive)
-      if ($path && isset($data) && $link['action'] !== 'view') {
+      if ($path && isset($data) && !in_array($link['action'], ['view', 'preview'], TRUE)) {
         $id = $data[$prefix . $idKey] ?? NULL;
         $id = is_array($id) ? $id[$index] ?? NULL : $id;
         if ($id) {
           $access = civicrm_api4($link['entity'], 'checkAccess', [
-            'action' => $link['action'],
+            // Fudge links with funny action names to check 'update'
+            'action' => $link['action'] === 'delete' ? 'delete' : 'update',
             'values' => [
               $idField => $id,
             ],
index 3268807f43dc072ffe630b847c5f275128ce98ed..4f9e3cce225b1e9ab76b2cef878caf50577e5cb7 100644 (file)
@@ -78,6 +78,14 @@ class Display {
           // Contacts and cases are too cumbersome to view in a popup
           'target' => in_array($entity, ['Contact', 'Case']) ? '_blank' : 'crm-popup',
         ],
+        'preview' => [
+          'action' => 'preview',
+          'entity' => $entity,
+          'text' => E::ts('Preview %1', $label),
+          'icon' => 'fa-eye',
+          'style' => 'default',
+          'target' => 'crm-popup',
+        ],
         'update' => [
           'action' => 'update',
           'entity' => $entity,
@@ -87,6 +95,14 @@ class Display {
           // Contacts and cases are too cumbersome to edit in a popup
           'target' => in_array($entity, ['Contact', 'Case']) ? '_blank' : 'crm-popup',
         ],
+        'move' => [
+          'action' => 'move',
+          'entity' => $entity,
+          'text' => E::ts('Move %1', $label),
+          'icon' => 'fa-random',
+          'style' => 'default',
+          'target' => 'crm-popup',
+        ],
         'delete' => [
           'action' => 'delete',
           'entity' => $entity,
index ead6037968751060b3c19102c7857eac05dfbfbc..93c0afd3bd2969f9dc8c25dd590ed1990554f1d9 100644 (file)
@@ -245,85 +245,4 @@ class CRM_Contact_BAO_ContactType_ContactSearchTest extends CiviUnitTestCase {
     $this->assertNotContains($this->household, $result['values']);
   }
 
-  /**
-   * Search with invalid type or subtype.
-   */
-  public function testSearchWithInvalidData() {
-    // for invalid type
-    $params = [
-      'contact_type' => 'Invalid' . CRM_Core_DAO::VALUE_SEPARATOR . 'Invalid',
-      'version' => 3,
-    ];
-    $result = civicrm_api('contact', 'get', $params);
-    $this->assertEquals(empty($result['values']), TRUE);
-
-    // for invalid subtype
-    $params = ['contact_sub_type' => 'Invalid', 'version' => 3];
-    $result = civicrm_api('contact', 'get', $params);
-    $this->assertEquals(empty($result['values']), TRUE);
-
-    // for invalid contact type as well as subtype
-    $params = [
-      'contact_type' => 'Invalid' . CRM_Core_DAO::VALUE_SEPARATOR . 'Invalid',
-      'version' => 3,
-    ];
-    $result = civicrm_api('contact', 'get', $params);
-    $this->assertEquals(empty($result['values']), TRUE);
-
-    // for valid type and invalid subtype
-    $params = [
-      'contact_type' => 'Individual' . CRM_Core_DAO::VALUE_SEPARATOR . 'Invalid',
-      'version' => 3,
-    ];
-    $result = civicrm_api('contact', 'get', $params);
-    $this->assertEquals(empty($result['values']), TRUE);
-
-    // for invalid type and valid subtype
-    $params = [
-      'contact_type' => 'Invalid' . CRM_Core_DAO::VALUE_SEPARATOR . 'indivi_student',
-      'version' => 3,
-    ];
-    $result = civicrm_api('contact', 'get', $params);
-    $this->assertEquals(empty($result['values']), TRUE);
-  }
-
-  /**
-   * Search with wrong type or subtype.
-   */
-  public function testSearchWithWrongdData() {
-
-    // for type:Individual subtype:Sponsor
-    $defaults = [];
-    $params = [
-      'contact_type' => 'Individual' . CRM_Core_DAO::VALUE_SEPARATOR . $this->sponsor,
-      'version' => 3,
-    ];
-    $result = civicrm_api('contact', 'get', $params);
-    $this->assertEquals(empty($result['values']), TRUE);
-
-    // for type:Orgaization subtype:Parent
-    $params = [
-      'contact_type' => 'Orgaization' . CRM_Core_DAO::VALUE_SEPARATOR . $this->parent,
-      'version' => 3,
-    ];
-    $result = civicrm_api('contact', 'get', $params, $defaults);
-    $this->assertEquals(empty($result['values']), TRUE);
-
-    // for type:Household subtype:Sponsor
-    $params = [
-      'contact_type' => 'Household' . CRM_Core_DAO::VALUE_SEPARATOR . $this->sponsor,
-      'version' => 3,
-    ];
-    $result = civicrm_api('contact', 'get', $params, $defaults);
-    $this->assertEquals(empty($result['values']), TRUE);
-
-    // for type:Household subtype:Student
-    $params = [
-      'contact_type' => 'Household' . CRM_Core_DAO::VALUE_SEPARATOR . $this->student,
-      'version' => 3,
-    ];
-    $result = civicrm_api('contact', 'get', $params, $defaults);
-    $this->assertEquals(empty($result['values']), TRUE);
-  }
-
 }
index 10362fb75f97c1ddeb15035a075520846e00748b..b8acd353c02322f0f684dc0553e15a81d2d990ab 100644 (file)
@@ -609,4 +609,21 @@ class api_v3_AddressTest extends CiviUnitTestCase {
     $this->assertNotContains('Alabama', $result['values']);
   }
 
+  public function testUpdateSharedAddressWithCustomFields() {
+    $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
+
+    $params = $this->_params;
+    $params['custom_' . $ids['custom_field_id']] = "custom string";
+
+    $firstAddress = $this->callAPISuccess($this->_entity, 'create', $params);
+
+    $contactIdB = $this->individualCreate();
+
+    $secondAddressParams = array_merge(['contact_id' => $contactIdB, 'master_id' => $firstAddress['id']], $firstAddress);
+    unset($secondAddressParams['id']);
+    $secondAddress = $this->callAPISuccess('Address', 'create', $secondAddressParams);
+    // Ensure an update to the second address doesn't cause a "db error: already exists" when resaving the custom fields.
+    $this->callAPISuccess('Address', 'create', ['id' => $secondAddress['id'], 'contact_id' => $contactIdB, 'master_id' => $firstAddress['id']]);
+  }
+
 }
index 71e18628508c162aa7202bdd941350858651ad3a..8fb1c82c10b0115454bff015afd9498d0de4ca4a 100644 (file)
@@ -8,6 +8,13 @@
   <add>1.1</add>
   <log>true</log>
   <labelField>label</labelField>
+  <paths>
+    <add>civicrm/admin/custom/group/field/add?reset=1&amp;action=add&amp;gid=[custom_group_id]</add>
+    <update>civicrm/admin/custom/group/field/update?action=update&amp;reset=1&amp;id=[id]&amp;gid=[custom_group_id]</update>
+    <preview>civicrm/admin/custom/group/field?action=preview&amp;reset=1&amp;id=[id]&amp;gid=[custom_group_id]</preview>
+    <delete>civicrm/admin/custom/group/field?action=delete&amp;reset=1&amp;id=[id]&amp;gid=[custom_group_id]</delete>
+    <move>civicrm/admin/custom/group/field/move?reset=1&amp;fid=[id]</move>
+  </paths>
   <field>
     <name>id</name>
     <type>int unsigned</type>
index d65d9c1ee85ffc8c819b0ec4227246529587ed1b..853a106e3263e247bbf5a71a530ccbc4588055a1 100644 (file)
   <log>true</log>
   <title>Custom Field Group</title>
   <labelField>title</labelField>
+  <paths>
+    <add>civicrm/admin/custom/group?action=add&amp;reset=1</add>
+    <update>civicrm/admin/custom/group?action=update&amp;reset=1&amp;id=[id]</update>
+    <preview>civicrm/admin/custom/group?action=preview&amp;reset=1&amp;id=[id]</preview>
+    <delete>civicrm/admin/custom/group?action=delete&amp;reset=1&amp;id=[id]</delete>
+  </paths>
   <field>
     <name>id</name>
     <type>int unsigned</type>