Add try catch to main loops on core ipn classes
[civicrm-core.git] / CRM / Core / Form.php
index a3ef1cc1a20552ea52511bb9392dc7a64feb4980..98526b5a8198102ab15a687c1b8f98faed0d2a9f 100644 (file)
@@ -366,6 +366,9 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
     $type, $name, $label = '',
     $attributes = '', $required = FALSE, $extra = NULL
   ) {
+    if ($type === 'radio') {
+      CRM_Core_Error::deprecatedFunctionWarning('CRM_Core_Form::addRadio');
+    }
     // Fudge some extra types that quickform doesn't support
     $inputType = $type;
     if ($type == 'wysiwyg' || in_array($type, self::$html5Types)) {
@@ -391,8 +394,8 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
     // @see https://docs.civicrm.org/dev/en/latest/framework/ui/#date-picker
     if ($type === 'datepicker') {
       $attributes = $attributes ?: [];
-      if (!empty($attributes['format'])) {
-        $dateAttributes = CRM_Core_SelectValues::date($attributes['format'], NULL, NULL, NULL, 'Input');
+      if (!empty($attributes['formatType'])) {
+        $dateAttributes = CRM_Core_SelectValues::date($attributes['formatType'], NULL, NULL, NULL, 'Input');
         if (empty($extra['minDate']) && !empty($dateAttributes['minYear'])) {
           $extra['minDate'] = $dateAttributes['minYear'] . '-01-01';
         }
@@ -439,7 +442,6 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
       unset($extra['option_context']);
     }
 
-    $this->addRequiredAttribute($required, $extra);
     $element = $this->addElement($type, $name, CRM_Utils_String::purifyHTML($label), $attributes, $extra);
     if (HTML_QuickForm::isError($element)) {
       CRM_Core_Error::statusBounce(HTML_QuickForm::errorMessage($element));
@@ -1174,20 +1176,6 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
     return self::$_template->get_template_vars($name);
   }
 
-  /**
-   * jQuery validate prefers to see a validation rule as a class (eg. "required").
-   * We can't add a class at the quickform level but jQuery validate also works with HTML5:
-   * HTML5 validation requires a separate attribute "required".
-   *
-   * @param $required
-   * @param $attributes
-   */
-  private function addRequiredAttribute($required, $attributes) {
-    // Ideally we do this by adding "required" as a class on the radio but we can't
-    // But adding the attribute "required" directly to the element also works.
-    $required ? $attributes['required'] = 1 : NULL;
-  }
-
   /**
    * @param string $name
    * @param $title
@@ -1205,8 +1193,6 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
     $allowClear = !empty($attributes['allowClear']);
     unset($attributes['allowClear']);
     $attributes['id_suffix'] = $name;
-    // For jquery validate we need to flag the actual radio as required.
-    $this->addRequiredAttribute($required, $attributes);
     foreach ($values as $key => $var) {
       $optAttributes = $attributes;
       if (!empty($optionAttributes[$key])) {
@@ -1219,7 +1205,13 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
           }
         }
       }
-      $options[] = $this->createElement('radio', NULL, NULL, $var, $key, $optAttributes);
+      // We use a class here to avoid html5 issues with collapsed cutsomfield sets.
+      $optAttributes['class'] = $optAttributes['class'] ?? '';
+      if ($required) {
+        $optAttributes['class'] .= ' required';
+      }
+      $element = $this->createElement('radio', NULL, NULL, $var, $key, $optAttributes);
+      $options[] = $element;
     }
     $group = $this->addGroup($options, $name, $title, $separator);
 
@@ -1411,7 +1403,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
       $required,
       ['class' => 'crm-select2']
     );
-    $attributes = ['format' => 'searchDate'];
+    $attributes = ['formatType' => 'searchDate'];
     $extra = ['time' => $isDateTime];
     $this->add('datepicker', $fieldName . $from, ts($fromLabel), $attributes, $required, $extra);
     $this->add('datepicker', $fieldName . $to, ts($toLabel), $attributes, $required, $extra);
@@ -1666,7 +1658,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
         }
         else {
           $fieldSpec = CRM_Utils_Date::addDateMetadataToField($fieldSpec, $fieldSpec);
-          $attributes = ['format' => $fieldSpec['html']['formatType']];
+          $attributes = ['format' => $fieldSpec['date_format']];
           return $this->add('datepicker', $name, $label, $attributes, $required, $fieldSpec['datepicker']['extra']);
         }
 
@@ -2236,11 +2228,13 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
 
   /**
    * Get the contact id of the logged in user.
+   *
+   * @return int|false
    */
   public function getLoggedInUserContactID() {
     // check if the user is logged in and has a contact ID
     $session = CRM_Core_Session::singleton();
-    return $session->get('userID');
+    return $session->get('userID') ? (int) $session->get('userID') : FALSE;
   }
 
   /**
@@ -2264,6 +2258,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    *   - id_field
    *   - url (for ajax lookup)
    *
+   * @throws \CRM_Core_Exception
    * @todo add data attributes so we can deal with multiple instances on a form
    */
   public function addAutoSelector($profiles = [], $autoCompleteField = []) {
@@ -2654,4 +2649,26 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
     }
   }
 
+  /**
+   * Get the contact if from the url, using the checksum or the cid if it is the logged in user.
+   *
+   * This function returns the user being validated. It is not intended to get another user
+   * they have permission to (setContactID does do that) and can be used to check if the user is
+   * accessing their own record.
+   *
+   * @return int|false
+   * @throws \CRM_Core_Exception
+   */
+  protected function getContactIDIfAccessingOwnRecord() {
+    $contactID = (int) CRM_Utils_Request::retrieve('cid', 'Positive', $this);
+    if (!$contactID) {
+      return FALSE;
+    }
+    if ($contactID === $this->getLoggedInUserContactID()) {
+      return $contactID;
+    }
+    $userChecksum = CRM_Utils_Request::retrieve('cs', 'String', $this);
+    return CRM_Contact_BAO_Contact_Utils::validChecksum($contactID, $userChecksum) ? $contactID : FALSE;
+  }
+
 }