Share event lookup functions in a trait
authorEileen McNaughton <emcnaughton@wikimedia.org>
Sat, 23 Sep 2023 23:30:26 +0000 (12:30 +1300)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Sun, 24 Sep 2023 00:24:24 +0000 (13:24 +1300)
This is a step to standardising our event-related forms to all supporting the same consistent
public functions
- getEventID()
- getParticipantID()
- getEventValue()
- getPartcipantValue()

& ouside this PR
- getContactID
- getContactValue()
- getPriceSetID()
- getDiscountID()

Note I didn't implement the participant stuff for the online registration form
at this point because it needs a bit more though

CRM/Event/Form/EventFormTrait.php [new file with mode: 0644]
CRM/Event/Form/Participant.php
CRM/Event/Form/ParticipantFeeSelection.php
CRM/Event/Form/Registration.php

diff --git a/CRM/Event/Form/EventFormTrait.php b/CRM/Event/Form/EventFormTrait.php
new file mode 100644 (file)
index 0000000..442cf56
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+
+use Civi\API\EntityLookupTrait;
+
+/**
+ * Trait implements getContactValue + overridable getContactID functions.
+ *
+ * These are commonly used on forms - although getContactID() would often
+ * be overridden. By using these functions it is not necessary to know
+ * if the Contact ID has already been defined as `getContactID()` will retrieve
+ * them form the values available (unless it is yet to be created).
+ */
+trait CRM_Event_Form_EventFormTrait {
+
+  use EntityLookupTrait;
+
+  /**
+   * Get the value for a field relating to the event.
+   *
+   * All values returned in apiv4 format. Escaping may be required.
+   *
+   * @api This function will not change in a minor release and is supported for
+   * use outside of core. This annotation / external support for properties
+   * is only given where there is specific test cover.
+   *
+   * @param string $fieldName
+   *
+   * @return mixed
+   * @throws \CRM_Core_Exception
+   */
+  public function getEventValue(string $fieldName) {
+    if ($this->isDefined('Event')) {
+      return $this->lookup('Event', $fieldName);
+    }
+    $id = $this->getEventID();
+    if ($id) {
+      $this->define('Event', 'Event', ['id' => $id]);
+      return $this->lookup('Event', $fieldName);
+    }
+    return NULL;
+  }
+
+  /**
+   * Get the selected Event ID.
+   *
+   * @api This function will not change in a minor release and is supported for
+   * use outside of core. This annotation / external support for properties
+   * is only given where there is specific test cover.
+   *
+   * @noinspection PhpUnhandledExceptionInspection
+   * @noinspection PhpDocMissingThrowsInspection
+   */
+  public function getEventID(): ?int {
+    throw new CRM_Core_Exception('`getEventID` must be implemented');
+  }
+
+  /**
+   * Get id of participant being acted on.
+   *
+   * @api This function will not change in a minor release and is supported for
+   * use outside of core. This annotation / external support for properties
+   * is only given where there is specific test cover.
+   */
+  public function getParticipantID(): ?int {
+    throw new CRM_Core_Exception('`getParticipantID` must be implemented');
+  }
+
+  /**
+   * Get a value from the participant being acted on.
+   *
+   * All values returned in apiv4 format. Escaping may be required.
+   *
+   * @api This function will not change in a minor release and is supported for
+   * use outside of core. This annotation / external support for properties
+   * is only given where there is specific test cover.
+   *
+   * @param string $fieldName
+   *
+   * @return mixed
+   *
+   * @throws \CRM_Core_Exception
+   */
+  public function getParticipantValue(string $fieldName) {
+    if ($this->isDefined('Participant')) {
+      return $this->lookup('Participant', $fieldName);
+    }
+    $id = $this->getParticipantID();
+    if ($id) {
+      $this->define('Participant', 'Participant', ['id' => $id]);
+      return $this->lookup('Participant', $fieldName);
+    }
+    return NULL;
+  }
+
+}
index 51eea6414b9439152cf77af2bc61570891557487..0d0ae5cced548a2689bc9a3e89eb991aa67d091a 100644 (file)
@@ -25,6 +25,7 @@ class CRM_Event_Form_Participant extends CRM_Contribute_Form_AbstractEditPayment
 
   use EntityLookupTrait;
   use CRM_Contact_Form_ContactFormTrait;
+  use CRM_Event_Form_EventFormTrait;
 
   /**
    * Participant ID - use getParticipantID.
@@ -94,13 +95,6 @@ class CRM_Event_Form_Participant extends CRM_Contribute_Form_AbstractEditPayment
    */
   public $_contactId;
 
-  /**
-   * Array of event values.
-   *
-   * @var array
-   */
-  protected $_event;
-
   /**
    * Are we operating in "single mode", i.e. adding / editing only
    * one participant record, or is this a batch add operation.
@@ -207,13 +201,6 @@ class CRM_Event_Form_Participant extends CRM_Contribute_Form_AbstractEditPayment
    */
   public $_onlinePendingContributionId;
 
-  /**
-   * Stored participant record.
-   *
-   * @var array
-   */
-  protected $participantRecord;
-
   /**
    * Params for creating a payment to add to the contribution.
    *
@@ -1889,36 +1876,6 @@ class CRM_Event_Form_Participant extends CRM_Contribute_Form_AbstractEditPayment
     return ($this->getParticipantID() && $this->_action & CRM_Core_Action::UPDATE) && $this->_paymentId;
   }
 
-  /**
-   * Get the value for a field relating to the event.
-   *
-   * @param string $fieldName
-   *
-   * @return mixed
-   * @throws \CRM_Core_Exception
-   */
-  protected function getEventValue(string $fieldName) {
-    if (!isset($this->_event)) {
-      $this->_event = civicrm_api3('Event', 'getsingle', ['id' => $this->_eventId]);
-    }
-    return $this->_event[$fieldName];
-  }
-
-  /**
-   * Get a value from the existing participant record (applies to edits).
-   *
-   * @param string $fieldName
-   *
-   * @return array
-   * @throws \CRM_Core_Exception
-   */
-  protected function getParticipantValue($fieldName) {
-    if (!$this->participantRecord) {
-      $this->participantRecord = civicrm_api3('Participant', 'getsingle', ['id' => $this->getParticipantID()]);
-    }
-    return $this->participantRecord[$fieldName] ?? $this->participantRecord['participant_' . $fieldName];
-  }
-
   /**
    * Get id of participant being edited.
    *
index 1bfe38dee8d4ea5617b39ae0d47fa724d66784c2..2e35fa4077e767c1e921a2fc8a35446006611890 100644 (file)
  *
  */
 class CRM_Event_Form_ParticipantFeeSelection extends CRM_Core_Form {
+  use CRM_Event_Form_EventFormTrait;
+  use CRM_Contact_Form_ContactFormTrait;
 
   public $useLivePageJS = TRUE;
 
-  protected $_contactId = NULL;
+  /**
+   * @var int
+   *
+   * @deprecated
+   */
+  protected $_contactId;
 
   protected $_contributorDisplayName = NULL;
 
@@ -42,9 +49,12 @@ class CRM_Event_Form_ParticipantFeeSelection extends CRM_Core_Form {
 
   public $_values = NULL;
 
-  public $_participantId = NULL;
-
-  protected $_participantStatus = NULL;
+  /**
+   * @var int
+   *
+   * @deprecated use getParticipantID().
+   */
+  public $_participantId;
 
   protected $_paidAmount = NULL;
 
@@ -53,26 +63,21 @@ class CRM_Event_Form_ParticipantFeeSelection extends CRM_Core_Form {
   protected $contributionAmt = NULL;
 
   public function preProcess() {
-    $this->_participantId = CRM_Utils_Request::retrieve('id', 'Positive', $this, TRUE);
-    $this->_contactId = CRM_Utils_Request::retrieve('cid', 'Positive', $this, TRUE);
-    $this->_eventId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $this->_participantId, 'event_id');
-    $this->_fromEmails = CRM_Event_BAO_Event::getFromEmailIds($this->_eventId);
+    $this->_fromEmails = CRM_Event_BAO_Event::getFromEmailIds($this->getEventID());
 
     if ($this->getContributionID()) {
       $this->_isPaidEvent = TRUE;
     }
     $this->_action = CRM_Utils_Request::retrieve('action', 'String', $this, TRUE);
 
-    [$this->_contributorDisplayName, $this->_contributorEmail] = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactId);
-    $this->assign('displayName', $this->_contributorDisplayName);
-    $this->assign('email', $this->_contributorEmail);
-
-    $this->_participantStatus = CRM_Core_DAO::getFieldValue('CRM_Event_BAO_Participant', $this->_participantId, 'status_id');
     //set the payment mode - _mode property is defined in parent class
     $this->_mode = CRM_Utils_Request::retrieve('mode', 'String', $this);
 
-    $this->assign('contactId', $this->_contactId);
-    $this->assign('id', $this->_participantId);
+    [$this->_contributorDisplayName, $this->_contributorEmail] = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->getContactID());
+    $this->assign('displayName', $this->getContactValue('display_name'));
+    $this->assign('email', $this->getContactValue('email_primary.email'));
+    $this->assign('contactId', $this->getContactID());
+    $this->assign('id', $this->getParticipantID());
 
     $paymentInfo = CRM_Contribute_BAO_Contribution::getPaymentInfo($this->_participantId, 'event');
     $this->_paidAmount = $paymentInfo['paid'];
@@ -103,10 +108,10 @@ class CRM_Event_Form_ParticipantFeeSelection extends CRM_Core_Form {
    */
   public function getContributionID(): ?int {
     if ($this->contributionID === NULL) {
-      $this->contributionID = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $this->_participantId, 'contribution_id', 'participant_id') ?: FALSE;
+      $this->contributionID = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $this->getParticipantID(), 'contribution_id', 'participant_id') ?: FALSE;
 
       if (!$this->contributionID) {
-        $primaryParticipantID = CRM_Core_DAO::getFieldValue('CRM_Event_BAO_Participant', $this->_participantId, 'registered_by_id');
+        $primaryParticipantID = $this->getParticipantValue('registered_by_id');
         if ($primaryParticipantID) {
           $this->contributionID = CRM_Core_DAO::getFieldValue('CRM_Event_BAO_ParticipantPayment', $primaryParticipantID, 'contribution_id', 'participant_id') ?: FALSE;
         }
@@ -159,7 +164,7 @@ class CRM_Event_Form_ParticipantFeeSelection extends CRM_Core_Form {
     $statuses = CRM_Event_PseudoConstant::participantStatus();
     $this->assign('partiallyPaid', array_search('Partially paid', $statuses));
     $this->assign('pendingRefund', array_search('Pending refund', $statuses));
-    $this->assign('participantStatus', $this->_participantStatus);
+    $this->assign('participantStatus', $this->getParticipantValue('status_id'));
 
     $this->assign('currencySymbol', CRM_Core_BAO_Country::defaultCurrencySymbol());
 
@@ -420,7 +425,7 @@ class CRM_Event_Form_ParticipantFeeSelection extends CRM_Core_Form {
    */
   public function getEventID(): int {
     if (!$this->_eventId) {
-      $this->_eventId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $this->_participantId, 'event_id');
+      $this->_eventId = $this->getParticipantValue('event_id');
     }
     return $this->_eventId;
   }
@@ -451,4 +456,41 @@ class CRM_Event_Form_ParticipantFeeSelection extends CRM_Core_Form {
     return $priceSetID;
   }
 
+  /**
+   * Get id of participant being acted on.
+   *
+   * @return int
+   *
+   * @api This function will not change in a minor release and is supported for
+   * use outside of core. This annotation / external support for properties
+   * is only given where there is specific test cover.
+   *
+   * No exception should be thrown... as it should be unreachable/overridden.
+   * @noinspection PhpUnhandledExceptionInspection
+   * @noinspection PhpDocMissingThrowsInspection
+   */
+  public function getParticipantID(): int {
+    if (!$this->_participantId) {
+      $this->_participantId = (int) CRM_Utils_Request::retrieve('id', 'Positive', $this, TRUE);
+    }
+    return $this->_participantId;
+  }
+
+  /**
+   * Get the contact ID.
+   *
+   * Override this for more complex retrieval as required by the form.
+   *
+   * @return int|null
+   *
+   * @noinspection PhpUnhandledExceptionInspection
+   * @noinspection PhpDocMissingThrowsInspection
+   */
+  public function getContactID(): ?int {
+    if (!$this->_contactId) {
+      $this->_contactId = (int) $this->getParticipantValue('contact_id');
+    }
+    return $this->_contactId;
+  }
+
 }
index 84f61d77b5de8a9e44bd45db0731900de23e8a17..e96c5cb07283f1eb0e1eef975f0c4a439d601604 100644 (file)
 class CRM_Event_Form_Registration extends CRM_Core_Form {
 
   use CRM_Financial_Form_FrontEndPaymentFormTrait;
+  use CRM_Event_Form_EventFormTrait;
 
   /**
    * The id of the event we are processing.
    *
    * @var int
+   *
+   * @deprecated access via `getEventID`
    */
   public $_eventId;
 
   /**
-   * Get the event it.
+   * Get the selected Event ID.
+   *
+   * @return int|null
+   *
+   * @throws \CRM_Core_Exception
+   * @api This function will not change in a minor release and is supported for
+   * use outside of core. This annotation / external support for properties
+   * is only given where there is specific test cover.
    *
-   * @return int
    */
-  protected function getEventID(): int {
+  public function getEventID(): int {
+    if (!$this->_eventId) {
+      $this->_eventId = (int) CRM_Utils_Request::retrieve('id', 'Positive', $this, TRUE);
+      // this is the first time we are hitting this, so check for permissions here
+      if (!CRM_Core_Permission::event(CRM_Core_Permission::EDIT, $this->_eventId, 'register for events')) {
+        CRM_Core_Error::statusBounce(ts('You do not have permission to register for this event'), $this->getInfoPageUrl());
+      }
+    }
     return $this->_eventId;
   }
 
@@ -179,9 +195,11 @@ class CRM_Event_Form_Registration extends CRM_Core_Form {
 
   /**
    * Set variables up before form is built.
+   *
+   * @throws \CRM_Core_Exception
    */
   public function preProcess() {
-    $this->_eventId = (int) CRM_Utils_Request::retrieve('id', 'Positive', $this, TRUE);
+    $this->setTitle($this->getEventValue('title'));
     $this->_action = CRM_Utils_Request::retrieve('action', 'Alphanumeric', $this, FALSE, CRM_Core_Action::ADD);
     //CRM-4320
     $this->_participantId = CRM_Utils_Request::retrieve('participantId', 'Positive', $this);
@@ -221,20 +239,16 @@ class CRM_Event_Form_Registration extends CRM_Core_Form {
     $this->assign('showPaymentOnConfirm', $this->showPaymentOnConfirm);
 
     if (!$this->_values) {
-      // this is the first time we are hitting this, so check for permissions here
-      if (!CRM_Core_Permission::event(CRM_Core_Permission::EDIT, $this->_eventId, 'register for events')) {
-        CRM_Core_Error::statusBounce(ts('You do not have permission to register for this event'), $this->getInfoPageUrl());
-      }
 
       // get all the values from the dao object
       $this->_values = $this->_fields = [];
 
       //retrieve event information
-      $params = ['id' => $this->_eventId];
+      $params = ['id' => $this->getEventID()];
       CRM_Event_BAO_Event::retrieve($params, $this->_values['event']);
 
       // check for is_monetary status
-      $isMonetary = $this->_values['event']['is_monetary'] ?? NULL;
+      $isMonetary = $this->getEventValue('is_monetary');
       // check for ability to add contributions of type
       if ($isMonetary
         && CRM_Financial_BAO_FinancialType::isACLFinancialTypeStatus()
@@ -260,7 +274,7 @@ class CRM_Event_Form_Registration extends CRM_Core_Form {
         $this->set('additionalParticipantIds', $this->_additionalParticipantIds);
       }
 
-      $eventFull = CRM_Event_BAO_Participant::eventFull($this->_eventId, FALSE,
+      $eventFull = CRM_Event_BAO_Participant::eventFull($this->getEventID(), FALSE,
         $this->_values['event']['has_waitlist'] ?? NULL
       );
 
@@ -287,7 +301,7 @@ class CRM_Event_Form_Registration extends CRM_Core_Form {
         $participant_role = CRM_Core_OptionGroup::values('participant_role');
         $this->_values['event']['participant_role'] = $participant_role["{$this->_values['event']['default_role_id']}"];
       }
-      $isPayLater = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $this->_eventId, 'is_pay_later');
+      $isPayLater = $this->getEventValue('is_pay_later');
       $this->setPayLaterLabel($isPayLater ? $this->_values['event']['pay_later_text'] : '');
       //check for various combinations for paylater, payment
       //process with paid event.
@@ -369,8 +383,6 @@ class CRM_Event_Form_Registration extends CRM_Core_Form {
     $this->_contributeMode = $this->get('contributeMode');
     $this->assign('contributeMode', $this->_contributeMode);
 
-    $this->setTitle($this->_values['event']['title']);
-
     $this->assign('paidEvent', $this->_values['event']['is_monetary']);
 
     // we do not want to display recently viewed items on Registration pages