Merge remote-tracking branch 'upstream/4.5' into 4.5-master-2015-03-09-21-44-34
[civicrm-core.git] / CRM / Core / Form.php
index 47303ba3b41849283824c71d1dc7aa02bf0fcf57..3b70af47c69f4118805d96baaf0d3abfc1d9a022 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
  +--------------------------------------------------------------------+
- | CiviCRM version 4.5                                                |
+ | CiviCRM version 4.6                                                |
  +--------------------------------------------------------------------+
  | Copyright CiviCRM LLC (c) 2004-2014                                |
  +--------------------------------------------------------------------+
@@ -23,7 +23,7 @@
  | GNU Affero General Public License or the licensing of CiviCRM,     |
  | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
  +--------------------------------------------------------------------+
-*/
+ */
 
 /**
  * This is our base form. It is part of the Form/Controller/StateMachine
@@ -74,7 +74,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   protected $_action;
 
   /**
-   * the renderer used for this form
+   * The renderer used for this form
    *
    * @var object
    */
@@ -96,7 +96,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   protected $_dateFields = array();
 
   /**
-   * cache the smarty template for efficiency reasons
+   * Cache the smarty template for efficiency reasons
    *
    * @var CRM_Core_Smarty
    */
@@ -127,13 +127,13 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   public $controller;
 
   /**
-   * constants for attributes for various form elements
+   * Constants for attributes for various form elements
    * attempt to standardize on the number of variations that we
    * use of the below form elements
    *
    * @var const string
    */
-  CONST ATTR_SPACING = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+  const ATTR_SPACING = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
 
   /**
    * All checkboxes are defined with a common prefix. This allows us to
@@ -143,7 +143,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    *
    * @var string|int
    */
-  CONST CB_PREFIX = 'mark_x_', CB_PREFIY = 'mark_y_', CB_PREFIZ = 'mark_z_', CB_PREFIX_LEN = 7;
+  const CB_PREFIX = 'mark_x_', CB_PREFIY = 'mark_y_', CB_PREFIZ = 'mark_z_', CB_PREFIX_LEN = 7;
 
   /**
    * @internal to keep track of chain-select fields
@@ -152,24 +152,26 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   private $_chainSelectFields = array();
 
   /**
-   * Constructor for the basic form page
+   * Constructor for the basic form page.
    *
    * We should not use QuickForm directly. This class provides a lot
    * of default convenient functions, rules and buttons
    *
-   * @param object $state State associated with this form
+   * @param object $state
+   *   State associated with this form.
    * @param \const|\enum|int $action The mode the form is operating in (None/Create/View/Update/Delete)
-   * @param string $method The type of http method used (GET/POST)
-   * @param string $name The name of the form if different from class name
+   * @param string $method
+   *   The type of http method used (GET/POST).
+   * @param string $name
+   *   The name of the form if different from class name.
    *
    * @return \CRM_Core_Form
-   * @access public
    */
-  function __construct(
+  public function __construct(
     $state = NULL,
     $action = CRM_Core_Action::NONE,
     $method = 'post',
-    $name   = NULL
+    $name = NULL
   ) {
 
     if ($name) {
@@ -200,12 +202,12 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
     $this->assign('snippet', CRM_Utils_Array::value('snippet', $_GET));
   }
 
-  static function generateID() {
+  public static function generateID() {
   }
 
   /**
    * Add one or more css classes to the form
-   * @param $className
+   * @param string $className
    */
   public function addClass($className) {
     $classes = $this->getAttribute('class');
@@ -213,22 +215,37 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * register all the standard rules that most forms potentially use
+   * Register all the standard rules that most forms potentially use.
    *
    * @return void
-   * @access private
-   *
    */
-  function registerRules() {
+  public function registerRules() {
     static $rules = array(
-      'title', 'longTitle', 'variable', 'qfVariable',
-      'phone', 'integer', 'query',
-      'url', 'wikiURL',
-      'domain', 'numberOfDigit',
-      'date', 'currentDate',
-      'asciiFile', 'htmlFile', 'utf8File',
-      'objectExists', 'optionExists', 'postalCode', 'money', 'positiveInteger',
-      'xssString', 'fileExists', 'autocomplete', 'validContact',
+      'title',
+      'longTitle',
+      'variable',
+      'qfVariable',
+      'phone',
+      'integer',
+      'query',
+      'url',
+      'wikiURL',
+      'domain',
+      'numberOfDigit',
+      'date',
+      'currentDate',
+      'asciiFile',
+      'htmlFile',
+      'utf8File',
+      'objectExists',
+      'optionExists',
+      'postalCode',
+      'money',
+      'positiveInteger',
+      'xssString',
+      'fileExists',
+      'autocomplete',
+      'validContact',
     );
 
     foreach ($rules as $rule) {
@@ -245,12 +262,13 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    * @param string $label
    * @param string|array $attributes (options for select elements)
    * @param bool $required
-   * @param array $extra (attributes for select elements)
+   * @param array $extra
+   *   (attributes for select elements).
    *
    * @return HTML_QuickForm_Element could be an error object
-   * @access public
    */
-  function &add($type, $name, $label = '',
+  public function &add(
+    $type, $name, $label = '',
     $attributes = '', $required = FALSE, $extra = NULL
   ) {
     if ($type == 'select' && is_array($extra)) {
@@ -292,44 +310,47 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * This function is called before buildForm. Any pre-processing that
+   * called before buildForm. Any pre-processing that
    * needs to be done for buildForm should be done here
    *
    * This is a virtual function and should be redefined if needed
    *
-   * @access public
    *
    * @return void
-   *
    */
-  function preProcess() {}
+  public function preProcess() {
+  }
 
   /**
-   * This function is called after the form is validated. Any
+   * called after the form is validated. Any
    * processing of form state etc should be done in this function.
    * Typically all processing associated with a form should be done
    * here and relevant state should be stored in the session
    *
    * This is a virtual function and should be redefined if needed
    *
-   * @access public
    *
    * @return void
-   *
    */
-  function postProcess() {}
+  public function postProcess() {
+  }
 
   /**
-   * This function is just a wrapper, so that we can call all the hook functions
-   * @param bool $allowAjax - FIXME: This feels kind of hackish, ideally we would take the json-related code from this function
+   * just a wrapper, so that we can call all the hook functions
+   * @param bool $allowAjax
+   *   FIXME: This feels kind of hackish, ideally we would take the json-related code from this function.
    *                          and bury it deeper down in the controller
    */
-  function mainProcess($allowAjax = TRUE) {
+  public function mainProcess($allowAjax = TRUE) {
     $this->postProcess();
     $this->postProcessHook();
 
     // Respond with JSON if in AJAX context (also support legacy value '6')
-    if ($allowAjax && !empty($_REQUEST['snippet']) && in_array($_REQUEST['snippet'], array(CRM_Core_Smarty::PRINT_JSON, 6))) {
+    if ($allowAjax && !empty($_REQUEST['snippet']) && in_array($_REQUEST['snippet'], array(
+          CRM_Core_Smarty::PRINT_JSON,
+          6,
+        ))
+    ) {
       $this->ajaxResponse['buttonName'] = str_replace('_qf_' . $this->getAttribute('id') . '_', '', $this->controller->getButtonName());
       $this->ajaxResponse['action'] = $this->_action;
       if (isset($this->_id) || isset($this->id)) {
@@ -340,14 +361,13 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * The postProcess hook is typically called by the framework
+   * The postProcess hook is typically called by the framework.
    * However in a few cases, the form exits or redirects early in which
    * case it needs to call this function so other modules can do the needful
    * Calling this function directly should be avoided if possible. In general a
    * better way is to do setUserContext so the framework does the redirect
-   *
    */
-  function postProcessHook() {
+  public function postProcessHook() {
     CRM_Utils_Hook::postProcess(get_class($this), $this);
   }
 
@@ -356,12 +376,11 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    * buildForm associated with QuickForm_Page. This allows us to put
    * preProcess in front of the actual form building routine
    *
-   * @access public
    *
    * @return void
-   *
    */
-  function buildQuickForm() {}
+  public function buildQuickForm() {
+  }
 
   /**
    * This virtual function is used to set the default values of
@@ -369,31 +388,32 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    *
    * access        public
    *
-   * @return array reference to the array of default values
-   *
+   * @return array|NULL
+   *   reference to the array of default values
    */
-  function setDefaultValues() {}
+  public function setDefaultValues() {
+    return NULL;
+  }
 
   /**
    * This is a virtual function that adds group and global rules to
    * the form. Keeping it distinct from the form to keep code small
    * and localized in the form building code
    *
-   * @access public
    *
    * @return void
-   *
    */
-  function addRules() {}
+  public function addRules() {
+  }
 
   /**
-   * Performs the server side validation
-   * @access    public
+   * Performs the server side validation.
    * @since     1.0
-   * @return    boolean   true if no error found
+   * @return bool
+   *   true if no error found
    * @throws    HTML_QuickForm_Error
    */
-  function validate() {
+  public function validate() {
     $error = parent::validate();
 
     $this->validateChainSelectFields();
@@ -428,13 +448,14 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    * Core function that builds the form. We redefine this function
    * here and expect all CRM forms to build their form in the function
    * buildQuickForm.
-   *
    */
-  function buildForm() {
+  public function buildForm() {
     $this->_formBuilt = TRUE;
 
     $this->preProcess();
 
+    CRM_Utils_Hook::preProcess(get_class($this), $this);
+
     $this->assign('translatePermission', CRM_Core_Permission::check('translate CiviCRM'));
 
     if (
@@ -469,47 +490,46 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
     $this->addRules();
 
     //Set html data-attribute to enable warning user of unsaved changes
-    if ($this->unsavedChangesWarn === true
-        || (!isset($this->unsavedChangesWarn)
-           && ($this->_action & CRM_Core_Action::ADD || $this->_action & CRM_Core_Action::UPDATE)
-           )
-        ) {
-          $this->setAttribute('data-warn-changes', 'true');
+    if ($this->unsavedChangesWarn === TRUE
+      || (!isset($this->unsavedChangesWarn)
+        && ($this->_action & CRM_Core_Action::ADD || $this->_action & CRM_Core_Action::UPDATE)
+      )
+    ) {
+      $this->setAttribute('data-warn-changes', 'true');
     }
   }
 
   /**
    * Add default Next / Back buttons
    *
-   * @param array   array of associative arrays in the order in which the buttons should be
-   *                displayed. The associate array has 3 fields: 'type', 'name' and 'isDefault'
-   *                The base form class will define a bunch of static arrays for commonly used
-   *                formats
+   * @param array $params
+   *   Array of associative arrays in the order in which the buttons should be
+   *   displayed. The associate array has 3 fields: 'type', 'name' and 'isDefault'
+   *   The base form class will define a bunch of static arrays for commonly used
+   *   formats.
    *
    * @return void
-   *
-   * @access public
-   *
    */
-  function addButtons($params) {
-    $prevnext = array();
-    $spacing = array();
+  public function addButtons($params) {
+    $prevnext = $spacing = array();
     foreach ($params as $button) {
-      $js = CRM_Utils_Array::value('js', $button);
-      $isDefault = CRM_Utils_Array::value('isDefault', $button, FALSE);
-      if ($isDefault) {
-        $attrs = array('class' => 'crm-form-submit default');
-      }
-      else {
-        $attrs = array('class' => 'crm-form-submit');
+      $attrs = array('class' => 'crm-form-submit') + (array) CRM_Utils_Array::value('js', $button);
+
+      if (!empty($button['class'])) {
+        $attrs['class'] .= ' ' . $button['class'];
       }
 
-      if ($js) {
-        $attrs = array_merge($js, $attrs);
+      if (!empty($button['isDefault'])) {
+        $attrs['class'] .= ' default';
       }
 
-      if ($button['type'] === 'cancel') {
+      if (in_array($button['type'], array('upload', 'next', 'submit', 'done', 'process', 'refresh'))) {
+        $attrs['class'] .= ' validate';
+        $defaultIcon = 'check';
+      }
+      else {
         $attrs['class'] .= ' cancel';
+        $defaultIcon = $button['type'] == 'back' ? 'triangle-1-w' : 'close';
       }
 
       if ($button['type'] === 'reset') {
@@ -517,15 +537,25 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
       }
       else {
         if (!empty($button['subName'])) {
-          $buttonName = $this->getButtonName($button['type'], $button['subName']);
-        }
-        else {
-          $buttonName = $this->getButtonName($button['type']);
+          if ($button['subName'] == 'new') {
+            $defaultIcon = 'plus';
+          }
+          if ($button['subName'] == 'done') {
+            $defaultIcon = 'circle-check';
+          }
+          if ($button['subName'] == 'next') {
+            $defaultIcon = 'circle-triangle-e';
+          }
         }
 
         if (in_array($button['type'], array('next', 'upload', 'done')) && $button['name'] === ts('Save')) {
-          $attrs = array_merge($attrs, (array('accesskey' => 'S')));
+          $attrs['accesskey'] = 'S';
         }
+        $icon = CRM_Utils_Array::value('icon', $button, $defaultIcon);
+        if ($icon) {
+          $attrs['crm-icon'] = $icon;
+        }
+        $buttonName = $this->getButtonName($button['type'], CRM_Utils_Array::value('subName', $button));
         $prevnext[] = $this->createElement('submit', $buttonName, $button['name'], $attrs);
       }
       if (!empty($button['isDefault'])) {
@@ -545,76 +575,70 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * getter function for Name
+   * Getter function for Name.
    *
    * @return string
-   * @access public
    */
-  function getName() {
+  public function getName() {
     return $this->_name;
   }
 
   /**
-   * getter function for State
+   * Getter function for State.
    *
    * @return object
-   * @access public
    */
-  function &getState() {
+  public function &getState() {
     return $this->_state;
   }
 
   /**
-   * getter function for StateType
+   * Getter function for StateType.
    *
    * @return int
-   * @access public
    */
-  function getStateType() {
+  public function getStateType() {
     return $this->_state->getType();
   }
 
   /**
-   * getter function for title. Should be over-ridden by derived class
+   * Getter function for title. Should be over-ridden by derived class
    *
    * @return string
-   * @access public
    */
-  function getTitle() {
+  public function getTitle() {
     return $this->_title ? $this->_title : ts('ERROR: Title is not Set');
   }
 
   /**
-   * setter function for title.
+   * Setter function for title.
    *
-   * @param string $title the title of the form
+   * @param string $title
+   *   The title of the form.
    *
    * @return void
-   * @access public
    */
-  function setTitle($title) {
+  public function setTitle($title) {
     $this->_title = $title;
   }
 
   /**
-   * Setter function for options
+   * Setter function for options.
    *
-   * @param mixed
+   * @param mixed $options
    *
    * @return void
-   * @access public
    */
-  function setOptions($options) {
+  public function setOptions($options) {
     $this->_options = $options;
   }
 
   /**
-   * getter function for link.
+   * Getter function for link.
    *
    * @return string
-   * @access public
    */
-  function getLink() {
+  public function getLink() {
     $config = CRM_Core_Config::singleton();
     return CRM_Utils_System::url($_GET[$config->userFrameworkURLVar],
       '_qf_' . $this->_name . '_display=true'
@@ -622,44 +646,40 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * boolean function to determine if this is a one form page
+   * Boolean function to determine if this is a one form page.
    *
-   * @return boolean
-   * @access public
+   * @return bool
    */
-  function isSimpleForm() {
+  public function isSimpleForm() {
     return $this->_state->getType() & (CRM_Core_State::START | CRM_Core_State::FINISH);
   }
 
   /**
-   * getter function for Form Action
+   * Getter function for Form Action.
    *
    * @return string
-   * @access public
    */
-  function getFormAction() {
+  public function getFormAction() {
     return $this->_attributes['action'];
   }
 
   /**
-   * setter function for Form Action
+   * Setter function for Form Action.
    *
-   * @param string
+   * @param string $action
    *
    * @return void
-   * @access public
    */
-  function setFormAction($action) {
+  public function setFormAction($action) {
     $this->_attributes['action'] = $action;
   }
 
   /**
-   * render form and return contents
+   * Render form and return contents.
    *
    * @return string
-   * @access public
    */
-  function toSmarty() {
+  public function toSmarty() {
     $this->preProcessChainSelectFields();
     $renderer = $this->getRenderer();
     $this->accept($renderer);
@@ -671,13 +691,12 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * getter function for renderer. If renderer is not set
+   * Getter function for renderer. If renderer is not set
    * create one and initialize it
    *
    * @return object
-   * @access public
    */
-  function &getRenderer() {
+  public function &getRenderer() {
     if (!isset($this->_renderer)) {
       $this->_renderer = CRM_Core_Form_Renderer::singleton();
     }
@@ -685,21 +704,23 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * Use the form name to create the tpl file name
+   * Use the form name to create the tpl file name.
    *
    * @return string
-   * @access public
    */
-  function getTemplateFileName() {
+  public function getTemplateFileName() {
     $ext = CRM_Extension_System::singleton()->getMapper();
     if ($ext->isExtensionClass(CRM_Utils_System::getClassName($this))) {
       $filename = $ext->getTemplateName(CRM_Utils_System::getClassName($this));
       $tplname = $ext->getTemplatePath(CRM_Utils_System::getClassName($this)) . DIRECTORY_SEPARATOR . $filename;
     }
     else {
-      $tplname = str_replace('_',
-        DIRECTORY_SEPARATOR,
-        CRM_Utils_System::getClassName($this)
+      $tplname = strtr(
+        CRM_Utils_System::getClassName($this),
+        array(
+          '_' => DIRECTORY_SEPARATOR,
+          '\\' => DIRECTORY_SEPARATOR,
+        )
       ) . '.tpl';
     }
     return $tplname;
@@ -709,7 +730,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    * A wrapper for getTemplateFileName that includes calling the hook to
    * prevent us from having to copy & paste the logic of calling the hook
    */
-  function getHookedTemplateFileName() {
+  public function getHookedTemplateFileName() {
     $pageTemplateFile = $this->getTemplateFileName();
     CRM_Utils_Hook::alterTemplateFile(get_class($this), $this, 'page', $pageTemplateFile);
     return $pageTemplateFile;
@@ -720,23 +741,24 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    * i.e. we dont override
    *
    * @return string
-   * @access public
    */
-  function overrideExtraTemplateFileName() {
+  public function overrideExtraTemplateFileName() {
     return NULL;
   }
 
   /**
-   * Error reporting mechanism
+   * Error reporting mechanism.
    *
-   * @param string  $message Error Message
-   * @param int     $code    Error Code
-   * @param CRM_Core_DAO $dao     A data access object on which we perform a rollback if non - empty
+   * @param string $message
+   *   Error Message.
+   * @param int $code
+   *   Error Code.
+   * @param CRM_Core_DAO $dao
+   *   A data access object on which we perform a rollback if non - empty.
    *
    * @return void
-   * @access public
    */
-  function error($message, $code = NULL, $dao = NULL) {
+  public function error($message, $code = NULL, $dao = NULL) {
     if ($dao) {
       $dao->query('ROLLBACK');
     }
@@ -747,109 +769,105 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * Store the variable with the value in the form scope
-   *
-   * @param  string name  : name  of the variable
-   * @param  mixed  value : value of the variable
+   * Store the variable with the value in the form scope.
    *
-   * @access public
+   * @param string $name
+   *   Name of the variable.
+   * @param mixed $value
+   *   Value of the variable.
    *
    * @return void
-   *
    */
-  function set($name, $value) {
+  public function set($name, $value) {
     $this->controller->set($name, $value);
   }
 
   /**
-   * Get the variable from the form scope
+   * Get the variable from the form scope.
    *
-   * @param  string name  : name  of the variable
-   *
-   * @access public
+   * @param string $name
+   *   Name of the variable
    *
    * @return mixed
-   *
    */
-  function get($name) {
+  public function get($name) {
     return $this->controller->get($name);
   }
 
   /**
-   * getter for action
+   * Getter for action.
    *
    * @return int
-   * @access public
    */
-  function getAction() {
+  public function getAction() {
     return $this->_action;
   }
 
   /**
-   * setter for action
+   * Setter for action.
    *
-   * @param  int  $action the mode we want to set the form
+   * @param int $action
+   *   The mode we want to set the form.
    *
    * @return void
-   * @access public
    */
-  function setAction($action) {
+  public function setAction($action) {
     $this->_action = $action;
   }
 
   /**
-   * assign value to name in template
+   * Assign value to name in template.
    *
-   * @param $var
-   * @param mixed $value value of varaible
+   * @param string $var
+   *   Name of variable.
+   * @param mixed $value
+   *   Value of variable.
    *
-   * @internal param array|string $name name  of variable
    * @return void
-   * @access public
    */
-  function assign($var, $value = NULL) {
+  public function assign($var, $value = NULL) {
     self::$_template->assign($var, $value);
   }
 
   /**
-   * assign value to name in template by reference
+   * Assign value to name in template by reference.
    *
-   * @param $var
-   * @param mixed $value value of varaible
+   * @param string $var
+   *   Name of variable.
+   * @param mixed $value
+   *   Value of varaible.
    *
-   * @internal param array|string $name name  of variable
    * @return void
-   * @access public
    */
-  function assign_by_ref($var, &$value) {
+  public function assign_by_ref($var, &$value) {
     self::$_template->assign_by_ref($var, $value);
   }
 
   /**
-   * appends values to template variables
+   * Appends values to template variables.
    *
    * @param array|string $tpl_var the template variable name(s)
-   * @param mixed $value the value to append
+   * @param mixed $value
+   *   The value to append.
    * @param bool $merge
    */
-  function append($tpl_var, $value=NULL, $merge=FALSE) {
+  public function append($tpl_var, $value = NULL, $merge = FALSE) {
     self::$_template->append($tpl_var, $value, $merge);
   }
 
   /**
-   * Returns an array containing template variables
+   * Returns an array containing template variables.
    *
    * @param string $name
    *
-   * @internal param string $type
    * @return array
    */
-  function get_template_vars($name=null) {
+  public function get_template_vars($name = NULL) {
     return self::$_template->get_template_vars($name);
   }
 
   /**
-   * @param $name
+   * @param string $name
    * @param $title
    * @param $values
    * @param array $attributes
@@ -858,12 +876,12 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    *
    * @return HTML_QuickForm_group
    */
-  function &addRadio($name, $title, $values, $attributes = array(), $separator = NULL, $required = FALSE) {
+  public function &addRadio($name, $title, $values, $attributes = array(), $separator = NULL, $required = FALSE) {
     $options = array();
     $attributes = $attributes ? $attributes : array();
     $allowClear = !empty($attributes['allowClear']);
     unset($attributes['allowClear']);
-    $attributes += array('id_suffix' => $name);
+    $attributes['id_suffix'] = $name;
     foreach ($values as $key => $var) {
       $options[] = $this->createElement('radio', NULL, NULL, $var, $key, $attributes);
     }
@@ -878,15 +896,15 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * @param $id
+   * @param int $id
    * @param $title
    * @param bool $allowClear
    * @param null $required
    * @param array $attributes
    */
-  function addYesNo($id, $title, $allowClear = FALSE, $required = NULL, $attributes = array()) {
+  public function addYesNo($id, $title, $allowClear = FALSE, $required = NULL, $attributes = array()) {
     $attributes += array('id_suffix' => $id);
-    $choice   = array();
+    $choice = array();
     $choice[] = $this->createElement('radio', NULL, '11', ts('Yes'), '1', $attributes);
     $choice[] = $this->createElement('radio', NULL, '11', ts('No'), '0', $attributes);
 
@@ -900,7 +918,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * @param $id
+   * @param int $id
    * @param $title
    * @param $values
    * @param null $other
@@ -910,10 +928,11 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    * @param string $separator
    * @param bool $flipValues
    */
-  function addCheckBox($id, $title, $values, $other = NULL,
-    $attributes       = NULL, $required = NULL,
+  public function addCheckBox(
+    $id, $title, $values, $other = NULL,
+    $attributes = NULL, $required = NULL,
     $javascriptMethod = NULL,
-    $separator        = '<br />', $flipValues = FALSE
+    $separator = '<br />', $flipValues = FALSE
   ) {
     $options = array();
 
@@ -952,25 +971,25 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
     }
   }
 
-  function resetValues() {
+  public function resetValues() {
     $data = $this->controller->container();
     $data['values'][$this->_name] = array();
   }
 
   /**
-   * simple shell that derived classes can call to add buttons to
+   * Simple shell that derived classes can call to add buttons to
    * the form with a customized title for the main Submit
    *
-   * @param string $title title of the main button
+   * @param string $title
+   *   Title of the main button.
    * @param string $nextType
+   *   Button type for the form after processing.
    * @param string $backType
    * @param bool|string $submitOnce If true, add javascript to next button submit which prevents it from being clicked more than once
    *
-   * @internal param string $type button type for the form after processing
    * @return void
-   * @access public
    */
-  function addDefaultButtons($title, $nextType = 'next', $backType = 'back', $submitOnce = FALSE) {
+  public function addDefaultButtons($title, $nextType = 'next', $backType = 'back', $submitOnce = FALSE) {
     $buttons = array();
     if ($backType != NULL) {
       $buttons[] = array(
@@ -993,7 +1012,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * @param $name
+   * @param string $name
    * @param string $from
    * @param string $to
    * @param string $label
@@ -1001,32 +1020,36 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    * @param bool $required
    * @param bool $displayTime
    */
-  function addDateRange($name, $from = '_from', $to = '_to', $label = 'From:', $dateFormat = 'searchDate', $required = FALSE, $displayTime = FALSE) {
+  public function addDateRange($name, $from = '_from', $to = '_to', $label = 'From:', $dateFormat = 'searchDate', $required = FALSE, $displayTime = FALSE) {
     if ($displayTime) {
       $this->addDateTime($name . $from, $label, $required, array('formatType' => $dateFormat));
       $this->addDateTime($name . $to, ts('To:'), $required, array('formatType' => $dateFormat));
-    } else {
+    }
+    else {
       $this->addDate($name . $from, $label, $required, array('formatType' => $dateFormat));
       $this->addDate($name . $to, ts('To:'), $required, array('formatType' => $dateFormat));
     }
   }
 
   /**
-   * Adds a select based on field metadata
+   * Adds a select based on field metadata.
    * TODO: This could be even more generic and widget type (select in this case) could also be read from metadata
    * Perhaps a method like $form->bind($name) which would look up all metadata for named field
-   * @param $name - field name to go on the form
-   * @param array $props - mix of html attributes and special properties, namely
+   * @param $name
+   *   Field name to go on the form.
+   * @param array $props
+   *   Mix of html attributes and special properties, namely.
    *   - entity (api entity name, can usually be inferred automatically from the form class)
    *   - field (field name - only needed if different from name used on the form)
    *   - option_url - path to edit this option list - usually retrieved automatically - set to NULL to disable link
    *   - placeholder - set to NULL to disable
    *   - multiple - bool
+   *   - context - @see CRM_Core_DAO::buildOptionsContext
    * @param bool $required
    * @throws CRM_Core_Exception
    * @return HTML_QuickForm_Element
    */
-  function addSelect($name, $props = array(), $required = FALSE) {
+  public function addSelect($name, $props = array(), $required = FALSE) {
     if (!isset($props['entity'])) {
       $props['entity'] = CRM_Utils_Api::getEntityName($this);
     }
@@ -1038,23 +1061,25 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
       $options = $props['options'];
     }
     else {
-      $info = civicrm_api3($props['entity'], 'getoptions', array('field' => $props['field']));
+      $info = civicrm_api3($props['entity'], 'getoptions', $props);
       $options = $info['values'];
     }
     if (!array_key_exists('placeholder', $props)) {
-      $props['placeholder'] = $required ? ts('- select -') : ts('- none -');
+      $props['placeholder'] = $required ? ts('- select -') : CRM_Utils_Array::value('context', $props) == 'search' ? ts('- any -') : ts('- none -');
     }
     // Handle custom field
     if (strpos($name, 'custom_') === 0 && is_numeric($name[7])) {
       list(, $id) = explode('_', $name);
       $label = isset($props['label']) ? $props['label'] : CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField', 'label', $id);
       $gid = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField', 'option_group_id', $id);
-      $props['data-option-edit-path'] = array_key_exists('option_url', $props) ? $props['option_url'] : 'civicrm/admin/options/' . CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', $gid);
+      if (CRM_Utils_Array::value('context', $props) != 'search') {
+        $props['data-option-edit-path'] = array_key_exists('option_url', $props) ? $props['option_url'] : 'civicrm/admin/options/' . CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', $gid);
+      }
     }
     // Core field
     else {
       $info = civicrm_api3($props['entity'], 'getfields');
-      foreach($info['values'] as $uniqueName => $fieldSpec) {
+      foreach ($info['values'] as $uniqueName => $fieldSpec) {
         if (
           $uniqueName === $props['field'] ||
           CRM_Utils_Array::value('name', $fieldSpec) === $props['field'] ||
@@ -1064,26 +1089,33 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
         }
       }
       $label = isset($props['label']) ? $props['label'] : $fieldSpec['title'];
-      $props['data-option-edit-path'] = array_key_exists('option_url', $props) ? $props['option_url'] : $props['data-option-edit-path'] = CRM_Core_PseudoConstant::getOptionEditUrl($fieldSpec);
+      if (CRM_Utils_Array::value('context', $props) != 'search') {
+        $props['data-option-edit-path'] = array_key_exists('option_url', $props) ? $props['option_url'] : $props['data-option-edit-path'] = CRM_Core_PseudoConstant::getOptionEditUrl($fieldSpec);
+      }
     }
     $props['class'] = (isset($props['class']) ? $props['class'] . ' ' : '') . "crm-select2";
     $props['data-api-entity'] = $props['entity'];
     $props['data-api-field'] = $props['field'];
-    CRM_Utils_Array::remove($props, 'label', 'entity', 'field', 'option_url', 'options');
+    CRM_Utils_Array::remove($props, 'label', 'entity', 'field', 'option_url', 'options', 'context');
     return $this->add('select', $name, $label, $options, $required, $props);
   }
 
   /**
    * Add a widget for selecting/editing/creating/copying a profile form
    *
-   * @param string $name HTML form-element name
-   * @param string $label Printable label
-   * @param string $allowCoreTypes only present a UFGroup if its group_type includes a subset of $allowCoreTypes; e.g. 'Individual', 'Activity'
-   * @param string $allowSubTypes only present a UFGroup if its group_type is compatible with $allowSubypes
+   * @param string $name
+   *   HTML form-element name.
+   * @param string $label
+   *   Printable label.
+   * @param string $allowCoreTypes
+   *   Only present a UFGroup if its group_type includes a subset of $allowCoreTypes; e.g. 'Individual', 'Activity'.
+   * @param string $allowSubTypes
+   *   Only present a UFGroup if its group_type is compatible with $allowSubypes.
    * @param array $entities
-   * @param bool $default //CRM-15427
+   * @param bool $default
+   *   //CRM-15427.
    */
-  function addProfileSelector($name, $label, $allowCoreTypes, $allowSubTypes, $entities, $default = FALSE) {
+  public function addProfileSelector($name, $label, $allowCoreTypes, $allowSubTypes, $entities, $default = FALSE) {
     // Output widget
     // FIXME: Instead of adhoc serialization, use a single json_encode()
     CRM_UF_Page_ProfileEditor::registerProfileScripts();
@@ -1099,20 +1131,20 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * @param $name
+   * @param string $name
    * @param $label
    * @param $attributes
    * @param bool $forceTextarea
    */
-  function addWysiwyg($name, $label, $attributes, $forceTextarea = FALSE) {
+  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')
-      ));
+      CRM_Core_OptionGroup::values('wysiwyg_editor')
+    ));
     if (!$editor || $forceTextarea) {
       $editor = 'textarea';
     }
@@ -1143,15 +1175,16 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * @param $id
+   * @param int $id
    * @param $title
    * @param null $required
    * @param null $extra
    */
-  function addCountry($id, $title, $required = NULL, $extra = NULL) {
+  public function addCountry($id, $title, $required = NULL, $extra = NULL) {
     $this->addElement('select', $id, $title,
       array(
-        '' => ts('- select -')) + CRM_Core_PseudoConstant::country(), $extra
+        '' => ts('- select -'),
+      ) + CRM_Core_PseudoConstant::country(), $extra
     );
     if ($required) {
       $this->addRule($id, ts('Please select %1', array(1 => $title)), 'required');
@@ -1159,14 +1192,14 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * @param $name
+   * @param string $name
    * @param $label
    * @param $options
    * @param $attributes
    * @param null $required
    * @param null $javascriptMethod
    */
-  function addSelectOther($name, $label, $options, $attributes, $required = NULL, $javascriptMethod = NULL) {
+  public function addSelectOther($name, $label, $options, $attributes, $required = NULL, $javascriptMethod = NULL) {
 
     $this->addElement('select', $name . '_id', $label, $options, $javascriptMethod);
 
@@ -1192,14 +1225,14 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   /**
    * @return CRM_Core_Smarty
    */
-  static function &getTemplate() {
+  public static function &getTemplate() {
     return self::$_template;
   }
 
   /**
    * @param $elementName
    */
-  function addUploadElement($elementName) {
+  public function addUploadElement($elementName) {
     $uploadNames = $this->get('uploadNames');
     if (!$uploadNames) {
       $uploadNames = array();
@@ -1227,7 +1260,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   /**
    * @return string
    */
-  function buttonType() {
+  public function buttonType() {
     $uploadNames = $this->get('uploadNames');
     $buttonType = (is_array($uploadNames) && !empty($uploadNames)) ? 'upload' : 'next';
     $this->assign('buttonType', $buttonType);
@@ -1239,7 +1272,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    *
    * @return null
    */
-  function getVar($name) {
+  public function getVar($name) {
     return isset($this->$name) ? $this->$name : NULL;
   }
 
@@ -1247,24 +1280,31 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    * @param $name
    * @param $value
    */
-  function setVar($name, $value) {
+  public function setVar($name, $value) {
     $this->$name = $value;
   }
 
   /**
-   *  Function to add date
-   *  @param string $name   name of the element
-   *  @param string $label  label of the element
-   *  @param array  $attributes key / value pair
+   * Add date.
    *
-   // if you need time
-   *  $attributes = array ( 'addTime' => true,
-   *                        'formatType' => 'relative' or 'birth' etc check advanced date settings
-   *                      );
-   *  @param boolean $required  true if required
+   * @code
+   * // if you need time
+   * $attributes = array(
+   *   'addTime' => true,
+   *   'formatType' => 'relative' or 'birth' etc check advanced date settings
+   * );
+   * @endcode
    *
+   * @param string $name
+   *   Name of the element.
+   * @param string $label
+   *   Label of the element.
+   * @param bool $required
+   *   True if required.
+   * @param array $attributes
+   *   Key / value pair.
    */
-  function addDate($name, $label, $required = FALSE, $attributes = NULL) {
+  public function addDate($name, $label, $required = FALSE, $attributes = NULL) {
     if (!empty($attributes['formatType'])) {
       // get actual format
       $params = array('name' => $attributes['formatType']);
@@ -1343,9 +1383,9 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   *  Function that will add date and time
+   *  Function that will add date and time.
    */
-  function addDateTime($name, $label, $required = FALSE, $attributes = NULL) {
+  public function addDateTime($name, $label, $required = FALSE, $attributes = NULL) {
     $addTime = array('addTime' => TRUE);
     if (is_array($attributes)) {
       $attributes = array_merge($attributes, $addTime);
@@ -1358,16 +1398,17 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * add a currency and money element to the form
+   * Add a currency and money element to the form.
    */
-  function addMoney($name,
+  public function addMoney(
+    $name,
     $label,
-    $required        = FALSE,
-    $attributes      = NULL,
-    $addCurrency     = TRUE,
-    $currencyName    = 'currency',
+    $required = FALSE,
+    $attributes = NULL,
+    $addCurrency = TRUE,
+    $currencyName = 'currency',
     $defaultCurrency = NULL,
-    $freezeCurrency  = FALSE
+    $freezeCurrency = FALSE
   ) {
     $element = $this->add('text', $name, $label, $attributes, $required);
     $this->addRule($name, ts('Please enter a valid amount.'), 'money');
@@ -1380,13 +1421,14 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * add currency element to the form
+   * Add currency element to the form.
    */
-  function addCurrency($name = 'currency',
-    $label           = NULL,
-    $required        = TRUE,
+  public function addCurrency(
+    $name = 'currency',
+    $label = NULL,
+    $required = TRUE,
     $defaultCurrency = NULL,
-    $freezeCurrency  = FALSE
+    $freezeCurrency = FALSE
   ) {
     $currencies = CRM_Core_OptionGroup::values('currencies_enabled');
     $options = array('class' => 'crm-select2 eight');
@@ -1406,27 +1448,27 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * Create a single or multiple entity ref field
+   * Create a single or multiple entity ref field.
    * @param string $name
    * @param string $label
-   * @param array $props mix of html and widget properties, including:
-   *  - select - params to give to select2 widget
-   *  - entity - defaults to contact
-   *  - create - can the user create a new entity on-the-fly?
+   * @param array $props
+   *   Mix of html and widget properties, including:.
+   *   - select - params to give to select2 widget
+   *   - entity - defaults to contact
+   *   - create - can the user create a new entity on-the-fly?
    *             Set to TRUE if entity is contact and you want the default profiles,
    *             or pass in your own set of links. @see CRM_Core_BAO_UFGroup::getCreateLinks for format
    *             note that permissions are checked automatically
-   *  - api - array of settings for the getlist api wrapper
+   *   - api - array of settings for the getlist api wrapper
    *          note that it accepts a 'params' setting which will be passed to the underlying api
-   *  - placeholder - string
-   *  - multiple - bool
-   *  - class, etc. - other html properties
+   *   - placeholder - string
+   *   - multiple - bool
+   *   - class, etc. - other html properties
    * @param bool $required
    *
-   * @access public
    * @return HTML_QuickForm_Element
    */
-  function addEntityRef($name, $label = '', $props = array(), $required = FALSE) {
+  public function addEntityRef($name, $label = '', $props = array(), $required = FALSE) {
     require_once "api/api.php";
     $config = CRM_Core_Config::singleton();
     // Default properties
@@ -1468,23 +1510,24 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    * BAO layer. In this case fields are checked against the $_datefields defined for the form
    * and if time is defined it is incorporated
    *
-   * @param array $params input params from the form
+   * @param array $params
+   *   Input params from the form.
    *
    * @todo it would probably be better to work on $this->_params than a passed array
    * @todo standardise the format which dates are passed to the BAO layer in & remove date
    * handling from BAO
    */
-  function convertDateFieldsToMySQL(&$params){
-    foreach ($this->_dateFields as $fieldName => $specs){
-      if(!empty($params[$fieldName])){
+  public function convertDateFieldsToMySQL(&$params) {
+    foreach ($this->_dateFields as $fieldName => $specs) {
+      if (!empty($params[$fieldName])) {
         $params[$fieldName] = CRM_Utils_Date::isoToMysql(
           CRM_Utils_Date::processDate(
-          $params[$fieldName],
-          CRM_Utils_Array::value("{$fieldName}_time", $params), TRUE)
+            $params[$fieldName],
+            CRM_Utils_Array::value("{$fieldName}_time", $params), TRUE)
         );
       }
-      else{
-        if(isset($specs['default'])){
+      else {
+        if (isset($specs['default'])) {
           $params[$fieldName] = date('YmdHis', strtotime($specs['default']));
         }
       }
@@ -1494,7 +1537,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   /**
    * @param $elementName
    */
-  function removeFileRequiredRules($elementName) {
+  public function removeFileRequiredRules($elementName) {
     $this->_required = array_diff($this->_required, array($elementName));
     if (isset($this->_rules[$elementName])) {
       foreach ($this->_rules[$elementName] as $index => $ruleInfo) {
@@ -1509,18 +1552,17 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * Function that can be defined in Form to override or
+   * Function that can be defined in Form to override or.
    * perform specific action on cancel action
-   *
-   * @access public
    */
-  function cancelAction() {}
+  public function cancelAction() {
+  }
 
   /**
-   * Helper function to verify that required fields have been filled
+   * Helper function to verify that required fields have been filled.
    * Typically called within the scope of a FormRule function
    */
-  static function validateMandatoryFields($fields, $values, &$errors) {
+  public static function validateMandatoryFields($fields, $values, &$errors) {
     foreach ($fields as $name => $fld) {
       if (!empty($fld['is_required']) && CRM_Utils_System::isNull(CRM_Utils_Array::value($name, $values))) {
         $errors[$name] = ts('%1 is a required field.', array(1 => $fld['title']));
@@ -1530,21 +1572,21 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
 
   /**
    * Get contact if for a form object. Prioritise
-   *  - cid in URL if 0 (on behalf on someoneelse)
+   *   - cid in URL if 0 (on behalf on someoneelse)
    *      (@todo consider setting a variable if onbehalf for clarity of downstream 'if's
-   *  - logged in user id if it matches the one in the cid in the URL
-   *  - contact id validated from a checksum from a checksum
-   *  - cid from the url if the caller has ACL permission to view
-   *  - fallback is logged in user (or ? NULL if no logged in user) (@todo wouldn't 0 be more intuitive?)
+   *   - logged in user id if it matches the one in the cid in the URL
+   *   - contact id validated from a checksum from a checksum
+   *   - cid from the url if the caller has ACL permission to view
+   *   - fallback is logged in user (or ? NULL if no logged in user) (@todo wouldn't 0 be more intuitive?)
    *
-   * @return mixed NULL|integer
+   * @return NULL|int
    */
-  function getContactID() {
+  public function getContactID() {
     $tempID = CRM_Utils_Request::retrieve('cid', 'Positive', $this);
-    if(isset($this->_params) && isset($this->_params['select_contact_id'])) {
+    if (isset($this->_params) && isset($this->_params['select_contact_id'])) {
       $tempID = $this->_params['select_contact_id'];
     }
-    if(isset($this->_params, $this->_params[0]) && !empty($this->_params[0]['select_contact_id'])) {
+    if (isset($this->_params, $this->_params[0]) && !empty($this->_params[0]['select_contact_id'])) {
       // event form stores as an indexed array, contribution form not so much...
       $tempID = $this->_params[0]['select_contact_id'];
     }
@@ -1575,24 +1617,24 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
       }
     }
     // check if user has permission, CRM-12062
-    else if ($tempID && CRM_Contact_BAO_Contact_Permission::allow($tempID)) {
+    elseif ($tempID && CRM_Contact_BAO_Contact_Permission::allow($tempID)) {
       return $tempID;
     }
 
     return $userID;
   }
 
- /**
-  * Get the contact id of the logged in user
-  */
-  function getLoggedInUserContactID() {
 /**
+   * Get the contact id of the logged in user.
+   */
+  public function getLoggedInUserContactID() {
     // check if the user is logged in and has a contact ID
     $session = CRM_Core_Session::singleton();
     return $session->get('userID');
   }
 
   /**
-   * add autoselector field -if user has permission to view contacts
+   * Add autoselector field -if user has permission to view contacts
    * If adding this to a form you also need to add to the tpl e.g
    *
    * {if !empty($selectable)}
@@ -1604,44 +1646,47 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    * </div>
    * {/if}
    *
-   * @param array $profiles ids of profiles that are on the form (to be autofilled)
+   * @param array $profiles
+   *   Ids of profiles that are on the form (to be autofilled).
    * @param array $autoCompleteField
    *
-   * @internal param array $field metadata of field to use as selector including
-   *  - name_field
-   *  - id_field
-   *  - url (for ajax lookup)
+   *   - name_field
+   *   - id_field
+   *   - url (for ajax lookup)
    *
    * @todo add data attributes so we can deal with multiple instances on a form
    */
-  function addAutoSelector($profiles = array(), $autoCompleteField = array()) {
+  public function addAutoSelector($profiles = array(), $autoCompleteField = array()) {
     $autoCompleteField = array_merge(array(
-        'id_field' => 'select_contact_id',
-        'placeholder' => ts('Select someone else ...'),
-        'show_hide' => TRUE,
-        'api' => array('params' => array('contact_type' => 'Individual'))
-      ), $autoCompleteField);
+      'id_field' => 'select_contact_id',
+      'placeholder' => ts('Select someone else ...'),
+      'show_hide' => TRUE,
+      'api' => array('params' => array('contact_type' => 'Individual')),
+    ), $autoCompleteField);
 
-    if($this->canUseAjaxContactLookups()) {
+    if ($this->canUseAjaxContactLookups()) {
       $this->assign('selectable', $autoCompleteField['id_field']);
-      $this->addEntityRef($autoCompleteField['id_field'], NULL, array('placeholder' => $autoCompleteField['placeholder'], 'api' => $autoCompleteField['api']));
+      $this->addEntityRef($autoCompleteField['id_field'], NULL, array(
+          'placeholder' => $autoCompleteField['placeholder'],
+          'api' => $autoCompleteField['api'],
+        ));
 
       CRM_Core_Resources::singleton()->addScriptFile('civicrm', 'js/AlternateContactSelector.js', 1, 'html-header')
-      ->addSetting(array(
-      'form' => array('autocompletes' => $autoCompleteField),
-      'ids' => array('profile' => $profiles),
-      ));
+        ->addSetting(array(
+          'form' => array('autocompletes' => $autoCompleteField),
+          'ids' => array('profile' => $profiles),
+        ));
     }
   }
 
   /**
-   *
    */
-  function canUseAjaxContactLookups() {
+  public function canUseAjaxContactLookups() {
     if (0 < (civicrm_api3('contact', 'getcount', array('check_permissions' => 1))) &&
-      CRM_Core_Permission::check(array(array('access AJAX API', 'access CiviCRM')))) {
-        return TRUE;
-      }
+      CRM_Core_Permission::check(array(array('access AJAX API', 'access CiviCRM')))
+    ) {
+      return TRUE;
+    }
   }
 
   /**
@@ -1651,20 +1696,22 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    * that small pieces of duplication are not being refactored into separate functions because their only shared parent
    * is this form. Inserting a class FrontEndForm.php between the contribution & event & this class would allow functions like this
    * and a dozen other small ones to be refactored into a shared parent with the reduction of much code duplication
+   *
+   * @param $onlinePaymentProcessorEnabled
    */
-  function addCIDZeroOptions($onlinePaymentProcessorEnabled) {
+  public function addCIDZeroOptions($onlinePaymentProcessorEnabled) {
     $this->assign('nocid', TRUE);
     $profiles = array();
-    if($this->_values['custom_pre_id']) {
+    if ($this->_values['custom_pre_id']) {
       $profiles[] = $this->_values['custom_pre_id'];
     }
-    if($this->_values['custom_post_id']) {
-      $profiles[] = $this->_values['custom_post_id'];
+    if ($this->_values['custom_post_id']) {
+      $profiles = array_merge($profiles, (array) $this->_values['custom_post_id']);
     }
-    if($onlinePaymentProcessorEnabled) {
+    if ($onlinePaymentProcessorEnabled) {
       $profiles[] = 'billing';
     }
-    if(!empty($this->_values)) {
+    if (!empty($this->_values)) {
       $this->addAutoSelector($profiles);
     }
   }
@@ -1672,13 +1719,14 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   /**
    * Set default values on form for given contact (or no contact defaults)
    *
-   * @param mixed $profile_id (can be id, or profile name)
-   * @param integer $contactID
+   * @param mixed $profile_id
+   *   (can be id, or profile name).
+   * @param int $contactID
    *
    * @return array
    */
-  function getProfileDefaults($profile_id = 'Billing', $contactID = NULL) {
-    try{
+  public function getProfileDefaults($profile_id = 'Billing', $contactID = NULL) {
+    try {
       $defaults = civicrm_api3('profile', 'getsingle', array(
         'profile_id' => (array) $profile_id,
         'contact_id' => $contactID,
@@ -1693,37 +1741,40 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   }
 
   /**
-   * Sets form attribute
+   * Sets form attribute.
    * @see CRM.loadForm
    */
-  function preventAjaxSubmit() {
+  public function preventAjaxSubmit() {
     $this->setAttribute('data-no-ajax-submit', 'true');
   }
 
   /**
-   * Sets form attribute
+   * Sets form attribute.
    * @see CRM.loadForm
    */
-  function allowAjaxSubmit() {
+  public function allowAjaxSubmit() {
     $this->removeAttribute('data-no-ajax-submit');
   }
 
   /**
-   * Sets page title based on entity and action
+   * Sets page title based on entity and action.
    * @param string $entityLabel
    */
-  function setPageTitle($entityLabel) {
+  public function setPageTitle($entityLabel) {
     switch ($this->_action) {
       case CRM_Core_Action::ADD:
         CRM_Utils_System::setTitle(ts('New %1', array(1 => $entityLabel)));
         break;
+
       case CRM_Core_Action::UPDATE:
         CRM_Utils_System::setTitle(ts('Edit %1', array(1 => $entityLabel)));
         break;
+
       case CRM_Core_Action::VIEW:
       case CRM_Core_Action::PREVIEW:
         CRM_Utils_System::setTitle(ts('View %1', array(1 => $entityLabel)));
         break;
+
       case CRM_Core_Action::DELETE:
         CRM_Utils_System::setTitle(ts('Delete %1', array(1 => $entityLabel)));
         break;
@@ -1740,7 +1791,12 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    */
   public function addChainSelect($elementName, $settings = array()) {
     $props = $settings += array(
-      'control_field' => str_replace(array('state_province', 'StateProvince', 'county', 'County'), array('country', 'Country', 'state_province', 'StateProvince'), $elementName),
+      'control_field' => str_replace(array('state_province', 'StateProvince', 'county', 'County'), array(
+          'country',
+          'Country',
+          'state_province',
+          'StateProvince',
+        ), $elementName),
       'data-callback' => strpos($elementName, 'rovince') ? 'civicrm/ajax/jqState' : 'civicrm/ajax/jqCounty',
       'label' => strpos($elementName, 'rovince') ? ts('State/Province') : ts('County'),
       'data-empty-prompt' => strpos($elementName, 'rovince') ? ts('Choose country first') : ts('Choose state first'),
@@ -1791,7 +1847,8 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
             if (!$options) {
               $targetField->setAttribute('placeholder', $targetField->getAttribute('data-none-prompt'));
             }
-          } else {
+          } 
+          else {
             $targetField->setAttribute('placeholder', $targetField->getAttribute('data-empty-prompt'));
             $targetField->setAttribute('disabled', 'disabled');
           }
@@ -1816,10 +1873,10 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
   private function validateChainSelectFields() {
     foreach ($this->_chainSelectFields as $control => $target) {
       if ($this->elementExists($control) && $this->elementExists($target)) {
-        $controlValue = (array)$this->getElementValue($control);
+        $controlValue = (array) $this->getElementValue($control);
         $targetField = $this->getElement($target);
         $controlType = $targetField->getAttribute('data-callback') == 'civicrm/ajax/jqCounty' ? 'stateProvince' : 'country';
-        $targetValue = array_filter((array)$targetField->getValue());
+        $targetValue = array_filter((array) $targetField->getValue());
         if ($targetValue || $this->getElementError($target)) {
           $options = CRM_Core_BAO_Location::getChainSelectValues($controlValue, $controlType, TRUE);
           if ($targetValue) {
@@ -1834,5 +1891,5 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
       }
     }
   }
-}
 
+}