dev/core#1374 dev/core#1374 Fix search formValue handling on contribution search
authorSeamus Lee <seamuslee001@gmail.com>
Wed, 20 Nov 2019 18:56:43 +0000 (05:56 +1100)
committerSeamus Lee <seamuslee001@gmail.com>
Wed, 20 Nov 2019 18:56:43 +0000 (05:56 +1100)
CRM/Contact/Form/Search/Advanced.php
CRM/Contribute/Form/Search.php
CRM/Core/Form/Search.php
tests/phpunit/CRM/Contact/BAO/SavedSearchTest.php

index a3f46e68de23c863c65d0926baf6c35ba2b50314..d2d29634255658f18541c6655b31454902f753fb 100644 (file)
@@ -201,7 +201,7 @@ class CRM_Contact_Form_Search_Advanced extends CRM_Contact_Form_Search {
       $this->_ssID = $this->get('ssID');
     }
 
-    $defaults = array_merge($this->_formValues, [
+    $defaults = array_merge((array) $this->_formValues, [
       'privacy_toggle' => 1,
       'operator' => 'AND',
     ], $defaults);
index 6fdb263afb1a390e9cd1203e4439d16a2a3c0a81..67b04cc55ae3970865a75febcfacea5143374e2c 100644 (file)
@@ -84,9 +84,7 @@ class CRM_Contribute_Form_Search extends CRM_Core_Form_Search {
 
     $this->_done = FALSE;
 
-    $this->loadStandardSearchOptionsFromUrl();
-
-    $this->_formValues = $this->getFormValues();
+    parent::preProcess();
 
     //membership ID
     $memberShipId = CRM_Utils_Request::retrieve('memberId', 'Positive', $this);
@@ -98,15 +96,6 @@ class CRM_Contribute_Form_Search extends CRM_Core_Form_Search {
       $this->_formValues['contribution_participant_id'] = $participantId;
     }
 
-    if ($this->_force) {
-      // Search field metadata is normally added in buildForm but we are bypassing that in this flow
-      // (I've always found the flow kinda confusing & perhaps that is the problem but this mitigates)
-      $this->addSearchFieldMetadata(['Contribution' => CRM_Contribute_BAO_Query::getSearchFieldMetadata()]);
-      $this->addSearchFieldMetadata(['ContributionRecur' => CRM_Contribute_BAO_ContributionRecur::getContributionRecurSearchFieldMetadata()]);
-      $this->postProcess();
-      $this->set('force', 0);
-    }
-
     $sortID = NULL;
     if ($this->get(CRM_Utils_Sort::SORT_ID)) {
       $sortID = CRM_Utils_Sort::sortIDValue($this->get(CRM_Utils_Sort::SORT_ID),
@@ -282,10 +271,12 @@ class CRM_Contribute_Form_Search extends CRM_Core_Form_Search {
     $this->_done = TRUE;
 
     $this->setFormValues();
+    // @todo - stop changing formValues - respect submitted form values, change a working array.
     $this->fixFormValues();
 
     // We don't show test records in summaries or dashboards
     if (empty($this->_formValues['contribution_test']) && $this->_force && !empty($this->_context) && $this->_context == 'dashboard') {
+      // @todo - stop changing formValues - respect submitted form values, change a working array.
       $this->_formValues["contribution_test"] = 0;
     }
 
@@ -294,11 +285,11 @@ class CRM_Contribute_Form_Search extends CRM_Core_Form_Search {
       'contribution_amount_high',
     ] as $f) {
       if (isset($this->_formValues[$f])) {
+        // @todo - stop changing formValues - respect submitted form values, change a working array.
         $this->_formValues[$f] = CRM_Utils_Rule::cleanMoney($this->_formValues[$f]);
       }
     }
 
-    $config = CRM_Core_Config::singleton();
     if (!empty($_POST)) {
       $specialParams = [
         'financial_type_id',
@@ -311,10 +302,12 @@ class CRM_Contribute_Form_Search extends CRM_Core_Form_Search {
         'payment_instrument_id',
         'contribution_batch_id',
       ];
+      // @todo - stop changing formValues - respect submitted form values, change a working array.
       CRM_Contact_BAO_Query::processSpecialFormValue($this->_formValues, $specialParams);
 
       $tags = CRM_Utils_Array::value('contact_tags', $this->_formValues);
       if ($tags && !is_array($tags)) {
+        // @todo - stop changing formValues - respect submitted form values, change a working array.
         unset($this->_formValues['contact_tags']);
         $this->_formValues['contact_tags'][$tags] = 1;
       }
@@ -322,17 +315,20 @@ class CRM_Contribute_Form_Search extends CRM_Core_Form_Search {
       if ($tags && is_array($tags)) {
         unset($this->_formValues['contact_tags']);
         foreach ($tags as $notImportant => $tagID) {
+          // @todo - stop changing formValues - respect submitted form values, change a working array.
           $this->_formValues['contact_tags'][$tagID] = 1;
         }
       }
 
       $group = CRM_Utils_Array::value('group', $this->_formValues);
       if ($group && !is_array($group)) {
+        // @todo - stop changing formValues - respect submitted form values, change a working array.
         unset($this->_formValues['group']);
         $this->_formValues['group'][$group] = 1;
       }
 
       if ($group && is_array($group)) {
+        // @todo - stop changing formValues - respect submitted form values, change a working array.
         unset($this->_formValues['group']);
         foreach ($group as $groupID) {
           $this->_formValues['group'][$groupID] = 1;
@@ -340,11 +336,12 @@ class CRM_Contribute_Form_Search extends CRM_Core_Form_Search {
       }
     }
 
+    // @todo - stop changing formValues - respect submitted form values, change a working array.
     CRM_Core_BAO_CustomValue::fixCustomFieldValue($this->_formValues);
 
+    // @todo - stop changing formValues - respect submitted form values, change a working array.
     $this->_queryParams = CRM_Contact_BAO_Query::convertFormValues($this->_formValues);
 
-    $this->set('formValues', $this->_formValues);
     $this->set('queryParams', $this->_queryParams);
 
     $buttonName = $this->controller->getButtonName();
@@ -365,6 +362,7 @@ class CRM_Contribute_Form_Search extends CRM_Core_Form_Search {
       );
     }
 
+    // @todo - stop changing formValues - respect submitted form values, change a working array.
     $this->_queryParams = CRM_Contact_BAO_Query::convertFormValues($this->_formValues);
     $selector = new CRM_Contribute_Selector_Search($this->_queryParams,
       $this->_action,
@@ -462,8 +460,6 @@ class CRM_Contribute_Form_Search extends CRM_Core_Form_Search {
       $this->_formValues['contribution_page_id'] = $contribPageId;
     }
 
-    //give values to default.
-    $this->_defaults = $this->_formValues;
   }
 
   /**
@@ -475,4 +471,14 @@ class CRM_Contribute_Form_Search extends CRM_Core_Form_Search {
     return ts('Find Contributions');
   }
 
+  /**
+   * Set the metadata for the form.
+   *
+   * @throws \CiviCRM_API3_Exception
+   */
+  protected function setSearchMetadata() {
+    $this->addSearchFieldMetadata(['Contribution' => CRM_Contribute_BAO_Query::getSearchFieldMetadata()]);
+    $this->addSearchFieldMetadata(['ContributionRecur' => CRM_Contribute_BAO_ContributionRecur::getContributionRecurSearchFieldMetadata()]);
+  }
+
 }
index fed155bbff75a8273d115a755ebe90ccdf455f18..cd2d5bfe63f8f224247b573271b73769297e35bf 100644 (file)
@@ -124,6 +124,20 @@ class CRM_Core_Form_Search extends CRM_Core_Form {
     $this->searchFieldMetadata = array_merge($this->searchFieldMetadata, $searchFieldMetadata);
   }
 
+  /**
+   * Prepare for search by loading options from the url, handling force searches, retrieving form values.
+   *
+   * @throws \CRM_Core_Exception
+   * @throws \CiviCRM_API3_Exception
+   */
+  public function preProcess() {
+    $this->loadStandardSearchOptionsFromUrl();
+    if ($this->_force) {
+      $this->handleForcedSearch();
+    }
+    $this->_formValues = $this->getFormValues();
+  }
+
   /**
    * This virtual function is used to set the default values of various form elements.
    *
@@ -132,7 +146,10 @@ class CRM_Core_Form_Search extends CRM_Core_Form {
    * @throws \CRM_Core_Exception
    */
   public function setDefaultValues() {
-    $defaults = (array) $this->_formValues;
+    // Use the form values stored to the form. Ideally 'formValues'
+    // would remain 'pure' & another array would be wrangled.
+    // We don't do that - so we want the version of formValues stored early on.
+    $defaults = (array) $this->get('formValues');
     foreach (array_keys($this->getSearchFieldMetadata()) as $entity) {
       $defaults = array_merge($this->getEntityDefaults($entity), $defaults);
     }
@@ -146,6 +163,7 @@ class CRM_Core_Form_Search extends CRM_Core_Form {
    */
   protected function setFormValues() {
     $this->_formValues = $this->getFormValues();
+    $this->set('formValues', $this->_formValues);
     $this->convertTextStringsToUseLikeOperator();
   }
 
@@ -491,4 +509,26 @@ class CRM_Core_Form_Search extends CRM_Core_Form {
     return (array) $this->get('formValues');
   }
 
+  /**
+   * Set the metadata for the form.
+   *
+   * @throws \CiviCRM_API3_Exception
+   */
+  protected function setSearchMetadata() {}
+
+  /**
+   * Handle force=1 in the url.
+   *
+   * Search field metadata is normally added in buildForm but we are bypassing that in this flow
+   * (I've always found the flow kinda confusing & perhaps that is the problem but this mitigates)
+   *
+   * @throws \CiviCRM_API3_Exception
+   */
+  protected function handleForcedSearch() {
+    $this->setSearchMetadata();
+    $this->addContactSearchFields();
+    $this->postProcess();
+    $this->set('force', 0);
+  }
+
 }
index 01b45fc6f0fff87cbbc3e9f3ef2a8e43db740efc..9b590a4054a7ad935eb8b6d2696c23588d23a236 100644 (file)
@@ -58,11 +58,13 @@ class CRM_Contact_BAO_SavedSearchTest extends CiviUnitTestCase {
 
   /**
    * Test setDefaults for privacy radio buttons.
+   *
+   * @throws \Exception
    */
   public function testDefaultValues() {
     $sg = new CRM_Contact_Form_Search_Advanced();
     $sg->controller = new CRM_Core_Controller();
-    $sg->_formValues = [
+    $formValues = [
       'group_search_selected' => 'group',
       'privacy_options' => ['do_not_email'],
       'privacy_operator' => 'OR',
@@ -71,14 +73,15 @@ class CRM_Contact_BAO_SavedSearchTest extends CiviUnitTestCase {
       'component_mode' => 1,
     ];
     CRM_Core_DAO::executeQuery(
-      "INSERT INTO civicrm_saved_search (form_values) VALUES('" . serialize($sg->_formValues) . "')"
+      "INSERT INTO civicrm_saved_search (form_values) VALUES('" . serialize($formValues) . "')"
     );
     $ssID = CRM_Core_DAO::singleValueQuery('SELECT LAST_INSERT_ID()');
     $sg->set('ssID', $ssID);
+    $sg->set('formValues', $formValues);
 
     $defaults = $sg->setDefaultValues();
 
-    $this->checkArrayEquals($defaults, $sg->_formValues);
+    $this->checkArrayEquals($defaults, $formValues);
   }
 
   /**