Merge pull request #6036 from mallezie/16629
[civicrm-core.git] / CRM / Core / Form.php
index 68f7197fed857a931a0a1c9c0ddf569c4c2f0f25..b7fa74c12b6e4384bbc5aaa87530893d8f96755d 100644 (file)
@@ -3,7 +3,7 @@
  +--------------------------------------------------------------------+
  | CiviCRM version 4.6                                                |
  +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2014                                |
+ | Copyright CiviCRM LLC (c) 2004-2015                                |
  +--------------------------------------------------------------------+
  | This file is a part of CiviCRM.                                    |
  |                                                                    |
@@ -31,7 +31,7 @@
  * machine. Each form can also operate in various modes
  *
  * @package CRM
- * @copyright CiviCRM LLC (c) 2004-2014
+ * @copyright CiviCRM LLC (c) 2004-2015
  * $Id$
  *
  */
@@ -271,6 +271,11 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
     $type, $name, $label = '',
     $attributes = '', $required = FALSE, $extra = NULL
   ) {
+    if ($type == 'wysiwyg') {
+      $attributes = ($attributes ? $attributes : array()) + array('class' => '');
+      $attributes['class'] .= ' crm-form-wysiwyg';
+      $type = "textarea";
+    }
     if ($type == 'select' && is_array($extra)) {
       // Normalize this property
       if (!empty($extra['multiple'])) {
@@ -483,7 +488,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
     }
 
     // call the form hook
-    // also call the hook function so any modules can set thier own custom defaults
+    // also call the hook function so any modules can set their own custom defaults
     // the user can do both the form and set default values with this hook
     CRM_Utils_Hook::buildForm(get_class($this), $this);
 
@@ -615,13 +620,22 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    *
    * @param string $title
    *   The title of the form.
-   *
-   * @return void
    */
   public function setTitle($title) {
     $this->_title = $title;
   }
 
+  /**
+   * Assign billing type id to bltID.
+   *
+   * @throws CRM_Core_Exception
+   */
+  public function assignBillingType() {
+    $this->_bltID = CRM_Core_BAO_Location::getBillingLocationId();
+    $this->set('bltID', $this->_bltID);
+    $this->assign('bltID', $this->_bltID);
+  }
+
   /**
    * Setter function for options.
    *
@@ -1175,10 +1189,9 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
       $props['action'] = $this->getApiAction();
     }
     // Get field metadata.
-    $fieldSpec = civicrm_api3($props['entity'], 'getfield', array('options' => array('get_options' => 1)) + $props);
+    $fieldSpec = civicrm_api3($props['entity'], 'getfield', $props);
     $fieldSpec = $fieldSpec['values'];
-
-    $label = CRM_Utils_Array::value('label', $props, $fieldSpec['title']);
+    $label = CRM_Utils_Array::value('label', $props, isset($fieldSpec['title']) ? $fieldSpec['title'] : NULL);
 
     $widget = isset($props['type']) ? $props['type'] : $fieldSpec['html']['type'];
     if ($widget == 'TextArea' && $props['context'] == 'search') {
@@ -1193,7 +1206,8 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
           'Select Country',
           'Multi-Select Country',
           'AdvMulti-Select',
-          'CheckBox',
+          'CheckBoxGroup',
+          'RadioGroup',
           'Radio',
     )));
 
@@ -1205,23 +1219,13 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
         unset($props['options']);
       }
       else {
-        $options = $fieldSpec['options'];
+        $options = isset($fieldSpec['options']) ? $fieldSpec['options'] : NULL;
       }
-
-      // The placeholder is only used for select-elements.
-      if (!array_key_exists('placeholder', $props)) {
-        $props['placeholder'] = $required ? ts('- select -') : $props['context'] == 'search' ? ts('- any -') : ts('- none -');
-      }
-
+      //@TODO AdvMulti-Select is deprecated, drop support.
       if ($props['context'] == 'search' || ($widget !== 'AdvMulti-Select' && strpos($widget, 'Select') !== FALSE)) {
         $widget = 'Select';
       }
-      $props['class'] = (isset($props['class']) ? $props['class'] . ' ' : '') . "crm-select2";
-      if ($props['context'] == 'search' || strpos($widget, 'Multi') !== FALSE) {
-        $props['class'] .= ' huge';
-        $props['multiple'] = 'multiple';
-      }
-      // Set default options-url value. 
+      // Set default options-url value.
       if ((!isset($props['options-url']))) {
         $props['options-url'] = TRUE;
       }
@@ -1236,58 +1240,100 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
         }
       }
     }
+    //Use select2 library for following widgets.
+    $isSelect2 = (in_array($widget, array(
+          'Select',
+          'Multi-Select',
+          'Select State/Province',
+          'Multi-Select State/Province',
+          'Select Country',
+          'Multi-Select Country',
+    )));
+    if ($isSelect2) {
+      $props['class'] = (isset($props['class']) ? $props['class'] . ' ' : '') . "crm-select2";
+      if ($props['context'] == 'search' || strpos($widget, 'Multi') !== FALSE) {
+        $props['class'] .= ' huge';
+        $props['multiple'] = 'multiple';
+      }
+      // The placeholder is only used for select-elements.
+      if (!array_key_exists('placeholder', $props)) {
+        $props['placeholder'] = $required ? ts('- select -') : $props['context'] == 'search' ? ts('- any -') : ts('- none -');
+      }
+    }
     $props += CRM_Utils_Array::value('html', $fieldSpec, array());
     CRM_Utils_Array::remove($props, 'entity', 'name', 'context', 'label', 'action', 'type');
-    // TODO: refactor switch statement, to seperate methods.
+    // TODO: refactor switch statement, to separate methods.
     switch ($widget) {
       case 'Text':
       case 'Link':
         //TODO: Autodetect ranges
-        $element = $this->addElement('text', $name, $label, $props);
-        if ($required) {
-          $this->addRequiredRule($element);
-        }
+        $props['size'] = isset($props['size']) ? $props['size'] : 60;
+        $this->add('text', $name, $label, $props, $required);
         break;
 
       case 'hidden':
-        $this->addElement('hidden', $name, $label, $props);
+        $this->add('hidden', $name, NULL, $props, $required);
+        break;
+
+      case 'TextArea':
+        //Set default columns and rows for textarea.
+        $props['rows'] = isset($props['rows']) ? $props['rows'] : 4;
+        $props['cols'] = isset($props['cols']) ? $props['cols'] : 60;
+        $this->addElement('textarea', $name, $label, $props, $required);
+        break;
+
+      case 'Select Date':
+        //TODO: add range support
+        //TODO: Add date formats
+        //TODO: Add javascript template for dates.
+        $this->addDate($name, $label, $required, $props);
+        break;
+
+      case 'Radio':
+        $separator = isset($props['separator']) ? $props['separator'] : NULL;
+        unset($props['separator']);
+        if (!isset($props['allowClear'])) {
+          $props['allowClear'] = !$required;
+        }
+        $this->addRadio($name, $label, $options, $props, $separator, $required);
         break;
 
-      //case 'TextArea':
-      //case 'Select Date':
-      //TODO: Add date formats
-      //TODO: Add javascript template for dates.
-      // case 'Radio':
       case 'Select':
         if (empty($props['multiple'])) {
           $options = array('' => $props['placeholder']) + $options;
         }
-        $this->addElement('select', $name, $label, $options, $props);
-        if ($required) {
-          $this->addRequiredRule($element);
-        }
+        $this->add('select', $name, $label, $options, $required, $props);
         // TODO: Add and/or option for fields that store multiple values
         break;
 
+      case 'CheckBoxGroup':
+        $this->addCheckBox($name, $label, array_flip($options), $required, $props);
+        break;
+
+      case 'RadioGroup':
+        $this->addRadio($name, $label, $options, $props, NULL, $required);
+        break;
+
       //case 'AdvMulti-Select':
-      //case 'CheckBox':
+      case 'CheckBox':
+        $text = isset($props['text']) ? $props['text'] : NULL;
+        unset($props['text']);
+        $this->addElement('checkbox', $name, $label, $text, $props);
+        break;
+
       case 'File':
         // We should not build upload file in search mode.
         if (isset($props['context']) && $props['context'] == 'search') {
           return;
         }
-        $this->addElement('file', $name, $label, $props);
+        $this->add('file', $name, $label, $props, $required);
         $this->addUploadElement($name);
-        if ($required) {
-          $this->addRequiredRule($element, 'uploadedfile');
-        }
         break;
 
       //case 'RichTextEditor':
       //TODO: Add javascript template for wysiwyg.
       case 'Autocomplete-Select':
       case 'EntityRef':
-        //TODO: Refactor to avoid add-method.
         $this->addEntityRef($name, $label, $props, $required);
         break;
 
@@ -1302,16 +1348,6 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
     }
   }
 
-  /**
-   * Add a required rule to a form element.
-   */
-  public function addRequiredRule($element, $rule = 'required') {
-    $error = $this->addRule($element->getName(), ts('%1 is a required field.', array(1 => $element->getLabel())), $rule);
-    if (HTML_QuickForm::isError($error)) {
-      CRM_Core_Error::fatal(HTML_QuickForm::errorMessage($element));
-    }
-  }
-
   /**
    * Add a widget for selecting/editing/creating/copying a profile form
    *
@@ -1342,50 +1378,6 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
     ));
   }
 
-  /**
-   * @param string $name
-   * @param $label
-   * @param $attributes
-   * @param bool $forceTextarea
-   */
-  public function addWysiwyg($name, $label, $attributes, $forceTextarea = FALSE) {
-    // 1. Get configuration option for editor (tinymce, ckeditor, pure textarea)
-    // 2. Based on the option, initialise proper editor
-    $editorID = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
-      'editor_id'
-    );
-    $editor = strtolower(CRM_Utils_Array::value($editorID,
-      CRM_Core_OptionGroup::values('wysiwyg_editor')
-    ));
-    if (!$editor || $forceTextarea) {
-      $editor = 'textarea';
-    }
-    if ($editor == 'joomla default editor') {
-      $editor = 'joomlaeditor';
-    }
-
-    if ($editor == 'drupal default editor') {
-      $editor = 'drupalwysiwyg';
-    }
-
-    //lets add the editor as a attribute
-    $attributes['editor'] = $editor;
-
-    $this->addElement($editor, $name, $label, $attributes);
-    $this->assign('editor', $editor);
-
-    // include wysiwyg editor js files
-    // FIXME: This code does not make any sense
-    $includeWysiwygEditor = FALSE;
-    $includeWysiwygEditor = $this->get('includeWysiwygEditor');
-    if (!$includeWysiwygEditor) {
-      $includeWysiwygEditor = TRUE;
-      $this->set('includeWysiwygEditor', $includeWysiwygEditor);
-    }
-
-    $this->assign('includeWysiwygEditor', $includeWysiwygEditor);
-  }
-
   /**
    * @param int $id
    * @param $title
@@ -1810,13 +1802,13 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
       // from that page
       // we don't really need to set it when $tempID is set because the params have that stored
       $this->set('cid', 0);
-      return $tempID;
+      return (int) $tempID;
     }
 
     $userID = $this->getLoggedInUserContactID();
 
-    if ($tempID == $userID) {
-      return $userID;
+    if (!is_null($tempID) && $tempID === $userID) {
+      return (int) $userID;
     }
 
     //check if this is a checksum authentication
@@ -1833,7 +1825,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
       return $tempID;
     }
 
-    return $userID;
+    return is_numeric($userID) ? $userID : NULL;
   }
 
   /**