Cleanup on PriceSetCustom search
authorEileen McNaughton <emcnaughton@wikimedia.org>
Mon, 5 Jun 2023 01:32:03 +0000 (13:32 +1200)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Mon, 5 Jun 2023 03:19:52 +0000 (15:19 +1200)
Having fixed up the test on this I also fixed a couple of bits of red and
also replaced calls to internal Core CiviCRM functions
with api calls

ext/legacycustomsearches/CRM/Contact/Form/Search/Custom/Base.php
ext/legacycustomsearches/CRM/Contact/Form/Search/Custom/PriceSet.php
ext/legacycustomsearches/CRM/Contact/Selector/Custom.php
ext/legacycustomsearches/templates/CRM/Contact/Form/Search/Custom.tpl

index 2ff571d5a26521a4c04c2d9c43b8520663c91a22..fa5eddcd282a1c60897d7bb24ae0ddcf0a2cbcec 100644 (file)
@@ -22,6 +22,16 @@ class CRM_Contact_Form_Search_Custom_Base {
 
   protected $_stateID;
 
+  /**
+   * Does the search class handle the prev next cache saving.
+   *
+   * This can be set to yes as long as a UI test works, and the deprecation
+   * notice will disappear.
+   *
+   * @var bool
+   */
+  public $searchClassHandlesPrevNextCache = FALSE;
+
   /**
    * The title of this form
    * @var string
@@ -185,10 +195,8 @@ class CRM_Contact_Form_Search_Custom_Base {
   /**
    * @param $sql
    * @param bool $onlyWhere
-   *
-   * @throws Exception
    */
-  public function validateUserSQL(&$sql, $onlyWhere = FALSE) {
+  public function validateUserSQL($sql, $onlyWhere = FALSE): void {
     $includeStrings = ['contact_a'];
     $excludeStrings = ['insert', 'delete', 'update'];
 
@@ -260,4 +268,29 @@ class CRM_Contact_Form_Search_Custom_Base {
     return [];
   }
 
+  /**
+   * Fill the prevNextCache with the found contacts
+   *
+   * @return bool TRUE if the search was able to process it.
+   */
+  public function fillPrevNextCache($cacheKey, $start, $end, $sort): bool {
+    if ($this->searchClassHandlesPrevNextCache) {
+      $sql = $this->sql(
+        '"' . $cacheKey . '"  as cache_key, contact_a.id as id,  contact_a.sort_name',
+        $start,
+        $end,
+        $sort
+      );
+      $this->validateUserSQL($sql);
+      Civi::service('prevnext')->fillWithSql($cacheKey, $sql);
+      if (Civi::service('prevnext') instanceof CRM_Core_PrevNextCache_Sql) {
+        // SQL-backed prevnext cache uses an extra record for pruning the cache.
+        // Also ensure that caches stay alive for 2 days as per previous code
+        Civi::cache('prevNextCache')->set($cacheKey, $cacheKey, 60 * 60 * 24 * CRM_Core_PrevNextCache_Sql::cacheDays);
+      }
+      return TRUE;
+    }
+    return FALSE;
+  }
+
 }
index 444f84ce2dd8e186899ba1f3754cc19020ead690..544af45fb0fbb18426972ae756ff72475753ae94 100644 (file)
@@ -9,6 +9,9 @@
  +--------------------------------------------------------------------+
  */
 
+use Civi\Api4\PriceFieldValue;
+use Civi\Api4\PriceSetEntity;
+
 /**
  *
  * @package CRM
  */
 class CRM_Contact_Form_Search_Custom_PriceSet extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
 
-  protected $_eventID = NULL;
-  protected $_aclFrom = NULL;
-  protected $_aclWhere = NULL;
-  protected $_tableName = NULL;
+  protected $eventID;
+  protected $_aclFrom;
+  protected $_aclWhere;
+  protected $_tableName;
   public $_permissionedComponent;
 
+  /**
+   * Does the search class handle the prev next cache saving.
+   *
+   * This can be set to yes as long as a UI test works, and the deprecation
+   * notice will disappear.
+   *
+   * @var bool
+   */
+  public $searchClassHandlesPrevNextCache = TRUE;
+
   /**
    * Class constructor.
    *
@@ -30,13 +43,14 @@ class CRM_Contact_Form_Search_Custom_PriceSet extends CRM_Contact_Form_Search_Cu
   public function __construct(&$formValues) {
     parent::__construct($formValues);
 
-    $this->_eventID = CRM_Utils_Array::value('event_id',
+    $this->eventID = (int) CRM_Utils_Array::value('event_id',
       $this->_formValues
     );
 
     $this->setColumns();
 
-    if ($this->_eventID) {
+    // Actually impossible for it to not be set...
+    if ($this->eventID) {
       $this->buildTempTable();
       $this->fillTable();
     }
@@ -45,22 +59,13 @@ class CRM_Contact_Form_Search_Custom_PriceSet extends CRM_Contact_Form_Search_Cu
     $this->_permissionedComponent = 'CiviEvent';
   }
 
-  public function __destruct() {
-    /*
-    if ( $this->_eventID ) {
-    $sql = "DROP TEMPORARY TABLE {$this->_tableName}";
-    CRM_Core_DAO::executeQuery( $sql );
-    }
-     */
-  }
-
-  public function buildTempTable() {
+  public function buildTempTable(): void {
     $sql = 'id int unsigned NOT NULL AUTO_INCREMENT,
   contact_id int unsigned NOT NULL,
   participant_id int unsigned NOT NULL,
 ';
 
-    foreach ($this->_columns as $dontCare => $fieldName) {
+    foreach ($this->_columns as $fieldName) {
       if (in_array($fieldName, [
         'contact_id',
         'participant_id',
@@ -71,14 +76,14 @@ class CRM_Contact_Form_Search_Custom_PriceSet extends CRM_Contact_Form_Search_Cu
       $sql .= "{$fieldName} int default 0,\n";
     }
 
-    $sql .= "
+    $sql .= '
       PRIMARY KEY ( id ),
-      UNIQUE INDEX unique_participant_id ( participant_id )";
+      UNIQUE INDEX unique_participant_id ( participant_id )';
 
     $this->_tableName = CRM_Utils_SQL_TempTable::build()->setCategory('priceset')->setMemory()->createWithColumns($sql)->getName();
   }
 
-  public function fillTable() {
+  public function fillTable(): void {
     $sql = "
 REPLACE INTO {$this->_tableName}
 ( contact_id, participant_id )
@@ -91,7 +96,7 @@ WHERE  p.contact_id = c.id
   AND  p.status_id NOT IN (4,11,12)
   AND  ( c.is_deleted = 0 OR c.is_deleted IS NULL )
 ";
-    CRM_Core_DAO::executeQuery($sql, [1 => [$this->_eventID, 'Positive']]);
+    CRM_Core_DAO::executeQuery($sql, [1 => [$this->eventID, 'Positive']]);
 
     $sql = "
       SELECT c.id as contact_id,
@@ -113,12 +118,11 @@ WHERE  p.contact_id = c.id
       ORDER BY c.id, l.price_field_value_id;
     ";
 
-    $dao = CRM_Core_DAO::executeQuery($sql, [1 => [$this->_eventID, 'Positive']]);
+    $dao = CRM_Core_DAO::executeQuery($sql, [1 => [$this->eventID, 'Positive']]);
 
     // first store all the information by option value id
     $rows = [];
     while ($dao->fetch()) {
-      $contactID = $dao->contact_id;
       $participantID = $dao->participant_id;
       if (!isset($rows[$participantID])) {
         $rows[$participantID] = [];
@@ -141,11 +145,10 @@ WHERE participant_id = $participantID;
   }
 
   /**
-   * @param int $eventID
    *
    * @return Object
    */
-  public function priceSetDAO($eventID = NULL) {
+  public function priceSetDAO() {
 
     // get all the events that have a price set associated with it
     $sql = "
@@ -158,17 +161,7 @@ FROM   civicrm_event      e,
 WHERE  p.entity_table = 'civicrm_event'
 AND    p.entity_id    = e.id
 ";
-
-    $params = [];
-    if ($eventID) {
-      $params[1] = [$eventID, 'Integer'];
-      $sql .= " AND e.id = $eventID";
-    }
-
-    $dao = CRM_Core_DAO::executeQuery($sql,
-      $params
-    );
-    return $dao;
+    return CRM_Core_DAO::executeQuery($sql);
   }
 
   /**
@@ -207,42 +200,40 @@ AND    p.entity_id    = e.id
     $form->assign('elements', ['event_id']);
   }
 
-  public function setColumns() {
+  /**
+   * @throws \Civi\API\Exception\UnauthorizedException
+   * @throws \CRM_Core_Exception
+   */
+  public function setColumns(): void {
     $this->_columns = [
       ts('Contact ID') => 'contact_id',
       ts('Participant ID') => 'participant_id',
       ts('Name') => 'display_name',
     ];
 
-    if (!$this->_eventID) {
+    if (!$this->eventID) {
       return;
     }
 
     // for the selected event, find the price set and all the columns associated with it.
     // create a column for each field and option group within it
-    $dao = $this->priceSetDAO($this->_formValues['event_id']);
-
-    if ($dao->fetch() &&
-      !$dao->price_set_id
-    ) {
-      throw new CRM_Core_Exception(ts('There are no events with Price Sets'));
-    }
-
-    // get all the fields and all the option values associated with it
-    $priceSet = CRM_Price_BAO_PriceSet::getSetDetail($dao->price_set_id);
-    if (is_array($priceSet[$dao->price_set_id])) {
-      foreach ($priceSet[$dao->price_set_id]['fields'] as $key => $value) {
-        if (is_array($value['options'])) {
-          foreach ($value['options'] as $oKey => $oValue) {
-            $columnHeader = $value['label'] ?? NULL;
-            if (CRM_Utils_Array::value('html_type', $value) != 'Text') {
-              $columnHeader .= ' - ' . $oValue['label'];
-            }
-
-            $this->_columns[$columnHeader] = "price_field_{$oValue['id']}";
-          }
+    $priceSetEntity = PriceSetEntity::get()
+      ->addWhere('entity_table',  '=', 'civicrm_event')
+      ->addWhere('entity_id', '=', $this->eventID)
+      ->addSelect('price_set_id')
+      ->execute()->first();
+    $priceSetID = $priceSetEntity['price_set_id'];
+    $priceFieldValues = PriceFieldValue::get()
+      ->addWhere('price_field_id.price_set_id', '=', $priceSetID)
+      ->addSelect('label', 'price_field_id.html_type', 'price_field_id.label')
+      ->execute();
+
+    foreach ($priceFieldValues as $value) {
+        $columnHeader = $value['price_field_id.label'] ?? NULL;
+        if ($value['price_field_id.html_type'] !== 'Text') {
+          $columnHeader .= ' - ' . $value['label'];
         }
-      }
+        $this->_columns[$columnHeader] = "price_field_{$value['id']}";
     }
   }
 
@@ -294,7 +285,7 @@ contact_a.display_name   as display_name";
   /**
    * @return string
    */
-  public function from() {
+  public function from(): string {
     $this->buildACLClause('contact_a');
     $from = "
 FROM       civicrm_contact contact_a
@@ -343,7 +334,7 @@ INNER JOIN {$this->_tableName} tempTable ON ( tempTable.contact_id = contact_a.i
    * @param string $tableAlias
    */
   public function buildACLClause($tableAlias = 'contact') {
-    list($this->_aclFrom, $this->_aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
+    [$this->_aclFrom, $this->_aclWhere] = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
   }
 
 }
index 7c0a3b50f39c09658701a0e0675a9ada830766ea..b58922b0e50b1387c752d25edf1bcd30db055e68 100644 (file)
@@ -74,8 +74,9 @@ class CRM_Contact_Selector_Custom extends CRM_Contact_Selector {
   protected $_fields;
 
   /**
-   * The object that implements the search interface
-   * @var object
+   * The object that implements the search interface.
+   *
+   * @var CRM_Contact_Form_Search_Custom_Base
    */
   protected $_search;
 
@@ -425,6 +426,9 @@ class CRM_Contact_Selector_Custom extends CRM_Contact_Selector {
    * @throws \CRM_Core_Exception
    */
   public function fillPrevNextCache($sort, $cacheKey, $start = 0, $end = self::CACHE_SIZE): void {
+    if ($this->_search->fillPrevNextCache($cacheKey, $start, $end, $sort)) {
+      return;
+    }
     $sql = $this->_search->contactIDs($start, $end, $sort, TRUE);
 
     // CRM-9096
index 4a1a7bfdf9a6445d844ef6e2b0ad8645a3761f69..89d6c23cfe6fe8b19d711b377d814674f6eb9abd 100644 (file)
@@ -54,7 +54,7 @@
         {include file="CRM/common/pager.tpl" location="top"}
 
         {* Include alpha pager if defined. *}
-        {if $atoZ}
+        {if $aToZ}
             {include file="CRM/common/pagerAToZ.tpl"}
         {/if}