*/
public $ajaxResponse = array();
+ /**
+ * Url path used to reach this page
+ *
+ * @var array
+ */
+ public $urlPath = array();
+
/**
* constants for attributes for various form elements
* attempt to standardize on the number of variations that we
* These are not default values
* @param bool is this a required field
*
- * @return object html element, could be an error object
+ * @return HTML_QuickForm_Element could be an error object
* @access public
*
*/
$prevnext[] = $this->createElement($button['type'], 'reset', $button['name'], $attrs);
}
else {
- if (CRM_Utils_Array::value('subName', $button)) {
+ if (!empty($button['subName'])) {
$buttonName = $this->getButtonName($button['type'], $button['subName']);
}
else {
}
$prevnext[] = $this->createElement('submit', $buttonName, $button['name'], $attrs);
}
- if (CRM_Utils_Array::value('isDefault', $button)) {
+ if (!empty($button['isDefault'])) {
$this->setDefaultAction($button['type']);
}
return self::$_template->get_template_vars($name);
}
- function &addRadio($name, $title, &$values, $attributes = NULL, $separator = NULL, $required = FALSE) {
+ function &addRadio($name, $title, $values, $attributes = array(), $separator = NULL, $required = FALSE) {
$options = array();
- if (empty($attributes)) {
- $attributes = array('id_suffix' => $name);
- }
- else {
- $attributes = array_merge($attributes, array('id_suffix' => $name));
- }
+ $attributes = $attributes ? $attributes : array();
+ $unselectable = !empty($attributes['unselectable']);
+ unset($attributes['unselectable']);
+ $attributes += array('id_suffix' => $name);
foreach ($values as $key => $var) {
$options[] = $this->createElement('radio', NULL, NULL, $var, $key, $attributes);
}
if ($required) {
$this->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
}
+ if ($unselectable) {
+ $group->setAttribute('unselectable', TRUE);
+ }
return $group;
}
- function addYesNo($id, $title, $dontKnow = NULL, $required = NULL, $attribute = NULL) {
- if (empty($attribute)) {
- $attribute = array('id_suffix' => $id);
- }
- else {
- $attribute = array_merge($attribute, array('id_suffix' => $id));
- }
+ function addYesNo($id, $title, $unselectable = FALSE, $required = NULL, $attributes = array()) {
+ $attributes += array('id_suffix' => $id);
$choice = array();
- $choice[] = $this->createElement('radio', NULL, '11', ts('Yes'), '1', $attribute);
- $choice[] = $this->createElement('radio', NULL, '11', ts('No'), '0', $attribute);
- if ($dontKnow) {
- $choice[] = $this->createElement('radio', NULL, '22', ts("Don't Know"), '2', $attribute);
- }
- $this->addGroup($choice, $id, $title);
+ $choice[] = $this->createElement('radio', NULL, '11', ts('Yes'), '1', $attributes);
+ $choice[] = $this->createElement('radio', NULL, '11', ts('No'), '0', $attributes);
+ $group = $this->addGroup($choice, $id, $title);
+ if ($unselectable) {
+ $group->setAttribute('unselectable', TRUE);
+ }
if ($required) {
$this->addRule($id, ts('%1 is a required field.', array(1 => $title)), 'required');
}
}
}
- function addSelect($name, $label, $prefix = NULL, $required = NULL, $extra = NULL, $select = '- select -') {
- if ($prefix) {
- $this->addElement('select', $name . '_id' . $prefix, $label,
- array(
- '' => $select) + CRM_Core_OptionGroup::values($name), $extra
- );
- if ($required) {
- $this->addRule($name . '_id' . $prefix, ts('Please select %1', array(1 => $label)), 'required');
- }
+ /**
+ * 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
+ * - 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
+ * @param bool $required
+ * @throws CRM_Core_Exception
+ * @return HTML_QuickForm_Element
+ */
+ function addSelect($name, $props = array(), $required = FALSE) {
+ if (!isset($props['entity'])) {
+ $props['entity'] = CRM_Utils_Api::getEntityName($this);
+ }
+ if (!isset($props['field'])) {
+ $props['field'] = strrpos($name, '[') ? rtrim(substr($name, 1 + strrpos($name, '[')), ']') : $name;
+ }
+ $info = civicrm_api3($props['entity'], 'getoptions', array(
+ 'field' => $props['field'],
+ 'options' => array('metadata' => array('fields'))
+ )
+ );
+ $options = $info['values'];
+ if (!array_key_exists('placeholder', $props)) {
+ $props['placeholder'] = $required ? ts('- select -') : ts('- none -');
+ }
+ if ($props['placeholder'] !== NULL && empty($props['multiple'])) {
+ $options = array('' => '') + $options;
}
+ // 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);
+ }
+ // Core field
else {
- $this->addElement('select', $name . '_id', $label,
- array(
- '' => $select) + CRM_Core_OptionGroup::values($name), $extra
- );
- if ($required) {
- $this->addRule($name . '_id', ts('Please select %1', array(1 => $label)), 'required');
+ foreach($info['metadata']['fields'] as $uniqueName => $fieldSpec) {
+ if (
+ $uniqueName === $props['field'] ||
+ CRM_Utils_Array::value('name', $fieldSpec) === $props['field'] ||
+ in_array($props['field'], CRM_Utils_Array::value('api.aliases', $fieldSpec, array()))
+ ) {
+ break;
+ }
}
+ $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);
}
+ $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');
+ return $this->add('select', $name, $label, $options, $required, $props);
}
/**
}
}
- function buildAddressBlock($locationId, $title, $phone,
- $alternatePhone = NULL, $addressRequired = NULL,
- $phoneRequired = NULL, $altPhoneRequired = NULL,
- $locationName = NULL
- ) {
- if (!$locationName) {
- $locationName = "location";
- }
-
- $config = CRM_Core_Config::singleton();
- $attributes = CRM_Core_DAO::getAttribute('CRM_Core_DAO_Address');
-
- $location[$locationId]['address']['street_address'] = $this->addElement('text', "{$locationName}[$locationId][address][street_address]", $title,
- $attributes['street_address']
- );
- if ($addressRequired) {
- $this->addRule("{$locationName}[$locationId][address][street_address]", ts("Please enter the Street Address for %1.", array(1 => $title)), 'required');
- }
-
- $location[$locationId]['address']['supplemental_address_1'] = $this->addElement('text', "{$locationName}[$locationId][address][supplemental_address_1]", ts('Supplemental Address 1'),
- $attributes['supplemental_address_1']
- );
- $location[$locationId]['address']['supplemental_address_2'] = $this->addElement('text', "{$locationName}[$locationId][address][supplemental_address_2]", ts('Supplemental Address 2'),
- $attributes['supplemental_address_2']
- );
-
- $location[$locationId]['address']['city'] = $this->addElement('text', "{$locationName}[$locationId][address][city]", ts('City'),
- $attributes['city']
- );
- if ($addressRequired) {
- $this->addRule("{$locationName}[$locationId][address][city]", ts("Please enter the City for %1.", array(1 => $title)), 'required');
- }
-
- $location[$locationId]['address']['postal_code'] = $this->addElement('text', "{$locationName}[$locationId][address][postal_code]", ts('Zip / Postal Code'),
- $attributes['postal_code']
- );
- if ($addressRequired) {
- $this->addRule("{$locationName}[$locationId][address][postal_code]", ts("Please enter the Zip/Postal Code for %1.", array(1 => $title)), 'required');
- }
-
- $location[$locationId]['address']['postal_code_suffix'] = $this->addElement('text', "{$locationName}[$locationId][address][postal_code_suffix]", ts('Add-on Code'),
- array('size' => 4, 'maxlength' => 12)
- );
- $this->addRule("{$locationName}[$locationId][address][postal_code_suffix]", ts('Zip-Plus not valid.'), 'positiveInteger');
-
- if ($config->includeCounty) {
- $location[$locationId]['address']['county_id'] = $this->addElement('select', "{$locationName}[$locationId][address][county_id]", ts('County'),
- array('' => ts('- select -')) + CRM_Core_PseudoConstant::county()
- );
- }
-
- $location[$locationId]['address']['state_province_id'] = $this->addElement('select', "{$locationName}[$locationId][address][state_province_id]", ts('State / Province'),
- array('' => ts('- select -')) + CRM_Core_PseudoConstant::stateProvince()
- );
-
- $location[$locationId]['address']['country_id'] = $this->addElement('select', "{$locationName}[$locationId][address][country_id]", ts('Country'),
- array('' => ts('- select -')) + CRM_Core_PseudoConstant::country()
- );
- if ($addressRequired) {
- $this->addRule("{$locationName}[$locationId][address][country_id]", ts("Please select the Country for %1.", array(1 => $title)), 'required');
- }
-
-
- if ($phone) {
- $location[$locationId]['phone'][1]['phone'] = $this->addElement('text',
- "{$locationName}[$locationId][phone][1][phone]",
- $phone,
- CRM_Core_DAO::getAttribute('CRM_Core_DAO_Phone',
- 'phone'
- )
- );
- if ($phoneRequired) {
- $this->addRule("{$locationName}[$locationId][phone][1][phone]", ts('Please enter a value for %1', array(1 => $phone)), 'required');
- }
- $this->addRule("{$locationName}[$locationId][phone][1][phone]", ts('Please enter a valid number for %1', array(1 => $phone)), 'phone');
- }
-
- if ($alternatePhone) {
- $location[$locationId]['phone'][2]['phone'] = $this->addElement('text',
- "{$locationName}[$locationId][phone][2][phone]",
- $alternatePhone,
- CRM_Core_DAO::getAttribute('CRM_Core_DAO_Phone',
- 'phone'
- )
- );
- if ($alternatePhoneRequired) {
- $this->addRule("{$locationName}[$locationId][phone][2][phone]", ts('Please enter a value for %1', array(1 => $alternatePhone)), 'required');
- }
- $this->addRule("{$locationName}[$locationId][phone][2][phone]", ts('Please enter a valid number for %1', array(1 => $alternatePhone)), 'phone');
- }
- }
-
public function getRootTitle() {
return NULL;
}
*
*/
function addDate($name, $label, $required = FALSE, $attributes = NULL) {
- if (CRM_Utils_Array::value('formatType', $attributes)) {
+ if (!empty($attributes['formatType'])) {
// get actual format
$params = array('name' => $attributes['formatType']);
$values = array();
// cache date information
static $dateFormat;
$key = "dateFormat_" . str_replace(' ', '_', $attributes['formatType']);
- if (!CRM_Utils_Array::value($key, $dateFormat)) {
+ if (empty($dateFormat[$key])) {
CRM_Core_DAO::commonRetrieve('CRM_Core_DAO_PreferencesDate', $params, $values);
$dateFormat[$key] = $values;
}
$attributes['format'] = $values['date_format'];
}
- if (CRM_Utils_Array::value('time_format', $values)) {
+ if (!empty($values['time_format'])) {
$attributes['timeFormat'] = $values['time_format'];
}
$attributes['startOffset'] = $values['start'];
}
$config = CRM_Core_Config::singleton();
- if (!CRM_Utils_Array::value('format', $attributes)) {
+ if (empty($attributes['format'])) {
$attributes['format'] = $config->dateInputFormat;
}
$this->add('text', $name, $label, $attributes);
- if (CRM_Utils_Array::value('addTime', $attributes) ||
- CRM_Utils_Array::value('timeFormat', $attributes)
- ) {
+ if (!empty($attributes['addTime']) || !empty($attributes['timeFormat'])) {
if (!isset($attributes['timeFormat'])) {
$timeFormat = $config->timeInputFormat;
if ($required) {
$this->addRule($name, ts('Please select %1', array(1 => $label)), 'required');
- if (CRM_Utils_Array::value('addTime', $attributes) && CRM_Utils_Array::value('addTimeRequired', $attributes)) {
+ if (!empty($attributes['addTime']) && !empty($attributes['addTimeRequired'])) {
$this->addRule($elementName, ts('Please enter a time.'), 'required');
}
}
$freezeCurrency = FALSE
) {
$currencies = CRM_Core_OptionGroup::values('currencies_enabled');
+ $options = array('class' => 'crm-select2 eight');
if (!$required) {
- $currencies = array(
- '' => ts('- select -')) + $currencies;
+ $currencies = array('' => '') + $currencies;
+ $options['placeholder'] = ts('- none -');
}
- $ele = $this->add('select', $name, $label, $currencies, $required);
+ $ele = $this->add('select', $name, $label, $currencies, $required, $options);
if ($freezeCurrency) {
$ele->freeze();
}
$this->setDefaults(array($name => $defaultCurrency));
}
+ /**
+ * 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?
+ * 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
+ * - api - array of settings for the getlist api
+ * - 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) {
+ $config = CRM_Core_Config::singleton();
+ // Default properties
+ $props['api'] = CRM_Utils_Array::value('api', $props, array());
+ $props['entity'] = CRM_Utils_Array::value('entity', $props, 'contact');
+
+ $props['class'] = isset($props['class']) ? $props['class'] . ' ' : '';
+ $props['class'] .= "crm-select2 crm-form-entityref";
+
+ if ($props['entity'] == 'contact' && isset($props['create']) && !(CRM_Core_Permission::check('edit all contacts') || CRM_Core_Permission::check('add contacts'))) {
+ unset($props['create']);
+ }
+ // Convenient shortcut to passing in array create links
+ if ($props['entity'] == 'contact' && isset($props['create']) && $props['create'] === TRUE) {
+ if (empty($props['api']['params']['contact_type'])) {
+ $props['create'] = CRM_Core_BAO_UFGroup::getCreateLinks(array('new_individual', 'new_organization', 'new_household'));
+ }
+ else {
+ $props['create'] = CRM_Core_BAO_UFGroup::getCreateLinks('new_' . strtolower($props['api']['params']['contact_type']));
+ }
+ }
+
+ $defaults = array(
+ 'minimumInputLength' => 1,
+ 'multiple' => !empty($props['multiple']),
+ 'placeholder' => CRM_Utils_Array::value('placeholder', $props, $required ? ts('- select %1 -', array(1 => ts($props['entity']))) : ts('- none -')),
+ 'allowClear' => !$required,
+ );
+ if ($props['entity'] == 'contact') {
+ $defaults['formatInputTooShort'] = $config->includeEmailInName ? ts('Start typing a name or email...') : ts('Start typing a name...');
+ }
+ $props['select'] = CRM_Utils_Array::value('select', $props, array()) + $defaults;
+
+ $this->formatReferenceFieldAttributes($props);
+ return $this->add('text', $name, $label, $props, $required);
+ }
+
+ /**
+ * @param $props
+ */
+ private function formatReferenceFieldAttributes(&$props) {
+ $props['data-select-params'] = json_encode($props['select']);
+ $props['data-api-params'] = $props['api'] ? json_encode($props['api']) : NULL;
+ $props['data-api-entity'] = $props['entity'];
+ if (!empty($props['create'])) {
+ $props['data-create-links'] = json_encode($props['create']);
+ }
+ CRM_Utils_Array::remove($props, 'multiple', 'select', 'api', 'entity', 'placeholder', 'create');
+ }
+
/**
* Convert all date fields within the params to mysql date ready for the
* BAO layer. In this case fields are checked against the $_datefields defined for the form
// event form stores as an indexed array, contribution form not so much...
$tempID = $this->_params[0]['select_contact_id'];
}
+
// force to ignore the authenticated user
- if ($tempID === '0') {
+ if ($tempID === '0' || $tempID === 0) {
+ // we set the cid on the form so that this will be retained for the Confirm page
+ // in the multi-page form & prevent us returning the $userID when this is called
+ // 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;
}