dev/core#2422 Add created_id, modified_id, expires_date to saved search table
authoreileen <emcnaughton@wikimedia.org>
Tue, 2 Mar 2021 04:52:18 +0000 (17:52 +1300)
committereileen <emcnaughton@wikimedia.org>
Wed, 3 Mar 2021 06:08:54 +0000 (19:08 +1300)
Per

https://lab.civicrm.org/dev/core/-/issues/2422

These can be exposed in the search kit saved search listing as filters when
we get to that point but the earlier we start
saving them the better the data will be when we do expose

CRM/Contact/BAO/SavedSearch.php
CRM/Contact/DAO/SavedSearch.php
CRM/Upgrade/Incremental/php/FiveThirtySix.php
tests/phpunit/CRM/Dedupe/MergerTest.php
tests/phpunit/api/v3/SavedSearchTest.php
xml/schema/Contact/SavedSearch.xml

index d5e4456720c3d1e230e943ddc5c3d03f8b7917a7..6c4b97674906ab405d71335b5ceb5f750162fc76 100644 (file)
@@ -355,7 +355,13 @@ LEFT JOIN civicrm_email ON (contact_a.id = civicrm_email.contact_id AND civicrm_
       }
       $params['name'] = $name . $suffix;
     }
-
+    $loggedInContactID = CRM_Core_Session::getLoggedInContactID();
+    if ($loggedInContactID) {
+      if (empty($params['id'])) {
+        $params['created_id'] = $loggedInContactID;
+      }
+      $params['modified_id'] = $loggedInContactID;
+    }
     return self::writeRecord($params);
   }
 
@@ -419,7 +425,7 @@ LEFT JOIN civicrm_email ON (contact_a.id = civicrm_email.contact_id AND civicrm_
 
     switch ($op) {
       case 'BETWEEN':
-        list($formValues[$fieldName . '_from'], $formValues[$fieldName . '_to']) = $value;
+        [$formValues[$fieldName . '_from'], $formValues[$fieldName . '_to']] = $value;
         break;
 
       case '>=':
index 32d39796eb53dd73a69086d8bb141af0bb49c82b..0cbbcca57661782905033e8335547dd255dcd50e 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Generated from xml/schema/CRM/Contact/SavedSearch.xml
  * DO NOT EDIT.  Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:165072ec4f0aa9a3002222c544b3047c)
+ * (GenCodeChecksum:6a33a7d434232c0d9796934dcb29edf8)
  */
 
 /**
@@ -86,6 +86,27 @@ class CRM_Contact_DAO_SavedSearch extends CRM_Core_DAO {
    */
   public $api_params;
 
+  /**
+   * FK to contact table.
+   *
+   * @var int
+   */
+  public $created_id;
+
+  /**
+   * FK to contact table.
+   *
+   * @var int
+   */
+  public $modified_id;
+
+  /**
+   * Optional date after which the search is not needed
+   *
+   * @var timestamp
+   */
+  public $expires_date;
+
   /**
    * Class constructor.
    */
@@ -114,6 +135,8 @@ class CRM_Contact_DAO_SavedSearch extends CRM_Core_DAO {
     if (!isset(Civi::$statics[__CLASS__]['links'])) {
       Civi::$statics[__CLASS__]['links'] = static::createReferenceColumns(__CLASS__);
       Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName(), 'mapping_id', 'civicrm_mapping', 'id');
+      Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName(), 'created_id', 'civicrm_contact', 'id');
+      Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName(), 'modified_id', 'civicrm_contact', 'id');
       CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']);
     }
     return Civi::$statics[__CLASS__]['links'];
@@ -250,6 +273,51 @@ class CRM_Contact_DAO_SavedSearch extends CRM_Core_DAO {
           'serialize' => self::SERIALIZE_JSON,
           'add' => '5.24',
         ],
+        'created_id' => [
+          'name' => 'created_id',
+          'type' => CRM_Utils_Type::T_INT,
+          'title' => ts('Created By Contact ID'),
+          'description' => ts('FK to contact table.'),
+          'where' => 'civicrm_saved_search.created_id',
+          'table_name' => 'civicrm_saved_search',
+          'entity' => 'SavedSearch',
+          'bao' => 'CRM_Contact_BAO_SavedSearch',
+          'localizable' => 0,
+          'FKClassName' => 'CRM_Contact_DAO_Contact',
+          'html' => [
+            'label' => ts("Created By"),
+          ],
+          'add' => '5.36',
+        ],
+        'modified_id' => [
+          'name' => 'modified_id',
+          'type' => CRM_Utils_Type::T_INT,
+          'title' => ts('Modified By Contact ID'),
+          'description' => ts('FK to contact table.'),
+          'where' => 'civicrm_saved_search.modified_id',
+          'table_name' => 'civicrm_saved_search',
+          'entity' => 'SavedSearch',
+          'bao' => 'CRM_Contact_BAO_SavedSearch',
+          'localizable' => 0,
+          'FKClassName' => 'CRM_Contact_DAO_Contact',
+          'html' => [
+            'label' => ts("Modified By"),
+          ],
+          'add' => '5.36',
+        ],
+        'expires_date' => [
+          'name' => 'expires_date',
+          'type' => CRM_Utils_Type::T_TIMESTAMP,
+          'title' => ts('Search Expiry Date'),
+          'description' => ts('Optional date after which the search is not needed'),
+          'required' => FALSE,
+          'where' => 'civicrm_saved_search.expires_date',
+          'table_name' => 'civicrm_saved_search',
+          'entity' => 'SavedSearch',
+          'bao' => 'CRM_Contact_BAO_SavedSearch',
+          'localizable' => 0,
+          'add' => '5.36',
+        ],
       ];
       CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
     }
index 61494ada18f017a54fa97a78e028197de84a97fa..ab903d7061c19a77b93a72dc16fcb14dbcebb638 100644 (file)
@@ -61,21 +61,40 @@ class CRM_Upgrade_Incremental_php_FiveThirtySix extends CRM_Upgrade_Incremental_
    * (change the x in the function name):
    */
 
-  //  /**
-  //   * Upgrade function.
-  //   *
-  //   * @param string $rev
-  //   */
-  //  public function upgrade_5_0_x($rev) {
-  //    $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev);
-  //    $this->addTask('Do the foo change', 'taskFoo', ...);
-  //    // Additional tasks here...
-  //    // Note: do not use ts() in the addTask description because it adds unnecessary strings to transifex.
-  //    // The above is an exception because 'Upgrade DB to %1: SQL' is generic & reusable.
-  //  }
+  /**
+   * Upgrade function.
+   *
+   * @param string $rev
+   */
+  public function upgrade_5_36_alpha1(string $rev): void {
+    $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev);
+
+    $this->addTask('core-issue#2422 - Add created_id to civicrm_saved_search', 'addColumn',
+      'civicrm_saved_search', 'created_id', "int(10) unsigned DEFAULT NULL COMMENT 'FK to contact table.'");
+    $this->addTask('core-issue#2422 - Add modified_id to civicrm_saved_search', 'addColumn',
+      'civicrm_saved_search', 'modified_id', "int(10) unsigned DEFAULT NULL COMMENT 'FK to contact table.'");
+    $this->addTask('core-issue#2422 - Add expires_date to civicrm_saved_search', 'addColumn',
+      'civicrm_saved_search', 'expires_date', "timestamp NULL DEFAULT NULL COMMENT 'Optional date after which the search is not needed'");
+    $this->addTask('core-issue#2422 - Add constraints to civicrm_saved_search', 'taskAddConstraints');
 
-  // public static function taskFoo(CRM_Queue_TaskContext $ctx, ...) {
-  //   return TRUE;
-  // }
+  }
+
+  /**
+   * @param \CRM_Queue_TaskContext $ctx
+   *
+   * @return bool
+   */
+  public static function taskAddConstraints(CRM_Queue_TaskContext $ctx): bool {
+    CRM_Core_DAO::executeQuery("
+      ALTER TABLE `civicrm_saved_search`
+        ADD CONSTRAINT `FK_civicrm_saved_search_created_id`
+          FOREIGN KEY (`created_id`) REFERENCES `civicrm_contact` (`id`)
+          ON DELETE SET NULL,
+        ADD CONSTRAINT `FK_civicrm_saved_search_modified_id`
+          FOREIGN KEY (`modified_id`) REFERENCES `civicrm_contact` (`id`)
+          ON DELETE SET NULL;
+    ");
+    return TRUE;
+  }
 
 }
index 8b4b57383abfb967ca87e5a5309cf65a67a196b8..2029614645c496703292b5a7deb03a229085b3f1 100644 (file)
@@ -283,7 +283,7 @@ class CRM_Dedupe_MergerTest extends CiviUnitTestCase {
   /**
    * The goal of this function is to test that all required tables are returned.
    */
-  public function testGetCidRefs() {
+  public function testGetCidRefs(): void {
     $sortRefs = function($a) {
       ksort($a);
       foreach ($a as &$fields) {
@@ -1368,6 +1368,7 @@ class CRM_Dedupe_MergerTest extends CiviUnitTestCase {
       'civicrm_print_label' => [
         0 => 'created_id',
       ],
+      'civicrm_saved_search' => ['created_id', 'modified_id'],
       'civicrm_relationship' => [
         0 => 'contact_id_a',
         1 => 'contact_id_b',
index 1bf99e4f611d26e25e7e87eb4ef252ad06ed90f1..2b227ca07d56f76564b363440262617a9e79937c 100644 (file)
@@ -53,13 +53,10 @@ class api_v3_SavedSearchTest extends CiviUnitTestCase {
     // I created a smart group using the CiviCRM gui. The smart group contains
     // all contacts tagged with 'company'.
     // I got the params below from the database.
-
-    $url = CIVICRM_UF_BASEURL . "/civicrm/contact/search/advanced?reset=1";
-    $serialized_url = serialize($url);
-
     // params for saved search that returns all volunteers for the
     // default organization.
     $this->params = [
+      'expires_date' => '2021-08-08',
       'form_values' => [
         // Is volunteer for
         'relation_type_id' => '6_a_b',
@@ -72,21 +69,22 @@ class api_v3_SavedSearchTest extends CiviUnitTestCase {
    * Create a saved search, and see whether the returned values make sense.
    */
   public function testCreateSavedSearch() {
-    // Act:
+    $contactID = $this->createLoggedInUser();
     $result = $this->callAPIAndDocument(
-        $this->_entity, 'create', $this->params, __FUNCTION__, __FILE__);
-    $this->assertEquals(1, $result['count']);
+        $this->_entity, 'create', $this->params, __FUNCTION__, __FILE__)['values'];
+    $this->assertEquals(1, count($result));
+    $savedSearch = reset($result);
 
-    // Assert:
-    // getAndCheck fails, I think because form_values is an array.
-    //$this->getAndCheck($this->params, $result['id'], $this->_entity);
-    // Check whether the new ID is correctly returned by the API.
-    $this->assertNotNull($result['values'][$result['id']]['id']);
+    $this->assertEquals($contactID, $savedSearch['created_id']);
+    $this->assertEquals($contactID, $savedSearch['modified_id']);
+    $this->assertEquals('20210808000000', $savedSearch['expires_date']);
+
+    $this->assertNotNull($savedSearch['id']);
 
     // Check whether the relation type ID is correctly returned.
     $this->assertEquals(
         $this->params['form_values']['relation_type_id'],
-        $result['values'][$result['id']]['form_values']['relation_type_id']);
+        $savedSearch['form_values']['relation_type_id']);
   }
 
   /**
index fa209f0785d540c554789c387dada7e64097213d..452c320f3a3136dec049e30652040710ff4adadd 100644 (file)
     <serialize>JSON</serialize>
     <add>5.24</add>
   </field>
+  <field>
+    <name>created_id</name>
+    <type>int unsigned</type>
+    <title>Created By Contact ID</title>
+    <comment>FK to contact table.</comment>
+    <html>
+      <label>Created By</label>
+    </html>
+    <add>5.36</add>
+  </field>
+  <foreignKey>
+    <name>created_id</name>
+    <table>civicrm_contact</table>
+    <key>id</key>
+    <add>5.36</add>
+    <onDelete>SET NULL</onDelete>
+  </foreignKey>
+  <field>
+    <name>modified_id</name>
+    <type>int unsigned</type>
+    <title>Modified By Contact ID</title>
+    <comment>FK to contact table.</comment>
+    <html>
+      <label>Modified By</label>
+    </html>
+    <add>5.36</add>
+  </field>
+  <foreignKey>
+    <name>modified_id</name>
+    <table>civicrm_contact</table>
+    <key>id</key>
+    <add>5.36</add>
+    <onDelete>SET NULL</onDelete>
+  </foreignKey>
+  <field>
+    <name>expires_date</name>
+    <type>timestamp</type>
+    <title>Search Expiry Date</title>
+    <required>false</required>
+    <comment>Optional date after which the search is not needed</comment>
+    <add>5.36</add>
+  </field>
 </table>